From 6576640b55777bd811a12a188b9b1f3c63653799 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 27 Mar 2013 09:15:23 -0700 Subject: [PATCH 1/1] Imported Upstream version 2.0.19 --- ABOUT-NLS | 1068 ++ AUTHORS | 180 + COPYING | 676 + COPYING.LIB | 165 + ChangeLog | 140 + ChangeLog-2011 | 1207 ++ INSTALL | 234 + Makefile.am | 104 + Makefile.in | 928 + NEWS | 823 + README | 151 + README.SVN | 51 + THANKS | 294 + TODO | 118 + VERSION | 1 + acinclude.m4 | 308 + aclocal.m4 | 1239 ++ agent/ChangeLog-2011 | 2617 +++ agent/Makefile.am | 110 + agent/Makefile.in | 1164 ++ agent/agent.h | 373 + agent/cache.c | 340 + agent/call-pinentry.c | 1178 ++ agent/call-scd.c | 1167 ++ agent/command-ssh.c | 3089 ++++ agent/command.c | 2073 +++ agent/divert-scd.c | 451 + agent/findkey.c | 952 + agent/genkey.c | 484 + agent/gpg-agent.c | 2291 +++ agent/learncard.c | 472 + agent/minip12.c | 2360 +++ agent/minip12.h | 36 + agent/pkdecrypt.c | 151 + agent/pksign.c | 261 + agent/preset-passphrase.c | 270 + agent/protect-tool.c | 1271 ++ agent/protect.c | 1321 ++ agent/t-protect.c | 310 + agent/trans.c | 41 + agent/trustlist.c | 763 + am/cmacros.am | 55 + autogen.sh | 243 + common/ChangeLog-2011 | 1638 ++ common/Makefile.am | 142 + common/Makefile.in | 2035 +++ common/README | 11 + common/asshelp.c | 457 + common/asshelp.h | 50 + common/audit-events.h | 114 + common/audit.c | 1324 ++ common/audit.h | 224 + common/b64dec.c | 217 + common/b64enc.c | 351 + common/common-defs.h | 33 + common/convert.c | 249 + common/dns-cert.c | 342 + common/dns-cert.h | 26 + common/estream-printf.c | 1788 ++ common/estream-printf.h | 110 + common/estream.c | 3687 ++++ common/estream.h | 379 + common/exaudit.awk | 43 + common/exechelp.c | 1033 ++ common/exechelp.h | 97 + common/exstatus.awk | 40 + common/gc-opt-flags.h | 40 + common/get-passphrase.c | 262 + common/get-passphrase.h | 45 + common/gettime.c | 592 + common/gpgrlhelp.c | 91 + common/helpfile.c | 262 + common/homedir.c | 449 + common/http.c | 2068 +++ common/http.h | 116 + common/i18n.c | 107 + common/i18n.h | 47 + common/init.c | 71 + common/init.h | 26 + common/iobuf.c | 2595 +++ common/iobuf.h | 162 + common/keyserver.h | 42 + common/localename.c | 116 + common/membuf.c | 118 + common/membuf.h | 47 + common/miscellaneous.c | 241 + common/mkstrtable.awk | 185 + common/openpgpdefs.h | 87 + common/percent.c | 229 + common/pka.c | 323 + common/pka.h | 25 + common/session-env.c | 385 + common/session-env.h | 43 + common/sexp-parse.h | 128 + common/sexputil.c | 429 + common/signal.c | 262 + common/simple-pwquery.c | 690 + common/simple-pwquery.h | 115 + common/srv.c | 321 + common/srv.h | 49 + common/ssh-utils.c | 187 + common/ssh-utils.h | 36 + common/status-codes.h | 206 + common/status.c | 66 + common/status.h | 137 + common/sysutils.c | 492 + common/sysutils.h | 59 + common/t-b64.c | 182 + common/t-convert.c | 461 + common/t-exechelp.c | 188 + common/t-gettime.c | 103 + common/t-helpfile.c | 67 + common/t-percent.c | 115 + common/t-session-env.c | 294 + common/t-sexputil.c | 192 + common/t-ssh-utils.c | 233 + common/t-sysutils.c | 85 + common/tlv.c | 305 + common/tlv.h | 113 + common/ttyio.c | 690 + common/ttyio.h | 63 + common/util.h | 333 + common/xasprintf.c | 62 + common/xreadline.c | 117 + common/yesno.c | 141 + config.h.in | 891 + configure | 17748 +++++++++++++++++++ configure.ac | 1544 ++ doc/ChangeLog-2011 | 798 + doc/DETAILS | 1299 ++ doc/FAQ | 13 + doc/HACKING | 200 + doc/KEYSERVER | 83 + doc/Makefile.am | 150 + doc/Makefile.in | 1029 ++ doc/OpenPGP | 108 + doc/TRANSLATE | 62 + doc/com-certs.pem | 484 + doc/contrib.texi | 106 + doc/debugging.texi | 277 + doc/examples/README | 9 + doc/examples/gpgconf.conf | 63 + doc/examples/pwpattern.list | 48 + doc/examples/scd-event | 102 + doc/examples/trustlist.txt | 66 + doc/glossary.texi | 72 + doc/gnupg-card-architecture.eps | 1003 ++ doc/gnupg-card-architecture.fig | 419 + doc/gnupg-card-architecture.pdf | Bin 0 -> 19685 bytes doc/gnupg-card-architecture.png | Bin 0 -> 15022 bytes doc/gnupg-logo.eps | 2704 +++ doc/gnupg-logo.pdf | Bin 0 -> 11736 bytes doc/gnupg-logo.png | Bin 0 -> 8988 bytes doc/gnupg.info | 178 + doc/gnupg.info-1 | 7752 ++++++++ doc/gnupg.info-2 | 2125 +++ doc/gnupg.texi | 222 + doc/gnupg7.texi | 31 + doc/gpg-agent.texi | 1386 ++ doc/gpg.texi | 3394 ++++ doc/gpgsm.texi | 1458 ++ doc/gpgv.texi | 163 + doc/gpl.texi | 725 + doc/help.be.txt | 286 + doc/help.ca.txt | 286 + doc/help.cs.txt | 286 + doc/help.da.txt | 286 + doc/help.de.txt | 279 + doc/help.el.txt | 286 + doc/help.eo.txt | 286 + doc/help.es.txt | 251 + doc/help.et.txt | 286 + doc/help.fi.txt | 256 + doc/help.fr.txt | 256 + doc/help.gl.txt | 286 + doc/help.hu.txt | 257 + doc/help.id.txt | 251 + doc/help.it.txt | 251 + doc/help.ja.txt | 286 + doc/help.nb.txt | 286 + doc/help.pl.txt | 250 + doc/help.pt.txt | 253 + doc/help.pt_BR.txt | 253 + doc/help.ro.txt | 251 + doc/help.ru.txt | 250 + doc/help.sk.txt | 254 + doc/help.sv.txt | 286 + doc/help.tr.txt | 242 + doc/help.txt | 372 + doc/help.zh_CN.txt | 233 + doc/help.zh_TW.txt | 245 + doc/howto-create-a-server-cert.texi | 288 + doc/howtos.texi | 15 + doc/instguide.texi | 91 + doc/opt-homedir.texi | 10 + doc/qualified.txt | 243 + doc/samplekeys.asc | 939 + doc/scdaemon.texi | 731 + doc/see-also-note.texi | 14 + doc/specify-user-id.texi | 171 + doc/stamp-vti | 4 + doc/sysnotes.texi | 86 + doc/texi.css | 6 + doc/tools.texi | 1899 ++ doc/version.texi | 4 + doc/yat2m.c | 1360 ++ g10/ChangeLog-2011 | 11041 ++++++++++++ g10/Makefile.am | 141 + g10/Makefile.in | 962 + g10/armor.c | 1498 ++ g10/build-packet.c | 1362 ++ g10/call-agent.c | 1369 ++ g10/call-agent.h | 145 + g10/card-util.c | 1996 +++ g10/cipher.c | 163 + g10/compress-bz2.c | 253 + g10/compress.c | 351 + g10/cpr.c | 526 + g10/dearmor.c | 134 + g10/decrypt.c | 199 + g10/delkey.c | 219 + g10/encode.c | 912 + g10/encr-data.c | 373 + g10/exec.c | 624 + g10/exec.h | 51 + g10/export.c | 756 + g10/filter.h | 163 + g10/free-packet.c | 567 + g10/getkey.c | 3156 ++++ g10/gpg.c | 4368 +++++ g10/gpg.h | 122 + g10/gpgv.c | 537 + g10/helptext.c | 88 + g10/import.c | 2525 +++ g10/kbnode.c | 398 + g10/keydb.c | 828 + g10/keydb.h | 317 + g10/keyedit.c | 5271 ++++++ g10/keygen.c | 4316 +++++ g10/keyid.c | 831 + g10/keylist.c | 1665 ++ g10/keyring.c | 1693 ++ g10/keyring.h | 44 + g10/keyserver-internal.h | 52 + g10/keyserver.c | 2203 +++ g10/main.h | 350 + g10/mainproc.c | 2184 +++ g10/mdfilter.c | 75 + g10/misc.c | 1415 ++ g10/openfile.c | 436 + g10/options.h | 361 + g10/options.skel | 206 + g10/packet.h | 514 + g10/parse-packet.c | 2569 +++ g10/passphrase.c | 685 + g10/photoid.c | 375 + g10/photoid.h | 33 + g10/pkclist.c | 1531 ++ g10/pkglue.c | 341 + g10/pkglue.h | 34 + g10/plaintext.c | 663 + g10/progress.c | 159 + g10/pubkey-enc.c | 357 + g10/revoke.c | 736 + g10/rmd160.c | 425 + g10/rmd160.h | 24 + g10/seckey-cert.c | 473 + g10/server.c | 609 + g10/seskey.c | 282 + g10/sig-check.c | 666 + g10/sign.c | 1575 ++ g10/skclist.c | 256 + g10/t-rmd160.c | 92 + g10/tdbdump.c | 234 + g10/tdbio.c | 1516 ++ g10/tdbio.h | 118 + g10/textfilter.c | 250 + g10/trustdb.c | 2503 +++ g10/trustdb.h | 97 + g10/verify.c | 278 + gl/Makefile.am | 145 + gl/Makefile.in | 640 + gl/alloca_.h | 53 + gl/allocsa.c | 136 + gl/allocsa.h | 127 + gl/allocsa.valgrind | 7 + gl/m4/absolute-header.m4 | 44 + gl/m4/alloca.m4 | 42 + gl/m4/allocsa.m4 | 15 + gl/m4/eealloc.m4 | 32 + gl/m4/gnulib-comp.m4 | 82 + gl/m4/gnulib-tool.m4 | 33 + gl/m4/mkdtemp.m4 | 22 + gl/m4/setenv.m4 | 68 + gl/m4/stdint.m4 | 368 + gl/m4/strpbrk.m4 | 16 + gl/m4/unistd_h.m4 | 18 + gl/mkdtemp.c | 208 + gl/mkdtemp.h | 31 + gl/setenv.c | 327 + gl/setenv.h | 53 + gl/size_max.h | 30 + gl/stdint_.h | 491 + gl/strpbrk.c | 41 + gl/strpbrk.h | 27 + gl/unsetenv.c | 91 + gl/xsize.h | 107 + include/ChangeLog-2011 | 444 + include/Makefile.am | 1 + include/Makefile.in | 445 + include/_regex.h | 574 + include/cipher.h | 110 + include/host2net.h | 42 + include/types.h | 134 + jnlib/ChangeLog-2011 | 709 + jnlib/Makefile.am | 70 + jnlib/Makefile.in | 727 + jnlib/README | 8 + jnlib/argparse.c | 1205 ++ jnlib/argparse.h | 183 + jnlib/dotlock.c | 697 + jnlib/dotlock.h | 33 + jnlib/dynload.h | 72 + jnlib/libjnlib-config.h | 84 + jnlib/logging.c | 651 + jnlib/logging.h | 88 + jnlib/mischelp.c | 133 + jnlib/mischelp.h | 98 + jnlib/stringhelp.c | 1141 ++ jnlib/stringhelp.h | 136 + jnlib/strlist.c | 185 + jnlib/strlist.h | 49 + jnlib/t-stringhelp.c | 414 + jnlib/t-support.c | 143 + jnlib/t-support.h | 50 + jnlib/types.h | 114 + jnlib/utf8conv.c | 738 + jnlib/utf8conv.h | 41 + jnlib/w32-afunix.c | 137 + jnlib/w32-afunix.h | 49 + jnlib/w32-gettext.c | 1703 ++ jnlib/w32-reg.c | 182 + jnlib/w32help.h | 41 + kbx/ChangeLog-2011 | 349 + kbx/Makefile.am | 53 + kbx/Makefile.in | 657 + kbx/kbxutil.c | 594 + kbx/keybox-blob.c | 1047 ++ kbx/keybox-defs.h | 261 + kbx/keybox-dump.c | 699 + kbx/keybox-file.c | 163 + kbx/keybox-init.c | 202 + kbx/keybox-openpgp.c | 508 + kbx/keybox-search-desc.h | 73 + kbx/keybox-search.c | 1031 ++ kbx/keybox-update.c | 720 + kbx/keybox-util.c | 71 + kbx/keybox.h | 119 + kbx/mkerrors | 70 + keyserver/ChangeLog-2011 | 1349 ++ keyserver/Makefile.am | 86 + keyserver/Makefile.in | 1076 ++ keyserver/curl-shim.c | 382 + keyserver/curl-shim.h | 111 + keyserver/gpg2keys_mailto.in | 211 + keyserver/gpg2keys_test.in | 97 + keyserver/gpgkeys_curl.c | 419 + keyserver/gpgkeys_finger.c | 500 + keyserver/gpgkeys_hkp.c | 977 + keyserver/gpgkeys_kdns.c | 444 + keyserver/gpgkeys_ldap.c | 2379 +++ keyserver/ksutil.c | 622 + keyserver/ksutil.h | 149 + keyserver/no-libgcrypt.c | 107 + m4/ChangeLog-2011 | 159 + m4/Makefile.am | 20 + m4/Makefile.in | 453 + m4/autobuild.m4 | 34 + m4/codeset.m4 | 21 + m4/estream.m4 | 49 + m4/gettext.m4 | 381 + m4/glibc2.m4 | 30 + m4/glibc21.m4 | 30 + m4/gnupg-pth.m4 | 105 + m4/gpg-error.m4 | 65 + m4/iconv.m4 | 180 + m4/intdiv0.m4 | 70 + m4/intl.m4 | 259 + m4/intldir.m4 | 19 + m4/intmax.m4 | 33 + m4/inttypes-pri.m4 | 36 + m4/inttypes.m4 | 27 + m4/inttypes_h.m4 | 26 + m4/isc-posix.m4 | 26 + m4/ksba.m4 | 109 + m4/lcmessage.m4 | 30 + m4/ldap.m4 | 100 + m4/lib-ld.m4 | 110 + m4/lib-link.m4 | 709 + m4/lib-prefix.m4 | 185 + m4/libassuan.m4 | 175 + m4/libcurl.m4 | 239 + m4/libgcrypt.m4 | 108 + m4/libusb.m4 | 69 + m4/lock.m4 | 311 + m4/longdouble.m4 | 31 + m4/nls.m4 | 31 + m4/po.m4 | 449 + m4/printf-posix.m4 | 44 + m4/progtest.m4 | 92 + m4/readline.m4 | 63 + m4/signed.m4 | 17 + m4/size_max.m4 | 62 + m4/socklen.m4 | 52 + m4/stdint_h.m4 | 26 + m4/sys_socket_h.m4 | 23 + m4/tar-ustar.m4 | 43 + m4/uintmax_t.m4 | 30 + m4/visibility.m4 | 52 + m4/wchar_t.m4 | 20 + m4/wint_t.m4 | 20 + m4/xsize.m4 | 13 + po/ChangeLog-2011 | 336 + po/LINGUAS | 30 + po/Makefile.in.in | 429 + po/Makevars | 41 + po/POTFILES.in | 109 + po/Rules-quot | 47 + po/be.gmo | Bin 0 -> 9060 bytes po/be.po | 8531 +++++++++ po/boldquot.sed | 10 + po/ca.gmo | Bin 0 -> 57453 bytes po/ca.po | 10383 +++++++++++ po/cs.gmo | Bin 0 -> 186067 bytes po/cs.po | 9079 ++++++++++ po/da.gmo | Bin 0 -> 14162 bytes po/da.po | 9298 ++++++++++ po/de.gmo | Bin 0 -> 190092 bytes po/de.po | 9034 ++++++++++ po/el.gmo | Bin 0 -> 57433 bytes po/el.po | 10024 +++++++++++ po/en@boldquot.gmo | Bin 0 -> 173263 bytes po/en@boldquot.header | 25 + po/en@boldquot.po | 8373 +++++++++ po/en@quot.gmo | Bin 0 -> 171263 bytes po/en@quot.header | 22 + po/en@quot.po | 8362 +++++++++ po/eo.gmo | Bin 0 -> 38570 bytes po/eo.po | 10135 +++++++++++ po/es.gmo | Bin 0 -> 172779 bytes po/es.po | 10178 +++++++++++ po/et.gmo | Bin 0 -> 54136 bytes po/et.po | 9902 +++++++++++ po/fi.gmo | Bin 0 -> 56808 bytes po/fi.po | 10006 +++++++++++ po/fr.gmo | Bin 0 -> 113512 bytes po/fr.po | 9455 ++++++++++ po/gl.gmo | Bin 0 -> 56225 bytes po/gl.po | 10327 +++++++++++ po/gnupg2.pot | 8085 +++++++++ po/hu.gmo | Bin 0 -> 56243 bytes po/hu.po | 9983 +++++++++++ po/id.gmo | Bin 0 -> 54707 bytes po/id.po | 9984 +++++++++++ po/insert-header.sin | 23 + po/it.gmo | Bin 0 -> 56352 bytes po/it.po | 10018 +++++++++++ po/ja.gmo | Bin 0 -> 91476 bytes po/ja.po | 9453 ++++++++++ po/nb.gmo | Bin 0 -> 79298 bytes po/nb.po | 8824 +++++++++ po/pl.gmo | Bin 0 -> 182381 bytes po/pl.po | 8479 +++++++++ po/pt.gmo | Bin 0 -> 48183 bytes po/pt.po | 9962 +++++++++++ po/pt_BR.gmo | Bin 0 -> 28325 bytes po/pt_BR.po | 10177 +++++++++++ po/quot.sed | 6 + po/remove-potcdate.sin | 19 + po/ro.gmo | Bin 0 -> 108775 bytes po/ro.po | 9850 ++++++++++ po/ru.gmo | Bin 0 -> 199848 bytes po/ru.po | 8427 +++++++++ po/sk.gmo | Bin 0 -> 55493 bytes po/sk.po | 9989 +++++++++++ po/stamp-po | 1 + po/sv.gmo | Bin 0 -> 181397 bytes po/sv.po | 8836 +++++++++ po/tr.gmo | Bin 0 -> 178211 bytes po/tr.po | 8531 +++++++++ po/uk.gmo | Bin 0 -> 245099 bytes po/uk.po | 8541 +++++++++ po/zh_CN.gmo | Bin 0 -> 111017 bytes po/zh_CN.po | 9056 ++++++++++ po/zh_TW.gmo | Bin 0 -> 170841 bytes po/zh_TW.po | 8907 ++++++++++ scd/ChangeLog-2011 | 2427 +++ scd/Makefile.am | 71 + scd/Makefile.in | 763 + scd/apdu.c | 3543 ++++ scd/apdu.h | 140 + scd/app-common.h | 228 + scd/app-dinsig.c | 574 + scd/app-geldkarte.c | 409 + scd/app-help.c | 182 + scd/app-nks.c | 1420 ++ scd/app-openpgp.c | 3813 ++++ scd/app-p15.c | 3423 ++++ scd/app.c | 981 + scd/ccid-driver.c | 3490 ++++ scd/ccid-driver.h | 109 + scd/command.c | 2327 +++ scd/iso7816.c | 873 + scd/iso7816.h | 123 + scd/pcsc-wrapper.c | 848 + scd/scdaemon.c | 1318 ++ scd/scdaemon.h | 132 + scripts/ChangeLog-2011 | 52 + scripts/compile | 141 + scripts/config.guess | 1530 ++ scripts/config.rpath | 666 + scripts/config.sub | 1773 ++ scripts/depcomp | 582 + scripts/install-sh | 507 + scripts/mdate-sh | 199 + scripts/missing | 365 + scripts/mkinstalldirs | 161 + scripts/texinfo.tex | 8638 +++++++++ sm/ChangeLog-2011 | 2705 +++ sm/Makefile.am | 71 + sm/Makefile.in | 711 + sm/base64.c | 733 + sm/call-agent.c | 1069 ++ sm/call-dirmngr.c | 1126 ++ sm/certchain.c | 2044 +++ sm/certcheck.c | 439 + sm/certdump.c | 974 + sm/certlist.c | 555 + sm/certreqgen-ui.c | 415 + sm/certreqgen.c | 884 + sm/decrypt.c | 586 + sm/delete.c | 182 + sm/encrypt.c | 513 + sm/export.c | 749 + sm/fingerprint.c | 347 + sm/gpgsm.c | 2181 +++ sm/gpgsm.h | 423 + sm/import.c | 807 + sm/keydb.c | 1535 ++ sm/keydb.h | 86 + sm/keylist.c | 1562 ++ sm/misc.c | 89 + sm/qualified.c | 321 + sm/server.c | 1464 ++ sm/sign.c | 780 + sm/verify.c | 660 + tests/ChangeLog-2011 | 142 + tests/Makefile.am | 75 + tests/Makefile.in | 845 + tests/asschk.c | 1092 ++ tests/inittests | 99 + tests/openpgp/ChangeLog-2011 | 379 + tests/openpgp/Makefile.am | 124 + tests/openpgp/Makefile.in | 660 + tests/openpgp/armdetach.test | 19 + tests/openpgp/armdetachm.test | 17 + tests/openpgp/armencrypt.test | 19 + tests/openpgp/armencryptp.test | 20 + tests/openpgp/armor.test | 764 + tests/openpgp/armsignencrypt.test | 21 + tests/openpgp/armsigs.test | 19 + tests/openpgp/bug537-test.data.asc | 960 + tests/openpgp/bug894-test.asc | 565 + tests/openpgp/clearsig.test | 110 + tests/openpgp/conventional-mdc.test | 30 + tests/openpgp/conventional.test | 29 + tests/openpgp/decrypt-dsa.test | 18 + tests/openpgp/decrypt.test | 18 + tests/openpgp/defs.inc | 193 + tests/openpgp/detach.test | 18 + tests/openpgp/detachm.test | 17 + tests/openpgp/encrypt-dsa.test | 29 + tests/openpgp/encrypt.test | 28 + tests/openpgp/encryptp.test | 18 + tests/openpgp/genkey1024.test | 39 + tests/openpgp/gpg-agent.conf.tmpl | 2 + tests/openpgp/gpg.conf.tmpl | 5 + tests/openpgp/import.test | 26 + tests/openpgp/mds.test | 77 + tests/openpgp/mkdemodirs | 41 + tests/openpgp/multisig.test | 154 + tests/openpgp/plain-1-pgp.asc | 27 + tests/openpgp/plain-1.asc | 26 + tests/openpgp/plain-1o.asc | 28 + tests/openpgp/plain-2.asc | 31 + tests/openpgp/plain-2o.asc | 36 + tests/openpgp/plain-3.asc | 13 + tests/openpgp/plain-3o.asc | 10 + tests/openpgp/pubdemo.asc | 566 + tests/openpgp/pubring.asc | 720 + tests/openpgp/pubring.pkr.asc | 28 + tests/openpgp/seat.test | 19 + tests/openpgp/secdemo.asc | 737 + tests/openpgp/secring.asc | 73 + tests/openpgp/secring.skr.asc | 27 + tests/openpgp/signdemokey | 16 + tests/openpgp/signencrypt-dsa.test | 30 + tests/openpgp/signencrypt.test | 34 + tests/openpgp/sigs-dsa.test | 30 + tests/openpgp/sigs.test | 45 + tests/openpgp/verify.test | 260 + tests/openpgp/version.test | 17 + tests/pkits/ChangeLog-2011 | 71 + tests/pkits/Makefile.am | 75 + tests/pkits/Makefile.in | 607 + tests/pkits/README | 37 + tests/pkits/basic-certificate-revocation | 31 + tests/pkits/certificate-policies | 31 + tests/pkits/common.sh | 275 + tests/pkits/delta-crls | 31 + tests/pkits/distribution-points | 31 + tests/pkits/import-all-certs | 58 + tests/pkits/import-all-certs.data | 471 + tests/pkits/inhibit-any-policy | 31 + tests/pkits/inhibit-policy-mapping | 31 + tests/pkits/inittests | 108 + tests/pkits/key-usage | 28 + tests/pkits/name-constraints | 31 + tests/pkits/policy-mappings | 31 + tests/pkits/private-certificate-extensions | 31 + tests/pkits/require-explicit-policy | 31 + tests/pkits/runtest | 4 + tests/pkits/signature-verification | 167 + tests/pkits/validate-all-certs | 59 + tests/pkits/validity-periods | 218 + tests/pkits/verifying-basic-constraints | 31 + tests/pkits/verifying-name-chaining | 31 + tests/pkits/verifying-paths-self-issued | 31 + tests/runtest | 4 + .../32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key | 18 + tests/samplekeys/cert_g10code_pete1.pem | 24 + tests/samplekeys/cert_g10code_test1.pem | 19 + tests/samplekeys/cert_g10code_theo1.pem | 40 + 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.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-2011 | 1098 ++ tools/Makefile.am | 121 + tools/Makefile.in | 1078 ++ tools/Manifest | 6 + tools/addgnupghome | 122 + tools/applygnupgdefaults | 82 + tools/ccidmon.c | 879 + tools/clean-sat.c | 36 + tools/convert-from-106 | 55 + tools/gpg-check-pattern.c | 503 + tools/gpg-connect-agent.c | 2228 +++ tools/gpg-zip.in | 140 + tools/gpgconf-comp.c | 3623 ++++ tools/gpgconf.c | 348 + tools/gpgconf.h | 80 + tools/gpgkey2ssh.c | 306 + tools/gpgparsemail.c | 809 + tools/gpgsm-gencert.sh | 203 + tools/gpgsplit.c | 882 + tools/gpgtar-create.c | 903 + tools/gpgtar-extract.c | 349 + tools/gpgtar-list.c | 332 + tools/gpgtar.c | 538 + tools/gpgtar.h | 132 + tools/lspgpot | 27 + tools/mail-signed-keys | 114 + tools/make-dns-cert.c | 247 + tools/mk-tdata.c | 69 + tools/no-libgcrypt.c | 144 + tools/rfc822parse.c | 1256 ++ tools/rfc822parse.h | 79 + tools/sockprox.c | 550 + tools/symcryptrun.c | 1027 ++ tools/watchgnupg.c | 392 + 687 files changed, 620406 insertions(+) create mode 100644 ABOUT-NLS create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 ChangeLog-2011 create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 README.SVN create mode 100644 THANKS create mode 100644 TODO create mode 100644 VERSION create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100644 agent/ChangeLog-2011 create mode 100644 agent/Makefile.am create mode 100644 agent/Makefile.in create mode 100644 agent/agent.h create mode 100644 agent/cache.c create mode 100644 agent/call-pinentry.c create mode 100644 agent/call-scd.c create mode 100644 agent/command-ssh.c create mode 100644 agent/command.c create mode 100644 agent/divert-scd.c create mode 100644 agent/findkey.c create mode 100644 agent/genkey.c create mode 100644 agent/gpg-agent.c create mode 100644 agent/learncard.c create mode 100644 agent/minip12.c create mode 100644 agent/minip12.h create mode 100644 agent/pkdecrypt.c create mode 100644 agent/pksign.c create mode 100644 agent/preset-passphrase.c create mode 100644 agent/protect-tool.c create mode 100644 agent/protect.c create mode 100644 agent/t-protect.c create mode 100644 agent/trans.c create mode 100644 agent/trustlist.c create mode 100644 am/cmacros.am create mode 100755 autogen.sh create mode 100644 common/ChangeLog-2011 create mode 100644 common/Makefile.am create mode 100644 common/Makefile.in create mode 100644 common/README create mode 100644 common/asshelp.c create mode 100644 common/asshelp.h create mode 100644 common/audit-events.h create mode 100644 common/audit.c create mode 100644 common/audit.h create mode 100644 common/b64dec.c create mode 100644 common/b64enc.c create mode 100644 common/common-defs.h create mode 100644 common/convert.c create mode 100644 common/dns-cert.c create mode 100644 common/dns-cert.h create mode 100644 common/estream-printf.c create mode 100644 common/estream-printf.h create mode 100644 common/estream.c create mode 100644 common/estream.h create mode 100644 common/exaudit.awk create mode 100644 common/exechelp.c create mode 100644 common/exechelp.h create mode 100644 common/exstatus.awk create mode 100644 common/gc-opt-flags.h create mode 100644 common/get-passphrase.c create mode 100644 common/get-passphrase.h create mode 100644 common/gettime.c create mode 100644 common/gpgrlhelp.c create mode 100644 common/helpfile.c create mode 100644 common/homedir.c create mode 100644 common/http.c create mode 100644 common/http.h create mode 100644 common/i18n.c create mode 100644 common/i18n.h create mode 100644 common/init.c create mode 100644 common/init.h create mode 100644 common/iobuf.c create mode 100644 common/iobuf.h create mode 100644 common/keyserver.h create mode 100644 common/localename.c create mode 100644 common/membuf.c create mode 100644 common/membuf.h create mode 100644 common/miscellaneous.c create mode 100644 common/mkstrtable.awk create mode 100644 common/openpgpdefs.h create mode 100644 common/percent.c create mode 100644 common/pka.c create mode 100644 common/pka.h create mode 100644 common/session-env.c create mode 100644 common/session-env.h create mode 100644 common/sexp-parse.h create mode 100644 common/sexputil.c create mode 100644 common/signal.c create mode 100644 common/simple-pwquery.c create mode 100644 common/simple-pwquery.h create mode 100644 common/srv.c create mode 100644 common/srv.h create mode 100644 common/ssh-utils.c create mode 100644 common/ssh-utils.h create mode 100644 common/status-codes.h create mode 100644 common/status.c create mode 100644 common/status.h create mode 100644 common/sysutils.c create mode 100644 common/sysutils.h create mode 100644 common/t-b64.c create mode 100644 common/t-convert.c create mode 100644 common/t-exechelp.c create mode 100644 common/t-gettime.c create mode 100644 common/t-helpfile.c create mode 100644 common/t-percent.c create mode 100644 common/t-session-env.c create mode 100644 common/t-sexputil.c create mode 100644 common/t-ssh-utils.c create mode 100644 common/t-sysutils.c create mode 100644 common/tlv.c create mode 100644 common/tlv.h create mode 100644 common/ttyio.c create mode 100644 common/ttyio.h create mode 100644 common/util.h create mode 100644 common/xasprintf.c create mode 100644 common/xreadline.c create mode 100644 common/yesno.c create mode 100644 config.h.in create mode 100755 configure create mode 100644 configure.ac create mode 100644 doc/ChangeLog-2011 create mode 100644 doc/DETAILS create mode 100644 doc/FAQ create mode 100644 doc/HACKING create mode 100644 doc/KEYSERVER create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/OpenPGP create mode 100644 doc/TRANSLATE create mode 100644 doc/com-certs.pem create mode 100644 doc/contrib.texi create mode 100644 doc/debugging.texi create mode 100644 doc/examples/README create mode 100644 doc/examples/gpgconf.conf create mode 100644 doc/examples/pwpattern.list create mode 100755 doc/examples/scd-event create mode 100644 doc/examples/trustlist.txt create mode 100644 doc/glossary.texi create mode 100644 doc/gnupg-card-architecture.eps create mode 100644 doc/gnupg-card-architecture.fig create mode 100644 doc/gnupg-card-architecture.pdf create mode 100644 doc/gnupg-card-architecture.png create mode 100644 doc/gnupg-logo.eps create mode 100644 doc/gnupg-logo.pdf create mode 100644 doc/gnupg-logo.png create mode 100644 doc/gnupg.info create mode 100644 doc/gnupg.info-1 create mode 100644 doc/gnupg.info-2 create mode 100644 doc/gnupg.texi create mode 100644 doc/gnupg7.texi create mode 100644 doc/gpg-agent.texi create mode 100644 doc/gpg.texi create mode 100644 doc/gpgsm.texi create mode 100644 doc/gpgv.texi create mode 100644 doc/gpl.texi create mode 100644 doc/help.be.txt create mode 100644 doc/help.ca.txt create mode 100644 doc/help.cs.txt create mode 100644 doc/help.da.txt create mode 100644 doc/help.de.txt create mode 100644 doc/help.el.txt create mode 100644 doc/help.eo.txt create mode 100644 doc/help.es.txt create mode 100644 doc/help.et.txt create mode 100644 doc/help.fi.txt create mode 100644 doc/help.fr.txt create mode 100644 doc/help.gl.txt create mode 100644 doc/help.hu.txt create mode 100644 doc/help.id.txt create mode 100644 doc/help.it.txt create mode 100644 doc/help.ja.txt create mode 100644 doc/help.nb.txt create mode 100644 doc/help.pl.txt create mode 100644 doc/help.pt.txt create mode 100644 doc/help.pt_BR.txt create mode 100644 doc/help.ro.txt create mode 100644 doc/help.ru.txt create mode 100644 doc/help.sk.txt create mode 100644 doc/help.sv.txt create mode 100644 doc/help.tr.txt create mode 100644 doc/help.txt create mode 100644 doc/help.zh_CN.txt create mode 100644 doc/help.zh_TW.txt create mode 100644 doc/howto-create-a-server-cert.texi create mode 100644 doc/howtos.texi create mode 100644 doc/instguide.texi create mode 100644 doc/opt-homedir.texi create mode 100644 doc/qualified.txt create mode 100644 doc/samplekeys.asc create mode 100644 doc/scdaemon.texi create mode 100644 doc/see-also-note.texi create mode 100644 doc/specify-user-id.texi create mode 100644 doc/stamp-vti create mode 100644 doc/sysnotes.texi create mode 100644 doc/texi.css create mode 100644 doc/tools.texi create mode 100644 doc/version.texi create mode 100644 doc/yat2m.c create mode 100644 g10/ChangeLog-2011 create mode 100644 g10/Makefile.am create mode 100644 g10/Makefile.in create mode 100644 g10/armor.c create mode 100644 g10/build-packet.c create mode 100644 g10/call-agent.c create mode 100644 g10/call-agent.h create mode 100644 g10/card-util.c create mode 100644 g10/cipher.c create mode 100644 g10/compress-bz2.c create mode 100644 g10/compress.c create mode 100644 g10/cpr.c create mode 100644 g10/dearmor.c create mode 100644 g10/decrypt.c create mode 100644 g10/delkey.c create mode 100644 g10/encode.c create mode 100644 g10/encr-data.c create mode 100644 g10/exec.c create mode 100644 g10/exec.h create mode 100644 g10/export.c create mode 100644 g10/filter.h create mode 100644 g10/free-packet.c create mode 100644 g10/getkey.c create mode 100644 g10/gpg.c create mode 100644 g10/gpg.h create mode 100644 g10/gpgv.c create mode 100644 g10/helptext.c create mode 100644 g10/import.c create mode 100644 g10/kbnode.c create mode 100644 g10/keydb.c create mode 100644 g10/keydb.h create mode 100644 g10/keyedit.c create mode 100644 g10/keygen.c create mode 100644 g10/keyid.c create mode 100644 g10/keylist.c create mode 100644 g10/keyring.c create mode 100644 g10/keyring.h create mode 100644 g10/keyserver-internal.h create mode 100644 g10/keyserver.c create mode 100644 g10/main.h create mode 100644 g10/mainproc.c create mode 100644 g10/mdfilter.c create mode 100644 g10/misc.c create mode 100644 g10/openfile.c create mode 100644 g10/options.h create mode 100644 g10/options.skel create mode 100644 g10/packet.h create mode 100644 g10/parse-packet.c create mode 100644 g10/passphrase.c create mode 100644 g10/photoid.c create mode 100644 g10/photoid.h create mode 100644 g10/pkclist.c create mode 100644 g10/pkglue.c create mode 100644 g10/pkglue.h create mode 100644 g10/plaintext.c create mode 100644 g10/progress.c create mode 100644 g10/pubkey-enc.c create mode 100644 g10/revoke.c create mode 100644 g10/rmd160.c create mode 100644 g10/rmd160.h create mode 100644 g10/seckey-cert.c create mode 100644 g10/server.c create mode 100644 g10/seskey.c create mode 100644 g10/sig-check.c create mode 100644 g10/sign.c create mode 100644 g10/skclist.c create mode 100644 g10/t-rmd160.c create mode 100644 g10/tdbdump.c create mode 100644 g10/tdbio.c create mode 100644 g10/tdbio.h create mode 100644 g10/textfilter.c create mode 100644 g10/trustdb.c create mode 100644 g10/trustdb.h create mode 100644 g10/verify.c create mode 100644 gl/Makefile.am create mode 100644 gl/Makefile.in create mode 100644 gl/alloca_.h create mode 100644 gl/allocsa.c create mode 100644 gl/allocsa.h create mode 100644 gl/allocsa.valgrind create mode 100644 gl/m4/absolute-header.m4 create mode 100644 gl/m4/alloca.m4 create mode 100644 gl/m4/allocsa.m4 create mode 100644 gl/m4/eealloc.m4 create mode 100644 gl/m4/gnulib-comp.m4 create mode 100644 gl/m4/gnulib-tool.m4 create mode 100644 gl/m4/mkdtemp.m4 create mode 100644 gl/m4/setenv.m4 create mode 100644 gl/m4/stdint.m4 create mode 100644 gl/m4/strpbrk.m4 create mode 100644 gl/m4/unistd_h.m4 create mode 100644 gl/mkdtemp.c create mode 100644 gl/mkdtemp.h create mode 100644 gl/setenv.c create mode 100644 gl/setenv.h create mode 100644 gl/size_max.h create mode 100644 gl/stdint_.h create mode 100644 gl/strpbrk.c create mode 100644 gl/strpbrk.h create mode 100644 gl/unsetenv.c create mode 100644 gl/xsize.h create mode 100644 include/ChangeLog-2011 create mode 100644 include/Makefile.am create mode 100644 include/Makefile.in create mode 100644 include/_regex.h create mode 100644 include/cipher.h create mode 100644 include/host2net.h create mode 100644 include/types.h create mode 100644 jnlib/ChangeLog-2011 create mode 100644 jnlib/Makefile.am create mode 100644 jnlib/Makefile.in create mode 100644 jnlib/README create mode 100644 jnlib/argparse.c create mode 100644 jnlib/argparse.h create mode 100644 jnlib/dotlock.c create mode 100644 jnlib/dotlock.h create mode 100644 jnlib/dynload.h create mode 100644 jnlib/libjnlib-config.h create mode 100644 jnlib/logging.c create mode 100644 jnlib/logging.h create mode 100644 jnlib/mischelp.c create mode 100644 jnlib/mischelp.h create mode 100644 jnlib/stringhelp.c create mode 100644 jnlib/stringhelp.h create mode 100644 jnlib/strlist.c create mode 100644 jnlib/strlist.h create mode 100644 jnlib/t-stringhelp.c create mode 100644 jnlib/t-support.c create mode 100644 jnlib/t-support.h create mode 100644 jnlib/types.h create mode 100644 jnlib/utf8conv.c create mode 100644 jnlib/utf8conv.h create mode 100644 jnlib/w32-afunix.c create mode 100644 jnlib/w32-afunix.h create mode 100644 jnlib/w32-gettext.c create mode 100644 jnlib/w32-reg.c create mode 100644 jnlib/w32help.h create mode 100644 kbx/ChangeLog-2011 create mode 100644 kbx/Makefile.am create mode 100644 kbx/Makefile.in create mode 100644 kbx/kbxutil.c create mode 100644 kbx/keybox-blob.c create mode 100644 kbx/keybox-defs.h create mode 100644 kbx/keybox-dump.c create mode 100644 kbx/keybox-file.c create mode 100644 kbx/keybox-init.c create mode 100644 kbx/keybox-openpgp.c create mode 100644 kbx/keybox-search-desc.h create mode 100644 kbx/keybox-search.c create mode 100644 kbx/keybox-update.c create mode 100644 kbx/keybox-util.c create mode 100644 kbx/keybox.h create mode 100755 kbx/mkerrors create mode 100644 keyserver/ChangeLog-2011 create mode 100644 keyserver/Makefile.am create mode 100644 keyserver/Makefile.in create mode 100644 keyserver/curl-shim.c create mode 100644 keyserver/curl-shim.h create mode 100755 keyserver/gpg2keys_mailto.in create mode 100755 keyserver/gpg2keys_test.in create mode 100644 keyserver/gpgkeys_curl.c create mode 100644 keyserver/gpgkeys_finger.c create mode 100644 keyserver/gpgkeys_hkp.c create mode 100644 keyserver/gpgkeys_kdns.c create mode 100644 keyserver/gpgkeys_ldap.c create mode 100644 keyserver/ksutil.c create mode 100644 keyserver/ksutil.h create mode 100644 keyserver/no-libgcrypt.c create mode 100644 m4/ChangeLog-2011 create mode 100644 m4/Makefile.am create mode 100644 m4/Makefile.in create mode 100644 m4/autobuild.m4 create mode 100644 m4/codeset.m4 create mode 100644 m4/estream.m4 create mode 100644 m4/gettext.m4 create mode 100644 m4/glibc2.m4 create mode 100644 m4/glibc21.m4 create mode 100644 m4/gnupg-pth.m4 create mode 100644 m4/gpg-error.m4 create mode 100644 m4/iconv.m4 create mode 100644 m4/intdiv0.m4 create mode 100644 m4/intl.m4 create mode 100644 m4/intldir.m4 create mode 100644 m4/intmax.m4 create mode 100644 m4/inttypes-pri.m4 create mode 100644 m4/inttypes.m4 create mode 100644 m4/inttypes_h.m4 create mode 100644 m4/isc-posix.m4 create mode 100644 m4/ksba.m4 create mode 100644 m4/lcmessage.m4 create mode 100644 m4/ldap.m4 create mode 100644 m4/lib-ld.m4 create mode 100644 m4/lib-link.m4 create mode 100644 m4/lib-prefix.m4 create mode 100644 m4/libassuan.m4 create mode 100644 m4/libcurl.m4 create mode 100644 m4/libgcrypt.m4 create mode 100644 m4/libusb.m4 create mode 100644 m4/lock.m4 create mode 100644 m4/longdouble.m4 create mode 100644 m4/nls.m4 create mode 100644 m4/po.m4 create mode 100644 m4/printf-posix.m4 create mode 100644 m4/progtest.m4 create mode 100644 m4/readline.m4 create mode 100644 m4/signed.m4 create mode 100644 m4/size_max.m4 create mode 100644 m4/socklen.m4 create mode 100644 m4/stdint_h.m4 create mode 100644 m4/sys_socket_h.m4 create mode 100644 m4/tar-ustar.m4 create mode 100644 m4/uintmax_t.m4 create mode 100644 m4/visibility.m4 create mode 100644 m4/wchar_t.m4 create mode 100644 m4/wint_t.m4 create mode 100644 m4/xsize.m4 create mode 100644 po/ChangeLog-2011 create mode 100644 po/LINGUAS create mode 100644 po/Makefile.in.in create mode 100644 po/Makevars create mode 100644 po/POTFILES.in create mode 100644 po/Rules-quot create mode 100644 po/be.gmo create mode 100644 po/be.po create mode 100644 po/boldquot.sed create mode 100644 po/ca.gmo create mode 100644 po/ca.po create mode 100644 po/cs.gmo create mode 100644 po/cs.po create mode 100644 po/da.gmo create mode 100644 po/da.po create mode 100644 po/de.gmo create mode 100644 po/de.po create mode 100644 po/el.gmo create mode 100644 po/el.po create mode 100644 po/en@boldquot.gmo create mode 100644 po/en@boldquot.header create mode 100644 po/en@boldquot.po create mode 100644 po/en@quot.gmo create mode 100644 po/en@quot.header create mode 100644 po/en@quot.po create mode 100644 po/eo.gmo create mode 100644 po/eo.po create mode 100644 po/es.gmo create mode 100644 po/es.po create mode 100644 po/et.gmo create mode 100644 po/et.po create mode 100644 po/fi.gmo create mode 100644 po/fi.po create mode 100644 po/fr.gmo create mode 100644 po/fr.po create mode 100644 po/gl.gmo create mode 100644 po/gl.po create mode 100644 po/gnupg2.pot create mode 100644 po/hu.gmo create mode 100644 po/hu.po create mode 100644 po/id.gmo create mode 100644 po/id.po create mode 100644 po/insert-header.sin create mode 100644 po/it.gmo create mode 100644 po/it.po create mode 100644 po/ja.gmo create mode 100644 po/ja.po create mode 100644 po/nb.gmo create mode 100644 po/nb.po create mode 100644 po/pl.gmo create mode 100644 po/pl.po create mode 100644 po/pt.gmo create mode 100644 po/pt.po create mode 100644 po/pt_BR.gmo create mode 100644 po/pt_BR.po create mode 100644 po/quot.sed create mode 100644 po/remove-potcdate.sin create mode 100644 po/ro.gmo create mode 100644 po/ro.po create mode 100644 po/ru.gmo create mode 100644 po/ru.po create mode 100644 po/sk.gmo create mode 100644 po/sk.po create mode 100644 po/stamp-po create mode 100644 po/sv.gmo create mode 100644 po/sv.po create mode 100644 po/tr.gmo create mode 100644 po/tr.po create mode 100644 po/uk.gmo create mode 100644 po/uk.po create mode 100644 po/zh_CN.gmo create mode 100644 po/zh_CN.po create mode 100644 po/zh_TW.gmo create mode 100644 po/zh_TW.po create mode 100644 scd/ChangeLog-2011 create mode 100644 scd/Makefile.am create mode 100644 scd/Makefile.in create mode 100644 scd/apdu.c create mode 100644 scd/apdu.h create mode 100644 scd/app-common.h create mode 100644 scd/app-dinsig.c create mode 100644 scd/app-geldkarte.c create mode 100644 scd/app-help.c create mode 100644 scd/app-nks.c create mode 100644 scd/app-openpgp.c create mode 100644 scd/app-p15.c create mode 100644 scd/app.c create mode 100644 scd/ccid-driver.c create mode 100644 scd/ccid-driver.h create mode 100644 scd/command.c create mode 100644 scd/iso7816.c create mode 100644 scd/iso7816.h create mode 100644 scd/pcsc-wrapper.c create mode 100644 scd/scdaemon.c create mode 100644 scd/scdaemon.h create mode 100644 scripts/ChangeLog-2011 create mode 100755 scripts/compile create mode 100755 scripts/config.guess create mode 100755 scripts/config.rpath create mode 100755 scripts/config.sub create mode 100755 scripts/depcomp create mode 100755 scripts/install-sh create mode 100755 scripts/mdate-sh create mode 100755 scripts/missing create mode 100755 scripts/mkinstalldirs create mode 100644 scripts/texinfo.tex create mode 100644 sm/ChangeLog-2011 create mode 100644 sm/Makefile.am create mode 100644 sm/Makefile.in create mode 100644 sm/base64.c create mode 100644 sm/call-agent.c create mode 100644 sm/call-dirmngr.c create mode 100644 sm/certchain.c create mode 100644 sm/certcheck.c create mode 100644 sm/certdump.c create mode 100644 sm/certlist.c create mode 100644 sm/certreqgen-ui.c create mode 100644 sm/certreqgen.c create mode 100644 sm/decrypt.c create mode 100644 sm/delete.c create mode 100644 sm/encrypt.c create mode 100644 sm/export.c create mode 100644 sm/fingerprint.c create mode 100644 sm/gpgsm.c create mode 100644 sm/gpgsm.h create mode 100644 sm/import.c create mode 100644 sm/keydb.c create mode 100644 sm/keydb.h create mode 100644 sm/keylist.c create mode 100644 sm/misc.c create mode 100644 sm/qualified.c create mode 100644 sm/server.c create mode 100644 sm/sign.c create mode 100644 sm/verify.c create mode 100644 tests/ChangeLog-2011 create mode 100644 tests/Makefile.am create mode 100644 tests/Makefile.in create mode 100644 tests/asschk.c create mode 100755 tests/inittests create mode 100644 tests/openpgp/ChangeLog-2011 create mode 100644 tests/openpgp/Makefile.am create mode 100644 tests/openpgp/Makefile.in create mode 100755 tests/openpgp/armdetach.test create mode 100755 tests/openpgp/armdetachm.test create mode 100755 tests/openpgp/armencrypt.test create mode 100755 tests/openpgp/armencryptp.test create mode 100755 tests/openpgp/armor.test create mode 100755 tests/openpgp/armsignencrypt.test create mode 100755 tests/openpgp/armsigs.test create mode 100644 tests/openpgp/bug537-test.data.asc create mode 100644 tests/openpgp/bug894-test.asc create mode 100755 tests/openpgp/clearsig.test create mode 100755 tests/openpgp/conventional-mdc.test create mode 100755 tests/openpgp/conventional.test create mode 100755 tests/openpgp/decrypt-dsa.test create mode 100755 tests/openpgp/decrypt.test create mode 100755 tests/openpgp/defs.inc create mode 100755 tests/openpgp/detach.test create mode 100755 tests/openpgp/detachm.test create mode 100755 tests/openpgp/encrypt-dsa.test create mode 100755 tests/openpgp/encrypt.test create mode 100755 tests/openpgp/encryptp.test create mode 100755 tests/openpgp/genkey1024.test create mode 100644 tests/openpgp/gpg-agent.conf.tmpl create mode 100644 tests/openpgp/gpg.conf.tmpl create mode 100755 tests/openpgp/import.test create mode 100755 tests/openpgp/mds.test create mode 100755 tests/openpgp/mkdemodirs create mode 100755 tests/openpgp/multisig.test create mode 100644 tests/openpgp/plain-1-pgp.asc create mode 100644 tests/openpgp/plain-1.asc create mode 100644 tests/openpgp/plain-1o.asc create mode 100644 tests/openpgp/plain-2.asc create mode 100644 tests/openpgp/plain-2o.asc create mode 100644 tests/openpgp/plain-3.asc create mode 100644 tests/openpgp/plain-3o.asc create mode 100644 tests/openpgp/pubdemo.asc create mode 100644 tests/openpgp/pubring.asc create mode 100644 tests/openpgp/pubring.pkr.asc create mode 100755 tests/openpgp/seat.test create mode 100644 tests/openpgp/secdemo.asc create mode 100644 tests/openpgp/secring.asc create mode 100644 tests/openpgp/secring.skr.asc create mode 100755 tests/openpgp/signdemokey create mode 100755 tests/openpgp/signencrypt-dsa.test create mode 100755 tests/openpgp/signencrypt.test create mode 100755 tests/openpgp/sigs-dsa.test create mode 100755 tests/openpgp/sigs.test create mode 100755 tests/openpgp/verify.test create mode 100755 tests/openpgp/version.test create mode 100644 tests/pkits/ChangeLog-2011 create mode 100644 tests/pkits/Makefile.am create mode 100644 tests/pkits/Makefile.in create mode 100644 tests/pkits/README create mode 100755 tests/pkits/basic-certificate-revocation create mode 100755 tests/pkits/certificate-policies create mode 100644 tests/pkits/common.sh create mode 100755 tests/pkits/delta-crls create mode 100755 tests/pkits/distribution-points create mode 100755 tests/pkits/import-all-certs create mode 100644 tests/pkits/import-all-certs.data create mode 100755 tests/pkits/inhibit-any-policy create mode 100755 tests/pkits/inhibit-policy-mapping create mode 100755 tests/pkits/inittests create mode 100755 tests/pkits/key-usage create mode 100755 tests/pkits/name-constraints create mode 100755 tests/pkits/policy-mappings create mode 100755 tests/pkits/private-certificate-extensions create mode 100755 tests/pkits/require-explicit-policy create mode 100755 tests/pkits/runtest create mode 100755 tests/pkits/signature-verification create mode 100755 tests/pkits/validate-all-certs create mode 100755 tests/pkits/validity-periods create mode 100755 tests/pkits/verifying-basic-constraints create mode 100755 tests/pkits/verifying-name-chaining create mode 100755 tests/pkits/verifying-paths-self-issued create mode 100755 tests/runtest create mode 100644 tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key create mode 100644 tests/samplekeys/cert_g10code_pete1.pem create mode 100644 tests/samplekeys/cert_g10code_test1.pem create mode 100644 tests/samplekeys/cert_g10code_theo1.pem create mode 100644 tests/sm-sign+verify create mode 100644 tests/sm-verify create mode 100644 tests/text-1.dsig.pem create mode 100644 tests/text-1.osig-bad.pem create mode 100644 tests/text-1.osig.pem create mode 100644 tests/text-1.txt create mode 100644 tests/text-2.osig-bad.pem create mode 100644 tests/text-2.osig.pem create mode 100644 tests/text-2.txt create mode 100644 tests/text-3.txt create mode 100644 tools/ChangeLog-2011 create mode 100644 tools/Makefile.am create mode 100644 tools/Makefile.in create mode 100644 tools/Manifest create mode 100755 tools/addgnupghome create mode 100755 tools/applygnupgdefaults create mode 100644 tools/ccidmon.c create mode 100644 tools/clean-sat.c create mode 100755 tools/convert-from-106 create mode 100644 tools/gpg-check-pattern.c create mode 100644 tools/gpg-connect-agent.c create mode 100644 tools/gpg-zip.in create mode 100644 tools/gpgconf-comp.c create mode 100644 tools/gpgconf.c create mode 100644 tools/gpgconf.h create mode 100644 tools/gpgkey2ssh.c create mode 100644 tools/gpgparsemail.c create mode 100755 tools/gpgsm-gencert.sh create mode 100644 tools/gpgsplit.c create mode 100644 tools/gpgtar-create.c create mode 100644 tools/gpgtar-extract.c create mode 100644 tools/gpgtar-list.c create mode 100644 tools/gpgtar.c create mode 100644 tools/gpgtar.h create mode 100755 tools/lspgpot create mode 100755 tools/mail-signed-keys create mode 100644 tools/make-dns-cert.c create mode 100644 tools/mk-tdata.c create mode 100644 tools/no-libgcrypt.c create mode 100644 tools/rfc822parse.c create mode 100644 tools/rfc822parse.h create mode 100644 tools/sockprox.c create mode 100644 tools/symcryptrun.c create mode 100644 tools/watchgnupg.c diff --git a/ABOUT-NLS b/ABOUT-NLS new file mode 100644 index 0000000..83bc72e --- /dev/null +++ b/ABOUT-NLS @@ -0,0 +1,1068 @@ +1 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 free software 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 on translations can 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. + +1.1 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'. + +1.2 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 included GNU +`gettext' 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 not be 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 usually have 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. + +1.3 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. If you happen to have the `LC_ALL' or some other +`LC_xxx' environment variables set, you should unset them before +setting `LANG', otherwise the setting of `LANG' will not have the +desired effect. 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 language 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'. + + Special advice for Norwegian users: The language code for Norwegian +bokma*l changed from `no' to `nb' recently (in 2003). During the +transition period, while some message catalogs for this language are +installed under `nb' and some older ones under `no', it's recommended +for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and +older translations are used. + + 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. + +1.4 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://translationproject.org/', in the "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 `coordinator@translationproject.org' 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 skills are praised more than +programming skills, here. + +1.5 Available Packages +====================== + +Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of November +2007. 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 af am ar az be bg bs ca cs cy da de el en en_GB eo + +----------------------------------------------------+ + Compendium | [] [] [] [] | + a2ps | [] [] [] [] [] | + aegis | () | + ant-phone | () | + anubis | [] | + ap-utils | | + aspell | [] [] [] [] [] | + bash | [] | + bfd | | + bibshelf | [] | + binutils | | + bison | [] [] | + bison-runtime | [] | + bluez-pin | [] [] [] [] [] | + cflow | [] | + clisp | [] [] [] | + console-tools | [] [] | + coreutils | [] [] [] [] | + cpio | | + cpplib | [] [] [] | + cryptonit | [] | + dialog | | + diffutils | [] [] [] [] [] [] | + doodle | [] | + e2fsprogs | [] [] | + enscript | [] [] [] [] | + fetchmail | [] [] () [] [] | + findutils | [] | + findutils_stable | [] [] [] | + flex | [] [] [] | + fslint | | + gas | | + gawk | [] [] [] | + gcal | [] | + gcc | [] | + gettext-examples | [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] | + gettext-tools | [] [] | + gip | [] | + gliv | [] [] | + glunarclock | [] | + gmult | [] [] | + gnubiff | () | + gnucash | [] [] () () [] | + gnuedu | | + gnulib | [] | + gnunet | | + gnunet-gtk | | + gnutls | [] | + gpe-aerial | [] [] | + gpe-beam | [] [] | + gpe-calendar | | + gpe-clock | [] [] | + gpe-conf | [] [] | + gpe-contacts | | + gpe-edit | [] | + gpe-filemanager | | + gpe-go | [] | + gpe-login | [] [] | + gpe-ownerinfo | [] [] | + gpe-package | | + gpe-sketchbook | [] [] | + gpe-su | [] [] | + gpe-taskmanager | [] [] | + gpe-timesheet | [] | + gpe-today | [] [] | + gpe-todo | | + gphoto2 | [] [] [] [] | + gprof | [] [] | + gpsdrive | | + gramadoir | [] [] | + grep | [] [] | + gretl | () | + gsasl | | + gss | | + gst-plugins-bad | [] [] | + gst-plugins-base | [] [] | + gst-plugins-good | [] [] [] | + gst-plugins-ugly | [] [] | + gstreamer | [] [] [] [] [] [] [] | + gtick | () | + gtkam | [] [] [] [] | + gtkorphan | [] [] | + gtkspell | [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] | + herrie | [] | + hylafax | | + idutils | [] [] | + indent | [] [] [] [] | + iso_15924 | | + iso_3166 | [] [] [] [] [] [] [] [] [] [] [] | + iso_3166_2 | | + iso_4217 | [] [] [] | + iso_639 | [] [] [] [] | + jpilot | [] | + jtag | | + jwhois | | + kbd | [] [] [] [] | + keytouch | [] [] | + keytouch-editor | [] | + keytouch-keyboa... | [] | + latrine | () | + ld | [] | + leafpad | [] [] [] [] [] | + libc | [] [] [] [] | + libexif | [] | + libextractor | [] | + libgpewidget | [] [] [] | + libgpg-error | [] | + libgphoto2 | [] [] | + libgphoto2_port | [] [] | + libgsasl | | + libiconv | [] [] | + libidn | [] [] [] | + lifelines | [] () | + lilypond | [] | + lingoteach | | + lprng | | + lynx | [] [] [] [] | + m4 | [] [] [] [] | + mailfromd | | + mailutils | [] | + make | [] [] | + man-db | [] [] [] | + minicom | [] [] [] | + nano | [] [] [] | + opcodes | [] | + parted | [] [] | + pilot-qof | | + popt | [] [] [] | + psmisc | [] | + pwdutils | | + qof | | + radius | [] | + recode | [] [] [] [] [] [] | + rpm | [] | + screem | | + scrollkeeper | [] [] [] [] [] [] [] [] | + sed | [] [] [] | + shared-mime-info | [] [] [] [] () [] [] [] | + sharutils | [] [] [] [] [] [] | + shishi | | + skencil | [] () | + solfege | | + soundtracker | [] [] | + sp | [] | + system-tools-ba... | [] [] [] [] [] [] [] [] [] | + tar | [] [] | + texinfo | [] [] [] | + tin | () () | + tuxpaint | [] [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] [] | + util-linux-ng | [] [] [] [] | + vorbis-tools | [] | + wastesedge | () | + wdiff | [] [] [] [] | + wget | [] [] [] | + xchat | [] [] [] [] [] [] [] | + xkeyboard-config | [] | + xpad | [] [] [] | + +----------------------------------------------------+ + af am ar az be bg bs ca cs cy da de el en en_GB eo + 6 0 2 1 8 26 2 40 48 2 56 88 15 1 15 18 + + es et eu fa fi fr ga gl gu he hi hr hu id is it + +--------------------------------------------------+ + Compendium | [] [] [] [] [] | + a2ps | [] [] [] () | + aegis | | + ant-phone | [] | + anubis | [] | + ap-utils | [] [] | + aspell | [] [] [] | + bash | [] | + bfd | [] [] | + bibshelf | [] [] [] | + binutils | [] [] [] | + bison | [] [] [] [] [] [] | + bison-runtime | [] [] [] [] [] | + bluez-pin | [] [] [] [] [] | + cflow | [] | + clisp | [] [] | + console-tools | | + coreutils | [] [] [] [] [] [] | + cpio | [] [] [] | + cpplib | [] [] | + cryptonit | [] | + dialog | [] [] [] | + diffutils | [] [] [] [] [] [] [] [] [] | + doodle | [] [] | + e2fsprogs | [] [] [] | + enscript | [] [] [] | + fetchmail | [] | + findutils | [] [] [] | + findutils_stable | [] [] [] [] | + flex | [] [] [] | + fslint | | + gas | [] [] | + gawk | [] [] [] [] () | + gcal | [] [] | + gcc | [] | + gettext-examples | [] [] [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] [] | + gettext-tools | [] [] [] [] | + gip | [] [] [] [] | + gliv | () | + glunarclock | [] [] [] | + gmult | [] [] [] | + gnubiff | () () | + gnucash | () () () | + gnuedu | [] | + gnulib | [] [] [] | + gnunet | | + gnunet-gtk | | + gnutls | | + gpe-aerial | [] [] | + gpe-beam | [] [] | + gpe-calendar | | + gpe-clock | [] [] [] [] | + gpe-conf | [] | + gpe-contacts | [] [] | + gpe-edit | [] [] [] [] | + gpe-filemanager | [] | + gpe-go | [] [] [] | + gpe-login | [] [] [] | + gpe-ownerinfo | [] [] [] [] [] | + gpe-package | [] | + gpe-sketchbook | [] [] | + gpe-su | [] [] [] [] | + gpe-taskmanager | [] [] [] | + gpe-timesheet | [] [] [] [] | + gpe-today | [] [] [] [] | + gpe-todo | [] | + gphoto2 | [] [] [] [] [] | + gprof | [] [] [] [] [] | + gpsdrive | [] | + gramadoir | [] [] | + grep | [] [] [] | + gretl | [] [] [] () | + gsasl | [] [] | + gss | [] [] | + gst-plugins-bad | [] [] [] [] | + gst-plugins-base | [] [] [] [] | + gst-plugins-good | [] [] [] [] [] | + gst-plugins-ugly | [] [] [] [] | + gstreamer | [] [] [] | + gtick | [] [] [] | + gtkam | [] [] [] [] | + gtkorphan | [] [] | + gtkspell | [] [] [] [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | + herrie | [] | + hylafax | | + idutils | [] [] [] [] [] | + indent | [] [] [] [] [] [] [] [] [] [] | + iso_15924 | [] | + iso_3166 | [] [] [] [] [] [] [] [] [] [] [] [] [] | + iso_3166_2 | [] | + iso_4217 | [] [] [] [] [] [] | + iso_639 | [] [] [] [] [] [] | + jpilot | [] [] | + jtag | [] | + jwhois | [] [] [] [] [] | + kbd | [] [] | + keytouch | [] [] [] | + keytouch-editor | [] | + keytouch-keyboa... | [] [] | + latrine | [] [] | + ld | [] [] [] [] | + leafpad | [] [] [] [] [] [] | + libc | [] [] [] [] [] | + libexif | [] | + libextractor | [] | + libgpewidget | [] [] [] [] [] | + libgpg-error | [] | + libgphoto2 | [] [] [] | + libgphoto2_port | [] [] | + libgsasl | [] [] | + libiconv | [] [] [] | + libidn | [] [] | + lifelines | () | + lilypond | [] [] [] | + lingoteach | [] [] [] | + lprng | | + lynx | [] [] [] | + m4 | [] [] [] [] | + mailfromd | | + mailutils | [] [] | + make | [] [] [] [] [] [] [] [] | + man-db | [] | + minicom | [] [] [] [] | + nano | [] [] [] [] [] [] [] | + opcodes | [] [] [] [] | + parted | [] [] [] | + pilot-qof | | + popt | [] [] [] [] | + psmisc | [] [] | + pwdutils | | + qof | [] | + radius | [] [] | + recode | [] [] [] [] [] [] [] [] | + rpm | [] [] | + screem | | + scrollkeeper | [] [] [] | + sed | [] [] [] [] [] | + shared-mime-info | [] [] [] [] [] [] | + sharutils | [] [] [] [] [] [] [] [] | + shishi | [] | + skencil | [] [] | + solfege | [] | + soundtracker | [] [] [] | + sp | [] | + system-tools-ba... | [] [] [] [] [] [] [] [] [] | + tar | [] [] [] [] [] | + texinfo | [] [] [] | + tin | [] () | + tuxpaint | [] [] | + unicode-han-tra... | | + unicode-transla... | [] [] | + util-linux | [] [] [] [] [] [] [] | + util-linux-ng | [] [] [] [] [] [] [] | + vorbis-tools | | + wastesedge | () | + wdiff | [] [] [] [] [] [] [] [] | + wget | [] [] [] [] [] [] [] [] | + xchat | [] [] [] [] [] [] [] | + xkeyboard-config | [] [] [] [] | + xpad | [] [] [] | + +--------------------------------------------------+ + es et eu fa fi fr ga gl gu he hi hr hu id is it + 85 22 14 2 48 101 61 12 2 8 2 6 53 29 1 52 + + ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl nn + +--------------------------------------------------+ + Compendium | [] | + a2ps | () [] [] | + aegis | () | + ant-phone | [] | + anubis | [] [] [] | + ap-utils | [] | + aspell | [] [] | + bash | [] | + bfd | | + bibshelf | [] | + binutils | | + bison | [] [] [] | + bison-runtime | [] [] [] | + bluez-pin | [] [] [] | + cflow | | + clisp | [] | + console-tools | | + coreutils | [] | + cpio | [] | + cpplib | [] | + cryptonit | [] | + dialog | [] [] | + diffutils | [] [] [] | + doodle | | + e2fsprogs | [] | + enscript | [] | + fetchmail | [] [] | + findutils | [] | + findutils_stable | [] | + flex | [] [] | + fslint | | + gas | | + gawk | [] [] | + gcal | | + gcc | | + gettext-examples | [] [] [] | + gettext-runtime | [] [] [] | + gettext-tools | [] [] | + gip | [] [] | + gliv | [] | + glunarclock | [] [] | + gmult | [] [] [] | + gnubiff | | + gnucash | () () () | + gnuedu | | + gnulib | [] [] | + gnunet | | + gnunet-gtk | | + gnutls | [] | + gpe-aerial | [] | + gpe-beam | [] | + gpe-calendar | [] | + gpe-clock | [] [] [] | + gpe-conf | [] [] [] | + gpe-contacts | [] | + gpe-edit | [] [] [] | + gpe-filemanager | [] [] | + gpe-go | [] [] [] | + gpe-login | [] [] [] | + gpe-ownerinfo | [] [] | + gpe-package | [] [] | + gpe-sketchbook | [] [] | + gpe-su | [] [] [] | + gpe-taskmanager | [] [] [] [] | + gpe-timesheet | [] | + gpe-today | [] [] | + gpe-todo | [] | + gphoto2 | [] [] | + gprof | [] | + gpsdrive | [] | + gramadoir | () | + grep | [] [] | + gretl | | + gsasl | [] | + gss | | + gst-plugins-bad | [] | + gst-plugins-base | [] | + gst-plugins-good | [] | + gst-plugins-ugly | [] | + gstreamer | [] | + gtick | [] | + gtkam | [] [] | + gtkorphan | [] | + gtkspell | [] [] | + gutenprint | [] | + hello | [] [] [] [] [] [] [] | + herrie | [] | + hylafax | | + idutils | [] | + indent | [] [] | + iso_15924 | [] | + iso_3166 | [] [] [] [] [] [] [] [] | + iso_3166_2 | [] | + iso_4217 | [] [] [] | + iso_639 | [] [] [] [] | + jpilot | () () | + jtag | | + jwhois | [] | + kbd | [] | + keytouch | [] | + keytouch-editor | [] | + keytouch-keyboa... | | + latrine | [] | + ld | | + leafpad | [] [] | + libc | [] [] [] | + libexif | | + libextractor | | + libgpewidget | [] | + libgpg-error | | + libgphoto2 | [] | + libgphoto2_port | [] | + libgsasl | [] | + libiconv | [] | + libidn | [] [] | + lifelines | [] | + lilypond | [] | + lingoteach | [] | + lprng | | + lynx | [] [] | + m4 | [] [] | + mailfromd | | + mailutils | | + make | [] [] [] | + man-db | | + minicom | [] | + nano | [] [] [] | + opcodes | [] | + parted | [] [] | + pilot-qof | | + popt | [] [] [] | + psmisc | [] [] [] | + pwdutils | | + qof | | + radius | | + recode | [] | + rpm | [] [] | + screem | [] | + scrollkeeper | [] [] [] [] | + sed | [] [] | + shared-mime-info | [] [] [] [] [] [] [] | + sharutils | [] [] | + shishi | | + skencil | | + solfege | () () | + soundtracker | | + sp | () | + system-tools-ba... | [] [] [] [] | + tar | [] [] [] | + texinfo | [] [] | + tin | | + tuxpaint | () [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] | + util-linux-ng | [] [] | + vorbis-tools | | + wastesedge | [] | + wdiff | [] [] | + wget | [] [] | + xchat | [] [] [] [] | + xkeyboard-config | [] [] [] | + xpad | [] [] [] | + +--------------------------------------------------+ + ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl nn + 51 2 25 3 2 0 6 0 2 2 20 0 11 1 103 6 + + or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta + +--------------------------------------------------+ + Compendium | [] [] [] [] [] | + a2ps | () [] [] [] [] [] [] | + aegis | () () | + ant-phone | [] [] | + anubis | [] [] [] | + ap-utils | () | + aspell | [] [] [] | + bash | [] [] | + bfd | | + bibshelf | [] | + binutils | [] [] | + bison | [] [] [] [] [] | + bison-runtime | [] [] [] [] [] | + bluez-pin | [] [] [] [] [] [] [] [] [] | + cflow | [] | + clisp | [] | + console-tools | [] | + coreutils | [] [] [] [] | + cpio | [] [] [] | + cpplib | [] | + cryptonit | [] [] | + dialog | [] | + diffutils | [] [] [] [] [] [] | + doodle | [] [] | + e2fsprogs | [] [] | + enscript | [] [] [] [] [] | + fetchmail | [] [] [] | + findutils | [] [] [] | + findutils_stable | [] [] [] [] [] [] | + flex | [] [] [] [] [] | + fslint | [] | + gas | | + gawk | [] [] [] [] | + gcal | [] | + gcc | [] [] | + gettext-examples | [] [] [] [] [] [] [] [] | + gettext-runtime | [] [] [] [] [] [] [] [] | + gettext-tools | [] [] [] [] [] [] [] | + gip | [] [] [] [] | + gliv | [] [] [] [] [] [] | + glunarclock | [] [] [] [] [] [] | + gmult | [] [] [] [] | + gnubiff | () [] | + gnucash | () [] | + gnuedu | | + gnulib | [] [] [] | + gnunet | | + gnunet-gtk | [] | + gnutls | [] [] | + gpe-aerial | [] [] [] [] [] [] [] | + gpe-beam | [] [] [] [] [] [] [] | + gpe-calendar | [] [] [] [] | + gpe-clock | [] [] [] [] [] [] [] [] | + gpe-conf | [] [] [] [] [] [] [] | + gpe-contacts | [] [] [] [] [] | + gpe-edit | [] [] [] [] [] [] [] [] [] | + gpe-filemanager | [] [] | + gpe-go | [] [] [] [] [] [] [] [] | + gpe-login | [] [] [] [] [] [] [] [] | + gpe-ownerinfo | [] [] [] [] [] [] [] [] | + gpe-package | [] [] | + gpe-sketchbook | [] [] [] [] [] [] [] [] | + gpe-su | [] [] [] [] [] [] [] [] | + gpe-taskmanager | [] [] [] [] [] [] [] [] | + gpe-timesheet | [] [] [] [] [] [] [] [] | + gpe-today | [] [] [] [] [] [] [] [] | + gpe-todo | [] [] [] [] | + gphoto2 | [] [] [] [] [] [] | + gprof | [] [] [] | + gpsdrive | [] [] | + gramadoir | [] [] | + grep | [] [] [] [] | + gretl | [] [] [] | + gsasl | [] [] [] | + gss | [] [] [] [] | + gst-plugins-bad | [] [] [] | + gst-plugins-base | [] [] | + gst-plugins-good | [] [] | + gst-plugins-ugly | [] [] [] | + gstreamer | [] [] [] [] | + gtick | [] | + gtkam | [] [] [] [] [] | + gtkorphan | [] | + gtkspell | [] [] [] [] [] [] [] [] | + gutenprint | [] | + hello | [] [] [] [] [] [] [] [] | + herrie | [] [] [] | + hylafax | | + idutils | [] [] [] [] [] | + indent | [] [] [] [] [] [] [] | + iso_15924 | | + iso_3166 | [] [] [] [] [] [] [] [] [] [] [] [] [] | + iso_3166_2 | | + iso_4217 | [] [] [] [] [] [] [] | + iso_639 | [] [] [] [] [] [] [] | + jpilot | | + jtag | [] | + jwhois | [] [] [] [] | + kbd | [] [] [] | + keytouch | [] | + keytouch-editor | [] | + keytouch-keyboa... | [] | + latrine | | + ld | [] | + leafpad | [] [] [] [] [] [] | + libc | [] [] [] [] | + libexif | [] [] | + libextractor | [] [] | + libgpewidget | [] [] [] [] [] [] [] [] | + libgpg-error | [] [] [] | + libgphoto2 | [] | + libgphoto2_port | [] [] [] | + libgsasl | [] [] [] [] | + libiconv | [] [] [] | + libidn | [] [] () | + lifelines | [] [] | + lilypond | | + lingoteach | [] | + lprng | [] | + lynx | [] [] [] | + m4 | [] [] [] [] [] | + mailfromd | [] | + mailutils | [] [] [] | + make | [] [] [] [] | + man-db | [] [] [] [] | + minicom | [] [] [] [] [] | + nano | [] [] [] [] | + opcodes | [] [] | + parted | [] | + pilot-qof | | + popt | [] [] [] [] | + psmisc | [] [] | + pwdutils | [] [] | + qof | [] [] | + radius | [] [] | + recode | [] [] [] [] [] [] [] | + rpm | [] [] [] [] | + screem | | + scrollkeeper | [] [] [] [] [] [] [] | + sed | [] [] [] [] [] [] [] [] [] | + shared-mime-info | [] [] [] [] [] [] | + sharutils | [] [] [] [] | + shishi | [] | + skencil | [] [] [] | + solfege | [] | + soundtracker | [] [] | + sp | | + system-tools-ba... | [] [] [] [] [] [] [] [] [] | + tar | [] [] [] [] | + texinfo | [] [] [] [] | + tin | () | + tuxpaint | [] [] [] [] [] [] | + unicode-han-tra... | | + unicode-transla... | | + util-linux | [] [] [] [] | + util-linux-ng | [] [] [] [] | + vorbis-tools | [] | + wastesedge | | + wdiff | [] [] [] [] [] [] [] | + wget | [] [] [] [] | + xchat | [] [] [] [] [] [] [] | + xkeyboard-config | [] [] [] | + xpad | [] [] [] | + +--------------------------------------------------+ + or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta + 0 5 77 31 53 4 58 72 3 45 46 9 45 122 3 + + tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu + +---------------------------------------------------+ + Compendium | [] [] [] [] | 19 + a2ps | [] [] [] | 19 + aegis | [] | 1 + ant-phone | [] [] | 6 + anubis | [] [] [] | 11 + ap-utils | () [] | 4 + aspell | [] [] [] | 16 + bash | [] | 6 + bfd | | 2 + bibshelf | [] | 7 + binutils | [] [] [] [] | 9 + bison | [] [] [] [] | 20 + bison-runtime | [] [] [] [] | 18 + bluez-pin | [] [] [] [] [] [] | 28 + cflow | [] [] | 5 + clisp | | 9 + console-tools | [] [] | 5 + coreutils | [] [] [] | 18 + cpio | [] [] [] [] | 11 + cpplib | [] [] [] [] [] | 12 + cryptonit | [] | 6 + dialog | [] [] [] | 9 + diffutils | [] [] [] [] [] | 29 + doodle | [] | 6 + e2fsprogs | [] [] | 10 + enscript | [] [] [] | 16 + fetchmail | [] [] | 12 + findutils | [] [] [] | 11 + findutils_stable | [] [] [] [] | 18 + flex | [] [] | 15 + fslint | [] | 2 + gas | [] | 3 + gawk | [] [] [] | 16 + gcal | [] | 5 + gcc | [] [] [] | 7 + gettext-examples | [] [] [] [] [] [] | 29 + gettext-runtime | [] [] [] [] [] [] | 28 + gettext-tools | [] [] [] [] [] | 20 + gip | [] [] | 13 + gliv | [] [] | 11 + glunarclock | [] [] [] | 15 + gmult | [] [] [] [] | 16 + gnubiff | [] | 2 + gnucash | () [] | 5 + gnuedu | [] | 2 + gnulib | [] | 10 + gnunet | | 0 + gnunet-gtk | [] [] | 3 + gnutls | | 4 + gpe-aerial | [] [] | 14 + gpe-beam | [] [] | 14 + gpe-calendar | [] [] | 7 + gpe-clock | [] [] [] [] | 21 + gpe-conf | [] [] [] | 16 + gpe-contacts | [] [] | 10 + gpe-edit | [] [] [] [] [] | 22 + gpe-filemanager | [] [] | 7 + gpe-go | [] [] [] [] | 19 + gpe-login | [] [] [] [] [] | 21 + gpe-ownerinfo | [] [] [] [] | 21 + gpe-package | [] | 6 + gpe-sketchbook | [] [] | 16 + gpe-su | [] [] [] [] | 21 + gpe-taskmanager | [] [] [] [] | 21 + gpe-timesheet | [] [] [] [] | 18 + gpe-today | [] [] [] [] [] | 21 + gpe-todo | [] [] | 8 + gphoto2 | [] [] [] [] | 21 + gprof | [] [] | 13 + gpsdrive | [] | 5 + gramadoir | [] | 7 + grep | [] | 12 + gretl | | 6 + gsasl | [] [] [] | 9 + gss | [] | 7 + gst-plugins-bad | [] [] [] | 13 + gst-plugins-base | [] [] | 11 + gst-plugins-good | [] [] [] [] [] | 16 + gst-plugins-ugly | [] [] [] | 13 + gstreamer | [] [] [] | 18 + gtick | [] [] | 7 + gtkam | [] | 16 + gtkorphan | [] | 7 + gtkspell | [] [] [] [] [] [] | 27 + gutenprint | | 4 + hello | [] [] [] [] [] | 38 + herrie | [] [] | 8 + hylafax | | 0 + idutils | [] [] | 15 + indent | [] [] [] [] [] | 28 + iso_15924 | [] [] | 4 + iso_3166 | [] [] [] [] [] [] [] [] [] | 54 + iso_3166_2 | [] [] | 4 + iso_4217 | [] [] [] [] [] | 24 + iso_639 | [] [] [] [] [] | 26 + jpilot | [] [] [] [] | 7 + jtag | [] | 3 + jwhois | [] [] [] | 13 + kbd | [] [] [] | 13 + keytouch | [] | 8 + keytouch-editor | [] | 5 + keytouch-keyboa... | [] | 5 + latrine | [] [] | 5 + ld | [] [] [] [] | 10 + leafpad | [] [] [] [] [] | 24 + libc | [] [] [] | 19 + libexif | [] | 5 + libextractor | [] | 5 + libgpewidget | [] [] [] | 20 + libgpg-error | [] | 6 + libgphoto2 | [] [] | 9 + libgphoto2_port | [] [] [] | 11 + libgsasl | [] | 8 + libiconv | [] [] | 11 + libidn | [] [] | 11 + lifelines | | 4 + lilypond | [] | 6 + lingoteach | [] | 6 + lprng | [] | 2 + lynx | [] [] [] | 15 + m4 | [] [] [] | 18 + mailfromd | [] [] | 3 + mailutils | [] [] | 8 + make | [] [] [] | 20 + man-db | [] | 9 + minicom | [] | 14 + nano | [] [] [] | 20 + opcodes | [] [] | 10 + parted | [] [] [] | 11 + pilot-qof | [] | 1 + popt | [] [] [] [] | 18 + psmisc | [] [] | 10 + pwdutils | [] | 3 + qof | [] | 4 + radius | [] [] | 7 + recode | [] [] [] | 25 + rpm | [] [] [] [] | 13 + screem | [] | 2 + scrollkeeper | [] [] [] [] | 26 + sed | [] [] [] [] | 23 + shared-mime-info | [] [] [] | 29 + sharutils | [] [] [] | 23 + shishi | [] | 3 + skencil | [] | 7 + solfege | [] | 3 + soundtracker | [] [] | 9 + sp | [] | 3 + system-tools-ba... | [] [] [] [] [] [] [] | 38 + tar | [] [] [] | 17 + texinfo | [] [] [] | 15 + tin | | 1 + tuxpaint | [] [] [] | 19 + unicode-han-tra... | | 0 + unicode-transla... | | 2 + util-linux | [] [] [] | 20 + util-linux-ng | [] [] [] | 20 + vorbis-tools | [] [] | 4 + wastesedge | | 1 + wdiff | [] [] | 23 + wget | [] [] [] | 20 + xchat | [] [] [] [] | 29 + xkeyboard-config | [] [] [] | 14 + xpad | [] [] [] | 15 + +---------------------------------------------------+ + 76 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu + 163 domains 0 3 1 74 51 0 143 21 1 57 7 45 0 2036 + + 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 November 2007 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://translationproject.org/extra/matrix.html'. + +1.6 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 +`coordinator@translationproject.org' to make the `.pot' files available +to the translation teams. + diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..eea52a8 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,180 @@ +Program: GnuPG +Homepage: http://www.gnupg.org +Maintainer: Werner Koch +Bug reports: http://bugs.gnupg.org +Security related bug reports: +License: GPLv3+ + + +Authors +======= + +Ales Nyakhaychyk Translations [be] + +Birger Langkjer Translations [da] + +Maxim Britov Translations [ru] + +Daniel Resare Translations [sv] +Per Tunedal Translations [sv] +Daniel Nylander Translations [sv] + +Daiki Ueno Assigns Past and Future Changes. + (changed:passphrase.c and related code) + +David Shaw Assigns past and future changes. + (all in keyserver/, + a lot of changes in g10/ see the ChangeLog, + bug fixes here and there) + +Dokianakis Theofanis Translations [el] + +Edmund GRIMLEY EVANS Translations [eo] + +Florian Weimer Assigns past and future changes + (changed:g10/parse-packet.c, include/iobuf.h, util/iobuf.c) + +g10 Code GmbH Assigns past and future changes + (all work since 2001 as indicated by mail addresses in ChangeLogs) + +Gaël Quéri Translations [fr] + (fixed a lot of typos) + +Gregory Steuck Translations [ru] + +Nagy Ferenc László Translations [hu] + +Ivo Timmermans Translations [nl] + +Jacobo Tarri'o Barreiro Translations [gl] + +Janusz Aleksander Urbanowicz Translations [pl] +Jakub Bogusz Translations [pl] + +Jedi Lin Translations [zh-tw] + +Jouni Hiltunen Translations [fi] +Tommi Vainikainen Translations [fi] + +Laurentiu Buzdugan Translations [ro] + +Magda Procha'zkova' Translations [cs] + +Michael Roth Assigns changes. + (wrote cipher/des.c., changes and bug fixes all over the place) + +Michal Majer Translations [sk] + +Marco d'Itri Translations [it] + +Marcus Brinkmann + (gpgconf and fixes all over the place) + +Matthew Skala Disclaimer + (wrote cipher/twofish.c) + +Moritz Schulte + (ssh support gpg-agent) + +Niklas Hernaeus Disclaimer + (weak key patches) + +Nilgun Belma Buguner Translations [tr] + +Nils Ellmenreich + Assigns past and future changes + (configure.in, cipher/rndlinux.c, FAQ) + +Paul Eggert + (configuration macros for LFS) + +Pavel I. Shajdo Translations [ru] + (man pages) + +Pedro Morais Translations [pt_PT] + +Petr Pisar Translations [cs] + +Rémi Guyomarch Assigns past and future changes. + (g10/compress.c, g10/encr-data.c, + g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c) + +Stefan Bellon Assigns past and future changes. + (All patches to support RISC OS) + +Timo Schulz Assigns past and future changes. + (util/w32reg.c, g10/passphrase.c, g10/hkp.c) + +Tedi Heriyanto Translations [id] + +Thiago Jung Bauermann Translations [pt_BR] +Rafael Caetano dos Santos Translations [pt_BR] + +Toomas Soome Translations [et] + +Urko Lusa Translations [es_ES] + +Walter Koch Translations [de] + +Werner Koch Assigns GNU Privacy Guard and future changes. + (started the whole thing, wrote the S/MIME extensions, the + smartcard daemon and the gpg-agent) + +Yosiaki IIDA Translations [ja] + +Yuri Chornoivan, yurchor at ukr dot net: Translations [uk] + + +Other authors +============= + +The files common/libestream.[ch] are maintained as a separate project +by g10 Code GmbH. These files, as used here, are considered part of +GnuPG. + +The RPM specs file scripts/gnupg.spec has been contributed by +several people. + +The function build_argv in agent/w32main.c is based on code from +Alexandre Julliard. + +The gpg-zip documentation is based on the manpage for gpg-zip, written +by Colin Tuckley and Daniel Leidert for the GNU/Debian distribution. + + +Copyright +========= + +GnuPG is distributed under the GNU General Public License, version 2 +or later. A few files are under the Lesser General Public License, a +few other files carry the all permissive license note as found at the +bottom of this file. Certain files in keyserver/ allow one specific +exception: + + In addition, as a special exception, the Free Software Foundation + gives permission to link the code of the keyserver helper tools: + gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL + project's "OpenSSL" library (or with modified versions of it that + use the same license as the "OpenSSL" library), and distribute the + linked executables. You must obey the GNU General Public License + in all respects for all of the code used other than "OpenSSL". If + you modify this file, you may extend this exception to your version + of the file, but you are not obligated to do so. If you do not + wish to do so, delete this exception statement from your version. + +Note that the gpgkeys_* binaries are currently installed under the +name gpg2keys_*. + +========= + + Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005, + 2006, 2007, 2008 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/COPYING b/COPYING new file mode 100644 index 0000000..4432540 --- /dev/null +++ b/COPYING @@ -0,0 +1,676 @@ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. + diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..6d12f01 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,140 @@ +2012-03-27 Werner Koch + + Release 2.0.19. + + Update zh_TW translation. + + Update config.{sub,guess} to version 2012-02-10. + * scripts/config.guess, scripts/config.sub: Update. + + Update texinfo source from master. + * doc/gpg-agent.texi, doc/gpg.texi, doc/gpgsm.texi + * doc/scdaemon.texi, doc/tools.texi: Update. + * doc/yat2m.c: Update. + + Add target to update the texinfo files from master. + * doc/Makefile.am (update-source): New. + +2012-03-26 Werner Koch + + Fix make rules for audit-events.h et al. + * common/Makefile.am (audit-events.h, status-codes.h): Fix target file + name. + + Update samplekeys and NEWS. + * doc/samplekeys.asc: Update. + + Allow compressed data with algorithm 0. + * g10/mainproc.c (proc_compressed): Remove superfluous check for + an algorithm number of 0. This is bug#1326. + +2012-02-01 David Shaw + + Honor --cert-digest-algo when recreating a cert. + * g10/sign.c (update_keysig_packet): Honor --cert-digest-algo when + recreating a cert. + + This is used by various things in --edit-key like setpref, primary, + etc. Suggested by Christian Aistleitner. + +2012-01-31 Werner Koch + + Update copyright year. + + Require an installed gitlog_to_changelog for make dist. + * scripts/gitlog-to-changelog: Remove. + * Makefile.am (GITLOG_TO_CHANGELOG): New. + (gen-ChangeLog): Use it. Add set -e. + + Add Ukrainian translation. + * po/uk.po: New. + * po/LINGUAS: Add uk.po. + + estream: Avoid printing leading zeroes by %p on 32 bit systems. + * common/estream-printf.c (pr_pointer): Synchronize definition of + AULONG with its use. + + gpg: Add a DECRYPTION_INFO status. + * common/status.h (STATUS_DECRYPTION_INFO): New. + * g10/encr-data.c: Include status.h. + (decrypt_data): Emit STATUS_DECRYPTION_INFO line. + +2012-01-20 Werner Koch + + Do not copy default merge commit log entries into the ChangeLog. + * scripts/gitlog-to-changelog: Skip merge commits. + + Add files to .gitignore. + +2012-01-20 David Shaw + + Changes to --min-cert-level should cause a trustdb rebuild (issue 1366) + * g10/gpgv.c, g10/trustdb.c (read_trust_options): Add min_cert_level + + * g10/trustdb.c (check_trustdb_stale): Request a rebuild if + pending_check_trustdb is true (set when we detect a trustdb + parameter has changed). + + * g10/keylist.c (public_key_list): Use 'l' in the "tru" with-colons + listing for min_cert_level not matching. + + * g10/tdbio.c (tdbio_update_version_record, create_version_record, + tdbio_db_matches_options, tdbio_dump_record, tdbio_read_record, + tdbio_write_record): Add a byte for min_cert_level in the tdbio + version record. + +2012-01-11 David Shaw + + Refresh sample keys. + +2012-01-03 Werner Koch + + Terminate csh commands with a semicolon. + Fixes bug#1386. + + * agent/gpg-agent.c (main): Terminate csh style output with a semicolon. + * scd/scdaemon.c: Ditto. + +2011-12-28 David Shaw + + Use the longest key ID available when talking to a HKP server. + This is issue 1340. Now that PKSD is dead, and SKS supports long key + IDs, this is safe to do. Patch from Daniel Kahn Gillmor + . + +2011-12-15 David Shaw + + Merge fix for issue 1331 from 1.4. + * photoid.c (generate_photo_id): Check for the JPEG magic numbers + instead of JFIF since some programs generate an EXIF header first. + +2011-12-02 Werner Koch + + Generate the ChangeLog from commit logs. + * scripts/gitlog-to-changelog: New script. Taken from gnulib. + * scripts/git-log-fix: New file. + * scripts/git-log-footer: New file. + * scripts/git-hooks/commit-msg: New script. + * autogen.sh: Install commit-msg hook for git. + * doc/HACKING: Describe the ChangeLog policy. + * ChangeLog: New file. + * Makefile.am (EXTRA_DIST): Add new files. + (gen-ChangeLog): New. + (dist-hook): Run gen-ChangeLog. + + Rename all ChangeLog files to ChangeLog-2011. + +2011-12-01 Werner Koch + + NB: Changes done before December 1st, 2011 are described in + per directory files named ChangeLog-2011. See doc/HACKING for + details. + + ----- + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011 Free Software Foundation, Inc. + + Copying and distribution of this file and/or the original GIT + commit log messages, with or without modification, are + permitted provided the copyright notice and this notice are + preserved. diff --git a/ChangeLog-2011 b/ChangeLog-2011 new file mode 100644 index 0000000..46320b2 --- /dev/null +++ b/ChangeLog-2011 @@ -0,0 +1,1207 @@ +2011-12-02 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2011-08-04 Werner Koch + + Release 2.0.18. + + * configure.ac: Fix usage of AC_LANG_PROGRAM. + (AC_CHECK_HEADERS): Check for utmp.h. + +2011-02-04 Werner Koch + + * autogen.sh: Ensure that the git pre-commit hoom has been + enabled. Add a cleanpo filter if not yet set. + +2011-01-13 Werner Koch + + Release 2.0.17. + +2011-01-11 Werner Koch + + * configure.ac: Add option --enable-gpgtar. + (AC_CHECK_FUNCS): Add stat. + + * autogen.sh : Remove superfluous --without-included-gettext. + +2011-01-10 Werner Koch + + * configure.ac: Support a git_revision string. + +2010-07-19 Werner Koch + + Release 2.0.16. + + * configure.ac: Require libgpg-error 1.7 and libksba 1.0.7 to + force building with more recent versions. + +2010-05-04 Werner Koch + + * configure.ac: Add option --enable-standard-socket. + +2010-03-09 Werner Koch + + Release 2.0.15. + + * configure.ac: Add option --disable-ccid-driver. + +2010-02-18 Werner Koch + + Release 2.0.15rc1. + + * configure.ac: Remove double check for libassuan. + +2010-02-11 Marcus Brinkmann + + From trunk 2009-10-16: + + * configure.ac: Check for libassuan instead of libassuan-pth. + +2009-10-12 Werner Koch + + From trunk 2009-09-23: + + * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION): + Update to new API (2, 1.1.0). + +2009-12-21 Werner Koch + + Release 2.0.14. + +2009-12-08 Werner Koch + + * configure.ac (USE_DNS_CERT): Support via ADNS. + +2009-12-07 Werner Koch + + * configure.ac: Check for ADNS before checking for the BIND + resolver. + (USE_ADNS): Fallback macro for PKA and CERT lookups. + +2009-09-04 Werner Koch + + Release 2.0.13. + +2009-06-29 Werner Koch + + * configure.ac: Take care of --without-adns. Suggested by + Arfrever Frehtes Taifersar Arahesis. + +2009-06-17 Werner Koch + + Release 2.0.12. + +2009-06-05 David Shaw + + * configure.ac: Remove Camellia restriction. + +2009-04-01 Werner Koch + + * configure.ac: Test for fsync. + +2009-03-18 Werner Koch + + * configure.ac: Test for getrlimit. + +2009-03-03 Werner Koch + + Release 2.0.11. + +2009-01-12 Werner Koch + + Release 2.0.10. + +2008-12-09 Werner Koch + + Release 2.0.10rc1. + +2008-10-17 Werner Koch + + * configure.ac: Use more warning options with modern GCCs. + +2008-09-29 Werner Koch + + * configure.ac: Require libgcrypt 1.4. + +2008-08-27 David Shaw + + * configure.ac: Use printf for the most portable SVN version + detection. + + * configure.ac: Darwin's /bin/sh has a builtin echo that doesn't + understand '-n'. Use tr to trim the carriage return instead. + +2008-04-23 Werner Koch + + * configure.ac: Call gl_HEADER_SYS_SOCKET and gl_TYPE_SOCKLEN_T. + +2008-04-07 Werner Koch + + * configure.ac (ADNSLIBS): Test for adns. + (GPGKEYS_KDNS): New. + +2008-04-01 Werner Koch + + * configure.ac: Require curl 7.10 (Oct 1 2002) or later as we use + curl_version_info(). + (AC_INIT): Fix quoting. + +2008-03-27 Werner Koch + + * Makefile.am (dist_doc_DATA): New. Install README. + +2008-03-26 Werner Koch + + Release 2.0.9. + +2008-02-19 Werner Koch + + * configure.ac: Remove --with-pkits-tests. + +2008-02-15 Werner Koch + + * gl/allocsa.h, gl/m4/allocsa.m4: Replace HAVE_LONG_LONG by + HAVE_LONG_LONG_INT. + +2008-02-15 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.17. + +2007-12-20 Werner Koch + + Released 2.0.8. + +2007-12-17 Werner Koch + + * configure.ac: Add treatment for HAVE_LDAP_START_TLS_SA. + +2007-12-14 Werner Koch + + Released 2.0.8rc1. + +2007-12-12 Werner Koch + + * configure.ac (USE_CAMELLIA): Define by new option --enable-camellia. + +2007-12-03 Werner Koch + + * configure.ac: Add test gt_LC_MESSAGES.. + +2007-10-01 Werner Koch + + * configure.ac: Require assuan 1.0.4. + +2007-09-14 Werner Koch + + * configure.ac (GNUPG_LIBASSUAN_VERSION): New. + +2007-09-10 Werner Koch + + Released 2.0.7. + +2007-08-27 Werner Koch + + * configure.ac: Remove remaining support for internal regex. + Define DISABLE_REGEX automake conditional. Add option + --with-regex. + * autogen.sh [--build-w32]: Remove --disable-regex. Use --with-regex. + +2007-08-16 Werner Koch + + Released 2.0.6. + +2007-08-08 Werner Koch + + * configure.ac: Use AC_CANONICAL_HOST and not AC_CANONICAL_TARGET. + +2007-07-09 Werner Koch + + * configure.ac (AM_ICONV): Check for it even when building without + NLS. + +2007-07-05 Werner Koch + + Released 2.0.5. + + * configure.ac: Require libassuan 1.0.2. + +2007-07-05 Marcus Brinkmann + + * configure.ac: Invoke AM_LANGINFO_CODESET. + +2007-07-04 Werner Koch + + * Makefile.am (AUTOMAKE_OPTIONS): Add no-dist-gzip. + + Switched entire package to GPLv3+. + + * configure.ac: Require libksba 1.0.2. + + * COPYING: Updated to GPLv3. + * COPYING.LIB: New as jnlib/ uses this license. + + * gl/: Switched to GPLv3+. + + * intl/ Removed. + * configure.ac (AM_GNU_GETTEXT): Add external flag. + (AM_ICONV): New. + +2007-07-03 Werner Koch + + * configure.ac [W32]: Use ws2_32 instead of wsock32. + +2007-06-25 Werner Koch + + * gl/mkdtemp.c (gen_tempname) [MKDIR_TAKES_ONE_ARG]: Avoid + compiler warning by using the proper config macro. + +2007-06-15 Werner Koch + + * configure.ac: Call AM_PO_SUBDIRS. + (W32SOCKLIBS): New. + + * autogen.sh: Use = and not == in test to be POSIXly correct. + : Disable use of regex. + +2007-06-14 Werner Koch + + * configure.ac [AH_BOTTOM]: Remove the hardwired names of modules. + +2007-06-12 Werner Koch + + * configure.ac [AH_BOTTOM]: Define HTTP_NO_WSASTARTUP. + +2007-06-11 Werner Koch + + * am/cmacros.am (libcommonstd, libcommonpth, libcommonstd_ldadd) + (libcommonpth_ldadd): Add macros. + +2007-06-06 Werner Koch + + * configure.ac: Add a few notices message so make browsing of the + log file easier. + (CC_FOR_BUILD): New. + +2007-05-30 Werner Koch + + * configure.ac [W32]: Do not create a symlink to w32-pth.h. + Require the installation of the w32pth package. + +2007-05-29 Werner Koch + + * gl/: Updated to a newer version. + +2007-05-24 Werner Koch + + * configure.ac: Use -Wpointer-arith is possible. + +2007-05-15 Werner Koch + + * configure.ac: Renamed the estream macros. Remove -Wformat-nonliteral. + + * configure.ac: Call ESTREAM_INIT and define the memory + allocators for estream_asprintf. + (gl_MODULES): Remove vasprintf. + +2007-05-09 Werner Koch + + Released 2.0.4. + +2007-05-07 Werner Koch + + * configure.ac: Require libgcrypt 1.2.2 to avoid compiler warnings. + +2007-05-07 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.16.1. + +2007-05-07 Werner Koch + + * configure.ac: Bail out if no C-89 compiler has been found. + +2007-05-04 Werner Koch + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-mailto + + * configure.ac: Require automake 1.10 + (AC_CONFIG_FILES): Rename gpgkeys_ to gpg2keys_. + (AM_PROG_CC_C_O): New. + +2007-03-08 Werner Koch + + Released 2.0.3. + + * autogen.sh: Add option --force. + +2007-01-31 Werner Koch + + Released 2.0.2. + +2006-11-30 Werner Koch + + * configure.ac: Save original LIBS when testing for dlopen. + +2006-11-28 Werner Koch + + Released 2.0.1. + +2006-11-23 Werner Koch + + Released 2.0.1rc1. + +2006-11-21 Werner Koch + + * configure.ac [AH_BOTTOM]: Disable PTH soft mapping. + (AC_CHECK_SIZEOF): Check for time_t. + (BUILD_INCLUDED_LIBINTL): Remove AM_PO_SUBDIRS as it is not + required for C. + +2006-11-15 Werner Koch + + * autogen.sh: Add convenience option --build-amd64. + +2006-11-14 Werner Koch + + * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it. + +2006-11-11 Werner Koch + + Released 2.0.0. + +2006-11-06 Werner Koch + + Released 1.9.95. + +2006-11-03 Werner Koch + + * configure.ac: Test for pty.h. From Gentoo. + +2006-10-24 Werner Koch + + Released 1.9.94. + +2006-10-20 Werner Koch + + * Makefile.am (stowinstall): Add convenience target. + +2006-10-18 Werner Koch + + * configure.ac: svn revison magic fixes for old bashs. Suggested + by Alain Guibert. + +2006-10-18 Werner Koch + + Released 1.9.93. + +2006-10-17 Werner Koch + + * autogen.sh <--build-w32>: Test also for a host "mingw32". + + * configure.ac: Removed W32LIBS. Use NETLIBS instead. + +2006-10-11 Werner Koch + + Released 1.9.92. + + * configure.ac: Require libassuan 0.9.3. + +2006-10-09 Werner Koch + + * acinclude.m4: Moved pth check to m4/gnupg-pth.m4. + +2006-10-06 Werner Koch + + * configure.ac: Also check for libassuan's pth version. + +2006-10-04 Werner Koch + + Released 1.9.91. + + * configure.ac: Require libassuan 0.9.1 which fixes a problem with + gpgsm. + +2006-09-27 Werner Koch + + * gl/strsep.h, gl/strsep.c, gl/m4/strsep.m4: Removed. + * gl/strpbrk.h, gl/strpbrk.c, gl/m4/strpbrk.m4: Removed. + * gl/Makefile.am: Removed module strsep and strpbrk. + * configure.ac: Check for strsep in the context of jnlib. Remove + check from gl_MODULES. Moved check for timegm into the jnlib context. + +2006-09-27 Marcus Brinkmann + + * Makefile.am: Fix cut & paste error. + +2006-09-25 Werner Koch + + Released 1.9.90. + +2006-09-22 Werner Koch + + * AUTHORS: Add information about used licenses. + +2006-09-20 Werner Koch + + * Makefile.am (dist-hook): Removed distfiles cruft. + (SUBDIRS): Added include + +2006-09-18 Werner Koch + + Released 1.9.23. + + * configure.ac (--enable-agent-only): Donot build tools and doc + (--disable-tools,--disable-doc): New. + * Makefile.am (SUBDIRS): Allow to conditional build tools and doc. + +2006-09-14 Werner Koch + + Replaced all call gpg_error_from_errno(errno) by + gpg_error_from_syserror(). + + * configure.ac: Build gpg by default. + (GNUPG_SYS_SO_PEERCRED): Removed. + +2006-09-13 Werner Koch + + * autogen.sh: Better detection of the cross compiler kit. + +2006-09-06 Marcus Brinkmann + + * configure.ac: New automake conditional RUN_GPG_TESTS. + +2006-09-06 Werner Koch + + * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS. Require Assuan + 0.9 and libgpg-error 1.4 + +2006-08-31 Werner Koch + + * configure.ac: Require libksba 1.0 and added API check for it. + (GPG_ERR_LOCKED): Removed DECL check as we require 1.2 anyway. + (have_libusb): New to give a feedback about CCID support + +2006-08-21 Werner Koch + + * configure.ac: Removed docbook tests. + (AC_CONFIG_FILES): Added gpgkeys_test and gpgkeys_mailto. + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Enable gpg. + +2006-08-17 Werner Koch + + * THANKS: Merged with the 1.4 one. + +2006-08-16 Werner Koch + + * configure.ac: Removed test for capabilities and mlock. + +2006-08-15 Werner Koch + + * Makefile.am (keyserver): Enable building of keyserver helpers. + + * configure.ac: Merged with the current configure from 1.4.5. + Require libgpg-error 1.2 and libksba 0.9.16. + +2006-07-29 Marcus Brinkmann + + * README: Spelling fixes. + +2006-07-27 Werner Koch + + Released 1.9.22. + + * configure.ac: Call AB_INIT. + +2006-07-03 Werner Koch + + * configure.ac: Test for ksba_dn_teststr. + +2006-06-30 Werner Koch + + * keyserver/: New. Taken from 1.4.4 + * Makefile.am (SUBDIRS): Include keyserver/. + * configure.ac: Include keyserver/. + (FAKE_CURL, GPGKEYS_CURL): New. + +2006-06-20 Werner Koch + + Released 1.9.21. + +2006-06-08 Marcus Brinkmann + + * configure.ac (PTH_LIBS): Add --all to pth-config invocation. + +2006-05-24 Werner Koch + + * configure.ac: New option --disable-optimization taked from 1.4.3. + +2006-05-23 Werner Koch + + * configure.ac (ZLIBS): New for zlib link commands. Add bzip2 + support. + +2006-05-22 Werner Koch + + * configure.ac (EXEEXT): New. + +2006-04-18 Werner Koch + + * configure.ac (PK_UID_CACHE_SIZE): New. + +2006-04-07 Werner Koch + + * configure.ac: Use new method to include the SVN revison. Now it + is the actual global revision number. + +2005-12-20 Werner Koch + + Released 1.9.20. + +2005-11-28 Werner Koch + + * configure.ac: Append the revision to the version string. + +2005-11-13 Werner Koch + + * am/cmacros.am (-DGNUPG_SYSCONFDIR): Define it. + +2005-11-11 Werner Koch + + * configure.ac (NEED_KSBA_VERSION: Require 0.9.13. + +2005-09-12 Werner Koch + + Released 1.9.19. + +2005-08-01 Werner Koch + + Released 1.9.18. + + * configure.ac: Require libksba 0.9.12 to match new features in gpgsm. + +2005-06-20 Werner Koch + + Released 1.9.17. + +2005-06-02 Werner Koch + + * configure.ac (HAVE_PTH): Define as alias for USE_GNU_PTH. It is + used by common/estream.c. + +2005-06-01 Werner Koch + + * configure.ac (gl_INIT): Add gnulib stuff. + (fseeko, ftello, ttyname, isascii): Replaced the AC_REPLACE_FUNCS + by a simple check. + (putc_unlocked): Removed check. Not used. + (strsep, mkdtemp, asprintf): Replaced checks by gnulib checks. + (xsize): Added will probably come handy soon. + (CFLAGS): Use -Wformat-security instead of + -Wformat-nonliteral. Add --Wno-format-y2k. + * gl/, gl/m4/: New. + +2005-05-15 Werner Koch + + * configure.ac: Remove option --disable-threads; require the use + of GNU Pth. + +2005-04-27 Werner Koch + + * configure.ac: Removed OpenSC detection and options. + * acinclude.m4: Ditto. + +2005-04-21 Werner Koch + + Released 1.9.16. + + * configure.ac: Do not build gpg by default. + +2005-04-20 Werner Koch + + * configure.ac: Test whether GPG_ERR_LOCKED is declared and + provide a replacement if not. + +2005-04-15 Werner Koch + + * configure.ac: Require libksba 0.9.11. + +2005-04-15 Marcus Brinkmann + + * configure.ac: Check for /usr/bin/shred and define SHRED. + + * configure.ac: Add --enable-symcryptrun, disabled by default. + Define automake variable BUILD_SYMCRYPTRUN. + Check for openpty -lutil, define LIBUTIL_LIBS. + +2005-03-03 Werner Koch + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Accidently used + --ldflags instead of --cflags. Reported by Kazu Yamamoto. + +2005-02-03 Werner Koch + + * AUTHORS: Copied from 1.4 and edited to refelct the changes in + 1.9. + +2005-01-17 Werner Koch + + * configure.ac: Make --without-included-regex work as expected. + Fixed FTP location info for some libraries. + +2005-01-13 Werner Koch + + Released 1.9.15. + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Link a simple test + program to see whether the installation is sane. + +2005-01-07 Werner Koch + + * configure.ac: Require gpg-error 1.0. + +2005-01-04 Werner Koch + + * configure.ac: Remove hack not to build gpg2 for W32. + * autogen.sh : Pass option --disable-gpg instead. + +2004-12-22 Werner Koch + + Released 1.9.14. + +2004-12-20 Werner Koch + + * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all + directories default to c:/gnupg. Require libassuan 0.6.9. + +2004-12-18 Werner Koch + + * configure.ac (AH_BOTTOM): Define EXEEXT_S. + + * autogen.sh: Updated --build-w32 feature. + +2004-12-15 Werner Koch + + * Makefile.am (SUBDIRS) [W32]: Do not build in tests/. + + * acinclude.m4: Add proper macro name quoting for use with + automake 1.9. + + * configure.ac: Add replacement check for ttyname. + Removed support for a included zlib. + +2004-12-06 Werner Koch + + * configure.ac (have_w32_system): New. Disable Pth checks for W32. + Link jnlib/w32-pth.h to pth.h. + +2004-12-03 Werner Koch + + Released 1.9.13. + +2004-11-26 Werner Koch + + * configure.ac: Replace strsep. Replaced use of "target" by + "host". + +2004-10-22 Werner Koch + + Released 1.9.12. + + * Makefile.am (AUTOMAKE_OPTIONS): Set option to create bzip2 tarball. + +2004-10-01 Werner Koch + + Released 1.9.11. + +2004-09-30 Werner Koch + + * README: Minor updates. + +2004-09-30 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1. + +2004-08-16 Werner Koch + + * configure.ac: Build Makefile for tests/pkits. New option + --with-pkits-tests. + +2004-08-05 Werner Koch + + * configure.ac: Changed tests for libusb to also suuport the + stable version 0.1.x. + +2004-07-22 Werner Koch + + Released 1.9.10. + + * configure.ac: Define AM conditional HAVE_OPENSC. + +2004-07-21 Werner Koch + + * configure.ac: Don't set DIE to no after it might has been set to + yes. + +2004-07-20 Werner Koch + + * Makefile.am (sm): Build kbx only if gpgsm is to be build. + +2004-07-20 Werner Koch + + * configure.ac: New option --enable-agent-only. + +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, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010 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 new file mode 100644 index 0000000..5458714 --- /dev/null +++ b/INSTALL @@ -0,0 +1,234 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + 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 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. + + Running `configure' might take a while. 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=c99 CFLAGS=-g 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 can use 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 `..'. + + With a non-GNU `make', it is safer 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' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' 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 option `--target=TYPE' 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 + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`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 new file mode 100644 index 0000000..447976e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,104 @@ +# Makefile.am - Top level makefile for GnuPG +# Copyright (C) 2001, 2004, 2012 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 3 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, see . + +## Process this file with automake to produce Makefile.in + +ACLOCAL_AMFLAGS = -I m4 -I gl/m4 +AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip +DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-mailto --enable-gpgtar + +GITLOG_TO_CHANGELOG=gitlog-to-changelog + +EXTRA_DIST = scripts/config.rpath autogen.sh README.SVN \ + ChangeLog-2011 po/ChangeLog-2011 scripts/ChangeLog-2011 + +DISTCLEANFILES = g10defs.h + +if BUILD_GPGSM +kbx = kbx +else +kbx = +endif + + +if BUILD_GPG +gpg = g10 +keyserver = keyserver +else +gpg = +keyserver = +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 +if BUILD_TOOLS +tools = tools +else +tools = +endif +if BUILD_DOC +doc = doc +else +doc = +endif + +if HAVE_W32_SYSTEM +tests = +else +tests = tests +endif + +SUBDIRS = m4 gl include jnlib common ${kbx} \ + ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${tools} po ${doc} ${tests} + +dist_doc_DATA = README + + +dist-hook: gen-ChangeLog + echo "$(VERSION)" > $(distdir)/VERSION + + +gen_start_date = 2011-12-01T06:00:00 +.PHONY: gen-ChangeLog +gen-ChangeLog: + set -e; \ + if test -d $(top_srcdir)/.git; then \ + (cd $(top_srcdir) && \ + $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ + --amend=scripts/git-log-fix \ + --since=$(gen_start_date) ) > $(distdir)/cl-t; \ + cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t; \ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi + + +stowinstall: + $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/gnupg diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..db8950b --- /dev/null +++ b/Makefile.in @@ -0,0 +1,928 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# 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. + +@SET_MAKE@ + +# Makefile.am - Top level makefile for GnuPG +# Copyright (C) 2001, 2004, 2012 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 3 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, see . + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(top_srcdir)/configure ABOUT-NLS \ + AUTHORS COPYING COPYING.LIB ChangeLog INSTALL NEWS THANKS TODO \ + scripts/compile scripts/config.guess scripts/config.rpath \ + scripts/config.sub scripts/depcomp scripts/install-sh \ + scripts/mdate-sh scripts/missing scripts/mkinstalldirs \ + scripts/texinfo.tex +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/gl/m4/absolute-header.m4 \ + $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/allocsa.m4 \ + $(top_srcdir)/gl/m4/eealloc.m4 \ + $(top_srcdir)/gl/m4/gnulib-comp.m4 \ + $(top_srcdir)/gl/m4/gnulib-tool.m4 \ + $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/setenv.m4 \ + $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/strpbrk.m4 \ + $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/estream.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gnupg-pth.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/size_max.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(docdir)" +DATA = $(dist_doc_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = m4 gl include jnlib common kbx g10 keyserver sm agent \ + scd tools po doc tests +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +GZIP_ENV = --best +DIST_ARCHIVES = $(distdir).tar.bz2 +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@ +ACLOCAL = @ACLOCAL@ +ADNSLIBS = @ADNSLIBS@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAQPROG = @FAQPROG@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_CURL = @GPGKEYS_CURL@ +GPGKEYS_FINGER = @GPGKEYS_FINGER@ +GPGKEYS_HKP = @GPGKEYS_HKP@ +GPGKEYS_KDNS = @GPGKEYS_KDNS@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGKEYS_MAILTO = @GPGKEYS_MAILTO@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GREP = @GREP@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +PTH_CFLAGS = @PTH_CFLAGS@ +PTH_CONFIG = @PTH_CONFIG@ +PTH_LIBS = @PTH_LIBS@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +UNISTD_H = @UNISTD_H@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDRES = @WINDRES@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIBS = @ZLIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 -I gl/m4 +AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip +DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-mailto --enable-gpgtar +GITLOG_TO_CHANGELOG = gitlog-to-changelog +EXTRA_DIST = scripts/config.rpath autogen.sh README.SVN \ + ChangeLog-2011 po/ChangeLog-2011 scripts/ChangeLog-2011 + +DISTCLEANFILES = g10defs.h +@BUILD_GPGSM_FALSE@kbx = +@BUILD_GPGSM_TRUE@kbx = kbx +@BUILD_GPG_FALSE@gpg = +@BUILD_GPG_TRUE@gpg = g10 +@BUILD_GPG_FALSE@keyserver = +@BUILD_GPG_TRUE@keyserver = keyserver +@BUILD_GPGSM_FALSE@sm = +@BUILD_GPGSM_TRUE@sm = sm +@BUILD_AGENT_FALSE@agent = +@BUILD_AGENT_TRUE@agent = agent +@BUILD_SCDAEMON_FALSE@scd = +@BUILD_SCDAEMON_TRUE@scd = scd +@BUILD_TOOLS_FALSE@tools = +@BUILD_TOOLS_TRUE@tools = tools +@BUILD_DOC_FALSE@doc = +@BUILD_DOC_TRUE@doc = doc +@HAVE_W32_SYSTEM_FALSE@tests = tests +@HAVE_W32_SYSTEM_TRUE@tests = +SUBDIRS = m4 gl include jnlib common ${kbx} \ + ${gpg} ${keyserver} ${sm} ${agent} ${scd} ${tools} po ${doc} ${tests} + +dist_doc_DATA = README +gen_start_date = 2011-12-01T06:00:00 +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(docdir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dist_docDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-dist_docDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-hook dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_docDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-recursive uninstall uninstall-am uninstall-dist_docDATA + + +dist-hook: gen-ChangeLog + echo "$(VERSION)" > $(distdir)/VERSION +.PHONY: gen-ChangeLog +gen-ChangeLog: + set -e; \ + if test -d $(top_srcdir)/.git; then \ + (cd $(top_srcdir) && \ + $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ + --amend=scripts/git-log-fix \ + --since=$(gen_start_date) ) > $(distdir)/cl-t; \ + cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t; \ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi + +stowinstall: + $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/gnupg + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..39b3438 --- /dev/null +++ b/NEWS @@ -0,0 +1,823 @@ +Noteworthy changes in version 2.0.19 (2012-03-27) +------------------------------------------------- + + * GPG now accepts a space separated fingerprint as a user ID. This + allows to copy and paste the fingerprint from the key listing. + + * GPG now uses the longest key ID available. Removed support for the + original HKP keyserver which is not anymore used by any site. + + * Rebuild the trustdb after changing the option --min-cert-level. + + * Ukrainian translation. + + * Honor option --cert-digest-algo when creating a cert. + + * Emit a DECRYPTION_INFO status line. + + * Improved detection of JPEG files. + + +Noteworthy changes in version 2.0.18 (2011-08-04) +------------------------------------------------- + + * Bug fix for newer versions of Libgcrypt. + + * Support the SSH confirm flag and show SSH fingerprints in ssh + related pinentries. + + * Improved dirmngr/gpgsm interaction for OCSP. + + * Allow generation of card keys up to 4096 bit. + + +Noteworthy changes in version 2.0.17 (2011-01-13) +------------------------------------------------- + + * Allow more hash algorithms with the OpenPGP v2 card. + + * The gpg-agent now tests for a new gpg-agent.conf on a HUP. + + * Fixed output of "gpgconf --check-options". + + * Fixed a bug where Scdaemon sends a signal to Gpg-agent running in + non-daemon mode. + + * Fixed TTY management for pinentries and session variable update + problem. + + +Noteworthy changes in version 2.0.16 (2010-07-19) +------------------------------------------------- + + * If the agent's --use-standard-socket option is active, all tools + try to start and daemonize the agent on the fly. In the past this + was only supported on W32; on non-W32 systems the new configure + option --enable-standard-socket may now be used to use this feature + by default. + + * The gpg-agent commands KILLAGENT and RELOADAGENT are now available + on all platforms. + + * Minor bug fixes. + + +Noteworthy changes in version 2.0.15 (2010-03-09) +------------------------------------------------- + + * New command --passwd for GPG. + + * Fixes a regression in 2.0.14 which prevented unprotection of new + or changed gpg-agent passphrases. + + * Make use of libassuan 2.0 which is available as a DSO. + + +Noteworthy changes in version 2.0.14 (2009-12-21) +------------------------------------------------- + + * The default for --include-cert is now to include all certificates + in the chain except for the root certificate. + + * Numerical values may now be used as an alternative to the + debug-level keywords. + + * The GPGSM --audit-log feature is now more complete. + + * GPG now supports DNS lookups for SRV, PKA and CERT on W32. + + * New GPGSM option --ignore-cert-extension. + + * New and changed passphrases are now created with an iteration count + requiring about 100ms of CPU work. + + +Noteworthy changes in version 2.0.13 (2009-09-04) +------------------------------------------------- + + * GPG now generates 2048 bit RSA keys by default. The default hash + algorithm preferences has changed to prefer SHA-256 over SHA-1. + 2048 bit DSA keys are now generated to use a 256 bit hash algorithm + + * The envvars XMODIFIERS, GTK_IM_MODULE and QT_IM_MODULE are now + passed to the Pinentry to make SCIM work. + + * The GPGSM command --gen-key features a --batch mode and implements + all features of gpgsm-gencert.sh in standard mode. + + * New option --re-import for GPGSM's IMPORT server command. + + * Enhanced writing of existing keys to OpenPGP v2 cards. + + * Add hack to the internal CCID driver to allow the use of some + Omnikey based card readers with 2048 bit keys. + + * GPG now repeatly asks the user to insert the requested OpenPGP + card. This can be disabled with --limit-card-insert-tries=1. + + * Minor bug fixes. + + +Noteworthy changes in version 2.0.12 (2009-06-17) +------------------------------------------------- + + * GPGSM now always lists ephemeral certificates if specified by + fingerprint or keygrip. + + * New command "KEYINFO" for GPG_AGENT. GPGSM now also returns + information about smartcards. + + * Made sure not to leak file descriptors if running gpg-agent with a + command. Restore the signal mask to solve a problem in Mono. + + * Changed order of the confirmation questions for root certificates + and store negative answers in trustlist.txt. + + * Better synchronization of concurrent smartcard sessions. + + * Support 2048 bit OpenPGP cards. + + * Support Telesec Netkey 3 cards. + + * The gpg-protect-tool now uses gpg-agent via libassuan. Under + Windows the Pinentry will now be put into the foreground. + + * Changed code to avoid a possible Mac OS X system freeze. + + +Noteworthy changes in version 2.0.11 (2009-03-03) +------------------------------------------------- + + * Fixed a problem in SCDAEMON which caused unexpected card resets. + + * SCDAEMON is now aware of the Geldkarte. + + * The SCDAEMON option --allow-admin is now used by default. + + * GPGCONF now restarts SCdaemon if necessary. + + * The default cipher algorithm in GPGSM is now again 3DES. This is + due to interoperability problems with Outlook 2003 which still + can't cope with AES. + + +Noteworthy changes in version 2.0.10 (2009-01-12) +------------------------------------------------- + + * [gpg] New keyserver helper gpg2keys_kdns as generic DNS CERT + lookup. Run with --help for a short description. Requires the + ADNS library. + + * [gpg] New mechanisms "local" and "nodefault" for --auto-key-locate. + Fixed a few problems with this option. + + * [gpg] New command --locate-keys. + + * [gpg] New options --with-sig-list and --with-sig-check. + + * [gpg] The option "-sat" is no longer an alias for --clearsign. + + * [gpg] The option --fixed-list-mode is now implicitly used and obsolete. + + * [gpg] New control statement %ask-passphrase for the unattended key + generation. + + * [gpg] The algorithm to compute the SIG_ID status has been changed. + + * [gpgsm] Now uses AES by default. + + * [gpgsm] Made --output option work with --export-secret-key-p12. + + * [gpg-agent] Terminate process if the own listening socket is not + anymore served by ourself. + + * [scdaemon] Made it more robust on W32. + + * [gpg-connect-agent] Accept commands given as command line arguments. + + * [w32] Initialized the socket subsystem for all keyserver helpers. + + * [w32] The sysconf directory has been moved from a subdirectory of + the installation directory to %CSIDL_COMMON_APPDATA%/GNU/etc/gnupg. + + * [w32] The gnupg2.nls directory is not anymore used. The standard + locale directory is now used. + + * [w32] Fixed a race condition between gpg and gpgsm in the use of + temporary file names. + + * The gpg-preset-passphrase mechanism works again. An arbitrary + string may now be used for a custom cache ID. + + * Admin PINs are cached again (bug in 2.0.9). + + * Support for version 2 OpenPGP cards. + + * Libgcrypt 1.4 is now required. + + +Noteworthy changes in version 2.0.9 (2008-03-26) +------------------------------------------------ + + * Gpgsm always tries to locate missing certificates from a running + Dirmngr's cache. + + * Tweaks for Windows. + + * The Admin PIN for OpenPGP cards may now be entered with the pinpad. + + * Improved certificate chain construction. + + * Extended the PKITS framework. + + * Fixed a bug in the ambigious name detection. + + * Fixed possible memory corruption while importing OpenPGP keys (bug + introduced with 2.0.8). [CVE-2008-1530] + + * Minor bug fixes. + + +Noteworthy changes in version 2.0.8 (2007-12-20) +------------------------------------------------ + + * Enhanced gpg-connect-agent with a small scripting language. + + * New option --list-config for gpgconf. + + * Fixed a crash in gpgconf. + + * Gpg-agent now supports the passphrase quality bar of the latest + Pinentry. + + * The envvars XAUTHORITY and PINENTRY_USER_DATA are now passed to the + Pinentry. + + * Fixed the auto creation of the key stub for smartcards. + + * Fixed a rare bug in decryption using the OpenPGP card. + + * Creating DSA2 keys is now possible. + + * New option --extra-digest-algo for gpgsm to allow verification of + broken signatures. + + * Allow encryption with legacy Elgamal sign+encrypt keys with option + --rfc2440. + + * Windows is now a supported platform. + + * Made sure that under Windows the file permissions of the socket are + taken into account. This required a change of our socket emulation + code and changed the IPC protocol under Windows. + + +Noteworthy changes in version 2.0.7 (2007-09-10) +------------------------------------------------ + + * Fixed encryption problem if duplicate certificates are in the + keybox. + + * Made it work on Windows Vista. Note that the entire Windows port + is still considered Beta. + + * Add new options min-passphrase-nonalpha, check-passphrase-pattern, + enforce-passphrase-constraints and max-passphrase-days to + gpg-agent. + + * Add command --check-components to gpgconf. Gpgconf now uses the + installed versions of the programs and does not anymore search via + PATH for them. + + +Noteworthy changes in version 2.0.6 (2007-08-16) +------------------------------------------------ + + * GPGSM does now grok --default-key. + + * GPGCONF is now aware of --default-key and --encrypt-to. + + * GPGSM does again correctly print the serial number as well the the + various keyids. This was broken since 2.0.4. + + * New option --validation-model and support for the chain-model. + + * Improved Windows support. + + +Noteworthy changes in version 2.0.5 (2007-07-05) +------------------------------------------------ + + * Switched license to GPLv3. + + * Basic support for Windows. Run "./autogen.sh --build-w32" to build + it. As usual the mingw cross compiling toolchain is required. + + * Fixed bug when using the --p12-charset without --armor. + + * The command --gen-key may now be used instead of the + gpgsm-gencert.sh script. + + * Changed key generation to reveal less information about the + machine. Bug fixes for gpg2's card key generation. + + +Noteworthy changes in version 2.0.4 (2007-05-09) +------------------------------------------------ + + * The server mode key listing commands are now also working for + systems without the funopen/fopencookie API. + + * PKCS#12 import now tries several encodings in case the passphrase + was not utf-8 encoded. New option --p12-charset for gpgsm. + + * Improved the libgcrypt logging support in all modules. + + +Noteworthy changes in version 2.0.3 (2007-03-08) +------------------------------------------------ + + * By default, do not allow processing multiple plaintexts in a single + stream. Many programs that called GnuPG were assuming that GnuPG + did not permit this, and were thus not using the plaintext boundary + status tags that GnuPG provides. This change makes GnuPG reject + such messages by default which makes those programs safe again. + --allow-multiple-messages returns to the old behavior. [CVE-2007-1263]. + + * New --verify-option show-primary-uid-only. + + * gpgconf may now reads a global configuration file to select which + options are changeable by a frontend. The new applygnupgdefaults + tool may be used by an admin to set default options for all users. + + * The PIN pad of the Cherry XX44 keyboard is now supported. The + DINSIG and the NKS applications are now also aware of PIN pads. + + +Noteworthy changes in version 2.0.2 (2007-01-31) +------------------------------------------------ + + * Fixed a serious and exploitable bug in processing encrypted + packages. [CVE-2006-6235]. + + * Added --passphrase-repeat to set the number of times GPG will + prompt for a new passphrase to be repeated. This is useful to help + memorize a new passphrase. The default is 1 repetition. + + * Using a PIN pad does now also work for the signing key. + + * A warning is displayed by gpg-agent if a new passphrase is too + short. New option --min-passphrase-len defaults to 8. + + * The status code BEGIN_SIGNING now shows the used hash algorithms. + + +Noteworthy changes in version 2.0.1 (2006-11-28) +------------------------------------------------ + + * Experimental support for the PIN pads of the SPR 532 and the Kaan + Advanced card readers. Add "disable-keypad" scdaemon.conf if you + don't want it. Does currently only work for the OpenPGP card and + its authentication and decrypt keys. + + * Fixed build problems on some some platforms and crashes on amd64. + + * Fixed a buffer overflow in gpg2. [bug#728,CVE-2006-6169] + + +Noteworthy changes in version 2.0.0 (2006-11-11) +------------------------------------------------ + + * First stable version of a GnuPG integrating OpenPGP and S/MIME. + + +Noteworthy changes in version 1.9.95 (2006-11-06) +------------------------------------------------- + + * Minor bug fixes. + + +Noteworthy changes in version 1.9.94 (2006-10-24) +------------------------------------------------- + + * Keys for gpgsm may now be specified using a keygrip. A keygrip is + indicated by a prefixing it with an ampersand. + + * gpgconf now supports switching the CMS cipher algo (e.g. to AES). + + * New command --gpgconf-test for all major tools. This may be used to + check whether the configuration file is sane. + + +Noteworthy changes in version 1.9.93 (2006-10-18) +------------------------------------------------- + + * In --with-validation mode gpgsm will now also ask whether a root + certificate should be trusted. + + * Link to Pth only if really necessary. + + * Fixed a pubring corruption bug in gpg2 occurring when importing + signatures or keys with insane lengths. + + * Fixed v3 keyID calculation bug in gpg2. + + * More tweaks for certificates without extensions. + + +Noteworthy changes in version 1.9.92 (2006-10-11) +------------------------------------------------- + + * Bug fixes. + + +Noteworthy changes in version 1.9.91 (2006-10-04) +------------------------------------------------- + + * New "relax" flag for trustlist.txt to allow root CA certificates + without BasicContraints. + + * [gpg2] Removed the -k PGP 2 compatibility hack. -k is now an + alias for --list-keys. + + * [gpg2] Print a warning if "-sat" is used instead of "--clearsign". + + +Noteworthy changes in version 1.9.90 (2006-09-25) +------------------------------------------------- + + * Made readline work for gpg. + + * Cleanups und minor bug fixes. + + * Included translations from gnupg 1.4.5. + + +Noteworthy changes in version 1.9.23 (2006-09-18) +------------------------------------------------- + + * Regular man pages for most tools are now build directly from the + Texinfo source. + + * The gpg code from 1.4.5 has been fully merged into this release. + The configure option --enable-gpg is still required to build this + gpg part. For production use of OpenPGP the gpg version 1.4.5 is + still recommended. Note, that gpg will be installed under the name + gpg2 to allow coexisting with an 1.4.x gpg. + + * API change in gpg-agent's pkdecrypt command. Thus an older gpgsm + may not be used with the current gpg-agent. + + * The scdaemon will now call a script on reader status changes. + + * gpgsm now allows file descriptor passing for "INPUT", "OUTPUT" and + "MESSAGE". + + * The gpgsm server may now output a key listing to the output file + handle. This needs to be enabled using "OPTION list-to-output=1". + + * The --output option of gpgsm has now an effect on list-keys. + + * New gpgsm commands --dump-chain and list-chain. + + * gpg-connect-agent has new options to utilize descriptor passing. + + * A global trustlist may now be used. See doc/examples/trustlist.txt. + + * When creating a new pubring.kbx keybox common certificates are + imported. + + +Noteworthy changes in version 1.9.22 (2006-07-27) +------------------------------------------------- + + * Enhanced pkcs#12 support to allow import from simple keyBags. + + * Exporting to pkcs#12 now create bag attributes so that Mozilla is + able to import the files. + + * Fixed uploading of certain keys to the smart card. + + +Noteworthy changes in version 1.9.21 (2006-06-20) +------------------------------------------------- + + * New command APDU for scdaemon to allow using it for general card + access. Might be used through gpg-connect-agent by using the SCD + prefix command. + + * Support for the CardMan 4040 PCMCIA reader (Linux 2.6.15 required). + + * Scdaemon does not anymore reset cards at the end of a connection. + + * Kludge to allow use of Bundesnetzagentur issued X.509 certificates. + + * Added --hash=xxx option to scdaemon's PKSIGN command. + + * Pkcs#12 files are now created with a MAC. This is for better + interoperability. + + * Collected bug fixes and minor other changes. + + +Noteworthy changes in version 1.9.20 (2005-12-20) +------------------------------------------------- + + * Importing pkcs#12 files created be recent versions of Mozilla works + again. + + * Basic support for qualified signatures. + + * New debug tool gpgparsemail. + + +Noteworthy changes in version 1.9.19 (2005-09-12) +------------------------------------------------- + + * The Belgian eID card is now supported for signatures and ssh. + Other pkcs#15 cards should work as well. + + * Fixed bug in --export-secret-key-p12 so that certificates are again + included. + + +Noteworthy changes in version 1.9.18 (2005-08-01) +------------------------------------------------- + + * [gpgsm] Now allows for more than one email address as well as URIs + and dnsNames in certificate request generation. A keygrip may be + given to create a request from an existing key. + + * A couple of minor bug fixes. + + +Noteworthy changes in version 1.9.17 (2005-06-20) +------------------------------------------------- + + * gpg-connect-agent has now features to handle Assuan INQUIRE + commands. + + * Internal changes for OpenPGP cards. New Assuan command WRITEKEY. + + * GNU Pth is now a hard requirement. + + * [scdaemon] Support for OpenSC has been removed. Instead a new and + straightforward pkcs#15 modules has been written. As of now it + does allows only signing using TCOS cards but we are going to + enhance it to match all the old capabilities. + + * [gpg-agent] New option --write-env-file and Assuan command + UPDATESTARTUPTTY. + + * [gpg-agent] New option --default-cache-ttl-ssh to set the TTL for + SSH passphrase caching independent from the other passphrases. + + +Noteworthy changes in version 1.9.16 (2005-04-21) +------------------------------------------------- + + * gpg-agent does now support the ssh-agent protocol and thus allows + to use the pinentry as well as the OpenPGP smartcard with ssh. + + * New tool gpg-connect-agent as a general client for the gpg-agent. + + * New tool symcryptrun as a wrapper for certain encryption tools. + + * The gpg tool is not anymore build by default because those gpg + versions available in the gnupg 1.4 series are far more matured. + + +Noteworthy changes in version 1.9.15 (2005-01-13) +------------------------------------------------- + + * Fixed passphrase caching bug. + + * Better support for CCID readers; the reader from Cherry RS 6700 USB + does now work. + + +Noteworthy changes in version 1.9.14 (2004-12-22) +------------------------------------------------- + + * [gpg-agent] New option --use-standard-socket to allow the use of a + fixed socket. gpgsm falls back to this socket if GPG_AGENT_INFO + has not been set. + + * Ported to MS Windows with some functional limitations. + + * New tool gpg-preset-passphrase. + + +Noteworthy changes in version 1.9.13 (2004-12-03) +------------------------------------------------- + + * [gpgsm] New option --prefer-system-dirmngr. + + * Minor cleanups and debugging aids. + + +Noteworthy changes in version 1.9.12 (2004-10-22) +------------------------------------------------- + + * [scdaemon] Partly rewrote the PC/SC code. + + * Removed the sc-investigate tool. It is now in a separate package + available at ftp://ftp.g10code.com/g10code/gscutils/ . + + * [gpg-agent] Fixed logging problem. + + +Noteworthy changes in version 1.9.11 (2004-10-01) +------------------------------------------------- + + * When using --import along with --with-validation, the imported + certificates are validated and only imported if they are fully + valid. + + * [gpg-agent] New option --max-cache-ttl. + + * [gpg-agent] When used without --daemon or --server, gpg-agent now + check whether a agent is already running and usable. + + * Fixed some i18n problems. + + +Noteworthy changes in version 1.9.10 (2004-07-22) +------------------------------------------------- + + * Fixed a serious bug in the checking of trusted root certificates. + + * New configure option --enable-agent-pnly allows to build and + install just the agent. + + * Fixed a problem with the log file handling. + + +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, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011 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 new file mode 100644 index 0000000..e7289c9 --- /dev/null +++ b/README @@ -0,0 +1,151 @@ + The GNU Privacy Guard 2 + ========================= + Version 2.0 + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. + + +INTRODUCTION +============ + +GnuPG is GNU's tool for secure communication and data storage. It can +be used to encrypt data and to create digital signatures. It includes +an advanced key management facility and is compliant with the proposed +OpenPGP Internet standard as described in RFC4880 and the S/MIME +standard as described by several RFCs. + +GnuPG is distributed under the terms of the GNU General Public +License. See the file COPYING for details. GnuPG works best on +GNU/Linux or *BSD systems. Most other Unices are also supported but +are not as well tested as the Free Unices. + +GnuPG 2.0 is the stable version of GnuPG integrating support for +OpenPGP and S/MIME. It does not conflict with an installed 1.4 +OpenPGP-only version. + + + +BUILD INSTRUCTIONS +================== + +GnuPG 2.0 depends on the following packages: + + libgpg-error (ftp://ftp.gnupg.org/gcrypt/libgpg-error/) + libgcrypt (ftp://ftp.gnupg.org/gcrypt/libgcrypt/) + libksba (ftp://ftp.gnupg.org/gcrypt/libksba/) + libassuan >= 2.0 (ftp://ftp.gnupg.org/gcrypt/libassuan/) + +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 conflict with a GnuPG 1.4 installation. gpg2 +behaves just like gpg. + +In case of problem please ask on gnupg-users@gnupg.org for advise. + +Note that the PKITS tests are always skipped unless you copy the PKITS +test data file into the tests/pkits directory. + + +DOCUMENTATION +============= + +The complete documentation is in the texinfo manual named +`gnupg.info'. Run "info gnupg" to read it. If you want a a printable +copy of the manual, change to the "doc" directory and enter "make pdf" +For a HTML version enter "make html" and point your browser to +gnupg.html/index.html. Standard man pages for all components are +provided as well. An online version of the manual is available at +http://www.gnupg.org/documentation/manuals/gnupg/ . A version of the +manual pertaining to the current development snapshot is at +http://www.gnupg.org/documentation/manuals/gnupg-devel/ . + + +GNUPG 1.4 AND GNUPG 2.0 +======================= + +GnuPG 2.0 is a newer version of GnuPG with additional support for +S/MIME. It has a different design philosophy that splits +functionality up into several modules. Both versions may be installed +simultaneously without any conflict (gpg is called gpg2 in GnuPG 2). +In fact, the gpg version from GnuPG 1.4 is able to make use of the +gpg-agent as included in GnuPG 2 and allows for seamless passphrase +caching. The advantage of GnuPG 1.4 is its smaller size and no +dependency on other modules at run and build time. + + +HOW TO GET MORE INFORMATION +=========================== + +The primary WWW page is "http://www.gnupg.org" +The primary FTP site is "ftp://ftp.gnupg.org/gcrypt/" + +See http://www.gnupg.org/download/mirrors.html for a list of mirrors +and use them if possible. You may also find GnuPG mirrored on some of +the regular GNU mirrors. + +We have some mailing lists dedicated to GnuPG: + + gnupg-announce@gnupg.org For important announcements like new + versions and such stuff. This is a + moderated list and has very low traffic. + Do not post to this list. + + gnupg-users@gnupg.org For general user discussion and + help (English). + + gnupg-de@gnupg.org German speaking counterpart of + gnupg-users. + + gnupg-ru@gnupg.org Russian speaking counterpart of + gnupg-users. + + gnupg-devel@gnupg.org GnuPG developers main forum. + +You subscribe to one of the list by sending mail with a subject of +"subscribe" to x-request@gnupg.org, where x is the name of the mailing +list (gnupg-announce, gnupg-users, etc.). An archive of the mailing +lists is available at . + +Please direct bug reports to http://bugs.gnupg.org or post them direct +to the mailing list . + +Please direct questions about GnuPG to the users mailing list or one +of the pgp newsgroups; please do not direct questions to one of the +authors directly as we are busy working on improvements and bug fixes. +The English and German mailing lists are watched by the authors and we +try to answer questions when time allows us to do so. + +Commercial grade support for GnuPG is available; please see +. + + + This file is Free Software; as a special exception the authors gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. For conditions + of the whole package, please see the file COPYING. 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.SVN b/README.SVN new file mode 100644 index 0000000..c642282 --- /dev/null +++ b/README.SVN @@ -0,0 +1,51 @@ +If you are building from Subversion, 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. If you +have just updated from SVN, you should add the option "--force" to +autogen.sh so that meta data from SVN is noticed. 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 SVN 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 new file mode 100644 index 0000000..10e8631 --- /dev/null +++ b/THANKS @@ -0,0 +1,294 @@ +GnuPG was originally written by Werner Koch. Other people contributed +by reporting problems, suggesting various improvements or submitting +actual code. Here is a list of those people. Help us keep it +complete and free of errors. + + +Adam Mitchell adam at cafe21.org +Alain Guibert alguibert+gpd at free.fr +Albert Chin china at thewrittenword.com +Alec Habig habig at budoe2.bu.edu +Alexander Belopolsky belopolsky at mac.com +Allan Clark allanc at sco.com +Anand Kumria wildfire at progsoc.uts.edu.au +Andreas Haumer andreas at xss.co.at +Andrew J. Schorr aschorr at telemetry-investments.com +Anthony Carrico acarrico at memebeam.org +Anthony Mulcahy anthony at kcn.ne.jp +Ariel T Glenn ariel at columbia.edu +ARIGA Seiji ariga at os.rim.or.jp +Benjamin Donnachie benjamin at py-soft.co.uk +Bernhard Herzog bh at intevation.de +Bernard Leak thisisnotapipe.a-t.hotmail.com +Bernhard Reiter bernhard at intevation.de +Billy Halsey bshalsey at paxoo.com +Bob Dunlop bob at xyzzy.org.uk +Bob Mathews bobmathews at mindspring.com +Bodo Moeller Bodo_Moeller at public.uni-hamburg.de +Brendan O'Dea bod at debian.org +Brenno de Winter brenno at dewinter.com +Brian M. Carlson karlsson at hal-pc.org +Brian Moore bem at cmc.net +Brian Warner warner at lothar.com +Bryan Fullerton bryanf at samurai.com +Bryce Nichols bryce at bnichols.org +Carl Meijer carlm at prism.co.za +Caskey L. Dickson caskey at technocage.com +Cees van de Griend cees-list at griend.xs4all.nl +Charles Levert charles at comm.polymtl.ca +Charly Avital shavital at mac.com +Chip Salzenberg chip at valinux.com +Chris Adams cmadams at hiwaay.net +Christian Biere christianbiere at gmx.de +Christian Kurz shorty at debian.org +Christian von Roques roques at pond.sub.org +Christopher Oliver oliver at fritz.traverse.net +Christian Recktenwald chris at citecs.de +Colin Tuckley colin at tuckley.org +Daiki Ueno ueno at unixuser.org +Dan Winship danw at helixcode.com +Daniel Eisenbud eisenbud at cs.swarthmore.edu +Daniel Kahn Gillmor dkg at fifthhorseman dot net +Daniel Koening dan at chaosdorf.de +Daniel Leidert daniel leidert at wgdd.de +Daniel Resare daniel at resare.com +Dany Nativel dany at natzo.com +Dave Dykstra dwd at bell-labs.com +David C Niemi niemi at tuxers.net +David Champion dgc at uchicago.edu +David D. Scribner dscribner at bigfoot.com +David Ellement ellement at sdd.hp.com +David Hallinan hallinan at rtd.com +David Hollenberg dhollen at ISI.EDU +David Mathog MATHOG at seqaxp.bio.caltech.edu +David R. Bergstein dbergstein at home.com +David Shaw dshaw at jabberwocky.com +Detlef Lannert lannert at lannert.rz.uni-duesseldorf.de +Dimitri dmitri at advantrix.com +Dirk Lattermann dlatt at t-online.de +Dirk Meyer dirk.meyer at dinoex.sub.org +Disastry Disastry at saiknes.lv +Douglas Calvert dfc at anize.org +Ed Boraas ecxjo at esperanto.org +Edmund GRIMLEY EVANS edmundo at rano.org +Edwin Woudt edwin at woudt.nl +Enzo Michelangeli em at MailAndNews.com +Ernst Molitor ernst.molitor at uni-bonn.de +Evgeny Legerov +Fabian Keil fk at fabiankeil de +Fabio Coatti cova at ferrara.linux.it +Felix von Leitner leitner at amdiv.de +fish stiqz fish at analog.org +Florian Weimer Florian.Weimer at rus.uni-stuttgart.de +Francesco Potorti pot at gnu.org +Frank Donahoe fdonahoe at wilkes1.wilkes.edu +Frank Heckenbach heckenb at mi.uni-erlangen.de +Frank Stajano frank.stajano at cl.cam.ac.uk +Frank Tobin ftobin at uiuc.edu +Gabriel Rosenkoetter gr at eclipsed.net +Gaël Quéri gael at lautre.net +Gene Carter gcarter at lanier.com +Geoff Keating geoffk at ozemail.com.au +Georg Schwarz georg.schwarz at iname.com +Giampaolo Tomassoni g.tomassoni at libero.it +Gilbert Fernandes gilbert_fernandes at hotmail.com +Grant Olson kgo at grant-olson net +Greg Louis glouis at dynamicro.on.ca +Greg Troxel gdt at ir.bbn.com +Gregory Steuck steuck at iname.com +Harald Denker harry at hal.westfalen.de +Holger Baust Holger.Baust at freenet-ag.de +Henrik Nordstrom henrik at henriknordstrom.net +Hendrik Buschkamp buschkamp at rheumanet.org +Holger Schurig holger at d.om.org +Holger Smolinski smolinsk at de.ibm.com +Holger Trapp Holger.Trapp at informatik.tu-chemnitz.de +Hugh Daniel hugh at toad.com +Huy Le huyle at ugcs.caltech.edu +Ian McKellar imckellar at harvestroad.com.au +Ingo Klöcker kloecker at kde.org +Ivo Timmermans itimmermans at bigfoot.com +Jan Krueger max at physics.otago.ac.nz +Jan Niehusmann jan at gondor.com +Jan-0liver Wagner jan @ intevation.de +Janusz A. Urbanowicz alex at bofh.torun.pl +James Troup james at nocrew.org +Jean-loup Gailly gzip at prep.ai.mit.edu +Jeff Long long at kestrel.cc.ukans.edu +Jeffery Von Ronne jronne at ics.uci.edu +Jens Bachem bachem at rrz.uni-koeln.de +Jens Seidel jensseidel at users.sf.net +Jeroen C. van Gelderen jeroen at vangelderen.org +Jeroen Schot schot at a-eskwadraat nl +J Horacio MG homega at ciberia.es +J. Michael Ashley jashley at acm.org +Jim Bauer jfbauer at home.com +Jim Small cavenewt at my-deja.com +Joachim Backes backes at rhrk.uni-kl.de +Joe Rhett jrhett at isite.net +Joerg Honegger Joerg.Honegger at hp.com +John A. Martin jam at jamux.com +John Clizbe JPClizbe at comcast.net +John R. Shannon john at johnrshannon.com +Johnny Teveßen j.tevessen at gmx.de +Jörg Schilling schilling at fokus.gmd.de +Jos Backus Jos.Backus at nl.origin-it.com +Joseph Walton joe at kafsemo.org +Juan F. Codagnone juam at arnet.com.ar +Jun Kuriyama kuriyama at sky.rim.or.jp +Kahil D. Jallad kdj4 at cs.columbia.edu +Karl Fogel kfogel at guanabana.onshore.com +Karsten Thygesen karthy at kom.auc.dk +Katsuhiro Kondou kondou at nec.co.jp +Kazu Yamamoto kazu at iij.ad.jp +Kazuyoshi Kakihara +Keith Clayton keith at claytons.org +Ken Takusagawa ken.takusagawa.2 at gmail.com +Kevin Ryde user42 at zip.com.au +Kiss Gabor kissg at ssg.ki.iif.hu +Klaus Singvogel ks at caldera.de +Kurt Garloff garloff at suse.de +Lars Kellogg-Stedman lars at bu.edu +L. Sassaman rabbi at quickie.net +M Taylor mctaylor at privacy.nb.ca +Marcel Waldvogel mwa at arl.wustl.edu +Marco d'Itri md at linux.it +Marco Parrone marc0 at autistici.org +Marcus Brinkmann Marcus.Brinkmann at ruhr-uni-bochum.de +Mark Adler madler at alumni.caltech.edu +Mark Elbrecht snowball3 at bigfoot.com +Mark Pettit pettit at yahoo-inc.com +Markus Friedl Markus.Friedl at informatik.uni-erlangen.de +Martin Kahlert martin.kahlert at provi.de +Martin Hamilton +Martin Schulte schulte at thp.uni-koeln.de +Matt Kraai kraai at alumni.carnegiemellon.edu +Matthew Skala mskala at ansuz.sooke.bc.ca +Matthew Wilcox matthew at wil.cx +Matthias Urlichs smurf at noris.de +Max Valianskiy maxcom at maxcom.ml.org +Michael Engels michael.engels at uni-duesseldorf.de +Michael Fischer v. Mollard mfvm at gmx.de +Michael Nottebrock michaelnottebrock at gmx.net +Michael Roth mroth at nessie.de +Michael Sobolev mss at despair.transas.com +Michael Tokarev mjt at tls.msk.ru +Mike Dowling ML.Dowling at tu-bs.de +Mike McEwan mike at lotusland.demon.co.uk +Moritz Schulte moritz at chaosdorf.de +Neal H Walfield neal at cs.uml.edu +Nelson H. F. Beebe beebe at math.utah.edu +Nicolas Graner Nicolas.Graner at cri.u-psud.fr +NIIBE Yutaka gniibe at chroot.org +Niklas Hernaeus +Nimrod Zimerman zimerman at forfree.at +Norihiko Murase skeleten at shillest.net +N J Doye nic at niss.ac.uk +Oliver Haakert haakert at hsp.de +Oskari Jääskeläinen f33003a at cc.hut.fi +Pascal Scheffers Pascal at scheffers.net +Paul D. Smith psmith at baynetworks.com +Per Cederqvist ceder at lysator.liu.se +Petr Cerny pcerny at suse.cz +Phil Blundell pb at debian.org +Philippe Laliberte arsphl at oeil.qc.ca +Peter Fales psfales at lucent.com +Peter Gutmann pgut001 at cs.auckland.ac.nz +Peter Marschall Peter.Marschall at gedos.de +Peter Valchev pvalchev at openbsd.org +Petr Uzel petr.uzel at suse cz +Phong Nguyen Phong.Nguyen at ens.fr +Piotr Krukowiecki piotr at pingu.ii.uj.edu.pl +QingLong qinglong at bolizm.ihep.su +Ralph Gillen gillen at theochem.uni-duesseldorf.de +Rat ratinox at peorth.gweep.net +Ray Link rlink at pitt.edu +Reinhard Wobst R.Wobst at ifw-dresden.de +Rémi Guyomarch rguyom at mail.dotcom.fr +Reuben Sumner rasumner at wisdom.weizmann.ac.il +Richard Lefebvre rick at cerca.umontreal.ca +Richard Outerbridge outer at interlog.com +Richard Patterson vectro at yahoo.com +Robert Joop rj at rainbow.in-berlin.de +Roddy Strachan roddy at satlink.com.au +Roger Sondermann r.so at bigfoot.com +Roland Rosenfeld roland at spinnaker.rhein.de +Roman Pavlik rp at tns.cz +Ross Golder rossigee at bigfoot.com +Russell Coker russell at coker.com.au +Ryan Malayter rmalayter at bai.org +Sam Roberts sam at cogent.ca +Sami Tolvanen sami at tolvanen.com +Sascha Kiefer sk at intertivity.com +Scott Worley sworley at chkno.net +Sean MacLennan seanm at netwinder.org +Sebastian Klemke packet at convergence.de +Serge Munhoven munhoven at mema.ucl.ac.be +SL Baur steve at xemacs.org +Sten Lindgren ged at solace dot miun dot se +Stefan Bellon sbellon at sbellon.de +Dr.Stefan.Dalibor Dr.Stefan.Dalibor at bfa.de +Stefan Karrmann S.Karrmann at gmx.net +Stefan Keller dres at cs.tu-berlin.de +Steffen Ullrich ccrlphr at xensei.com +Steffen Zahn zahn at berlin.snafu.de +Steven Bakker steven at icoe.att.com +Steven Murdoch sjmurdoch at bigfoot.com +Stoyan Angelov s_angelov at filibeto.org +Susanne Schultz schultz at hsp.de +Tavis Ormandy taviso at gentoo.org +Ted Cabeen secabeen at pobox.com +Thiago Jung Bauermann jungmann at cwb.matrix.com.br +Thijmen Klok thijmen at xs4all.nl +Thomas Roessler roessler at guug.de +Tim Mooney mooney at dogbert.cc.ndsu.nodak.edu +Timo Schulz twoaday at freakmail.de +Tobias Winkler tobias.winkler at s1998.tu-chemnitz.de +Todd Vierling tv at pobox.com +TOGAWA Satoshi Satoshi.Togawa at jp.yokogawa.com +Tom Duerbusch DuerbuschT at stlouiscity.com +Tom Pegios tomp at idirect.com +Tom Spindler dogcow at home.merit.edu +Tom Zerucha tzeruch at ceddec.com +Tomas Fasth tomas.fasth at twinspot.net +Tommi Komulainen Tommi.Komulainen at iki.fi +Thomas Klausner wiz at danbala.ifoer.tuwien.ac.at +Tomasz Kozlowski tomek at rentec.com +Thomas Mikkelsen tbm at image.dk +Ulf Möller 3umoelle at informatik.uni-hamburg.de +Urko Lusa ulusa at euskalnet.net +Vincent P. Broman broman at spawar.navy.mil +Volker Quetschke quetschke at scytek.de +W Lewis wiml at hhhh.org +Walter Hofmann Walter.Hofmann at physik.stud.uni-erlangen.de +Walter Koch koch at hsp.de +Wayne Chapeskie waynec at spinnaker.com +Werner Koch wk at gnupg.org +Wim Vandeputte bunbun at reptile.rug.ac.be +Winona Brown win at huh.org +Yosiaki IIDA iida at ring.gr.jp +Yoshihiro Kajiki kajiki at ylug.org + nbecker at hns.com + + +Thanks to the German Unix User Group for sponsoring this project, +Martin Hamilton for hosting the first mailing list and OpenIT for +hosting the server. + +The development of this software has partly (i.e. the Windows port) +been funded by the German Ministry for Economics and Technology under +grant VIB3-68553.168-001/1999. + +Many thanks to my wife Gerlinde for having so much patience with +me while hacking late in the evening. + + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 + 2006 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/TODO b/TODO new file mode 100644 index 0000000..5182fc8 --- /dev/null +++ b/TODO @@ -0,0 +1,118 @@ + -*- outline -*- + +* src/base64 +** Make parsing more robust + Currently we don't cope with overlong lines in the best way. +** Check that we really release the ksba reader/writer objects. + +* sm/call-agent.c +** 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/certchain.c +** Try to keep certificate references somewhere + This will help with some of our caching code. We also need to test + that caching; in particular "regtp_ca_chainlen". + +* sm/decrypt.c +** replace leading zero in integer hack by a cleaner solution + +* sm/gpgsm.c +** Implement --default-key +** support the anyPolicy semantic +** Should we prefer nonRepudiation certs over plain signing certs? + Also: Do we need a way to allow the selection of a qualSig cert + over a plain one? The background is that the Telesec cards have 3 + certs capable of signing all with the same subject name. + +* 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/ +** If we detect that a private key has been deleted + Bump the key event counter. + +* agent/command.c +** Make sure that secure memory is used where appropriate + +* agent/pkdecrypt.c, agent/pksign.c +** Support DSA + +* Move pkcs-1 encoding into libgcrypt. + +* Use a MAC to protect sensitive files. + The problem here is that we need yet another key and it is unlikely + that users are willing to remember that key too. It is possible to + do this with a smartcard, though. + +* sm/export.c +** Return an error code or a status info per user ID. + +* common/tlv.c + The parse_sexp function should not go into this file. Check whether + we can change all S-expression handling code to make use of this + function. + +* scd +** Application context vs. reader slot + We have 2 concurrent method of tracking whether a reader is in use: + Using the session_list in command.c and the lock_table in app.c. It + would be better to do this just at one place. First we need to see + how we can support cards with multiple applications. +** Resolve fixme in do_sign of app-dinsig. +** Disconnect + Card timeout is currently used as a boolean. + Add disconnect support for the ccid driver. + +* Regression tests +** Add a regression test to check the extkeyusage. + +* Windows port (W32) +** Regex support is disabled + We need to adjust the test to find the regex we have anyway in + gpg4win. Is that regex compatible to the OpenPGP requirement? + + +* sm/ +** check that we issue NO_SECKEY xxx if a -u key was not found + We don't. The messages returned are also wrong (recipient vs. signer). + +* g10/ +** issue a NO_SECKEY xxxx if a -u key was not found. + +* Extend selinux support to other modules + See also http://etbe.coker.com.au/2008/06/06/se-linux-support-gpg/ + +* UTF-8 specific TODOs + None. + +* Manual +** Document all gpgsm options. + + +* Pinpad Reader + We do not yet support P15 applications. The trivial thing using + ASCII characters will be easy to implement but the other cases need + some more work. + +* Bugs + + +* Howtos +** Migrate OpenPGP keys to another system + +* Gpg-Agent Locale + Although we pass LC_MESSAGE from gpgsm et al. to Pinentry, this has + only an effect on the stock GTK strings (e.g. "OK") and not on any + strings gpg-agent generates and passes to Pinentry. This defeats + our design goal to allow changing the locale without changing + gpg-agent's default locale (e.g. by the command updatestartuptty). + +* RFC 4387: Operational Protocols: Certificate Store Access via HTTP + Do we support this? + diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..ed2af5c --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.0.19 diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..d8f2e17 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,308 @@ +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 3 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, see . + +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 +AC_DEFUN([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 + ]) + + + + +# 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 + ]) + + + + +# 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 +AC_DEFUN([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 +]) + + + + diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..54c1b19 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1239 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# 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. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# intlmacosx.m4 serial 1 (gettext-0.17) +dnl Copyright (C) 2004-2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +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 Checks for special options needed on MacOS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in MacOS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + gt_cv_func_CFPreferencesCopyAppValue, + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include ], + [CFPreferencesCopyAppValue(NULL, NULL)], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], 1, + [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in MacOS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], gt_cv_func_CFLocaleCopyCurrent, + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include ], [CFLocaleCopyCurrent();], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], 1, + [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) + +# longlong.m4 serial 13 +dnl Copyright (C) 1999-2007 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), HAVE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. + dnl If cross compiling, assume the bug isn't important, since + dnl nobody cross compiles for this platform as far as we know. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[@%:@include + @%:@ifndef LLONG_MAX + @%:@ define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + @%:@ define LLONG_MAX (HALF - 1 + HALF) + @%:@endif]], + [[long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0;]])], + [ac_cv_type_long_long_int=yes], + [ac_cv_type_long_long_int=no], + [ac_cv_type_long_long_int=yes])], + [ac_cv_type_long_long_int=no])]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `long long int'.]) + fi +]) + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [ac_cv_type_unsigned_long_long_int=yes], + [ac_cv_type_unsigned_long_long_int=no])]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1, + [Define to 1 if the system has the type `unsigned long long int'.]) + fi +]) + +# Expands to a C program that can be used to test for simultaneous support +# of 'long long' and 'unsigned long long'. We don't want to say that +# 'long long' is available if 'unsigned long long' is not, or vice versa, +# because too many programs rely on the symmetry between signed and unsigned +# integer types (excluding 'bool'). +AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +[ + AC_LANG_PROGRAM( + [[/* Test preprocessor. */ + #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + error in preprocessor; + #endif + #if ! (18446744073709551615ULL <= -1ull) + error in preprocessor; + #endif + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull));]]) +]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([gl/m4/absolute-header.m4]) +m4_include([gl/m4/alloca.m4]) +m4_include([gl/m4/allocsa.m4]) +m4_include([gl/m4/eealloc.m4]) +m4_include([gl/m4/gnulib-comp.m4]) +m4_include([gl/m4/gnulib-tool.m4]) +m4_include([gl/m4/mkdtemp.m4]) +m4_include([gl/m4/setenv.m4]) +m4_include([gl/m4/stdint.m4]) +m4_include([gl/m4/strpbrk.m4]) +m4_include([gl/m4/unistd_h.m4]) +m4_include([m4/autobuild.m4]) +m4_include([m4/codeset.m4]) +m4_include([m4/estream.m4]) +m4_include([m4/gettext.m4]) +m4_include([m4/gnupg-pth.m4]) +m4_include([m4/gpg-error.m4]) +m4_include([m4/iconv.m4]) +m4_include([m4/isc-posix.m4]) +m4_include([m4/ksba.m4]) +m4_include([m4/lcmessage.m4]) +m4_include([m4/ldap.m4]) +m4_include([m4/lib-ld.m4]) +m4_include([m4/lib-link.m4]) +m4_include([m4/lib-prefix.m4]) +m4_include([m4/libassuan.m4]) +m4_include([m4/libcurl.m4]) +m4_include([m4/libgcrypt.m4]) +m4_include([m4/longdouble.m4]) +m4_include([m4/nls.m4]) +m4_include([m4/po.m4]) +m4_include([m4/progtest.m4]) +m4_include([m4/readline.m4]) +m4_include([m4/size_max.m4]) +m4_include([m4/socklen.m4]) +m4_include([m4/sys_socket_h.m4]) +m4_include([m4/tar-ustar.m4]) +m4_include([m4/xsize.m4]) +m4_include([acinclude.m4]) diff --git a/agent/ChangeLog-2011 b/agent/ChangeLog-2011 new file mode 100644 index 0000000..f543f27 --- /dev/null +++ b/agent/ChangeLog-2011 @@ -0,0 +1,2617 @@ +2011-12-02 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2011-08-04 Werner Koch + + * command.c (cmd_keyinfo, do_one_keyinfo): Support options --data + and --ssh-fpr. + + * command-ssh.c (ssh_identity_register): Display the ssh + fingerprint in the prompt. + (add_control_entry): Add arg FMTFPR and use it as comment in + sshcontrol. + (confirm_flag_from_sshcontrol): New. + (data_sign): Ask for confirmaton if requested. + (search_control_file): Add new arg R_CONFIRM and enhance parser. + * findkey.c (agent_raw_key_from_file): New. + (modify_description): Add format letter %F. + + * findkey.c (agent_key_from_file): Simplify comment extraction by + using gcry_sexp_nth_string. + +2011-08-04 Werner Koch + + * genkey.c (check_passphrase_pattern): Use gpg_strerror. + + * command-ssh.c (ssh_receive_mpint_list): Remove set but unused + var ELEMS_PUBLIC_N. + + * gpg-agent.c (main): Remove set but unused var MAY_COREDUMP. + +2011-07-22 Werner Koch + + * command-ssh.c (ssh_receive_key): Do not init comment to an empty + static string; in the error case it would be freed. + +2011-04-29 Werner Koch + + * gpg-agent.c: Include estream.h + (main): s/pth_kill/es_pth_kill/. + +2010-11-11 Werner Koch + + * agent.h (opt): Add field SIGUSR2_ENABLED. + * gpg-agent.c (handle_connections): Set that flag. + * call-scd.c (start_scd): Enable events depending on this flag. + +2010-09-30 Werner Koch + + * findkey.c (unprotect): Do not put the passphrase into the cache + if it has been changed. + +2010-09-24 Werner Koch + + * gpg-agent.c (main, reread_configuration): Always test whether + the default configuration file has been created in the meantime. + Fixes bug#1285. + +2010-08-11 Werner Koch + + * call-pinentry.c (agent_askpin, agent_get_passphrase): Fix + setting of confidential flag. + + * call-scd.c (agent_card_scd): Pass assuan comment lines to the + caller. + (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed. + +2010-05-12 Werner Koch + + * preset-passphrase.c (forget_passphrase): Actually implement + this. Fixes bug#1198. + + * gpg-agent.c (handle_tick): Do not print die message with option -q. + +2010-05-11 Werner Koch + + * agent.h (opt): Add field USE_STANDARD_SOCKET. + * gpg-agent.c (use_standard_socket): Remove. Use new option instead. + + * command.c (cmd_killagent, cmd_reloadagent): Provide command also + for non-W32 platforms. + (cmd_getinfo): New subcommands std_session_env and std_startup_env. + +2010-05-04 Werner Koch + + * gpg-agent.c (main): Add command --use-standard-socket-p. + +2010-05-03 Werner Koch + + * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME + too early. + +2010-03-17 Werner Koch + + * call-scd.c (unlock_scd): Send a BYE under certain conditions. + +2010-02-19 Werner Koch + + * call-pinentry.c (start_pinentry): Remove a translation prefix. + +2010-02-18 Werner Koch + + * protect.c (agent_unprotect): Initialize CLEARTEXT. + + * command.c (register_commands): Unconditionally use + assuan_register_post_cmd_notify. + (start_command_handler): Undocumented use assuan_set_io_monitor. + +2010-02-17 Werner Koch + + * call-pinentry.c (start_pinentry): Always free OPTSTR. Send + default-xxx strings. + +2010-02-11 Marcus Brinkmann + + From trunk 2009-09-23, 2009-11-02, 2009-11-04, 2009-11-05, 2009-11-25, + 2009-12-08: + + * Makefile.am (gpg_agent_CFLAGS, gpg_agent_LDADD): Use libassuan + instead of libassuan-pth. + * gpg-agent.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. + (main): Update to new API. Call assuan_set_system_hooks and + assuan_sock_init. Fix invocation of assuan_socket_connect. + Call assuan_set_assuan_log_stream here. + (parse_rereadable_options): Don't set global assuan log + file (there ain't one anymore). + (check_own_socket_pid_cb): Return gpg_error_t instead of int. + (check_own_socket_thread, check_for_running_agent): Create assuan + context before connecting to server. Update use of + assuan_socket_connect. + * command.c: Include "scdaemon.h" before because of + GPG_ERR_SOURCE_DEFAULT check. + (write_and_clear_outbuf): Use gpg_error_t instead of + assuan_error_t. + (cmd_geteventcounter, cmd_istrusted, cmd_listtrusted) + (cmd_marktrusted, cmd_havekey, cmd_sigkey, cmd_setkeydesc) + (cmd_sethash, cmd_pksign, cmd_pkdecrypt, cmd_genkey, cmd_readkey) + (cmd_keyinfo, cmd_get_passphrase, cmd_clear_passphrase) + (cmd_get_confirmation, cmd_learn, cmd_passwd) + (cmd_preset_passphrase, cmd_scd, cmd_getval, cmd_putval) + (cmd_updatestartuptty, cmd_killagent, cmd_reloadagent) + (cmd_getinfo, option_handler): Return gpg_error_t instead of int. + (post_cmd_notify): Change type of ERR to gpg_error_t from int. + (io_monitor): Add hook argument. Use symbols for constants. + (register_commands): Change return type of HANDLER to gpg_error_t. + Use assuan_handler_t type. Add NULL arg to assuan_register_command. + Add help arg to assuan_register_command. Convert all command + comments to help strings. + (start_command_handler): Allocate assuan context before starting + server. Change assuan_init_socket_server_ext into + assuan_init_socket_server. Use assuan_fd_t and assuan_fdopen on fds. + Do not call assuan_set_log_stream anymore. + (reset_notify): Take LINE arg and return error. + * call-pinentry.c: Include "scdaemon.h" before because + of GPG_ERR_SOURCE_DEFAULT check. + (unlock_pinentry): Call assuan_release instead of + assuan_disconnect. + (getinfo_pid_cb, getpin_cb): Return gpg_error_t instead of int. + (start_pinentry): Allocate assuan context before connecting to + server. Call assuan_pipe_connect, notassuan_pipe_connect_ext. + Convert posix fd to assuan fd. + * call-scd.c (membuf_data_cb, learn_status_cb, get_serialno_cb) + (membuf_data_cb, inq_needpin, card_getattr_cb, pass_status_thru) + (pass_data_thru): Change return type to gpg_error_t. + (start_scd): Allocate assuan context before connecting to server. + Update use of assuan_socket_connect and assuan_pipe_connect. + Convert posix fd to assuan fd. + +2010-01-26 Werner Koch + + * protect.c (do_encryption): Encode the s2kcount and do not use a + static value of 96. + +2009-12-21 Werner Koch + + * command.c (cmd_getinfo): Add sub-command "s2k_count". + +2009-12-14 Werner Koch + + * protect.c (agent_unprotect): Decode the S2K count here and take + care of the new unencoded values. Add a lower limit sanity check. + (hash_passphrase): Do not decode here. + (get_standard_s2k_count, calibrate_s2k_count): New. + (calibrate_get_time, calibrate_elapsed_time): New. + (do_encryption): Use get_standard_s2k_count. + +2009-12-03 Werner Koch + + * gpg-agent.c (set_debug): Allow for numerical debug leveles. Print + active debug flags. + +2009-12-02 Werner Koch + + * trustlist.c (read_trustfiles): Store the pointer returned from + shrinking the memory and not the orginal one. Fixes bug#1163. + Reported by TAKAHASHI Tamotsu. Also return correct error after + memory failure. + +2009-09-04 Marcus Brinkmann + + * command.c (start_command_handler): Add comment about gap in + implementation (in dead code), for future reference. + +2009-08-11 Werner Koch + + * divert-scd.c (ask_for_card): I18n a prompt string. + +2009-07-06 Werner Koch + + * agent.h: Include session-env.h. + (opt): Replace most of the startup_xxx fields by a session_env_t. + (struct server_control_s): Likewise. + * gpg-agent.c (main): Rewrite setting of the startup fields. + (handle_connections, main): Allocate SESSION_ENV. + (agent_init_default_ctrl, agent_deinit_default_ctrl): Change + accordingly. + * command.c (option_handler): Ditto. + (cmd_updatestartuptty): Change accordingly. Protect old values + from out of core failures. + * command-ssh.c (start_command_handler_ssh): Ditto. + (start_command_handler_ssh): Replace strdup by xtrystrdup. + * call-pinentry.c (atfork_cb): Pass new envrinmnet variables. + (start_pinentry): Use session_env stuff. + * protect-tool.c (main): Adjust call to gnupg_prepare_get_passphrase. + +2009-06-24 Werner Koch + + * genkey.c (agent_protect_and_store): Return RC and not 0. + * protect.c (do_encryption): Fix ignored error code from malloc. + Reported by Fabian Keil. + +2009-06-17 Werner Koch + + * call-pinentry.c (agent_get_confirmation): Add arg WITH_CANCEL. + Change all callers. + * trustlist.c (agent_marktrusted): Use WITH_CANCEL + +2009-06-09 Werner Koch + + * learncard.c (send_cert_back): Ignore certain error codes. + +2009-06-05 Werner Koch + + * protect-tool.c (store_private_key): Fix last change by appending + a ".key". + +2009-06-03 Werner Koch + + * protect-tool.c: Include estream.h. + (store_private_key): Replace stdio streams by estream functions + for a portable use of the "x" mode. + * trustlist.c: Include estream.h. + (agent_marktrusted): Replace stdio stream by estream functions. + + * protect-tool.c (store_private_key): Use bin2hex. + +2009-06-02 Werner Koch + + * gpg-agent.c (main): Run pth_kill after fork. Fixes bug#1066. + +2009-05-19 Werner Koch + + * gpg-agent.c (JNLIB_NEED_AFLOCAL): Define. + (create_server_socket): Use SUN_LEN macro. + +2009-05-15 Werner Koch + + Fix bug #1053. + + * agent.h (lookup_ttl_t): New. + * findkey.c (unprotect): Add arg LOOKUP_TTL. + (agent_key_from_file): Ditto. + * pksign.c (agent_pksign_do): Ditto. + * command-ssh.c (ttl_from_sshcontrol): New. + (data_sign): Pass new function to agent_pksign_do. + (search_control_file): Add new arg R_TTL. + +2009-05-14 Werner Koch + + * command.c (cmd_get_passphrase): Add option --qualitybar. + * call-pinentry.c (agent_askpin): Factor some code out to ... + (setup_qualitybar): .. new. + (agent_get_passphrase): Add arg WITH_QUALITYBAR and implement it. + +2009-04-14 Marcus Brinkmann + + * call-pinentry.c (agent_get_confirmation): Try SETNOTOK command + with pinentry. + +2009-04-01 Werner Koch + + * protect-tool.c (pe_opt): New. + (opts): Add option --agent-program. Use ARGPARSE macros. + (get_new_passphrase): Remove. + (get_passphrase): Use gpg-agent directly. Remove arg OPT_CHECK and + change all callers. + * Makefile.am (gpg_protect_tool_LDADD): Replace pwquery_libs by + LIBASSUAN_LIBS. + (gpg_protect_tool_CFLAGS): New. + + * command.c (percent_plus_unescape): Remove. + (cmd_putval): Use percent_plus_unescape_inplace. + * call-scd.c (unescape_status_string): Remove. + (card_getattr_cb): Use percent_plus_unescape. + * protect-tool.c (main): Use percent_plus_unescape from common/. + (percent_plus_unescape, percent_plus_unescape_string): Remove. + +2009-03-27 Werner Koch + + * learncard.c (agent_handle_learn): Add new certtype 111. + +2009-03-26 Werner Koch + + * agent.h (MAX_DIGEST_LEN): Change to 64. + * command.c (cmd_sethash): Allow digest length of 48 and 64. + (cmd_sethash): Allow more hash algos. + + * trustlist.c (reformat_name): New. + (agent_marktrusted): Use a reformatted name. Reload the table + before the update and always reload it at the end. + (agent_istrusted): Check early for the disabled flag. + +2009-03-25 Werner Koch + + * pkdecrypt.c (agent_pkdecrypt): Return a specific error message + if the key is not available. + + * gpg-agent.c (main): Print a started message to show the real pid. + +2009-03-20 Werner Koch + + * learncard.c (struct kpinfo_cp_parm_s): Add field CTRL. + (struct certinfo_cb_parm_s): Ditto. + (agent_handle_learn): Set CTRL field. + (kpinfo_cb, certinfo_cb): Send progress status. + + * agent.h (agent_write_status): Flag with GNUPG_GCC_A_SENTINEL. + +2009-03-19 Werner Koch + + * trustlist.c (struct trustitem_s): Add field DISABLED. + (read_one_trustfile): Parse the '!' flag. + (agent_istrusted, agent_listtrusted): Check flag. + (agent_istrusted): Add arg R_DISABLED. Change all callers. + (agent_marktrusted): Do not ask if flagged as disabled. Reverse + the order of the questions. Store the disabled flag. + + * gpg-agent.c (main): Save signal mask and open fds. Restore mask + and close all fds prior to the exec. Fixes bug#1013. + +2009-03-17 Werner Koch + + * command.c (cmd_get_passphrase): Break repeat loop on error. + Show error message. + (cmd_getinfo): Add subcommand "cmd_has_option". + (command_has_option): New. + +2009-03-17 Daiki Ueno + + * command.c (option_value): New function. + (cmd_get_passphrase): Accept new option --repeat, which makes + gpg-agent to ask passphrase several times. + +2009-03-06 Werner Koch + + * command.c (cmd_keyinfo): New command. + (register_commands): Register it. + (agent_write_status): Make sure not to print LR or CR. + * divert-scd.c (ask_for_card): Factor shadow info parsing out to ... + * protect.c (parse_shadow_info): New. + * findkey.c (agent_key_from_file): Use make_canon_sexp. + (agent_write_private_key, unprotect, read_key_file) + (agent_key_available): Use bin2hex. + (agent_key_info_from_file): New. + (read_key_file): Log no error message for ENOENT. + +2009-03-05 Werner Koch + + * divert-scd.c (getpin_cb): Support flag 'P'. Change max_digits + from 8 to 16. Append a message about keypads. + * findkey.c (unprotect): Change max digits to 16. + +2009-03-02 Werner Koch + + * command.c (cmd_getinfo): Add subcommand "scd_running". + + * call-scd.c (agent_scd_check_running): New. + + * gpg-agent.c: Add missing option strings for "--batch" and + "--homedir". Reported by Petr Uzel. + + * protect-tool.c (import_p12_file): Take care of canceled + passphrase entry. Fixes bug#1003. + (export_p12_file): Ditto. + +2008-12-17 Werner Koch + + * gpg-agent.c (handle_connections): Set action of all pth event + handled signals to SIG_IGN. Use a different pth_sigmask strategy. + +2008-12-10 Werner Koch + + * command.c (cmd_get_passphrase): Implement option --no-ask. + +2008-12-09 Werner Koch + + * gpg-agent.c (main): Call i18n_init before init_common_subsystems. + * preset-passphrase.c (main): Ditto. + * protect-tool.c (main): Ditto. + + * command.c (cmd_preset_passphrase): Allow an arbitrary string for + the cache id. + +2008-12-08 Werner Koch + + * gpg-agent.c (handle_connections): Sync the ticker to the next + full second. This is bug#871. + +2008-12-05 Werner Koch + + * minip12.c (decrypt_block): Fix const modified of CHARSETS. + * learncard.c (sinfo_cb_parm_s): Remove superflous semicolon. + Reported by Stoyan Angelov. + +2008-11-18 Werner Koch + + * gpg-agent.c (make_libversion): New. + (my_strusage): Print libgcrypt version + +2008-11-11 Werner Koch + + * call-scd.c (membuf_data_cb): Change return type to + assuan_error_t to avoid warnings with newer libassuan versions. + +2008-11-04 Werner Koch + + * command.c (cmd_killagent): Stop the agent immediately. + (start_command_handler): Take care of GPG_ERR_EOF. + +2008-10-29 Werner Koch + + * gpg-agent.c (main): Move USE_STANDARD_SOCKET to the outer scope. + (create_socket_name): Remove arg USE_STANDARD_SOCKET. Change all + callers. + (create_server_socket): Remove IS_STANDARD_NAME and replace it by + USE_STANDARD_SOCKET. Change all callers. + (check_own_socket_running): New. + (check_own_socket, check_own_socket_thread): New. + (handle_tick): Check server socket once a minute. + (handle_connections): Remove the extra pth_wait in the shutdown + case. + +2008-10-20 Werner Koch + + * command.c (cmd_geteventcounter): Mark unused arg. + (cmd_listtrusted, cmd_pksign, cmd_pkdecrypt, cmd_genkey): Ditto. + (cmd_updatestartuptty, post_cmd_notify): Ditto. + * command-ssh.c (add_control_entry) + (ssh_handler_request_identities, ssh_handler_remove_identity) + (ssh_handler_remove_all_identities, ssh_handler_lock) + (ssh_handler_unlock): Ditto. + * call-pinentry.c (pinentry_active_p, popup_message_thread) + (agent_popup_message_stop): Ditto. + * findkey.c (agent_public_key_from_file): Ditto. + * genkey.c (check_passphrase_pattern): Ditto. + * call-scd.c (atfork_cb): Ditto. + * protect-tool.c (import_p12_cert_cb): Ditto. + * t-protect.c (main): Ditto. + +2008-10-17 Werner Koch + + * call-scd.c (start_scd) [W32]: Use snprintf again because we now + always use the estream variant. + +2008-10-15 Werner Koch + + * call-scd.c (start_scd): Enable assuan loggging if requested. + (agent_scd_check_aliveness) [W32]: Fix use of GetExitCodeProcess. + +2008-10-14 Werner Koch + + * gpg-agent.c (get_agent_scd_notify_event): Need to use a manual + reset event. + +2008-09-29 Werner Koch + + * agent.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER. + (GCRY_MD_USER_TLS_MD5SHA1): Rename to MD_USER_TLS_MD5SHA1 and + change all users. + +2008-09-25 Werner Koch + + * divert-scd.c (getpin_cb): Support a Reset Code style PINs.. + +2008-09-03 Werner Koch + + * command.c (parse_keygrip): Use hex2bin. + (cmd_preset_passphrase): Decode the passphrase. Reported by Kiss + Gabor. Fixes #679 again. + * preset-passphrase.c (make_hexstring): Remove. + (preset_passphrase): Use bin2hex. + +2008-05-27 Werner Koch + + * trustlist.c (insert_colons): Fix stupidly wrong allocation size + computation. + +2008-05-26 Werner Koch + + * gpg-agent.c (main): Re-initialize default assuan log stream if a + log file is used. + + * trustlist.c (agent_marktrusted): Use xtryasprintf and xfree. + + * gpg-agent.c (main, agent_deinit_default_ctrl): Always use xfree + because our asprintf is mapped to an xmalloc style function in + util.h. Replace xstrdup by xtrystrdup. + * w32main.c (build_argv): Ditto. + * preset-passphrase.c (preset_passphrase): Ditto. + * divert-scd.c (ask_for_card): Ditto. + * command.c (option_handler): Ditto. + * command-ssh.c (ssh_handler_request_identities): Ditto. + * call-pinentry.c (start_pinentry): Ditto. + + * gpg-agent.c (start_connection_thread) + (start_connection_thread_ssh): Use pth_thread_id for useful output + under W32. + (pth_thread_id) [!PTH_HAVE_PTH_THREAD_ID]: New. + +2008-03-17 Werner Koch + + * agent.h (agent_inq_pinentry_launched): New prototype. + + * call-pinentry.c: Include sys/types.h and signal.h. + +2008-02-14 Werner Koch + + * command.c (agent_inq_pinentry_launched): New. + (option_handler): Add option allow-pinentry-notify. + * call-pinentry.c (getinfo_pid_cb): New. + (start_pinentry): Ask for the PID and notify the client. + +2008-01-15 Marcus Brinkmann + + * call-pinentry.c (start_pinentry): Start pinentry in detached + mode. + +2007-12-04 Werner Koch + + * call-pinentry.c (agent_askpin): Use gnupg_get_help_string. + +2007-12-03 Werner Koch + + * gpg-agent.c (main): s/standard_socket/use_standard_socket/ for + clarity. + (create_server_socket): New arg IS_SSH to avoid testing with + assuan commands. + +2007-11-20 Werner Koch + + * gpg-agent.c (get_agent_scd_notify_event): New. + (handle_signal): Factor SIGUSR2 code out to: + (agent_sigusr2_action): .. New. + (agent_sighup_action): Print info message here and not in + handle_signal. + (handle_connections) [PTH_EVENT_HANDLE]: Call agent_sigusr2_action. + + * call-scd.c (agent_scd_check_aliveness) [W32]: Implemented. + (start_scd) [W32]: Send event-signal option. + +2007-11-19 Werner Koch + + * call-pinentry.c (agent_askpin): Set the tooltip for the quality + bar. + +2007-11-15 Werner Koch + + * agent.h (struct server_control_s): Add XAUTHORITY and + PINENTRY_USER_DATA. + * gpg-agent.c: New option --xauthority. + (main, agent_init_default_ctrl) + (agent_deinit_default_ctrl): Implemented + * command.c (cmd_updatestartuptty): Ditto. + * command-ssh.c (start_command_handler_ssh): Ditto. + * call-pinentry.c (atfork_cb): Set the environment. + (start_pinentry): Pass CTRL as arg to atfork_cb. + +2007-11-14 Werner Koch + + * call-scd.c (start_scd) [W32]: Take care of fflush peculiarities. + +2007-11-07 Werner Koch + + * agent.h: Remove errors.h. + +2007-10-24 Werner Koch + + * genkey.c (check_passphrase_constraints): Changed the wording of + the warning messages. + +2007-10-19 Werner Koch + + * protect-tool.c (get_passphrase): Use new utf8 switch fucntions. + +2007-10-15 Daiki Ueno (wk) + + * command-ssh.c (reenter_compare_cb): New function; imported from + genkey.c. + (ssh_identity_register): Ask initial passphrase twice. + +2007-10-02 Werner Koch + + * command.c (cmd_getinfo): Add "pid" subcommand. + +2007-10-01 Werner Koch + + * agent.h (struct server_control_s): Remove unused CONNECTION_FD. + + * gpg-agent.c: Remove w32-afunix.h. Include mkdtemp.h. + (socket_nonce, socket_nonce_ssh): New. + (create_server_socket): Use assuan socket wrappers. Remove W32 + specific stuff. Save the server nonce. + (check_nonce): New. + (start_connection_thread, start_connection_thread_ssh): Call it. + (handle_connections): Change args to gnupg_fd_t. + * command.c (start_command_handler): Change LISTEN_FD to gnupg_fd_t. + * command-ssh.c (start_command_handler_ssh): Ditto. + +2007-09-18 Werner Koch + + * agent.h (struct pin_entry_info_s): Add element WITH_QUALITYBAR. + * genkey.c (check_passphrase_constraints): New arg SILENT. + Changed all callers. + (agent_protect_and_store, agent_genkey): Enable qualitybar. + * call-pinentry.c (agent_askpin): Send that option. + (unescape_passphrase_string): New. + (inq_quality): New. + (estimate_passphrase_quality): New. + +2007-09-14 Marcus Brinkmann + + * call-pinentry.c (agent_popup_message_stop): Implement kill for + Windows. + +2007-08-28 Werner Koch + + * gpg-agent.c (main): Add option --faked-system-time. + + * protect-tool.c (read_and_unprotect): Print the protected-at date. + + * agent.h (struct server_control_s): Add member IN_PASSWD. + * command.c (cmd_passwd): Set it. + * findkey.c (try_unprotect_cb): Use it. + + * protect.c (do_encryption): Replace asprintf by xtryasprint. + (agent_protect): Create the protected-at item. + (agent_unprotect): Add optional arg PROTECTED_AT. + (merge_lists): Add args CUTOFF and CUTLEN. + (agent_unprotect): Use them. + * findkey.c (try_unprotect_cb): Add code to test for expired keys. + (unprotect): Allow changing the passphrase. + +2007-08-27 Werner Koch + + * gpg-agent.c: Add options --min-passphrase-nonalpha, + --check-passphrase-pattern and --enforce-passphrase-constraints. + (MIN_PASSPHRASE_NONALPHA): Init nonalpha option to 1. + (main): Declare options for gpgconf. + * agent.h (struct): Add members MIN_PASSPHRASE_NONALPHA, + ENFORCE_PASSPHRASE_CONSTRAINTS and CHECK_PASSPHRASE_PATTERN. + * genkey.c (nonalpha_charcount): New. + (check_passphrase_pattern): New. + (check_passphrase_constraints): Implement. Factor some code out... + (take_this_one_anyway, take_this_one_anyway2): .. New. + + * call-pinentry.c (agent_show_message): New. + (agent_askpin): We better reset the pin buffer before asking. + + * trustlist.c (insert_colons): New. + (agent_marktrusted): Pretty print the fpr. + +2007-08-22 Werner Koch + + * findkey.c (O_BINARY): Make sure it is defined. + (agent_write_private_key): Use O_BINARY + + * protect-tool.c (import_p12_file): Add hack to allow importing of + gnupg 2.0.4 generated files. + +2007-08-06 Werner Koch + + * trustlist.c (read_one_trustfile): Add flag "cm". + (agent_istrusted): Ditto. + +2007-08-02 Werner Koch + + * gpg-agent.c: Include gc-opt-flags.h and remove their definition + here. + +2007-07-13 Werner Koch + + * genkey.c (check_passphrase_constraints): Require a confirmation + for an empty passphrase. + (agent_genkey, agent_protect_and_store): No need to repeat an + empty passphrase. + +2007-07-05 Werner Koch + + * call-scd.c (struct inq_needpin_s): New. + (inq_needpin): Pass unknown inquiries up. + +2007-07-04 Werner Koch + + * gpg-agent.c (TIMERTICK_INTERVAL): New. + (fixed_gcry_pth_init, main): Kludge to fix Pth initialization. + +2007-07-03 Werner Koch + + * gpg-agent.c (handle_connections): Do not use FD_SETSIZE for + select but compute the correct number. + +2007-07-02 Werner Koch + + * command.c (cmd_reloadagent) [W32]: New. + (register_commands) [W32]: New command RELOADAGENT. + + * Makefile.am (gpg_agent_SOURCES): Remove w32main.c and w32main.h. + (gpg_agent_res_ldflags): Remove icon file as we don't have a + proper icon yet. + * gpg-agent.c (main): do not include w32main.h. Remove all calls + to w32main.c. + (agent_sighup_action): New. + (handle_signal): Use it. + +2007-06-26 Werner Koch + + * gpg-agent.c (create_directories) [W32]: Made it work. + +2007-06-21 Werner Koch + + * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. + + * gpg-agent.c (check_for_running_agent): New arg SILENT. Changed + all callers. + (create_server_socket): If the standard socket is in use check + whether a agent is running and avoid starting another one. + +2007-06-18 Marcus Brinkmann + + * gpg-agent.c (main): Percent escape pathname in --gpgconf-list + output. + +2007-06-18 Werner Koch + + * w32main.c (build_argv): New. + (WinMain): Use it. + + * command.c (cmd_killagent) [W32]: New. + (cmd_getinfo): New. + * gpg-agent.c (get_agent_ssh_socket_name): New. + (no_force_standard_socket) New. + (create_server_socket): Use it. + * Makefile.am (gpg_agent_res_ldflags): Pass windows option to ld. + +2007-06-14 Werner Koch + + * protect-tool.c (main): Setup default socket name for + simple-pwquery. + (MAP_SPWQ_ERROR_IMPL): New. Use map_spwq_error for spqw related + error codes. + * preset-passphrase.c (main): Setup default socket name for + simple-pwquery. + (map_spwq_error): Remove. + (MAP_SPWQ_ERROR_IMPL): New. + + * call-pinentry.c (start_pinentry): Use gnupg_module_name. + * call-scd.c (start_scd): Ditto. + +2007-06-12 Werner Koch + + * taskbar.c: New. + + * trustlist.c (read_one_trustfile): Replace GNUPG_SYSCONFDIR by a + function call. + (read_trustfiles): Ditto. + + * gpg-agent.c (main): Replace some calls by init_common_subsystems. + * preset-passphrase.c (main): Ditto. + * protect-tool.c (main): Ditto. + +2007-06-11 Werner Koch + + * Makefile.am (common_libs): Use libcommonstd macro. + (commonpth_libs): Use libcommonpth macro. + + * protect-tool.c (main) [W32]: Call pth_init. + + * preset-passphrase.c (main) [W32]: Replace the explicit Winsocket + init by a call to pth_init. + + * trustlist.c (initialize_module_trustlist): New. + * gpg-agent.c (main): Call it. + + * call-pinentry.c (initialize_module_query): Rename to + initialize_module_call_pinentry. + + * minip12.c: Remove iconv.h. Add utf8conf.h. Changed all iconv + calss to use these jnlib wrappers. + +2007-06-06 Werner Koch + + * minip12.c (enum): Rename CONTEXT to ASNCONTEXT as winnt.h + defines such a symbol to access the process context. + + * call-pinentry.c (dump_mutex_state) [W32]: Handle the W32Pth case. + * call-scd.c (dump_mutex_state): Ditto. + + * protect-tool.c (i18n_init): Remove. + * preset-passphrase.c (i18n_init): Remove. + * gpg-agent.c (i18n_init): Remove. + +2007-05-19 Marcus Brinkmann + + * protect-tool.c (get_passphrase): Free ORIG_CODESET on error. + +2007-05-14 Werner Koch + + * protect.c (make_shadow_info): Replace sprintf by smklen. + +2007-04-20 Werner Koch + + * gpg-agent.c (my_gcry_logger, my_gcry_outofcore_handler): Removed. + (main): Call the setup_libgcrypt_logging helper. + * protect-tool.c (my_gcry_logger): Removed. + (main): Call the setup_libgcrypt_logging helper. + +2007-04-03 Werner Koch + + * trustlist.c (read_trustfiles): Take a missing trustlist as an + empty one. + +2007-03-20 Werner Koch + + * protect-tool.c: New option --p12-charset. + * minip12.c (p12_build): Implement it. + +2007-03-19 Werner Koch + + * minip12.c: Include iconv.h. + (decrypt_block): New. + (parse_bag_encrypted_data, parse_bag_data): Use it here. + (bag_data_p, bag_decrypted_data_p): New helpers. + +2007-03-06 Werner Koch + + * gpg-agent.c (main) : Add entries for all ttl options. + +2007-02-20 Werner Koch + + * call-pinentry.c (start_pinentry): Fix for OS X to allow loading + of the bundle. Tested by Benjamin Donnachie. + +2007-02-14 Werner Koch + + * gpg-agent.c: New option --pinentry-touch-file. + (get_agent_socket_name): New. + * agent.h (opt): Add pinentry_touch_file. + * call-pinentry.c (start_pinentry): Send new option to the + pinentry. + +2007-01-31 Moritz Schulte (wk) + + * command-ssh.c (stream_read_string): Initialize LENGTH to zero. + (start_command_handler_ssh): Use es_fgetc/es_ungetc to check if + EOF has been reached before trying to process another request. + +2007-01-31 Werner Koch + + * command-ssh.c (start_command_handler_ssh): + + * Makefile.am (t_common_ldadd): Add LIBICONV. + +2007-01-25 Werner Koch + + * genkey.c (check_passphrase_constraints): Get ngettext call right + and use UTF-8 aware strlen. + + * protect-tool.c (get_passphrase): New arg OPT_CHECK. + (get_new_passphrase): Enable OPT_CHECK on the first call. + * command.c (cmd_get_passphrase): Implement option --check. + +2007-01-24 Werner Koch + + * gpg-agent.c (MIN_PASSPHRASE_LEN): New + (parse_rereadable_options): New option --min-passphrase-len. + * genkey.c (check_passphrase_constraints): New. + (agent_genkey, agent_protect_and_store): Call new function. Fix + memory leak. + + * call-pinentry.c (agent_askpin): Allow translation of the displayed + error message. + (agent_popup_message_start): Remove arg CANCEL_BTN. + (popup_message_thread): Use --one-button option. + + * command.c (cmd_passwd): Now that we don't distinguish between + assuan and regular error codes we can jump to the end on error. + +2006-12-07 David Shaw + + * Makefile.am: Link to iconv for jnlib dependency. + +2006-11-20 Werner Koch + + * call-pinentry.c (agent_popup_message_stop): Use SIGKILL. + * call-scd.c (inq_needpin): Implement POPUPKEYPADPROMPT and + DISMISSKEYPADPROMPT. + +2006-11-15 Werner Koch + + * protect.c (make_shadow_info): Cast printf arg to unsigned int. + * minip12.c (parse_bag_encrypted_data): Ditto. + (parse_bag_data, p12_parse): Ditto. + * command-ssh.c (ssh_identity_register): Changed buffer_n to + size_t. + + * agent.h (struct server_control_s): New field thread_startup. + * command.c (start_command_handler): Moved CTRL init code to .. + * gpg-agent.c (start_connection_thread): .. here. + (agent_deinit_default_ctrl): New. + (agent_init_default_ctrl): Made static. + (handle_connections): Allocate CTRL and pass it pth_spawn. + * command-ssh.c (start_command_handler_ssh): Moved CTRL init code + to .. + * gpg-agent.c (start_connection_thread_ssh): .. here. + +2006-11-14 Werner Koch + + * command.c (bump_key_eventcounter): New. + (bump_card_eventcounter): New. + (cmd_geteventcounter): New command. + * gpg-agent.c (handle_signal): Call bump_card_eventcounter. + * findkey.c (agent_write_private_key): Call bump_key_eventcounter. + * trustlist.c (agent_reload_trustlist): Ditto. + + * command.c (post_cmd_notify, io_monitor): New. + (register_commands, start_command_handler): Register them. + +2006-11-09 Werner Koch + + * gpg-agent.c (main): In detached mode connect standard + descriptors to /dev/null. + + * trustlist.c (read_trustfiles): Make sure not to pass a zero size + to realloc as the C standards says that this behaves like free. + +2006-11-06 Werner Koch + + * protect-tool.c (my_strusage): Fixed typo. + +2006-10-23 Werner Koch + + * gpg-agent.c (main): New command --gpgconf-test. + + * minip12.c (parse_bag_encrypted_data, parse_bag_data): Allow for + a salt of 20 bytes. + +2006-10-20 Werner Koch + + * Makefile.am (t_common_ldadd): Use GPG_ERROR_LIBS instead -o just -l + +2006-10-19 Werner Koch + + * findkey.c (unprotect): Use it to avoid unnecessary calls to + agent_askpin. + * call-pinentry.c (pinentry_active_p): New. + +2006-10-17 Werner Koch + + * Makefile.am (gpg_agent_LDADD): Link to libcommonpth. + (gpg_agent_CFLAGS): New. This allows to only link this with Pth. + +2006-10-16 Werner Koch + + * call-pinentry.c (agent_get_confirmation): Map Cancel code here too. + * trustlist.c (agent_marktrusted): Return Cancel instead of + Not_Confirmed for the first question. + +2006-10-12 Werner Koch + + * protect-tool.c (get_passphrase): Fix if !HAVE_LANGINFO_CODESET. + +2006-10-06 Werner Koch + + * Makefile.am (AM_CFLAGS): Use PTH version of libassuan. + (gpg_agent_LDADD): Ditto. + + * divert-scd.c (divert_pksign): Use PKAUTH for the TLS algo. + +2006-10-05 Werner Koch + + * command.c (has_option_name): New. + (cmd_sethash): New --hash option. + * pksign.c (do_encode_raw_pkcs1): New. + (agent_pksign_do): Use it here for the TLS algo. + * agent.h (GCRY_MD_USER_TLS_MD5SHA1): New. + * divert-scd.c (pksign): Add case for tls-md5sha1. + + * divert-scd.c (encode_md_for_card): Check that the algo is valid. + +2006-10-04 Werner Koch + + * call-pinentry.c (agent_get_passphrase): Changed to return the + unencoded passphrase. + (agent_askpin, agent_get_passphrase, agent_get_confirmation): Need + to map the cancel error. + * command.c (send_back_passphrase): New. + (cmd_get_passphrase): Use it here. Also implement --data option. + (skip_options): New. + +2006-09-26 Werner Koch + + * learncard.c (agent_handle_learn): Send back the keypair + information. + +2006-09-25 Werner Koch + + * trustlist.c (read_one_trustfile): Allow extra flags. + (struct trustitem_s): Replaced KEYFLAGS by a FLAGS struct. + Changed all code to use this. + (agent_istrusted): New arg CTRL. Changed all callers. Send back + flags. + * command.c (agent_write_status): New. + +2006-09-20 Werner Koch + + * Makefile.am: Changes to allow parallel make runs. + +2006-09-15 Werner Koch + + * trustlist.c: Entirely rewritten. + (agent_trustlist_housekeeping): Removed and removed all calls. + +2006-09-14 Werner Koch + + Replaced all call gpg_error_from_errno(errno) by + gpg_error_from_syserror(). + + * call-pinentry.c (start_pinentry): Replaced pipe_connect2 by + pipe_connect_ext. + * call-scd.c (start_scd): Ditto. + * command.c (start_command_handler): Replaced + init_connected_socket_server by init_socket_server_ext. + +2006-09-13 Werner Koch + + * preset-passphrase.c (main) [W32]: Check for WSAStartup error. + +2006-09-08 Werner Koch + + * call-scd.c: Add signal.h as we are referencing SIGUSR2. + +2006-09-06 Marcus Brinkmann + + * Makefile.am (AM_CFLAGS): Add $(GPG_ERR_CFLAGS). + (gpg_agent_LDADD): Replace -lgpg-error with $(GPG_ERROR_LIBS). + +2006-09-06 Werner Koch + + * query.c: Renamed to .. + * call-pinentry.c: .. this. + + * agent.h (out_of_core): Removed. + (CTRL): Removed and changed everywhere to ctrl_t. + + Replaced all Assuan error codes by libgpg-error codes. Removed + all map_to_assuan_status and map_assuan_err. + + * gpg-agent.c (main): Call assuan_set_assuan_err_source to have Assuan + switch to gpg-error codes. + * command.c (set_error): Adjusted. + +2006-09-04 Werner Koch + + * command.c (percent_plus_unescape): New. + (cmd_get_val, cmd_putval): New. + +2006-08-29 Werner Koch + + * command-ssh.c (stream_read_mpi): Sanity check for early + detecting of too large keys. + * gpg-agent.c (my_gcry_outofcore_handler): New. + (main): Register it. + (main): No allocate 32k secure memory (was 16k). + +2006-07-31 Werner Koch + + * preset-passphrase.c (make_hexstring): For consistency use + xtrymalloc and changed caller to use xfree. Fixed function + comment. + +2006-07-29 Marcus Brinkmann + + * preset-passphrase.c (preset_passphrase): Do not strip off last + character of passphrase. + (make_hexstring): New function. + * command.c (cmd_preset_passphrase): Use parse_hexstring to syntax + check passphrase argument. Truncate passphrase at delimiter. + +2006-07-24 Werner Koch + + * minip12.c (build_key_bag): New args SHA1HASH and + KEYIDSTR. Append bag Attributes if these args are given. + (build_cert_sequence): ditto. + (p12_build): Calculate certificate hash and pass to build + functions. + +2006-07-21 Werner Koch + + * minip12.c (oid_pkcs_12_keyBag): New. + (parse_bag_encrypted_data): New arg R_RESULT. Support keybags and + return the key object. + (p12_parse): Take new arg into account. Free RESULT on error. + +2006-06-26 Werner Koch + + * gpg-agent.c (handle_signal): Print info for SIGUSR2 only in + verbose mode. + +2006-06-22 Werner Koch + + * command-ssh.c (make_cstring): Use memcpy instead of strncpy. + (ssh_receive_mpint_list, sexp_key_extract, data_sign): Use + xtrycalloc instead of xtrymalloc followed by memset. + +2006-06-20 Werner Koch + + * minip12.c (create_final): New arg PW. Add code to calculate the + MAC. + +2006-06-09 Marcus Brinkmann + + * Makefile.am (gpg_agent_LDADD): Add $(NETLIBS). + (gpg_protect_tool_LDADD): Likewise. + (gpg_preset_passphrase_LDADD): Likewise. + +2006-04-09 Moritz Schulte + + * command-ssh.c (ssh_request_process): Removed FIXME mentioning a + possible DoS attack. + +2006-04-01 Moritz Schulte + + * command-ssh.c (ssh_identity_register): Make KEY_GRIP_RAW be 20 + instead of 21 bytes long; do not fill KEY_GRIP_RAW[20] with NUL + byte - KEY_GRIP_RAW is a raw binary string anyway. + +2006-02-09 Werner Koch + + * call-scd.c (struct scd_local_s): New field next_local. + (scd_local_list): New. + (start_scd): Put new local into list. + (agent_reset_scd): Remove it from the list. + (agent_scd_check_aliveness): Here is the actual reason why we need + all this stuff. + (agent_reset_scd): Send the new command RESTART instead of RESET. + +2005-12-16 Werner Koch + + * minip12.c (cram_octet_string): New + (p12_parse): Use it for NDEFed bags. + (parse_bag_data): Ditto. + (string_to_key, set_key_iv, crypt_block): New arg SALTLEN. + (p12_build): Use old value 8 for new arg. + (parse_bag_encrypted_data, parse_bag_data): Allow for salts of 8 + to 16 bytes. Add new arg R_CONSUMED. + +2005-11-24 Werner Koch + + * minip12.c (p12_parse): Fixed for case that the key object comes + prior to the certificate. + +2005-10-19 Werner Koch + + * divert-scd.c (getpin_cb): Hack to use it for a keypad message. + + * call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO. + + * query.c (start_pinentry): Keep track of the owner. + (popup_message_thread, agent_popup_message_start) + (agent_popup_message_stop, agent_reset_query): New. + * command.c (start_command_handler): Make sure a popup window gets + closed. + +2005-10-08 Marcus Brinkmann + + * Makefile.am (gpg_protect_tool_LDADD): Add ../gl/libgnu.a. + (gpg_preset_passphrase_LDADD, t_common_ldadd): Likewise. + (gpg_agent_LDADD): Add ../gl/libgnu.a after ../common/libcommon.a. + +2005-09-16 Werner Koch + + * minip12.c (build_key_sequence, build_cert_sequence): Fixed + padding. + +2005-09-15 Moritz Schulte + + * t-protect.c (test_agent_protect): Implemented. + (main): Disable use of secure memory. + +2005-09-09 Werner Koch + + * minip12.c (p12_build): Oops, array needs to be larger for the + certificate. + (build_cert_bag): Fixed yesterdays change. + + * command-ssh.c (card_key_available): Let the card handler decide + whether the card is supported here. Also get a short serial + number to return from the card handler. + +2005-09-08 Werner Koch + + * minip12.c (build_cert_bag): Use a non constructed object. + i.e. 0x80 and not 0xa0. + +2005-08-16 Werner Koch + + * gpg-agent.c (main): Use a default file name for --write-env-file. + +2005-07-25 Werner Koch + + * findkey.c (agent_public_key_from_file): Fixed array assignment. + This was the cause for random segvs. + +2005-06-29 Werner Koch + + * command-ssh.c (data_sign): Removed empty statement. + +2005-06-21 Werner Koch + + * minip12.c (create_final): Cast size_t to ulong for printf. + (build_key_bag, build_cert_bag, build_cert_sequence): Ditto. + +2005-06-16 Werner Koch + + * protect-tool.c (make_advanced): Makde RESULT a plain char. + * call-scd.c (unescape_status_string): Need to cast unsigned char* + for strcpy. + (agent_card_pksign): Made arg R_BUF an unsigned char**. + * divert-scd.c (divert_pksign): Made SIGVAL unsigned char*. + (encode_md_for_card): Initialize R_VAL and R_LEN. + * genkey.c (store_key): Made BUF unsigned. + * protect.c (do_encryption): Ditto. + (do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT + and RESULTLEN even on error. + (merge_lists): Need to cast unsigned char * for strcpy. Initialize + RESULTand RESULTLEN even on error. + (agent_unprotect): Likewise for strtoul. + (make_shadow_info): Made P and INFO plain char. + (agent_shadow_key): Made P plain char. + +2005-06-15 Werner Koch + + * query.c (agent_get_passphrase): Made HEXSTRING a char*. + * command-ssh.c (ssh_key_grip): Made arg BUFFER unsigned. + (ssh_key_grip): Simplified. + (data_sign): Initialize variables with the definition. + (ssh_convert_key_to_blob): Make sure that BLOB and BLOB_SIZE + are set to NULL on error. Cool, gcc-4 detects uninitialized stuff + beyond function boundaries; well it can't know that we do error + proper error handling so that this was not a real error. + (file_to_buffer): Likewise for BUFFER and BUFFER_N. + (data_sign): Likewise for SIG and SIG_N. + (stream_read_byte): Set B to a value even on error. + * command.c (cmd_genkey): Changed VALUE to char. + (cmd_readkey): Cast arg for gcry_sexp_sprint. + * agent.h (struct server_control_s): Made KEYGRIP unsigned. + +2005-06-13 Werner Koch + + * command-ssh.c (start_command_handler_ssh): Reset the SCD. + +2005-06-09 Werner Koch + + * gpg-agent.c (create_socket_name): New option --max-cache-ttl-ssh. + * cache.c (housekeeping): Use it. + (agent_put_cache): Use a switch to get the default ttl so that it + is easier to add more cases. + +2005-06-06 Werner Koch + + * gpg-agent.c: New option --default-cache-ttl-ssh. + * agent.h (cache_mode_t): New. + * pksign.c (agent_pksign_do): New arg CACHE_MODE to replace the + ARG IGNORE_CACHE. Changed all callers. + (agent_pksign): Ditto. + * findkey.c (agent_key_from_file): Ditto. Canged all callers. + (unprotect): Ditto. + * command-ssh.c (data_sign): Use CACHE_MODE_SSH. + * cache.c (agent_get_cache): New arg CACHE_MODE. + (agent_put_cache): Ditto. Store it in the cache. + + * query.c (agent_query_dump_state, dump_mutex_state): New. + (unlock_pinentry): Reset the global context before releasing the + mutex. + * gpg-agent.c (handle_signal): Dump query.c info on SIGUSR1. + + * call-scd.c (agent_scd_check_aliveness): Always do a waitpid and + add a timeout to the locking. + +2005-06-03 Werner Koch + + * command.c (cmd_updatestartuptty): New. + + * gpg-agent.c: New option --write-env-file. + + * gpg-agent.c (handle_connections): Make sure that the signals we + are handling are not blocked.Block signals while creating new + threads. + +2005-06-02 Werner Koch + + * call-scd.c (agent_scd_dump_state, dump_mutex_state): New. + * gpg-agent.c (handle_signal): Print it on SIGUSR1. + (handle_connections): Include the file descriptor into the + threadnames. + +2005-06-01 Werner Koch + + * gpg-agent.c: Include setenv.h. + +2005-05-31 Werner Koch + + * agent.h (out_of_core): s/__inline__/inine. Noted by Ray Link. + +2005-05-25 Werner Koch + + * gpg-agent.c (main): Do not unset the DISPLAY when we are + continuing as child. + +2005-05-24 Werner Koch + + * call-scd.c (inq_needpin): Skip leading spaces in of PIN + description. + * divert-scd.c (getpin_cb): Enhanced to cope with description + flags. + * query.c (agent_askpin): Add arg PROMPT_TEXT. Changed all + callers. + +2005-05-21 Werner Koch + + * call-scd.c (start_scd): Don't test for an alive scdaemon here. + (agent_scd_check_aliveness): New. + * gpg-agent.c (handle_tick): Test for an alive scdaemon. + (handle_signal): Print thread info on SIGUSR1. + +2005-05-20 Werner Koch + + * protect-tool.c: New option --canonical. + (show_file): Implement it. + + * keyformat.txt: Define the created-at attribute for keys. + +2005-05-18 Werner Koch + + * divert-scd.c (ask_for_card): Removed the card reset kludge. + +2005-05-17 Werner Koch + + * call-scd.c (unlock_scd): Add new arg CTRL. Changed all callers. + (start_scd): Reoworked to allow for additional connections. + * agent.h (ctrl_t): Add local data for the SCdaemon. + * command.c (start_command_handler): Release SERVER_LOCAL. + + * gpg-agent.c (create_server_socket): Use xmalloc. + (main): Removed option --disable-pth a dummy. Removed non-pth + code path. + (cleanup_sh): Removed. Not needed anymore. + +2005-05-05 Moritz Schulte + + * command-ssh.c (ssh_key_to_buffer): Rename to ... + (ssh_key_to_protected_buffer): ... this; change callers. + Improved documentation. + Use ssh_key_grip(), where gcry_pk_get_keygrip() has been used + before. + (ssh_handler_sign_request): Removed unusued variable P. + +2005-04-20 Moritz Schulte + + * command-ssh.c (ssh_handler_request_identities): Removed + debugging code (sleep call), which was commited unintenionally. + +2005-04-20 Werner Koch + + * minip12.c (parse_bag_encrypted_data): Fix the unpadding hack. + + * gpg-agent.c: New option --disable-scdaemon. + (handle_connections): Add time event to drive ... + (handle_tick): New function. + (main): Record the parent PID. Fixed segv when using ssh and a + command. + + * call-scd.c (start_scd): Take care of this option. + +2005-04-03 Moritz Schulte + + * command-ssh.c (ssh_request_spec): New member: secret_input. + (REQUEST_SPEC_DEFINE): New argument: secret_input. + (request_specs): Add secret_input flag. + (request_spec_lookup): New function ... + (ssh_request_process): ... use it here; depending on secret_input + flag allocate secure or non-secure memory. + +2005-03-02 Moritz Schulte + + * command-ssh.c (sexp_key_extract): Removed FIXME, since + xtrymallos does set errno correctly by now. + (sexp_extract_identifier): Remove const attribute from identifier. + (ssh_handler_request_identities): Remove const attribute from + key_type; removes ugly casts and FIXME. + (sexp_key_extract): Remove const attribute from comment. + (ssh_send_key_public): Remove const attribute from + key_type/comment; removes ugly cast. + (data_sign): Remove const attribute from identifier; removes ugly + cast. + (key_secret_to_public): Remove const attribute from comment; + removes ugly cast. + (ssh_handler_sign_request): Remove const attribute from p. + (sexp_key_extract): Use make_cstring(). + (ssh_key_extract_comment): Likewise. + (ssh_key_to_buffer): Use secure memory for memory area to hold the + key S-Expression. + Added more comments. + +2005-02-25 Werner Koch + + * findkey.c (modify_description): Keep invalid % escapes, so that + %0A may pass through. + + * agent.h (server_control_s): New field USE_AUTH_CALL. + * call-scd.c (agent_card_pksign): Make use of it. + * command-ssh.c (data_sign): Set the flag. + (ssh_send_key_public): New arg OVERRIDE_COMMENT. + (card_key_available): Add new arg CARDSN. + (ssh_handler_request_identities): Use the card s/n as comment. + (sexp_key_extract): Use GCRYMPI_FMT_STD. + (data_sign): Ditto. + + * learncard.c (make_shadow_info): Moved to .. + * protect.c (make_shadow_info): .. here. Return NULL on malloc + failure. Made global. + * agent.h: Add prototype. + +2005-02-24 Werner Koch + + * call-scd.c (unescape_status_string): New. Actual a copy of + ../g10/call-agent.c + (card_getattr_cb, agent_card_getattr): New. + + * command-ssh.c (card_key_available): New. + (ssh_handler_request_identities): First see whether a card key is + available. + + * gpg-agent.c (handle_connections): Need to check for events if + select returns with -1. + +2005-02-23 Werner Koch + + * command-ssh.c (get_passphrase): Removed. + (ssh_identity_register): Partly rewritten. + (open_control_file, search_control_file, add_control_entry): New. + (ssh_handler_request_identities): Return only files listed in our + control file. + + * findkey.c (unprotect): Check for allocation error. + + * agent.h (opt): Add fields to record the startup terminal + settings. + * gpg-agent.c (main): Record them and do not force keep display + with --enable-ssh-support. + * command-ssh.c (start_command_handler_ssh): Use them here. + + * gpg-agent.c: Renamed option --ssh-support to + --enable-ssh-support. + + * command.c (cmd_readkey): New. + (register_commands): Register new command "READKEY". + + * command-ssh.c (ssh_request_process): Improved logging. + + * findkey.c (agent_write_private_key): Always use plain open. + Don't depend on an umask for permissions. + (agent_key_from_file): Factored file reading code out to .. + (read_key_file): .. new function. + (agent_public_key_from_file): New. + +2005-02-22 Werner Koch + + * command-ssh.c (stream_read_string): Removed call to abort on + memory error because the CVS version of libgcrypt makes sure + that ERRNO gets always set on error even with a faulty user + supplied function. + +2005-02-19 Moritz Schulte + + * command-ssh.c (ssh_receive_mpint_list): Slightly rewritten, do + not use elems_secret member of key_spec. + (ssh_key_type_spec): Removed member: elems_secret. + (ssh_key_types): Removed elems_secret data. + (ssh_sexp_construct): Renamed to ... + (sexp_key_construct): ... this; changed callers. + (ssh_sexp_extract): Renamed to ... + (sexp_key_extract): ... this; changed callers. + (ssh_sexp_extract_key_type): Renamed to ... + (sexp_extract_identifier): ... this; changed callers; use + make_cstring(). + Added more comments. + +2005-02-18 Moritz Schulte + + * command-ssh.c (ssh_sexp_construct): Rewritten generation of sexp + template, clarified. + (ssh_sexp_extract): Support shadowed-private-key-sexp; treat + protected-private key and shadowed-private-key as public keys. + (key_secret_to_public): Rewritten: simply use ssh_sexp_extract() + and ssh_sexp_construct(). + +2005-02-15 Werner Koch + + * findkey.c (modify_description): Don't increment OUT_LEN during + the second pass. + +2005-02-14 Moritz Schulte + + * command-ssh.c (es_read_byte): Renamed to ... + (stream_es_read_byte): ... this; changed callers. + (es_write_byte): Renamed to ... + (stream_write_byte): ... this; changed callers. + (es_read_uint32): Renamed to ... + (stream_read_uint32): ... this; changed callers. + (es_write_uint32): Renamed to ... + (stream_write_uint32): ... this; changed callers. + (es_read_data): Renamed to ... + (stream_read_data): ... this; changed callers. + (es_write_data): Renamed to ... + (stream_write_data): ... this; changed callers. + (es_read_string): Renamed to ... + (stream_read_string): ... this; changed callers. + (es_read_cstring): Renamed to ... + (stream_read_cstring): ... this; changed callers. + (es_write_string): Renamed to ... + (stream_write_string): ... this; changed callers. + (es_write_cstring): Renamed to ... + (stream_write_cstring): ... this; changed callers. + (es_read_mpi): Renamed to ... + (stream_read_mpi): ... this; changed callers. + (es_write_mpi): Renamed to ... + (stream_write_mpi): ... this; changed callers. + (es_copy): Renamed to ... + (stream_copy): ... this; changed callers. + (es_read_file): Renamed to ... + (file_to_buffer): ... this; changed callers. + (ssh_identity_register): Removed variable description_length; + changed code to use asprintf for description. + (stream_write_uint32): Do not filter out the last byte of shift + expression. + (uint32_construct): New macro ... + (stream_read_uint32): ... use it; removed unnecessary cast. + +2005-02-03 Werner Koch + + * agent.h (agent_exit): Add JNLIB_GCC_A_NR to indicate that this + function won't return. + + * gpg-agent.c (check_for_running_agent): Initialize pid to a + default value if not needed. + + * command-ssh.c: Removed stdint.h. s/byte_t/unsigned char/, + s/uint32/u32/ becuase that is what we have always used in GnuPG. + (ssh_request_specs): Moved to top of file. + (ssh_key_types): Ditto. + (make_cstring): Ditto. + (data_sign): Don't use a variable for the passphrase prompt, make + it translatable. + (ssh_request_process): + + + * findkey.c (modify_description): Renamed arguments for clarity, + polished documentation. Make comment a C-string. Fixed case of + DESCRIPTION being just "%". + (agent_key_from_file): Make sure comment string to a C-string. + + * gpg-agent.c (create_socket_name): Cleanup the implemntation, use + DIMof, agent_exit, removed superflous args and return the + allocated string as value. Documented. Changed callers. + (create_server_socket): Cleanups similar to above. Changed callers. + (cleanup_do): Renamed to .. + (remove_socket): .. this. Changed caller. + (handle_connections): The signals are to be handled in the select + and not in the accept. Test all FDs after returning from a + select. Remove the event tests from the accept calls. The select + already assured that the accept won't block. + +2005-01-29 Moritz Schulte + + * command-ssh.c (ssh_handler_request_identities) + (ssh_handler_sign_request, ssh_handler_add_identity) + (ssh_handler_remove_identity, ssh_handler_remove_all_identities) + (ssh_handler_lock, ssh_handler_unlock): Changed to return an error + code instead of a boolean. + (ssh_request_process): Changed to return a boolean instead of an + error; adjust caller. + (ssh_request_handle_t): Adjusted type. + (ssh_request_spec): New member: identifier. + (REQUEST_SPEC_DEFINE): New macro; use it for initialization of + request_specs[]. + (ssh_request_process): In debugging mode, log identifier of + handler to execute. + (start_command_handler_ssh): Moved most of the stream handling + code ... + (ssh_request_process): ... here. + +2005-01-28 Moritz Schulte + + * command-ssh.c (ssh_handler_add_identity): Pass ctrl to + ssh_identity_register(). + (ssh_identity_register): New argument: ctrl; pass ctrl to + get_passphrase(). + (get_passphrase): Pass ctrl instead of NULL to agent_askpin(). + (start_command_handler_ssh): Use agent_init_default_ctrl(); + deallocate structure members, which might be dynamically + allocated. + (lifetime_default): Removed variable. + (ssh_handler_add_identity): Fix ttl handling; renamed variable + `death' to `ttl'. + (ssh_identity_register): Fix key grip handling. + +2005-01-26 Moritz Schulte + + * command-ssh.c (ssh_handler_sign_request): Confirm to agent + protocol in case of failure. + + * command-ssh.c: New file. + + * Makefile.am (gpg_agent_SOURCES): New source file: command-ssh.c. + + * findkey.c (modify_description): New function. + (agent_key_from_file): Support comment field in key s-expressions. + + * gpg-agent.c (enum cmd_and_opt_values): New item: oSSHSupport. + (opts) New entry for oSSHSupport. + New variable: socket_name_ssh. + (cleanup_do): New function based on cleanup(). + (cleanup): Use cleanup_do() for socket_name and socket_name_ssh. + (main): New switch case for oSSHSupport. + (main): Move socket name creation code to ... + (create_socket_name): ... this new function. + (main): Use create_socket_name() for creating socket names for + socket_name and for socket_name_ssh in case ssh support is + enabled. + Move socket creation code to ... + (create_server_socket): ... this new function. + (main): Use create_server_socket() for creating sockets. + In case standard_socket is set, do not only store a socket name in + socket_name, but also in socket_name_ssh. + Generate additional environment info strings for ssh support. + Pass additional ssh socket argument to handle_connections. + (start_connection_thread_ssh): New function. + (handle_connections): Use select to multiplex between gpg-agent + and ssh-agent protocol. + + * agent.h (struct opt): New member: ssh_support. + (start_command_handler_ssh): Add prototype. + +2005-01-04 Werner Koch + + * trustlist.c (agent_marktrusted): Use "Cancel" for the first + confirmation and made the strings translatable. + + * cache.c (agent_put_cache): Fix the test for using the default + TTL. + +2004-12-21 Werner Koch + + * preset-passphrase.c (preset_passphrase): Handle --passphrase. + + * Makefile.am (gpg_preset_passphrase_LDADD): Reorder libs so that + pwquery may use stuff from jnlib. Conditionally add -lwsock2 + (gpg_protect_tool_LDADD): Ditto. + + * preset-passphrase.c (main): Use default_homedir(). + (main) [W32]: Initialize sockets. + +2004-12-21 Marcus Brinkmann + + * Makefile.am (libexec_PROGRAMS): Add gpg-preset-passphrase. + (gpg_preset_passphrase_SOURCES, gpg_preset_passphrase_LDADD): New + targets. + * agent.h (opt): New member allow_cache_passphrase. + * cache.c (housekeeping): Check if R->ttl is not negative. + (agent_put_cache): Allow ttl to be negative. + * command.c (parse_hexstring): Allow something to follow the + hexstring. + (cmd_cache_passphrase): New function. + (register_commands): Add it. + * gpg-agent.c: Handle --allow-preset-passphrase. + * preset-passphrase.c: New file. + +2004-12-21 Werner Koch + + * gpg-agent.c (main): Use default_homedir(). + * protect-tool.c (main): Ditto. + +2004-12-20 Werner Koch + + * gpg-agent.c (main) [W32]: Now that Mutexes work we can remove + the pth_init kludge. + (main): Add new options --[no-]use-standard-socket. + (check_for_running_agent): Check whether it is running on the + standard socket. + + * call-scd.c (init_membuf, put_membuf, get_membuf): Removed. We + now use the identical implementation from ../common/membuf.c. + + * pksign.c (agent_pksign): Changed arg OUTFP to OUTBUF and use + membuf functions to return the value. + * pkdecrypt.c (agent_pkdecrypt): Ditto. + * genkey.c (agent_genkey): Ditto. + * command.c (cmd_pksign, cmd_pkdecrypt, cmd_genkey): Replaced + assuan_get_data_fp() by a the membuf scheme. + (clear_outbuf, write_and_clear_outbuf): New. + +2004-12-19 Werner Koch + + * query.c (initialize_module_query): New. + * call-scd.c (initialize_module_call_scd): New. + * gpg-agent.c (main): Call them. + +2004-12-18 Werner Koch + + * gpg-agent.c (main): Remove special Pth initialize. + + * agent.h (map_assuan_err): Define in terms of + map_assuan_err_with_source. + +2004-12-17 Moritz Schulte + + * query.c: Undo change from 2004-12-05. + +2004-12-15 Werner Koch + + * gpg-agent.c [W32]: Various hacks to make it work. + + * findkey.c (agent_write_private_key) [W32]: Adjust open call. + + * call-scd.c (start_scd) [W32]: Don't check whether the daemon + didn't died. To hard to do under Windows. + (start_scd) [W32]: Disable sending of the event signal option. + + * protect-tool.c (read_file, export_p12_file) [W32]: Use setmode + to get stdout and stin into binary mode. + +2004-12-05 Moritz Schulte + + * query.c (start_pinentry): Allow CTRL be NULL. + +2004-10-22 Werner Koch + + * gpg-agent.c (parse_rereadable_options): Return "not handled" + when the log file has not beend hadled. This is will let the main + option processing continue. Fixed a bug introduced on 2004-09-4 + resulting in logging to stderr until a HUP has been given. + (main): Don't close the listen FD. + +2004-09-30 Werner Koch + + * Makefile.am: Adjusted from gettext 1.14. + +2004-09-29 Werner Koch + + * minip12.c (parse_bag_encrypted_data): Print error if a bad + passphrase has been given. + +2004-09-28 Werner Koch + + * protect.c (agent_unprotect): Fixed wiping of CLEARTEXT. Thanks + to Moritz for pointing this out. + +2004-09-25 Moritz Schulte + + * agent.h: Declare: agent_pksign_do. + (struct server_control_s): New member: raw_value. + + * pksign.c (do_encode_md): New argument: raw_value; support + generation of raw (non-pkcs1) data objects; adjust callers. + (agent_pksign_do): New function, based on code ripped + out from agent_pksign. + (agent_pksign): Use agent_pksign_do. + + * command.c (start_command_handler): Set ctrl.digest.raw_value. + +2004-09-09 Werner Koch + + * gpg-agent.c (check_for_running_agent): New. + (main): The default action is now to check for an already running + agent. + (parse_rereadable_options): Set logfile only on reread. + (main): Do not print the "is development version" note. + +2004-08-20 Werner Koch + + * gpg-agent.c: New option --max-cache-ttl. Suggested by Alexander + Belopolsky. + * cache.c (housekeeping): Use it here instead of the hardwired + default of 1 hour. + + * query.c (start_pinentry): Use a timeout for the pinentry lock. + +2004-08-18 Werner Koch + + * protect-tool.c (get_passphrase): Make sure that the default + prompts passed to gpg-agent are utf-8 encoded. Add new prompt values. + (import_p12_file, import_p12_file, export_p12_file): Changed calls + to get_passphrase so that better prompts are displayed. + (get_new_passphrase): New. + +2004-07-22 Werner Koch + + * trustlist.c (read_list): Allow colons in the fingerprint. + (headerblurb): Rephrased. + + * gpg-agent.c (handle_connections): Increase the stack size ot 256k. + +2004-06-20 Moritz Schulte + + * gpg-agent.c: Include (build fix for BSD). + +2004-05-11 Werner Koch + + * gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP. + (start_connection_thread): Hack to simulate a ticker. + * trustlist.c (agent_trustlist_housekeeping) + (agent_reload_trustlist): New. Protected all global functions + here with a simple counter which is sufficient for Pth. + +2004-05-03 Werner Koch + + * gpg-agent.c: Remove help texts for options lile --lc-ctype. + (main): New option --allow-mark-trusted. + * trustlist.c (agent_marktrusted): Use it here. + +2004-04-30 Werner Koch + + * protect-tool.c: New option --enable-status-msg. + (store_private_key): Print status messages for imported keys. + (read_and_unprotect): Ditto for bad passphrase. + + * gpg-agent.c (parse_rereadable_options): New arg REREAD. Allow + changing oLogFile. + (current_logfile): New. + +2004-04-26 Werner Koch + + * call-scd.c (start_scd): Do not register an event signal if we + are running as a pipe server. + +2004-04-21 Werner Koch + + * call-scd.c (start_scd): Send event-signal option. Always check + that the scdaemon is still running. + + * gpg-agent.c (handle_signal): Do not use SIGUSR{1,2} anymore for + changing the verbosity. + +2004-04-16 Werner Koch + + * gpg-agent.c (main): Tell the logging code that we are running + detached. + +2004-04-06 Werner Koch + + * gpg-agent.c (main): Use new libgcrypt thread library register + scheme. + +2004-03-23 Marcus Brinkmann + + * gpg-agent.c (main): For now, always print the default config + file name for --gpgconf-list. + +2004-03-17 Werner Koch + + * gpg-agent.c (main) : Fixed default value quoting. + +2004-03-16 Werner Koch + + * gpg-agent.c (parse_rereadable_options): Use the new + DEFAULT_CACHE_TTL macro. + (main): Updated --gpgconf-list output. + +2004-02-21 Werner Koch + + * command.c (cmd_passwd): Take acount of a key description. + + * genkey.c (reenter_compare_cb): Do not set the error text. + (agent_protect_and_store, agent_genkey): Force a re-enter after a + non-matching passphrase. + * query.c (agent_askpin): Add new arg INITIAL_ERRTEXT; changed + all callers. + +2004-02-19 Werner Koch + + * protect-tool.c: New options --have-cert and --prompt. + (export_p12_file): Read a certificate from STDIN and pass it to + p12_build. Detect a keygrip and construct the filename in that + case. Unprotcet a key if needed. Print error messages for key + formats we can't handle. + (release_passphrase): New. + (get_passphrase): New arg PROMPTNO. Return the allocated + string. Changed all callers. + + * minip12.c: Revamped the build part. + (p12_build): New args CERT and CERTLEN. + +2004-02-18 Werner Koch + + * protect-tool.c (main): Setup the used character set. + * gpg-agent.c (main): Ditto. + + * gpg-agent.c (set_debug): New. New option --debug-level. + (main): New option --gpgconf-list. + +2004-02-17 Werner Koch + + * pksign.c (do_encode_md): Cleaned up by using gcry_sexp_build. + + * Makefile.am (gpg_protect_tool_SOURCES): Removed + simple-pwquery.[ch], as we once moved it to ../common. + +2004-02-13 Werner Koch + + * command.c (cmd_setkeydesc): New. + (register_commands): Add command SETKEYDESC. + (cmd_pksign, cmd_pkdecrypt): Use the key description. + (reset_notify): Reset the description. + * findkey.c (unprotect): Add arg DESC_TEXT. + (agent_key_from_file): Ditto. + * pksign.c (agent_pksign): Ditto. + * pkdecrypt.c (agent_pkdecrypt): Ditto. Made CIPHERTEXT an + unsigned char*. + + * protect-tool.c (main): New options --no-fail-on-exist, --homedir. + (store_private_key): Use them here. + +2004-02-12 Werner Koch + + * protect-tool.c (read_file, main): Allow reading from stdin. + + * Makefile.am: Include cmacros.am for common flags. + (libexec_PROGRAMS): Put gpg-protect-tool there. + +2004-02-10 Werner Koch + + * minip12.c (parse_bag_encrypted_data): Finished implementation. + (p12_parse): Add callback args. + * protect-tool.c (import_p12_cert_cb): New. + (import_p12_file): Use it. + +2004-02-06 Werner Koch + + * minip12.c (crypt_block): Add arg CIPHER_ALGO; changed all callers. + (set_key_iv): Add arg KEYBYTES; changed caller. + +2004-02-03 Werner Koch + + * findkey.c (agent_key_from_file): Extra paranoid wipe. + * protect.c (agent_unprotect): Ditto. + (merge_lists): Ditto. Add arg RESULTLEN. + * pkdecrypt.c (agent_pkdecrypt): Don't show the secret key even in + debug mode. + + * protect.c: Add DSA and Elgamal description. + +2004-01-29 Werner Koch + + * agent.h (server_control_s): Add connection_fd field. + * command.c (start_command_handler): Init it here. + * gpg-agent.c (agent_init_default_ctrl): and here. + * call-scd.c: Add the CTRL arg to all functions calling start_scd + and pass it to start_scd. Changed all callers + (start_scd): Keep track of the current active connection. + (agent_reset_scd): New. + * command.c (start_command_handler): Call it here. + * learncard.c (agent_handle_learn): Add arg CTRL; changed caller. + (send_cert_back): Ditto. + +2004-01-28 Werner Koch + + * trustlist.c (agent_marktrusted): Check whether the trustlist is + writable. + +2004-01-27 Werner Koch + + * sexp-parse.h: Moved to ../common. + +2004-01-24 Werner Koch + + * call-scd.c (atfork_cb): New. + (start_scd): Make sure secmem gets cleared. + * query.c (atfork_cb): New. + (start_pinentry): Make sure secmem gets cleared. + +2004-01-16 Werner Koch + + * findkey.c (agent_key_from_file): Now return an error code so + that we have more detailed error messages in the upper layers. + This fixes the handling of pinentry's cancel button. + * pksign.c (agent_pksign): Changed accordingly. + * pkdecrypt.c (agent_pkdecrypt): Ditto. + * command.c (cmd_passwd): Ditto. + +2003-12-16 Werner Koch + + * gpg-agent.c (main): Set the prefixes for assuan logging. + +2003-12-15 Werner Koch + + * protect.c (do_encryption): Use gcry_create_nonce instad of the + obsolete WEAK_RANDOM. + +2003-11-20 Werner Koch + + * sexp-parse.h (snext): Don't use atoi_1 and digitp macros, so + that this file is useful by other applications too. + +2003-10-27 Werner Koch + + * command.c (cmd_get_confirmation): New command. + +2003-08-20 Timo Schulz + + * pksign.c (do_encode_md): Allocate enough space. Cast md + byte to unsigned char to prevent sign extension. + +2003-08-14 Timo Schulz + + * pksign.c (do_encode_md): Due to the fact pkcs#1 padding + is now in Libgcrypt, use the new interface. + +2003-07-31 Werner Koch + + * Makefile.am (gpg_agent_LDADD): Added INTLLIBS. + (gpg_protect_tool_SOURCES): Added simple-pwquery.[ch] + +2003-07-27 Werner Koch + + Adjusted for gcry_mpi_print and gcry_mpi_scan API change. + +2003-07-15 Werner Koch + + * simple-pwquery.c, simple-pwquery.h: Moved to ../common. + * Makefile.am (gpg_protect_tool_LDADD): Add simple-pwquery.o. + Removed it from xx_SOURCES. + +2003-07-04 Werner Koch + + * gpg-agent.c (handle_connections): Kludge to allow use of Pth 1 + and 2. + +2003-06-30 Werner Koch + + * call-scd.c (learn_status_cb): Store the serialno in PARM. + +2003-06-26 Werner Koch + + * call-scd.c (agent_card_serialno): Don't do a RESET anymore. + +2003-06-25 Werner Koch + + * command.c (cmd_scd): New. + * call-scd.c (agent_card_scd): New. + * divert-scd.c (divert_generic_cmd): New + + * call-scd.c (agent_card_learn): New callback args SINFO. + (learn_status_cb): Pass all other status lines to the sinfo + callback. + * learncard.c (release_sinfo, sinfo_cb): New. + (agent_handle_learn): Pass the new cb to the learn function and + pass the collected information back to the client's assuan + connection. + + * gpg-agent.c (main): Moved pth_init before gcry_check_version. + +2003-06-24 Werner Koch + + * gpg-agent.c (handle_connections): Adjusted for Pth 2.0 + + Adjusted for changes in the libgcrypt API. Some more fixes for the + libgpg-error stuff. + +2003-06-04 Werner Koch + + Renamed error codes from INVALID to INV and removed _ERROR suffixes. + +2003-06-03 Werner Koch + + Changed all error codes in all files to the new libgpg-error scheme. + + * agent.h: Include gpg-error.h and errno.h + * Makefile.am: Link with libgpg-error + + * query.c: assuan.h is now a system header. + * genkey.c (agent_genkey): Fixed silly use of xmalloc by + xtrymalloc. + +2003-04-29 Werner Koch + + * command.c (register_commands): Adjusted for new Assuan semantics. + + * Makefile.am: Don't override LDFLAGS. + +2002-12-04 Werner Koch + + * gpg-agent.c: New variable config_filename. + (parse_rereadable_options): New. + (main): Use it here. Add setting of default values, set + config_filename. + (reread_configuration): Filled with actual code. + +2002-12-03 Werner Koch + + * protect-tool.c (read_key): Don't run make_canonical on a NULL + buffer. + + * command.c (parse_hexstring): New. + (cmd_sethash): Use it. + (parse_keygrip): New. + (cmd_havekey, cmd_sigkey): Use it. + (cmd_passwd): New. + * genkey.c (agent_protect_and_store): New. + (store_key): Add arg FORCE. + (agent_genkey): Pass false to this force of store_key. + +2002-11-13 Werner Koch + + * gpg-agent.c (main): Switch all messages to utf-8. + + * simple-pwquery.c (agent_send_all_options): Use $GPG_TTY and + stdin with ttyname. + + * cache.c (new_data): Uiih - /sizeof d/sizeof *d/. + +2002-11-10 Werner Koch + + * command.c (option_handler): Fix keep_tty check. + +2002-11-06 Werner Koch + + * gpg-agent.c (main): Make sure we have a default ttyname. + * command.c (option_handler): Check opt.keep_tty here + * query.c (start_pinentry): but not anymore here. + +2002-11-05 Werner Koch + + * agent.h (opt,server_control_s): Move display and lc_ variables + to the control struct so that they are per connection. + * gpg-agent.c (agent_init_default_ctrl): New. + (main): Assign those command line options to new default_* variables. + Reset DISPLAY in server mode so that tehre is no implicit default. + * command.c (start_command_handler): Initialize and deinitialize + the control values. + (option_handler): Work on the ctrl values and not on the opt. + * query.c (start_pinentry): New argument CTRL to set the display + connection specific. Changed all callers to pass this value. + (agent_askpin,agent_get_passphrase,agent_get_confirmation): Add + CTRL arg and pass it ot start_pinentry. + * command.c (cmd_get_passphrase): Pass CTRL argument. + * trustlist.c (agent_marktrusted): Add CTRL argument + * command.c (cmd_marktrusted): Pass CTRL argument + * divert-scd.c (ask_for_card): Add CTRL arg. + (divert_pksign,divert_pkdecrypt): Ditto. Changed caller. + (getpin_cb): Use OPAQUE to pass the CTRL variable. Changed both + users. + * findkey.c (unprotect): Add CTRL arg. + (agent_key_from_file): Ditto. + + * query.c (unlock_pinentry): Disconnect the pinentry so that we + start a new one for each request. This is required to support + clients with different environments (e.g. X magic cookies). + +2002-09-05 Neal H. Walfield + + * gpg-agent.c (main) [USE_GNU_PTH]: No need to call + assuan_set_io_func as assuan is smart. + +2002-09-25 Werner Koch + + * gpg-agent.c (handle_signal): Flush cache on SIGHUP. + * cache.c (agent_flush_cache): New. + + * gpg-agent.c, agent.h: Add --keep-display and --keep-tty. + * query.c (start_pinentry): Implement them. The option passing + needs more thoughts. + +2002-09-09 Werner Koch + + * gpg-agent.c (create_private_keys_directory) + (create_directories): New. + (main): Try to create a home directory. + +2002-09-04 Neal H. Walfield + + * gpg-agent.c (main): Use sigaction, not signal. + +2002-09-03 Neal H. Walfield + + * findkey.c: Include . + (agent_write_private_key): Prefer POSIX compatibity, open and + fdopen, over the simplicity of GNU extensions, fopen(file, "x"). + +2002-08-22 Werner Koch + + * query.c (agent_askpin): Provide the default desc text depending + on the pininfo. Do the basic PIN verification only when + min_digits is set. + +2002-08-21 Werner Koch + + * query.c (agent_askpin): Hack to show the right default prompt. + (agent_get_passphrase): Ditto. + + * trans.c: Removed and replaced all usages with standard _() + + * divert-scd.c (getpin_cb): Pass a more descritive text to the + pinentry. + + * Makefile.am: Renamed the binary protect-tool to gpg-protect-tool. + * protect-tool.c: Removed the note about internal use only. + + * gpg-agent.c (main): New option --daemon so that the program is + not accidently started in the background. + +2002-08-16 Werner Koch + + * call-scd.c (learn_status_cb): Handle CERTINFO status. + (agent_card_learn): Add args for certinfo cb. + * learncard.c (release_certinfo,certinfo_cb): New. + (send_cert_back): New. With factored out code from .. + (agent_handle_learn): here. Return certinfo stuff. + +2002-07-26 Werner Koch + + * gpg-agent.c (main): New option --ignore-cache-for-signing. + * command.c (option_handler): New server option + use-cache-for-signing defaulting to true. + (cmd_pksign): handle global and per session option. + * findkey.c (agent_key_from_file, unprotect): New arg + ignore_cache. Changed all callers. + * pksign.c (agent_pksign): Likewise. + +2002-06-29 Werner Koch + + * query.c (start_pinentry): Use GNUPG_DERAULT_PINENTRY. + * call-scd.c (start_scd): Use GNUPG_DEFAULT_SCDAEMON. + +2002-06-28 Werner Koch + + * protect-tool.c (export_p12_file): New. + (main): New command --p12-export. + * minip12.c (create_final,p12_build,compute_tag_length): New. + (store_tag_length): New. + +2002-06-27 Werner Koch + + * minip12.c (crypt_block): Renamed from decrypt_block, add arg to + allow encryption. + + * Makefile.am (pkglib_PROGRAMS): Put protect-tool there. + + * findkey.c (agent_write_private_key,agent_key_from_file) + (agent_key_available): Use GNUPG_PRIVATE_KEYS_DIR constant. + * gpg-agent.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. + + * protect-tool.c (store_private_key): New. + (import_p12_file): Store the new file if requested. + (main): New options --force and --store. + + * gpg-agent.c (main): Set a global flag when running detached. + * query.c (start_pinentry): Pass the list of FD to keep in the + child when not running detached. + * call-scd.c (start_scd): Ditto. + +2002-06-26 Werner Koch + + * command.c (cmd_istrusted, cmd_listtrusted, cmd_marktrusted) + (cmd_pksign, cmd_pkdecrypt, cmd_genkey, cmd_get_passphrase) + (cmd_learn): Print an error message for a failed operation. + + * simple-pwquery.c, simple-pwquery.h: New. + * protect-tool. (get_passphrase): New, used to get a passphrase + from the agent if none was given on the command line. + +2002-06-25 Werner Koch + + * protect-tool.c (rsa_key_check): New. + (import_p12_file): New. + (main): New command --p12-import. + * minip12.c, minip12.h: New. + +2002-06-24 Werner Koch + + * protect-tool.c (read_file): New. + (read_key): Factored most code out to read_file. + +2002-06-17 Werner Koch + + * agent.h: Add a callback function to the pin_entry_info structure. + * query.c (agent_askpin): Use the callback to check for a correct + PIN. Removed the start_err_text argument because it is not + anymore needed; changed callers. + * findkey.c (unprotect): Replace our own check loop by a callback. + (try_unprotect_cb): New. + * genkey.c (reenter_compare_cb): New. + (agent_genkey): Use this callback here. Fixed setting of the pi2 + variable and a segv in case of an empty PIN. + + * divert-scd.c (getpin_cb): Removed some unused stuff and + explained what we still have to change. + +2002-06-12 Werner Koch + + * gpg-agent.c (main): New option --disable-pth. + +2002-06-11 Werner Koch + + * protect-tool.c: Add command --show-keygrip + (show_keygrip): New. + +2002-05-23 Werner Koch + + * call-scd.c: Seirialized all scdaeom access when using Pth. + + * cache.c: Made the cache Pth-thread-safe. + (agent_unlock_cache_entry): New. + * findkey.c (unprotect): Unlock the returned cache value. + * command.c (cmd_get_passphrase): Ditto. + + * gpg-agent.c (main): Register pth_read/write with Assuan. + +2002-05-22 Werner Koch + + * query.c: Serialized all pinentry access when using Pth. + + * gpg-agent.c (handle_signal,start_connection_thread) + (handle_connections): New + (main): Use the new Pth stuff to allow concurrent connections. + * command.c (start_command_handler): Add new arg FD so that the + fucntion can also be used for an already connected socket. + * Makefile.am: Link with Pth. + +2002-05-14 Werner Koch + + * cache.c (housekeeping, agent_put_cache): Use our time() wrapper. + +2002-04-26 Werner Koch + + * cache.c (agent_put_cache): Reinitialize the creation time and + the ttl when reusing a slot. + + * call-scd.c (start_scd): Print debug messages only with debug + flags set. + * query.c (start_pinentry): Ditto. + +2002-04-25 Marcus Brinkmann + + * agent.h (agent_get_confirmation): Replace paramter prompt with + two parameters ok and cancel. + * query.c (agent_get_confirmation): Likewise. Implement this. + * trustlist.c (agent_marktrusted): Fix invocation of + agent_get_confirmation. + * divert-scd.c (ask_for_card): Likewise. + +2002-04-24 Marcus Brinkmann + + * agent.h (struct opt): Add members display, ttyname, ttytype, + lc_ctype, and lc_messages. + * gpg-agent.c (enum cmd_and_opt_values): Add oDisplay, oTTYname, + oTTYtype, oLCctype, and LCmessages. + (main): Handle these options. + * command.c (option_handler): New function. + (register_commands): Register option handler. + * query.c (start_pinentry): Pass the various display and tty + options to the pinentry. + +2002-04-05 Werner Koch + + * protect-tool.c (show_file): New. Used as default action. + +2002-03-28 Werner Koch + + * divert-scd.c (encode_md_for_card): Don't do the pkcs-1 padding, + the scdaemon should take care of it. + (ask_for_card): Hack to not display the trailing zero. + +2002-03-11 Werner Koch + + * learncard.c (kpinfo_cb): Remove the content restrictions from + the keyID. + +2002-03-06 Werner Koch + + * learncard.c: New. + * divert-scd.c (ask_for_card): The serial number is binary so + convert it to hex here. + * findkey.c (agent_write_private_key): New. + * genkey.c (store_key): And use it here. + + * pkdecrypt.c (agent_pkdecrypt): Changed the way the diversion is done. + * divert-scd.c (divert_pkdecrypt): Changed interface and + implemented it. + +2002-03-05 Werner Koch + + * call-scd.c (inq_needpin): New. + (agent_card_pksign): Add getpin_cb args. + (agent_card_pkdecrypt): New. + +2002-03-04 Werner Koch + + * pksign.c (agent_pksign): Changed how the diversion is done. + * divert-scd.c (divert_pksign): Changed interface and implemented it. + (encode_md_for_card): New. + * call-scd.c (agent_card_pksign): New. + +2002-02-28 Werner Koch + + * pksign.c (agent_pksign): Detect whether a Smartcard is to be + used and divert the operation in this case. + * pkdecrypt.c (agent_pkdecrypt): Likewise + * findkey.c (agent_key_from_file): Add optional arg shadow_info + and have it return information about a shadowed key. + * protect.c (agent_get_shadow_info): New. + + * protect.c (snext,sskip,smatch): Moved to + * sexp-parse.h: New file. + * divert-scd.c: New. + +2002-02-27 Werner Koch + + * protect.c (agent_shadow_key): New. + + * command.c (cmd_learn): New command LEARN. + * gpg-agent.c: New option --scdaemon-program. + * call-scd.c (start_scd): New. Based on query.c + * query.c: Add 2 more arguments to all uses of assuan_transact. + +2002-02-18 Werner Koch + + * findkey.c (unprotect): Show an error message for a bad passphrase. + + * command.c (cmd_marktrusted): Implemented. + * trustlist.c (agent_marktrusted): New. + (open_list): Add APPEND arg. + + * query.c (agent_get_confirmation): New. + +2002-02-06 Werner Koch + + * cache.c (housekeeping): Fixed linking in the remove case. + +2002-02-01 Werner Koch + + * gpg-agent.c: New option --default-cache-ttl. + * cache.c (agent_put_cache): Use it. + + * cache.c: Add a few debug outputs. + + * protect.c (agent_private_key_type): New. + * agent.h: Add PRIVATE_KEY_ enums. + * findkey.c (agent_key_from_file): Use it to decide whether we + have to unprotect a key. + (unprotect): Cache the passphrase. + + * findkey.c (agent_key_from_file,agent_key_available): The key + files do now require a ".key" suffix to make a script's life + easier. + * genkey.c (store_key): Ditto. + +2002-01-31 Werner Koch + + * genkey.c (store_key): Protect the key. + (agent_genkey): Ask for the passphrase. + * findkey.c (unprotect): Actually unprotect the key. + * query.c (agent_askpin): Add an optional start_err_text. + +2002-01-30 Werner Koch + + * protect.c: New. + (hash_passphrase): Based on the GnuPG 1.0.6 version. + * protect-tool.c: New + +2002-01-29 Werner Koch + + * findkey.c (agent_key_available): New. + * command.c (cmd_havekey): New. + (register_commands): And register new command. + +2002-01-20 Werner Koch + + * command.c (cmd_get_passphrase): Remove the plus signs. + + * query.c (start_pinentry): Send no-grab option to pinentry + * gpg-agent.c (main): Move variable grab as no_grab to agent.h. + +2002-01-19 Werner Koch + + * gpg-agent.c (main): Disable core dumps. + + * cache.c: New. + * command.c (cmd_get_passphrase): Use the cache. + (cmd_clear_passphrase): Ditto. + + * gpg-agent.c: Removed unused cruft and implement the socket + based server. + (my_strusage): Take bug report address from configure.ac. + * command.c (start_command_handler): Add an argument to start as + regular server. + (start_command_handler): Enable Assuan logging. + +2002-01-15 Werner Koch + + * trustlist.c: New. + * command.c (cmd_istrusted, cmd_listtrusted, cmd_marktrusted): New. + +2002-01-07 Werner Koch + + * genkey.c: Store the secret part and return the public part. + +2002-01-03 Werner Koch + + * command.c (cmd_get_passphrase): New. + (cmd_clear_passphrase): New. + * query.c (agent_get_passphrase): New. + +2002-01-02 Werner Koch + + * genkey.c: New. + * command.c (cmd_genkey): New. + + * command.c (rc_to_assuan_status): Removed and changed all callers + to use map_to_assuan_status. + +2001-12-19 Werner Koch + + * keyformat.txt: New. + +2001-12-19 Marcus Brinkmann + + * query.c (start_pinentry): Add new argument to assuan_pipe_connect. + +2001-12-18 Werner Koch + + * Makefile.am: Use LIBGCRYPT macros + +2001-12-14 Werner Koch + + * gpg-agent.c (main): New option --batch. New option --debug-wait + n, so that it is possible to attach gdb when used in server mode. + * query.c (agent_askpin): Don't ask in batch mode. + + * command.c: Removed the conversion macros as they are now in + ../common/util.h. + +2001-12-14 Marcus Brinkmann + + * query.c (LINELENGTH): Removed. + (agent_askpin): Use ASSUAN_LINELENGTH, not LINELENGTH. + +2001-11-19 Werner Koch + + * gpg-agent.c: Removed all GUI code, removed code for old + protocol. New code to use the Assuan protocol as a server and + also to communicate with a new ask-passphrase utility. + +2000-11-22 Werner Koch + + * gpg-agent.c (main): csh support by Dan Winship, new options --sh + and --csh and set default by consulting $SHELL. + +Mon Aug 21 17:59:17 CEST 2000 Werner Koch + + * gpg-agent.c (passphrase_dialog): Cleanup the window and added the + user supplied text to the window. + (main): Fixed segv in gtk_init when used without a command to start. + + * gpg-agent.c: --flush option. + (req_flush): New. + (req_clear_passphrase): Implemented. + +Fri Aug 18 14:27:14 CEST 2000 Werner Koch + + * gpg-agent.c: New. + * Makefile.am: New. + + + Copyright 2001, 2002, 2003, 2004, 2005, + 2007, 2008, 2009, 2010 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/agent/Makefile.am b/agent/Makefile.am new file mode 100644 index 0000000..cc8a22a --- /dev/null +++ b/agent/Makefile.am @@ -0,0 +1,110 @@ +# Copyright (C) 2001, 2003, 2004, 2005 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 3 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, see . + +## Process this file with automake to produce Makefile.in + +bin_PROGRAMS = gpg-agent +libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase +noinst_PROGRAMS = $(TESTS) + +# EXTRA_DIST = gpg-agent.ico gpg-agent-resource.rc +EXTRA_DIST = ChangeLog-2011 + +AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl + +include $(top_srcdir)/am/cmacros.am + +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) + +gpg_agent_SOURCES = \ + gpg-agent.c agent.h \ + command.c command-ssh.c \ + call-pinentry.c \ + cache.c \ + trans.c \ + findkey.c \ + pksign.c \ + pkdecrypt.c \ + genkey.c \ + protect.c \ + trustlist.c \ + divert-scd.c \ + call-scd.c \ + learncard.c + +common_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a +commonpth_libs = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a +pwquery_libs = ../common/libsimple-pwquery.a + +#if HAVE_W32_SYSTEM +#.rc.o: +# $(WINDRES) `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ +# sed -e 's/-I/--include-dir /g;s/-D/--define /g'` -i $< -o $@ +# +#gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o -Wl,--subsystem,windows +#gpg_agent_res_deps = gpg-agent-resource.o +#else +gpg_agent_res_ldflags = +gpg_agent_res_deps = +#endif + + +gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +gpg_agent_LDADD = $(commonpth_libs) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) +gpg_agent_LDFLAGS = $(gpg_agent_res_ldflags) +gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) + +gpg_protect_tool_SOURCES = \ + protect-tool.c \ + protect.c \ + minip12.c minip12.h + +gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) +gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) + +gpg_preset_passphrase_SOURCES = \ + preset-passphrase.c + +# Needs $(NETLIBS) for libsimple-pwquery.la. +gpg_preset_passphrase_LDADD = \ + $(pwquery_libs) $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) + + +# Make sure that all libs are build before we use them. This is +# important for things like make -j2. +$(PROGRAMS): $(common_libs) $(commonpth_libs) $(pwquery_libs) + + + +# +# Module tests +# +TESTS = t-protect + +t_common_ldadd = $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +t_protect_SOURCES = t-protect.c protect.c +t_protect_LDADD = $(t_common_ldadd) + + + + diff --git a/agent/Makefile.in b/agent/Makefile.in new file mode 100644 index 0000000..e8aa48f --- /dev/null +++ b/agent/Makefile.in @@ -0,0 +1,1164 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# 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. + +@SET_MAKE@ + +# Copyright (C) 2001, 2003, 2004, 2005 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 3 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, see . + +# 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 3 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, see . + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = gpg-agent$(EXEEXT) +libexec_PROGRAMS = gpg-protect-tool$(EXEEXT) \ + gpg-preset-passphrase$(EXEEXT) +noinst_PROGRAMS = $(am__EXEEXT_1) +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/am/cmacros.am +@HAVE_DOSISH_SYSTEM_FALSE@am__append_1 = -DGNUPG_BINDIR="\"$(bindir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" + + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. +@GNUPG_AGENT_PGM_TRUE@am__append_2 = -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" +@GNUPG_PINENTRY_PGM_TRUE@am__append_3 = -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" +@GNUPG_SCDAEMON_PGM_TRUE@am__append_4 = -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" +@GNUPG_DIRMNGR_PGM_TRUE@am__append_5 = -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" +@GNUPG_PROTECT_TOOL_PGM_TRUE@am__append_6 = -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" +TESTS = t-protect$(EXEEXT) +subdir = agent +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/gl/m4/absolute-header.m4 \ + $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/allocsa.m4 \ + $(top_srcdir)/gl/m4/eealloc.m4 \ + $(top_srcdir)/gl/m4/gnulib-comp.m4 \ + $(top_srcdir)/gl/m4/gnulib-tool.m4 \ + $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/setenv.m4 \ + $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/strpbrk.m4 \ + $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/estream.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gnupg-pth.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/size_max.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" +am__EXEEXT_1 = t-protect$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS) +am_gpg_agent_OBJECTS = gpg_agent-gpg-agent.$(OBJEXT) \ + gpg_agent-command.$(OBJEXT) gpg_agent-command-ssh.$(OBJEXT) \ + gpg_agent-call-pinentry.$(OBJEXT) gpg_agent-cache.$(OBJEXT) \ + gpg_agent-trans.$(OBJEXT) gpg_agent-findkey.$(OBJEXT) \ + gpg_agent-pksign.$(OBJEXT) gpg_agent-pkdecrypt.$(OBJEXT) \ + gpg_agent-genkey.$(OBJEXT) gpg_agent-protect.$(OBJEXT) \ + gpg_agent-trustlist.$(OBJEXT) gpg_agent-divert-scd.$(OBJEXT) \ + gpg_agent-call-scd.$(OBJEXT) gpg_agent-learncard.$(OBJEXT) +gpg_agent_OBJECTS = $(am_gpg_agent_OBJECTS) +am__DEPENDENCIES_1 = +gpg_agent_LINK = $(CCLD) $(gpg_agent_CFLAGS) $(CFLAGS) \ + $(gpg_agent_LDFLAGS) $(LDFLAGS) -o $@ +am_gpg_preset_passphrase_OBJECTS = preset-passphrase.$(OBJEXT) +gpg_preset_passphrase_OBJECTS = $(am_gpg_preset_passphrase_OBJECTS) +gpg_preset_passphrase_DEPENDENCIES = $(pwquery_libs) $(common_libs) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_gpg_protect_tool_OBJECTS = gpg_protect_tool-protect-tool.$(OBJEXT) \ + gpg_protect_tool-protect.$(OBJEXT) \ + gpg_protect_tool-minip12.$(OBJEXT) +gpg_protect_tool_OBJECTS = $(am_gpg_protect_tool_OBJECTS) +gpg_protect_tool_DEPENDENCIES = $(common_libs) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +gpg_protect_tool_LINK = $(CCLD) $(gpg_protect_tool_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_t_protect_OBJECTS = t-protect.$(OBJEXT) protect.$(OBJEXT) +t_protect_OBJECTS = $(am_t_protect_OBJECTS) +am__DEPENDENCIES_2 = $(common_libs) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +t_protect_DEPENDENCIES = $(am__DEPENDENCIES_2) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(gpg_agent_SOURCES) $(gpg_preset_passphrase_SOURCES) \ + $(gpg_protect_tool_SOURCES) $(t_protect_SOURCES) +DIST_SOURCES = $(gpg_agent_SOURCES) $(gpg_preset_passphrase_SOURCES) \ + $(gpg_protect_tool_SOURCES) $(t_protect_SOURCES) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@ +ACLOCAL = @ACLOCAL@ +ADNSLIBS = @ADNSLIBS@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAQPROG = @FAQPROG@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_CURL = @GPGKEYS_CURL@ +GPGKEYS_FINGER = @GPGKEYS_FINGER@ +GPGKEYS_HKP = @GPGKEYS_HKP@ +GPGKEYS_KDNS = @GPGKEYS_KDNS@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGKEYS_MAILTO = @GPGKEYS_MAILTO@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GREP = @GREP@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +PTH_CFLAGS = @PTH_CFLAGS@ +PTH_CONFIG = @PTH_CONFIG@ +PTH_LIBS = @PTH_LIBS@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +UNISTD_H = @UNISTD_H@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDRES = @WINDRES@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIBS = @ZLIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# EXTRA_DIST = gpg-agent.ico gpg-agent-resource.rc +EXTRA_DIST = ChangeLog-2011 +AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \ + -I$(top_srcdir)/intl -DLOCALEDIR=\"$(localedir)\" \ + $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) +gpg_agent_SOURCES = \ + gpg-agent.c agent.h \ + command.c command-ssh.c \ + call-pinentry.c \ + cache.c \ + trans.c \ + findkey.c \ + pksign.c \ + pkdecrypt.c \ + genkey.c \ + protect.c \ + trustlist.c \ + divert-scd.c \ + call-scd.c \ + learncard.c + +common_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a +commonpth_libs = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a +pwquery_libs = ../common/libsimple-pwquery.a + +#if HAVE_W32_SYSTEM +#.rc.o: +# $(WINDRES) `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ +# sed -e 's/-I/--include-dir /g;s/-D/--define /g'` -i $< -o $@ +# +#gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o -Wl,--subsystem,windows +#gpg_agent_res_deps = gpg-agent-resource.o +#else +gpg_agent_res_ldflags = +gpg_agent_res_deps = +#endif +gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +gpg_agent_LDADD = $(commonpth_libs) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) + +gpg_agent_LDFLAGS = $(gpg_agent_res_ldflags) +gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) +gpg_protect_tool_SOURCES = \ + protect-tool.c \ + protect.c \ + minip12.c minip12.h + +gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) +gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) + +gpg_preset_passphrase_SOURCES = \ + preset-passphrase.c + + +# Needs $(NETLIBS) for libsimple-pwquery.la. +gpg_preset_passphrase_LDADD = \ + $(pwquery_libs) $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) + +t_common_ldadd = $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +t_protect_SOURCES = t-protect.c protect.c +t_protect_LDADD = $(t_common_ldadd) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/am/cmacros.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu agent/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu agent/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +gpg-agent$(EXEEXT): $(gpg_agent_OBJECTS) $(gpg_agent_DEPENDENCIES) + @rm -f gpg-agent$(EXEEXT) + $(gpg_agent_LINK) $(gpg_agent_OBJECTS) $(gpg_agent_LDADD) $(LIBS) +gpg-preset-passphrase$(EXEEXT): $(gpg_preset_passphrase_OBJECTS) $(gpg_preset_passphrase_DEPENDENCIES) + @rm -f gpg-preset-passphrase$(EXEEXT) + $(LINK) $(gpg_preset_passphrase_OBJECTS) $(gpg_preset_passphrase_LDADD) $(LIBS) +gpg-protect-tool$(EXEEXT): $(gpg_protect_tool_OBJECTS) $(gpg_protect_tool_DEPENDENCIES) + @rm -f gpg-protect-tool$(EXEEXT) + $(gpg_protect_tool_LINK) $(gpg_protect_tool_OBJECTS) $(gpg_protect_tool_LDADD) $(LIBS) +t-protect$(EXEEXT): $(t_protect_OBJECTS) $(t_protect_DEPENDENCIES) + @rm -f t-protect$(EXEEXT) + $(LINK) $(t_protect_OBJECTS) $(t_protect_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-cache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-call-pinentry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-call-scd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-command-ssh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-command.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-divert-scd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-findkey.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-genkey.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-gpg-agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-learncard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-pkdecrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-pksign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-protect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-trans.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_agent-trustlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_protect_tool-minip12.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_protect_tool-protect-tool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpg_protect_tool-protect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preset-passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-protect.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +gpg_agent-gpg-agent.o: gpg-agent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-gpg-agent.o -MD -MP -MF $(DEPDIR)/gpg_agent-gpg-agent.Tpo -c -o gpg_agent-gpg-agent.o `test -f 'gpg-agent.c' || echo '$(srcdir)/'`gpg-agent.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-gpg-agent.Tpo $(DEPDIR)/gpg_agent-gpg-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpg-agent.c' object='gpg_agent-gpg-agent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-gpg-agent.o `test -f 'gpg-agent.c' || echo '$(srcdir)/'`gpg-agent.c + +gpg_agent-gpg-agent.obj: gpg-agent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-gpg-agent.obj -MD -MP -MF $(DEPDIR)/gpg_agent-gpg-agent.Tpo -c -o gpg_agent-gpg-agent.obj `if test -f 'gpg-agent.c'; then $(CYGPATH_W) 'gpg-agent.c'; else $(CYGPATH_W) '$(srcdir)/gpg-agent.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-gpg-agent.Tpo $(DEPDIR)/gpg_agent-gpg-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpg-agent.c' object='gpg_agent-gpg-agent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-gpg-agent.obj `if test -f 'gpg-agent.c'; then $(CYGPATH_W) 'gpg-agent.c'; else $(CYGPATH_W) '$(srcdir)/gpg-agent.c'; fi` + +gpg_agent-command.o: command.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-command.o -MD -MP -MF $(DEPDIR)/gpg_agent-command.Tpo -c -o gpg_agent-command.o `test -f 'command.c' || echo '$(srcdir)/'`command.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-command.Tpo $(DEPDIR)/gpg_agent-command.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='command.c' object='gpg_agent-command.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-command.o `test -f 'command.c' || echo '$(srcdir)/'`command.c + +gpg_agent-command.obj: command.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-command.obj -MD -MP -MF $(DEPDIR)/gpg_agent-command.Tpo -c -o gpg_agent-command.obj `if test -f 'command.c'; then $(CYGPATH_W) 'command.c'; else $(CYGPATH_W) '$(srcdir)/command.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-command.Tpo $(DEPDIR)/gpg_agent-command.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='command.c' object='gpg_agent-command.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-command.obj `if test -f 'command.c'; then $(CYGPATH_W) 'command.c'; else $(CYGPATH_W) '$(srcdir)/command.c'; fi` + +gpg_agent-command-ssh.o: command-ssh.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-command-ssh.o -MD -MP -MF $(DEPDIR)/gpg_agent-command-ssh.Tpo -c -o gpg_agent-command-ssh.o `test -f 'command-ssh.c' || echo '$(srcdir)/'`command-ssh.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-command-ssh.Tpo $(DEPDIR)/gpg_agent-command-ssh.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='command-ssh.c' object='gpg_agent-command-ssh.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-command-ssh.o `test -f 'command-ssh.c' || echo '$(srcdir)/'`command-ssh.c + +gpg_agent-command-ssh.obj: command-ssh.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-command-ssh.obj -MD -MP -MF $(DEPDIR)/gpg_agent-command-ssh.Tpo -c -o gpg_agent-command-ssh.obj `if test -f 'command-ssh.c'; then $(CYGPATH_W) 'command-ssh.c'; else $(CYGPATH_W) '$(srcdir)/command-ssh.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-command-ssh.Tpo $(DEPDIR)/gpg_agent-command-ssh.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='command-ssh.c' object='gpg_agent-command-ssh.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-command-ssh.obj `if test -f 'command-ssh.c'; then $(CYGPATH_W) 'command-ssh.c'; else $(CYGPATH_W) '$(srcdir)/command-ssh.c'; fi` + +gpg_agent-call-pinentry.o: call-pinentry.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-call-pinentry.o -MD -MP -MF $(DEPDIR)/gpg_agent-call-pinentry.Tpo -c -o gpg_agent-call-pinentry.o `test -f 'call-pinentry.c' || echo '$(srcdir)/'`call-pinentry.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-call-pinentry.Tpo $(DEPDIR)/gpg_agent-call-pinentry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='call-pinentry.c' object='gpg_agent-call-pinentry.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-call-pinentry.o `test -f 'call-pinentry.c' || echo '$(srcdir)/'`call-pinentry.c + +gpg_agent-call-pinentry.obj: call-pinentry.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-call-pinentry.obj -MD -MP -MF $(DEPDIR)/gpg_agent-call-pinentry.Tpo -c -o gpg_agent-call-pinentry.obj `if test -f 'call-pinentry.c'; then $(CYGPATH_W) 'call-pinentry.c'; else $(CYGPATH_W) '$(srcdir)/call-pinentry.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-call-pinentry.Tpo $(DEPDIR)/gpg_agent-call-pinentry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='call-pinentry.c' object='gpg_agent-call-pinentry.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-call-pinentry.obj `if test -f 'call-pinentry.c'; then $(CYGPATH_W) 'call-pinentry.c'; else $(CYGPATH_W) '$(srcdir)/call-pinentry.c'; fi` + +gpg_agent-cache.o: cache.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-cache.o -MD -MP -MF $(DEPDIR)/gpg_agent-cache.Tpo -c -o gpg_agent-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-cache.Tpo $(DEPDIR)/gpg_agent-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='gpg_agent-cache.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c + +gpg_agent-cache.obj: cache.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-cache.obj -MD -MP -MF $(DEPDIR)/gpg_agent-cache.Tpo -c -o gpg_agent-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-cache.Tpo $(DEPDIR)/gpg_agent-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='gpg_agent-cache.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` + +gpg_agent-trans.o: trans.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-trans.o -MD -MP -MF $(DEPDIR)/gpg_agent-trans.Tpo -c -o gpg_agent-trans.o `test -f 'trans.c' || echo '$(srcdir)/'`trans.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-trans.Tpo $(DEPDIR)/gpg_agent-trans.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='trans.c' object='gpg_agent-trans.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-trans.o `test -f 'trans.c' || echo '$(srcdir)/'`trans.c + +gpg_agent-trans.obj: trans.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-trans.obj -MD -MP -MF $(DEPDIR)/gpg_agent-trans.Tpo -c -o gpg_agent-trans.obj `if test -f 'trans.c'; then $(CYGPATH_W) 'trans.c'; else $(CYGPATH_W) '$(srcdir)/trans.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-trans.Tpo $(DEPDIR)/gpg_agent-trans.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='trans.c' object='gpg_agent-trans.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-trans.obj `if test -f 'trans.c'; then $(CYGPATH_W) 'trans.c'; else $(CYGPATH_W) '$(srcdir)/trans.c'; fi` + +gpg_agent-findkey.o: findkey.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-findkey.o -MD -MP -MF $(DEPDIR)/gpg_agent-findkey.Tpo -c -o gpg_agent-findkey.o `test -f 'findkey.c' || echo '$(srcdir)/'`findkey.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-findkey.Tpo $(DEPDIR)/gpg_agent-findkey.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='findkey.c' object='gpg_agent-findkey.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-findkey.o `test -f 'findkey.c' || echo '$(srcdir)/'`findkey.c + +gpg_agent-findkey.obj: findkey.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-findkey.obj -MD -MP -MF $(DEPDIR)/gpg_agent-findkey.Tpo -c -o gpg_agent-findkey.obj `if test -f 'findkey.c'; then $(CYGPATH_W) 'findkey.c'; else $(CYGPATH_W) '$(srcdir)/findkey.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-findkey.Tpo $(DEPDIR)/gpg_agent-findkey.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='findkey.c' object='gpg_agent-findkey.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-findkey.obj `if test -f 'findkey.c'; then $(CYGPATH_W) 'findkey.c'; else $(CYGPATH_W) '$(srcdir)/findkey.c'; fi` + +gpg_agent-pksign.o: pksign.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-pksign.o -MD -MP -MF $(DEPDIR)/gpg_agent-pksign.Tpo -c -o gpg_agent-pksign.o `test -f 'pksign.c' || echo '$(srcdir)/'`pksign.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-pksign.Tpo $(DEPDIR)/gpg_agent-pksign.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pksign.c' object='gpg_agent-pksign.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-pksign.o `test -f 'pksign.c' || echo '$(srcdir)/'`pksign.c + +gpg_agent-pksign.obj: pksign.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-pksign.obj -MD -MP -MF $(DEPDIR)/gpg_agent-pksign.Tpo -c -o gpg_agent-pksign.obj `if test -f 'pksign.c'; then $(CYGPATH_W) 'pksign.c'; else $(CYGPATH_W) '$(srcdir)/pksign.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-pksign.Tpo $(DEPDIR)/gpg_agent-pksign.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pksign.c' object='gpg_agent-pksign.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-pksign.obj `if test -f 'pksign.c'; then $(CYGPATH_W) 'pksign.c'; else $(CYGPATH_W) '$(srcdir)/pksign.c'; fi` + +gpg_agent-pkdecrypt.o: pkdecrypt.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-pkdecrypt.o -MD -MP -MF $(DEPDIR)/gpg_agent-pkdecrypt.Tpo -c -o gpg_agent-pkdecrypt.o `test -f 'pkdecrypt.c' || echo '$(srcdir)/'`pkdecrypt.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-pkdecrypt.Tpo $(DEPDIR)/gpg_agent-pkdecrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkdecrypt.c' object='gpg_agent-pkdecrypt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-pkdecrypt.o `test -f 'pkdecrypt.c' || echo '$(srcdir)/'`pkdecrypt.c + +gpg_agent-pkdecrypt.obj: pkdecrypt.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-pkdecrypt.obj -MD -MP -MF $(DEPDIR)/gpg_agent-pkdecrypt.Tpo -c -o gpg_agent-pkdecrypt.obj `if test -f 'pkdecrypt.c'; then $(CYGPATH_W) 'pkdecrypt.c'; else $(CYGPATH_W) '$(srcdir)/pkdecrypt.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-pkdecrypt.Tpo $(DEPDIR)/gpg_agent-pkdecrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pkdecrypt.c' object='gpg_agent-pkdecrypt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-pkdecrypt.obj `if test -f 'pkdecrypt.c'; then $(CYGPATH_W) 'pkdecrypt.c'; else $(CYGPATH_W) '$(srcdir)/pkdecrypt.c'; fi` + +gpg_agent-genkey.o: genkey.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-genkey.o -MD -MP -MF $(DEPDIR)/gpg_agent-genkey.Tpo -c -o gpg_agent-genkey.o `test -f 'genkey.c' || echo '$(srcdir)/'`genkey.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-genkey.Tpo $(DEPDIR)/gpg_agent-genkey.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='genkey.c' object='gpg_agent-genkey.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-genkey.o `test -f 'genkey.c' || echo '$(srcdir)/'`genkey.c + +gpg_agent-genkey.obj: genkey.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-genkey.obj -MD -MP -MF $(DEPDIR)/gpg_agent-genkey.Tpo -c -o gpg_agent-genkey.obj `if test -f 'genkey.c'; then $(CYGPATH_W) 'genkey.c'; else $(CYGPATH_W) '$(srcdir)/genkey.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-genkey.Tpo $(DEPDIR)/gpg_agent-genkey.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='genkey.c' object='gpg_agent-genkey.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-genkey.obj `if test -f 'genkey.c'; then $(CYGPATH_W) 'genkey.c'; else $(CYGPATH_W) '$(srcdir)/genkey.c'; fi` + +gpg_agent-protect.o: protect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-protect.o -MD -MP -MF $(DEPDIR)/gpg_agent-protect.Tpo -c -o gpg_agent-protect.o `test -f 'protect.c' || echo '$(srcdir)/'`protect.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-protect.Tpo $(DEPDIR)/gpg_agent-protect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect.c' object='gpg_agent-protect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-protect.o `test -f 'protect.c' || echo '$(srcdir)/'`protect.c + +gpg_agent-protect.obj: protect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-protect.obj -MD -MP -MF $(DEPDIR)/gpg_agent-protect.Tpo -c -o gpg_agent-protect.obj `if test -f 'protect.c'; then $(CYGPATH_W) 'protect.c'; else $(CYGPATH_W) '$(srcdir)/protect.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-protect.Tpo $(DEPDIR)/gpg_agent-protect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect.c' object='gpg_agent-protect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-protect.obj `if test -f 'protect.c'; then $(CYGPATH_W) 'protect.c'; else $(CYGPATH_W) '$(srcdir)/protect.c'; fi` + +gpg_agent-trustlist.o: trustlist.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-trustlist.o -MD -MP -MF $(DEPDIR)/gpg_agent-trustlist.Tpo -c -o gpg_agent-trustlist.o `test -f 'trustlist.c' || echo '$(srcdir)/'`trustlist.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-trustlist.Tpo $(DEPDIR)/gpg_agent-trustlist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='trustlist.c' object='gpg_agent-trustlist.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-trustlist.o `test -f 'trustlist.c' || echo '$(srcdir)/'`trustlist.c + +gpg_agent-trustlist.obj: trustlist.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-trustlist.obj -MD -MP -MF $(DEPDIR)/gpg_agent-trustlist.Tpo -c -o gpg_agent-trustlist.obj `if test -f 'trustlist.c'; then $(CYGPATH_W) 'trustlist.c'; else $(CYGPATH_W) '$(srcdir)/trustlist.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-trustlist.Tpo $(DEPDIR)/gpg_agent-trustlist.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='trustlist.c' object='gpg_agent-trustlist.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-trustlist.obj `if test -f 'trustlist.c'; then $(CYGPATH_W) 'trustlist.c'; else $(CYGPATH_W) '$(srcdir)/trustlist.c'; fi` + +gpg_agent-divert-scd.o: divert-scd.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-divert-scd.o -MD -MP -MF $(DEPDIR)/gpg_agent-divert-scd.Tpo -c -o gpg_agent-divert-scd.o `test -f 'divert-scd.c' || echo '$(srcdir)/'`divert-scd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-divert-scd.Tpo $(DEPDIR)/gpg_agent-divert-scd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='divert-scd.c' object='gpg_agent-divert-scd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-divert-scd.o `test -f 'divert-scd.c' || echo '$(srcdir)/'`divert-scd.c + +gpg_agent-divert-scd.obj: divert-scd.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-divert-scd.obj -MD -MP -MF $(DEPDIR)/gpg_agent-divert-scd.Tpo -c -o gpg_agent-divert-scd.obj `if test -f 'divert-scd.c'; then $(CYGPATH_W) 'divert-scd.c'; else $(CYGPATH_W) '$(srcdir)/divert-scd.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-divert-scd.Tpo $(DEPDIR)/gpg_agent-divert-scd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='divert-scd.c' object='gpg_agent-divert-scd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-divert-scd.obj `if test -f 'divert-scd.c'; then $(CYGPATH_W) 'divert-scd.c'; else $(CYGPATH_W) '$(srcdir)/divert-scd.c'; fi` + +gpg_agent-call-scd.o: call-scd.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-call-scd.o -MD -MP -MF $(DEPDIR)/gpg_agent-call-scd.Tpo -c -o gpg_agent-call-scd.o `test -f 'call-scd.c' || echo '$(srcdir)/'`call-scd.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-call-scd.Tpo $(DEPDIR)/gpg_agent-call-scd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='call-scd.c' object='gpg_agent-call-scd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-call-scd.o `test -f 'call-scd.c' || echo '$(srcdir)/'`call-scd.c + +gpg_agent-call-scd.obj: call-scd.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-call-scd.obj -MD -MP -MF $(DEPDIR)/gpg_agent-call-scd.Tpo -c -o gpg_agent-call-scd.obj `if test -f 'call-scd.c'; then $(CYGPATH_W) 'call-scd.c'; else $(CYGPATH_W) '$(srcdir)/call-scd.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-call-scd.Tpo $(DEPDIR)/gpg_agent-call-scd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='call-scd.c' object='gpg_agent-call-scd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-call-scd.obj `if test -f 'call-scd.c'; then $(CYGPATH_W) 'call-scd.c'; else $(CYGPATH_W) '$(srcdir)/call-scd.c'; fi` + +gpg_agent-learncard.o: learncard.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-learncard.o -MD -MP -MF $(DEPDIR)/gpg_agent-learncard.Tpo -c -o gpg_agent-learncard.o `test -f 'learncard.c' || echo '$(srcdir)/'`learncard.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-learncard.Tpo $(DEPDIR)/gpg_agent-learncard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='learncard.c' object='gpg_agent-learncard.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-learncard.o `test -f 'learncard.c' || echo '$(srcdir)/'`learncard.c + +gpg_agent-learncard.obj: learncard.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -MT gpg_agent-learncard.obj -MD -MP -MF $(DEPDIR)/gpg_agent-learncard.Tpo -c -o gpg_agent-learncard.obj `if test -f 'learncard.c'; then $(CYGPATH_W) 'learncard.c'; else $(CYGPATH_W) '$(srcdir)/learncard.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_agent-learncard.Tpo $(DEPDIR)/gpg_agent-learncard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='learncard.c' object='gpg_agent-learncard.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_agent_CFLAGS) $(CFLAGS) -c -o gpg_agent-learncard.obj `if test -f 'learncard.c'; then $(CYGPATH_W) 'learncard.c'; else $(CYGPATH_W) '$(srcdir)/learncard.c'; fi` + +gpg_protect_tool-protect-tool.o: protect-tool.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-protect-tool.o -MD -MP -MF $(DEPDIR)/gpg_protect_tool-protect-tool.Tpo -c -o gpg_protect_tool-protect-tool.o `test -f 'protect-tool.c' || echo '$(srcdir)/'`protect-tool.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-protect-tool.Tpo $(DEPDIR)/gpg_protect_tool-protect-tool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect-tool.c' object='gpg_protect_tool-protect-tool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-protect-tool.o `test -f 'protect-tool.c' || echo '$(srcdir)/'`protect-tool.c + +gpg_protect_tool-protect-tool.obj: protect-tool.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-protect-tool.obj -MD -MP -MF $(DEPDIR)/gpg_protect_tool-protect-tool.Tpo -c -o gpg_protect_tool-protect-tool.obj `if test -f 'protect-tool.c'; then $(CYGPATH_W) 'protect-tool.c'; else $(CYGPATH_W) '$(srcdir)/protect-tool.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-protect-tool.Tpo $(DEPDIR)/gpg_protect_tool-protect-tool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect-tool.c' object='gpg_protect_tool-protect-tool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-protect-tool.obj `if test -f 'protect-tool.c'; then $(CYGPATH_W) 'protect-tool.c'; else $(CYGPATH_W) '$(srcdir)/protect-tool.c'; fi` + +gpg_protect_tool-protect.o: protect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-protect.o -MD -MP -MF $(DEPDIR)/gpg_protect_tool-protect.Tpo -c -o gpg_protect_tool-protect.o `test -f 'protect.c' || echo '$(srcdir)/'`protect.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-protect.Tpo $(DEPDIR)/gpg_protect_tool-protect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect.c' object='gpg_protect_tool-protect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-protect.o `test -f 'protect.c' || echo '$(srcdir)/'`protect.c + +gpg_protect_tool-protect.obj: protect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-protect.obj -MD -MP -MF $(DEPDIR)/gpg_protect_tool-protect.Tpo -c -o gpg_protect_tool-protect.obj `if test -f 'protect.c'; then $(CYGPATH_W) 'protect.c'; else $(CYGPATH_W) '$(srcdir)/protect.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-protect.Tpo $(DEPDIR)/gpg_protect_tool-protect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='protect.c' object='gpg_protect_tool-protect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-protect.obj `if test -f 'protect.c'; then $(CYGPATH_W) 'protect.c'; else $(CYGPATH_W) '$(srcdir)/protect.c'; fi` + +gpg_protect_tool-minip12.o: minip12.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-minip12.o -MD -MP -MF $(DEPDIR)/gpg_protect_tool-minip12.Tpo -c -o gpg_protect_tool-minip12.o `test -f 'minip12.c' || echo '$(srcdir)/'`minip12.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-minip12.Tpo $(DEPDIR)/gpg_protect_tool-minip12.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='minip12.c' object='gpg_protect_tool-minip12.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-minip12.o `test -f 'minip12.c' || echo '$(srcdir)/'`minip12.c + +gpg_protect_tool-minip12.obj: minip12.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -MT gpg_protect_tool-minip12.obj -MD -MP -MF $(DEPDIR)/gpg_protect_tool-minip12.Tpo -c -o gpg_protect_tool-minip12.obj `if test -f 'minip12.c'; then $(CYGPATH_W) 'minip12.c'; else $(CYGPATH_W) '$(srcdir)/minip12.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpg_protect_tool-minip12.Tpo $(DEPDIR)/gpg_protect_tool-minip12.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='minip12.c' object='gpg_protect_tool-minip12.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpg_protect_tool_CFLAGS) $(CFLAGS) -c -o gpg_protect_tool-minip12.obj `if test -f 'minip12.c'; then $(CYGPATH_W) 'minip12.c'; else $(CYGPATH_W) '$(srcdir)/minip12.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libexecPROGRAMS \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-libexecPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-generic clean-libexecPROGRAMS \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libexecPROGRAMS \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-libexecPROGRAMS + + +# Make sure that all libs are build before we use them. This is +# important for things like make -j2. +$(PROGRAMS): $(common_libs) $(commonpth_libs) $(pwquery_libs) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/agent/agent.h b/agent/agent.h new file mode 100644 index 0000000..15cf8bf --- /dev/null +++ b/agent/agent.h @@ -0,0 +1,373 @@ +/* agent.h - Global definitions for the agent + * Copyright (C) 2001, 2002, 2003, 2005 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 3 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, see . + */ + +#ifndef AGENT_H +#define AGENT_H + +#ifdef GPG_ERR_SOURCE_DEFAULT +#error GPG_ERR_SOURCE_DEFAULT already defined +#endif +#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGAGENT +#include +#define map_assuan_err(a) \ + map_assuan_err_with_source (GPG_ERR_SOURCE_DEFAULT, (a)) +#include + +#include +#include "../common/util.h" +#include "../common/membuf.h" +#include "../common/sysutils.h" /* (gnupg_fd_t) */ +#include "../common/session-env.h" + +/* To convey some special hash algorithms we use algorithm numbers + reserved for application use. */ +#ifndef GCRY_MODULE_ID_USER +#define GCRY_MODULE_ID_USER 1024 +#endif +#define MD_USER_TLS_MD5SHA1 (GCRY_MODULE_ID_USER+1) + +/* Maximum length of a digest. */ +#define MAX_DIGEST_LEN 64 + +/* A large struct name "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 dry_run; /* Don't change any persistent data */ + int batch; /* Batch mode */ + const char *homedir; /* Configuration directory name */ + + /* Environment setting gathered at program start or changed using the + Assuan command UPDATESTARTUPTTY. */ + session_env_t startup_env; + char *startup_lc_ctype; + char *startup_lc_messages; + + /* True if we are listening on the standard socket. */ + int use_standard_socket; + + /* True if we handle sigusr2. */ + int sigusr2_enabled; + + const char *pinentry_program; /* Filename of the program to start as + pinentry. */ + const char *scdaemon_program; /* Filename of the program to handle + smartcard tasks. */ + int disable_scdaemon; /* Never use the SCdaemon. */ + int no_grab; /* Don't let the pinentry grab the keyboard */ + + /* The name of the file pinentry shall tocuh before exiting. If + this is not set the filoe name of the standard socket is used. */ + const char *pinentry_touch_file; + + /* The default and maximum TTL of cache entries. */ + unsigned long def_cache_ttl; /* Default. */ + unsigned long def_cache_ttl_ssh; /* for SSH. */ + unsigned long max_cache_ttl; /* Default. */ + unsigned long max_cache_ttl_ssh; /* for SSH. */ + + /* Flag disallowing bypassing of the warning. */ + int enforce_passphrase_constraints; + /* The require minmum length of a passphrase. */ + unsigned int min_passphrase_len; + /* The minimum number of non-alpha characters in a passphrase. */ + unsigned int min_passphrase_nonalpha; + /* File name with a patternfile or NULL if not enabled. */ + const char *check_passphrase_pattern; + /* If not 0 the user is asked to change his passphrase after these + number of days. */ + unsigned int max_passphrase_days; + /* If set, a passphrase history will be written and checked at each + passphrase change. */ + int enable_passhrase_history; + + int running_detached; /* We are running detached from the tty. */ + + int ignore_cache_for_signing; + int allow_mark_trusted; + int allow_preset_passphrase; + int keep_tty; /* Don't switch the TTY (for pinentry) on request */ + int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ + int ssh_support; /* Enable ssh-agent emulation. */ +} 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_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) + +struct server_local_s; +struct scd_local_s; + +/* Collection of data per session (aka connection). */ +struct server_control_s +{ + /* Private data used to fire up the connection thread. We use this + structure do avoid an extra allocation for just a few bytes. */ + struct { + gnupg_fd_t fd; + } thread_startup; + + /* Private data of the server (command.c). */ + struct server_local_s *server_local; + + /* Private data of the SCdaemon (call-scd.c). */ + struct scd_local_s *scd_local; + + session_env_t session_env; + char *lc_ctype; + char *lc_messages; + + struct { + int algo; + unsigned char value[MAX_DIGEST_LEN]; + int valuelen; + int raw_value: 1; + } digest; + unsigned char keygrip[20]; + int have_keygrip; + + int use_auth_call; /* Hack to send the PKAUTH command instead of the + PKSIGN command to the scdaemon. */ + int in_passwd; /* Hack to inhibit enforced passphrase change + during an explicit passwd command. */ +}; + + +struct pin_entry_info_s +{ + int min_digits; /* min. number of digits required or 0 for freeform entry */ + int max_digits; /* max. number of allowed digits allowed*/ + int max_tries; + int failed_tries; + int with_qualitybar; /* Set if the quality bar should be displayed. */ + int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ + void *check_cb_arg; /* optional argument which might be of use in the CB */ + const char *cb_errtext; /* used by the cb to displaye a specific error */ + size_t max_length; /* allocated length of the buffer */ + char pin[1]; +}; + + +enum + { + PRIVATE_KEY_UNKNOWN = 0, + PRIVATE_KEY_CLEAR = 1, + PRIVATE_KEY_PROTECTED = 2, + PRIVATE_KEY_SHADOWED = 3 + }; + + +/* Values for the cache_mode arguments. */ +typedef enum + { + CACHE_MODE_IGNORE = 0, /* Special mode to bypass the cache. */ + CACHE_MODE_ANY, /* Any mode except ignore matches. */ + CACHE_MODE_NORMAL, /* Normal cache (gpg-agent). */ + CACHE_MODE_USER, /* GET_PASSPHRASE related cache. */ + CACHE_MODE_SSH /* SSH related cache. */ + } +cache_mode_t; + + +/* The type of a function to lookup a TTL by a keygrip. */ +typedef int (*lookup_ttl_t)(const char *hexgrip); + + +/*-- gpg-agent.c --*/ +void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ +const char *get_agent_socket_name (void); +const char *get_agent_ssh_socket_name (void); +#ifdef HAVE_W32_SYSTEM +void *get_agent_scd_notify_event (void); +#endif +void agent_sighup_action (void); + +/*-- command.c --*/ +gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid); +gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...) + GNUPG_GCC_A_SENTINEL(0); +void bump_key_eventcounter (void); +void bump_card_eventcounter (void); +void start_command_handler (ctrl_t, gnupg_fd_t, gnupg_fd_t); + +/*-- command-ssh.c --*/ +void start_command_handler_ssh (ctrl_t, gnupg_fd_t); + +/*-- findkey.c --*/ +int agent_write_private_key (const unsigned char *grip, + const void *buffer, size_t length, int force); +gpg_error_t agent_key_from_file (ctrl_t ctrl, + const char *desc_text, + const unsigned char *grip, + unsigned char **shadow_info, + cache_mode_t cache_mode, + lookup_ttl_t lookup_ttl, + gcry_sexp_t *result); +gpg_error_t agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t *result); +gpg_error_t agent_public_key_from_file (ctrl_t ctrl, + const unsigned char *grip, + gcry_sexp_t *result); +int agent_key_available (const unsigned char *grip); +gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, + int *r_keytype, + unsigned char **r_shadow_info); + +/*-- call-pinentry.c --*/ +void initialize_module_call_pinentry (void); +void agent_query_dump_state (void); +void agent_reset_query (ctrl_t ctrl); +int pinentry_active_p (ctrl_t ctrl, int waitseconds); +int agent_askpin (ctrl_t ctrl, + const char *desc_text, const char *prompt_text, + const char *inital_errtext, + struct pin_entry_info_s *pininfo); +int agent_get_passphrase (ctrl_t ctrl, char **retpass, + const char *desc, const char *prompt, + const char *errtext, int with_qualitybar); +int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, + const char *notokay, int with_cancel); +int agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn); +int agent_popup_message_start (ctrl_t ctrl, + const char *desc, const char *ok_btn); +void agent_popup_message_stop (ctrl_t ctrl); + + +/*-- cache.c --*/ +void agent_flush_cache (void); +int agent_put_cache (const char *key, cache_mode_t cache_mode, + const char *data, int ttl); +const char *agent_get_cache (const char *key, cache_mode_t cache_mode, + void **cache_id); +void agent_unlock_cache_entry (void **cache_id); + + +/*-- pksign.c --*/ +int agent_pksign_do (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t *signature_sexp, + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl); +int agent_pksign (ctrl_t ctrl, const char *desc_text, + membuf_t *outbuf, cache_mode_t cache_mode); + +/*-- pkdecrypt.c --*/ +int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *ciphertext, size_t ciphertextlen, + membuf_t *outbuf); + +/*-- genkey.c --*/ +int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent); +int agent_genkey (ctrl_t ctrl, + const char *keyparam, size_t keyparmlen, membuf_t *outbuf); +int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey); + +/*-- protect.c --*/ +unsigned long get_standard_s2k_count (void); +int agent_protect (const unsigned char *plainkey, const char *passphrase, + unsigned char **result, size_t *resultlen); +int agent_unprotect (const unsigned char *protectedkey, const char *passphrase, + gnupg_isotime_t protected_at, + unsigned char **result, size_t *resultlen); +int agent_private_key_type (const unsigned char *privatekey); +unsigned char *make_shadow_info (const char *serialno, const char *idstring); +int agent_shadow_key (const unsigned char *pubkey, + const unsigned char *shadow_info, + unsigned char **result); +int agent_get_shadow_info (const unsigned char *shadowkey, + unsigned char const **shadow_info); +gpg_error_t parse_shadow_info (const unsigned char *shadow_info, + char **r_hexsn, char **r_idstr); + + +/*-- trustlist.c --*/ +void initialize_module_trustlist (void); +gpg_error_t agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled); +gpg_error_t agent_listtrusted (void *assuan_context); +gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, + const char *fpr, int flag); +void agent_reload_trustlist (void); + + +/*-- divert-scd.c --*/ +int divert_pksign (ctrl_t ctrl, + const unsigned char *digest, size_t digestlen, int algo, + const unsigned char *shadow_info, unsigned char **r_sig); +int divert_pkdecrypt (ctrl_t ctrl, + const unsigned char *cipher, + const unsigned char *shadow_info, + char **r_buf, size_t *r_len); +int divert_generic_cmd (ctrl_t ctrl, + const char *cmdline, void *assuan_context); + + +/*-- call-scd.c --*/ +void initialize_module_call_scd (void); +void agent_scd_dump_state (void); +int agent_scd_check_running (void); +void agent_scd_check_aliveness (void); +int agent_reset_scd (ctrl_t ctrl); +int agent_card_learn (ctrl_t ctrl, + void (*kpinfo_cb)(void*, const char *), + void *kpinfo_cb_arg, + void (*certinfo_cb)(void*, const char *), + void *certinfo_cb_arg, + void (*sinfo_cb)(void*, const char *, + size_t, const char *), + void *sinfo_cb_arg); +int agent_card_serialno (ctrl_t ctrl, char **r_serialno); +int agent_card_pksign (ctrl_t ctrl, + const char *keyid, + int (*getpin_cb)(void *, const char *, char*, size_t), + void *getpin_cb_arg, + const unsigned char *indata, size_t indatalen, + unsigned char **r_buf, size_t *r_buflen); +int agent_card_pkdecrypt (ctrl_t ctrl, + const char *keyid, + int (*getpin_cb)(void *, const char *, char*,size_t), + void *getpin_cb_arg, + const unsigned char *indata, size_t indatalen, + char **r_buf, size_t *r_buflen); +int agent_card_readcert (ctrl_t ctrl, + const char *id, char **r_buf, size_t *r_buflen); +int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf); +gpg_error_t agent_card_getattr (ctrl_t ctrl, const char *name, char **result); +int agent_card_scd (ctrl_t ctrl, const char *cmdline, + int (*getpin_cb)(void *, const char *, char*, size_t), + void *getpin_cb_arg, void *assuan_context); + + +/*-- learncard.c --*/ +int agent_handle_learn (ctrl_t ctrl, void *assuan_context); + + +#endif /*AGENT_H*/ diff --git a/agent/cache.c b/agent/cache.c new file mode 100644 index 0000000..10f9ef6 --- /dev/null +++ b/agent/cache.c @@ -0,0 +1,340 @@ +/* cache.c - keep a cache of passphrases + * 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 3 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, see . + */ + +#include + +#include +#include +#include +#include +#include + +#include "agent.h" + +struct secret_data_s { + int totallen; /* this includes the padding */ + int datalen; /* actual data length */ + char data[1]; +}; + +typedef struct cache_item_s *ITEM; +struct cache_item_s { + ITEM next; + time_t created; + time_t accessed; + int ttl; /* max. lifetime given in seconds, -1 one means infinite */ + int lockcount; + struct secret_data_s *pw; + cache_mode_t cache_mode; + char key[1]; +}; + + +static ITEM thecache; + + +static void +release_data (struct secret_data_s *data) +{ + xfree (data); +} + +static struct secret_data_s * +new_data (const void *data, size_t length) +{ + struct secret_data_s *d; + int total; + + /* we pad the data to 32 bytes so that it get more complicated + finding something out by watching allocation patterns. This is + usally not possible but we better assume nothing about our + secure storage provider*/ + total = length + 32 - (length % 32); + + d = gcry_malloc_secure (sizeof *d + total - 1); + if (d) + { + d->totallen = total; + d->datalen = length; + memcpy (d->data, data, length); + } + return d; +} + + + +/* check whether there are items to expire */ +static void +housekeeping (void) +{ + ITEM r, rprev; + time_t current = gnupg_get_time (); + + /* First expire the actual data */ + for (r=thecache; r; r = r->next) + { + if (!r->lockcount && r->pw + && r->ttl >= 0 && r->accessed + r->ttl < current) + { + if (DBG_CACHE) + log_debug (" expired `%s' (%ds after last access)\n", + r->key, r->ttl); + release_data (r->pw); + r->pw = NULL; + r->accessed = current; + } + } + + /* Second, make sure that we also remove them based on the created stamp so + that the user has to enter it from time to time. */ + for (r=thecache; r; r = r->next) + { + unsigned long maxttl; + + switch (r->cache_mode) + { + case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; + default: maxttl = opt.max_cache_ttl; break; + } + if (!r->lockcount && r->pw && r->created + maxttl < current) + { + if (DBG_CACHE) + log_debug (" expired `%s' (%lus after creation)\n", + r->key, opt.max_cache_ttl); + release_data (r->pw); + r->pw = NULL; + r->accessed = current; + } + } + + /* Third, make sure that we don't have too many items in the list. + Expire old and unused entries after 30 minutes */ + for (rprev=NULL, r=thecache; r; ) + { + if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current) + { + if (r->lockcount) + { + log_error ("can't remove unused cache entry `%s' due to" + " lockcount=%d\n", + r->key, r->lockcount); + r->accessed += 60*10; /* next error message in 10 minutes */ + rprev = r; + r = r->next; + } + else + { + ITEM r2 = r->next; + if (DBG_CACHE) + log_debug (" removed `%s' (slot not used for 30m)\n", r->key); + xfree (r); + if (!rprev) + thecache = r2; + else + rprev->next = r2; + r = r2; + } + } + else + { + rprev = r; + r = r->next; + } + } +} + + +void +agent_flush_cache (void) +{ + ITEM r; + + if (DBG_CACHE) + log_debug ("agent_flush_cache\n"); + + for (r=thecache; r; r = r->next) + { + if (!r->lockcount && r->pw) + { + if (DBG_CACHE) + log_debug (" flushing `%s'\n", r->key); + release_data (r->pw); + r->pw = NULL; + r->accessed = 0; + } + else if (r->lockcount && r->pw) + { + if (DBG_CACHE) + log_debug (" marked `%s' for flushing\n", r->key); + r->accessed = 0; + r->ttl = 0; + } + } +} + + + +/* Store DATA of length DATALEN in the cache under KEY and mark it + with a maximum lifetime of TTL seconds. If there is already data + under this key, it will be replaced. Using a DATA of NULL deletes + the entry. A TTL of 0 is replaced by the default TTL and a TTL of + -1 set infinite timeout. CACHE_MODE is stored with the cache entry + and used to select different timeouts. */ +int +agent_put_cache (const char *key, cache_mode_t cache_mode, + const char *data, int ttl) +{ + ITEM r; + + if (DBG_CACHE) + log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n", + key, ttl, cache_mode); + housekeeping (); + + if (!ttl) + { + switch(cache_mode) + { + case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break; + default: ttl = opt.def_cache_ttl; break; + } + } + if (!ttl || cache_mode == CACHE_MODE_IGNORE) + return 0; + + for (r=thecache; r; r = r->next) + { + if (!r->lockcount && !strcmp (r->key, key)) + break; + } + if (r) + { /* replace */ + if (r->pw) + { + release_data (r->pw); + r->pw = NULL; + } + if (data) + { + r->created = r->accessed = gnupg_get_time (); + r->ttl = ttl; + r->cache_mode = cache_mode; + r->pw = new_data (data, strlen (data)+1); + if (!r->pw) + log_error ("out of core while allocating new cache item\n"); + } + } + else if (data) + { /* simply insert */ + r = xtrycalloc (1, sizeof *r + strlen (key)); + if (!r) + log_error ("out of core while allocating new cache control\n"); + else + { + strcpy (r->key, key); + r->created = r->accessed = gnupg_get_time (); + r->ttl = ttl; + r->cache_mode = cache_mode; + r->pw = new_data (data, strlen (data)+1); + if (!r->pw) + { + log_error ("out of core while allocating new cache item\n"); + xfree (r); + } + else + { + r->next = thecache; + thecache = r; + } + } + } + return 0; +} + + +/* Try to find an item in the cache. Note that we currently don't + make use of CACHE_MODE. */ +const char * +agent_get_cache (const char *key, cache_mode_t cache_mode, void **cache_id) +{ + ITEM r; + + if (cache_mode == CACHE_MODE_IGNORE) + return NULL; + + if (DBG_CACHE) + log_debug ("agent_get_cache `%s'...\n", key); + housekeeping (); + + /* first try to find one with no locks - this is an updated cache + entry: We might have entries with a lockcount and without a + lockcount. */ + for (r=thecache; r; r = r->next) + { + if (!r->lockcount && r->pw && !strcmp (r->key, key)) + { + /* put_cache does only put strings into the cache, so we + don't need the lengths */ + r->accessed = gnupg_get_time (); + if (DBG_CACHE) + log_debug ("... hit\n"); + r->lockcount++; + *cache_id = r; + return r->pw->data; + } + } + /* again, but this time get even one with a lockcount set */ + for (r=thecache; r; r = r->next) + { + if (r->pw && !strcmp (r->key, key)) + { + r->accessed = gnupg_get_time (); + if (DBG_CACHE) + log_debug ("... hit (locked)\n"); + r->lockcount++; + *cache_id = r; + return r->pw->data; + } + } + if (DBG_CACHE) + log_debug ("... miss\n"); + + *cache_id = NULL; + return NULL; +} + + +void +agent_unlock_cache_entry (void **cache_id) +{ + ITEM r; + + for (r=thecache; r; r = r->next) + { + if (r == *cache_id) + { + if (!r->lockcount) + log_error ("trying to unlock non-locked cache entry `%s'\n", + r->key); + else + r->lockcount--; + return; + } + } +} diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c new file mode 100644 index 0000000..ad1bd03 --- /dev/null +++ b/agent/call-pinentry.c @@ -0,0 +1,1178 @@ +/* call-pinentry.c - Spawn the pinentry to query stuff from the user + * Copyright (C) 2001, 2002, 2004, 2007, 2008, + * 2010 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef HAVE_W32_SYSTEM +# include +# include +# include +#endif +#include + +#include "agent.h" +#include +#include "setenv.h" +#include "i18n.h" + +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#define MAX_OPEN_FDS 20 +#endif + + +/* Because access to the pinentry must be serialized (it is and shall + be a global mutual dialog) we should better timeout further + requests after some time. 2 minutes seem to be a reasonable + time. */ +#define LOCK_TIMEOUT (1*60) + +/* The assuan context of the current pinentry. */ +static assuan_context_t entry_ctx; + +/* The control variable of the connection owning the current pinentry. + This is only valid if ENTRY_CTX is not NULL. Note, that we care + only about the value of the pointer and that it should never be + dereferenced. */ +static ctrl_t entry_owner; + +/* A mutex used to serialize access to the pinentry. */ +static pth_mutex_t entry_lock; + +/* The thread ID of the popup working thread. */ +static pth_t popup_tid; + +/* A flag used in communication between the popup working thread and + its stop function. */ +static int popup_finished; + + + +/* Data to be passed to our callbacks, */ +struct entry_parm_s +{ + int lines; + size_t size; + unsigned char *buffer; +}; + + + + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_call_pinentry (void) +{ + static int initialized; + + if (!initialized) + { + if (pth_mutex_init (&entry_lock)) + initialized = 1; + } +} + + + +static void +dump_mutex_state (pth_mutex_t *m) +{ +#ifdef _W32_PTH_H + (void)m; + log_printf ("unknown under W32"); +#else + if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) + log_printf ("not_initialized"); + else if (!(m->mx_state & PTH_MUTEX_LOCKED)) + log_printf ("not_locked"); + else + log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); +#endif +} + + +/* This function may be called to print infromation pertaining to the + current state of this module to the log. */ +void +agent_query_dump_state (void) +{ + log_info ("agent_query_dump_state: entry_lock="); + dump_mutex_state (&entry_lock); + log_printf ("\n"); + log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n", + entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid); +} + +/* Called to make sure that a popup window owned by the current + connection gets closed. */ +void +agent_reset_query (ctrl_t ctrl) +{ + if (entry_ctx && popup_tid && entry_owner == ctrl) + { + agent_popup_message_stop (ctrl); + } +} + + +/* Unlock the pinentry so that another thread can start one and + disconnect that pinentry - we do this after the unlock so that a + stalled pinentry does not block other threads. Fixme: We should + have a timeout in Assuan for the disconnect operation. */ +static int +unlock_pinentry (int rc) +{ + assuan_context_t ctx = entry_ctx; + + entry_ctx = NULL; + if (!pth_mutex_release (&entry_lock)) + { + log_error ("failed to release the entry lock\n"); + if (!rc) + rc = gpg_error (GPG_ERR_INTERNAL); + } + assuan_release (ctx); + return rc; +} + + +/* To make sure we leave no secrets in our image after forking of the + pinentry, we use this callback. */ +static void +atfork_cb (void *opaque, int where) +{ + ctrl_t ctrl = opaque; + + if (!where) + { + int iterator = 0; + const char *name, *assname, *value; + + gcry_control (GCRYCTL_TERM_SECMEM); + + while ((name = session_env_list_stdenvnames (&iterator, &assname))) + { + /* For all new envvars (!ASSNAME) and the two medium old + ones which do have an assuan name but are conveyed using + environment variables, update the environment of the + forked process. */ + if (!assname + || !strcmp (name, "XAUTHORITY") + || !strcmp (name, "PINENTRY_USER_DATA")) + { + value = session_env_getenv (ctrl->session_env, name); + if (value) + setenv (name, value, 1); + } + } + } +} + + +static gpg_error_t +getinfo_pid_cb (void *opaque, const void *buffer, size_t length) +{ + unsigned long *pid = opaque; + char pidbuf[50]; + + /* There is only the pid in the server's response. */ + if (length >= sizeof pidbuf) + length = sizeof pidbuf -1; + if (length) + { + strncpy (pidbuf, buffer, length); + pidbuf[length] = 0; + *pid = strtoul (pidbuf, NULL, 10); + } + return 0; +} + +/* Fork off the pin entry if this has not already been done. Note, + that this function must always be used to aquire the lock for the + pinentry - we will serialize _all_ pinentry calls. + */ +static int +start_pinentry (ctrl_t ctrl) +{ + int rc; + const char *pgmname; + assuan_context_t ctx; + const char *argv[5]; + int no_close_list[3]; + int i; + pth_event_t evt; + const char *tmpstr; + unsigned long pinentry_pid; + const char *value; + + evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); + if (!pth_mutex_acquire (&entry_lock, 0, evt)) + { + if (pth_event_occurred (evt)) + rc = gpg_error (GPG_ERR_TIMEOUT); + else + rc = gpg_error (GPG_ERR_INTERNAL); + pth_event_free (evt, PTH_FREE_THIS); + log_error (_("failed to acquire the pinentry lock: %s\n"), + gpg_strerror (rc)); + return rc; + } + pth_event_free (evt, PTH_FREE_THIS); + + entry_owner = ctrl; + + if (entry_ctx) + return 0; + + if (opt.verbose) + log_info ("starting a new PIN Entry\n"); + +#ifdef HAVE_W32_SYSTEM + fflush (stdout); + fflush (stderr); +#endif + if (fflush (NULL)) + { +#ifndef HAVE_W32_SYSTEM + gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); +#endif + log_error ("error flushing pending output: %s\n", strerror (errno)); + /* At least Windows XP fails here with EBADF. According to docs + and Wine an fflush(NULL) is the same as _flushall. However + the Wime implementaion does not flush stdin,stdout and stderr + - see above. Lets try to ignore the error. */ +#ifndef HAVE_W32_SYSTEM + return unlock_pinentry (tmperr); +#endif + } + + if (!opt.pinentry_program || !*opt.pinentry_program) + opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); + pgmname = opt.pinentry_program; + if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) + pgmname = opt.pinentry_program; + else + pgmname++; + + /* OS X needs the entire file name in argv[0], so that it can locate + the resource bundle. For other systems we stick to the usual + convention of supplying only the name of the program. */ +#ifdef __APPLE__ + argv[0] = opt.pinentry_program; +#else /*!__APPLE__*/ + argv[0] = pgmname; +#endif /*__APPLE__*/ + + if (!opt.keep_display + && (value = session_env_getenv (ctrl->session_env, "DISPLAY"))) + { + argv[1] = "--display"; + argv[2] = value; + argv[3] = NULL; + } + else + argv[1] = NULL; + + i=0; + if (!opt.running_detached) + { + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); + } + no_close_list[i] = -1; + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); + return rc; + } + + /* Connect to the pinentry and perform initial handshaking. Note + that atfork is used to change the environment for pinentry. We + start the server in detached mode to suppress the console window + under Windows. */ + rc = assuan_pipe_connect (ctx, opt.pinentry_program, argv, + no_close_list, atfork_cb, ctrl, + ASSUAN_PIPE_CONNECT_DETACHED); + if (rc) + { + log_error ("can't connect to the PIN entry module: %s\n", + gpg_strerror (rc)); + assuan_release (ctx); + return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY)); + } + entry_ctx = ctx; + + if (DBG_ASSUAN) + log_debug ("connection to PIN entry established\n"); + + rc = assuan_transact (entry_ctx, + opt.no_grab? "OPTION no-grab":"OPTION grab", + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + value = session_env_getenv (ctrl->session_env, "GPG_TTY"); + if (value) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 ) + return unlock_pinentry (out_of_core ()); + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + if (rc) + return unlock_pinentry (rc); + } + value = session_env_getenv (ctrl->session_env, "TERM"); + if (value) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 ) + return unlock_pinentry (out_of_core ()); + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + if (rc) + return unlock_pinentry (rc); + } + if (ctrl->lc_ctype) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 ) + return unlock_pinentry (out_of_core ()); + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + if (rc) + return unlock_pinentry (rc); + } + if (ctrl->lc_messages) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 ) + return unlock_pinentry (out_of_core ()); + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + if (rc) + return unlock_pinentry (rc); + } + + { + /* Provide a few default strings for use by the pinentries. This + may help a pinentry to avoid implementing localization code. */ + static struct { const char *key, *value; } tbl[] = { + /* TRANSLATORS: These are labels for buttons etc used in + Pinentries. An underscore indicates that the next letter + should be used as an accelerator. Double the underscore for + a literal one. The actual to be translated text starts after + the second vertical bar. */ + { "ok", N_("|pinentry-label|_OK") }, + { "cancel", N_("|pinentry-label|_Cancel") }, + { "prompt", N_("|pinentry-label|PIN:") }, + { NULL, NULL} + }; + char *optstr; + int idx; + const char *s, *s2; + + for (idx=0; tbl[idx].key; idx++) + { + s = _(tbl[idx].value); + if (*s == '|' && (s2=strchr (s+1,'|'))) + s = s2+1; + if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 ) + return unlock_pinentry (out_of_core ()); + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + } + } + + + /* Tell the pinentry the name of a file it shall touch after having + messed with the tty. This is optional and only supported by + newer pinentries and thus we do no error checking. */ + tmpstr = opt.pinentry_touch_file; + if (tmpstr && !strcmp (tmpstr, "/dev/null")) + tmpstr = NULL; + else if (!tmpstr) + tmpstr = get_agent_socket_name (); + if (tmpstr) + { + char *optstr; + + if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 ) + ; + else + { + assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + } + } + + + /* Now ask the Pinentry for its PID. If the Pinentry is new enough + it will send the pid back and we will use an inquire to notify + our client. The client may answer the inquiry either with END or + with CAN to cancel the pinentry. */ + rc = assuan_transact (entry_ctx, "GETINFO pid", + getinfo_pid_cb, &pinentry_pid, + NULL, NULL, NULL, NULL); + if (rc) + { + log_info ("You may want to update to a newer pinentry\n"); + rc = 0; + } + else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1)) + log_error ("pinentry did not return a PID\n"); + else + { + rc = agent_inq_pinentry_launched (ctrl, pinentry_pid); + if (gpg_err_code (rc) == GPG_ERR_CANCELED) + return unlock_pinentry (gpg_error (GPG_ERR_CANCELED)); + rc = 0; + } + + return 0; +} + + +/* Returns True is the pinentry is currently active. If WAITSECONDS is + greater than zero the function will wait for this many seconds + before returning. */ +int +pinentry_active_p (ctrl_t ctrl, int waitseconds) +{ + (void)ctrl; + + if (waitseconds > 0) + { + pth_event_t evt; + int rc; + + evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0)); + if (!pth_mutex_acquire (&entry_lock, 0, evt)) + { + if (pth_event_occurred (evt)) + rc = gpg_error (GPG_ERR_TIMEOUT); + else + rc = gpg_error (GPG_ERR_INTERNAL); + pth_event_free (evt, PTH_FREE_THIS); + return rc; + } + pth_event_free (evt, PTH_FREE_THIS); + } + else + { + if (!pth_mutex_acquire (&entry_lock, 1, NULL)) + return gpg_error (GPG_ERR_LOCKED); + } + + if (!pth_mutex_release (&entry_lock)) + log_error ("failed to release the entry lock at %d\n", __LINE__); + return 0; +} + + +static gpg_error_t +getpin_cb (void *opaque, const void *buffer, size_t length) +{ + struct entry_parm_s *parm = opaque; + + if (!buffer) + return 0; + + /* we expect the pin to fit on one line */ + if (parm->lines || length >= parm->size) + return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA); + + /* fixme: we should make sure that the assuan buffer is allocated in + secure memory or read the response byte by byte */ + memcpy (parm->buffer, buffer, length); + parm->buffer[length] = 0; + parm->lines++; + return 0; +} + + +static int +all_digitsp( const char *s) +{ + for (; *s && *s >= '0' && *s <= '9'; s++) + ; + return !*s; +} + + +/* 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. PArsing stops at the end of the string or + a white space character. */ +static char * +unescape_passphrase_string (const unsigned char *s) +{ + char *buffer, *d; + + buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1); + if (!buffer) + return NULL; + while (*s && !spacep (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; +} + + +/* Estimate the quality of the passphrase PW and return a value in the + range 0..100. */ +static int +estimate_passphrase_quality (const char *pw) +{ + int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3; + int length; + const char *s; + + if (goodlength < 1) + return 0; + + for (length = 0, s = pw; *s; s++) + if (!spacep (s)) + length ++; + + if (length > goodlength) + return 100; + return ((length*10) / goodlength)*10; +} + + +/* Handle the QUALITY inquiry. */ +static gpg_error_t +inq_quality (void *opaque, const char *line) +{ + assuan_context_t ctx = opaque; + char *pin; + int rc; + int percent; + char numbuf[20]; + + if (!strncmp (line, "QUALITY", 7) && (line[7] == ' ' || !line[7])) + { + line += 7; + while (*line == ' ') + line++; + + pin = unescape_passphrase_string (line); + if (!pin) + rc = gpg_error_from_syserror (); + else + { + percent = estimate_passphrase_quality (pin); + if (check_passphrase_constraints (NULL, pin, 1)) + percent = -percent; + snprintf (numbuf, sizeof numbuf, "%d", percent); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + xfree (pin); + } + } + else + { + log_error ("unsupported inquiry `%s' from pinentry\n", line); + rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE); + } + + return rc; +} + + +/* Helper for agent_askpin and agent_get_passphrase. */ +static int +setup_qualitybar (void) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + char *tmpstr, *tmpstr2; + const char *tooltip; + + /* TRANSLATORS: This string is displayed by Pinentry as the label + for the quality bar. */ + tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v"); + snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:""); + line[DIM(line)-1] = 0; + xfree (tmpstr); + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc == 103 /*(Old assuan error code)*/ + || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + ; /* Ignore Unknown Command from old Pinentry versions. */ + else if (rc) + return rc; + + tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0); + if (tmpstr2) + tooltip = tmpstr2; + else + { + /* TRANSLATORS: This string is a tooltip, shown by pinentry when + hovering over the quality bar. Please use an appropriate + string to describe what this is about. The length of the + tooltip is limited to about 900 characters. If you do not + translate this entry, a default english text (see source) + will be used. */ + tooltip = _("pinentry.qualitybar.tooltip"); + if (!strcmp ("pinentry.qualitybar.tooltip", tooltip)) + tooltip = ("The quality of the text entered above.\n" + "Please ask your administrator for " + "details about the criteria."); + } + tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v"); + xfree (tmpstr2); + snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:""); + line[DIM(line)-1] = 0; + xfree (tmpstr); + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc == 103 /*(Old assuan error code)*/ + || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + ; /* Ignore Unknown Command from old pinentry versions. */ + else if (rc) + return rc; + + return 0; +} + + + +/* Call the Entry and ask for the PIN. We do check for a valid PIN + number here and repeat it as long as we have invalid formed + numbers. */ +int +agent_askpin (ctrl_t ctrl, + const char *desc_text, const char *prompt_text, + const char *initial_errtext, + struct pin_entry_info_s *pininfo) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + struct entry_parm_s parm; + const char *errtext = NULL; + int is_pin = 0; + int saveflag; + + if (opt.batch) + return 0; /* fixme: we should return BAD PIN */ + + if (!pininfo || pininfo->max_length < 1) + return gpg_error (GPG_ERR_INV_VALUE); + if (!desc_text && pininfo->min_digits) + desc_text = _("Please enter your PIN, so that the secret key " + "can be unlocked for this session"); + else if (!desc_text) + desc_text = _("Please enter your passphrase, so that the secret key " + "can be unlocked for this session"); + + if (prompt_text) + is_pin = !!strstr (prompt_text, "PIN"); + else + is_pin = desc_text && strstr (desc_text, "PIN"); + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + snprintf (line, DIM(line)-1, "SETDESC %s", desc_text); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + snprintf (line, DIM(line)-1, "SETPROMPT %s", + prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + /* If a passphrase quality indicator has been requested and a + minimum passphrase length has not been disabled, send the command + to the pinentry. */ + if (pininfo->with_qualitybar && opt.min_passphrase_len ) + { + rc = setup_qualitybar (); + if (rc) + return unlock_pinentry (rc); + } + + if (initial_errtext) + { + snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + } + + for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++) + { + memset (&parm, 0, sizeof parm); + parm.size = pininfo->max_length; + *pininfo->pin = 0; /* Reset the PIN. */ + parm.buffer = (unsigned char*)pininfo->pin; + + if (errtext) + { + /* TRANLATORS: The string is appended to an error message in + the pinentry. The %s is the actual error message, the + two %d give the current and maximum number of tries. */ + snprintf (line, DIM(line)-1, _("SETERROR %s (try %d of %d)"), + errtext, pininfo->failed_tries+1, pininfo->max_tries); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + errtext = NULL; + } + + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (entry_ctx); + rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, + inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); + /* Most pinentries out in the wild return the old Assuan error code + for canceled which gets translated to an assuan Cancel error and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) + && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + + if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA) + errtext = is_pin? _("PIN too long") + : _("Passphrase too long"); + else if (rc) + return unlock_pinentry (rc); + + if (!errtext && pininfo->min_digits) + { + /* do some basic checks on the entered PIN. */ + if (!all_digitsp (pininfo->pin)) + errtext = _("Invalid characters in PIN"); + else if (pininfo->max_digits + && strlen (pininfo->pin) > pininfo->max_digits) + errtext = _("PIN too long"); + else if (strlen (pininfo->pin) < pininfo->min_digits) + errtext = _("PIN too short"); + } + + if (!errtext && pininfo->check_cb) + { + /* More checks by utilizing the optional callback. */ + pininfo->cb_errtext = NULL; + rc = pininfo->check_cb (pininfo); + if (rc == -1 && pininfo->cb_errtext) + errtext = pininfo->cb_errtext; + else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE + || gpg_err_code (rc) == GPG_ERR_BAD_PIN) + errtext = (is_pin? _("Bad PIN") + : _("Bad Passphrase")); + else if (rc) + return unlock_pinentry (rc); + } + + if (!errtext) + return unlock_pinentry (0); /* okay, got a PIN or passphrase */ + } + + return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN + : GPG_ERR_BAD_PASSPHRASE)); +} + + + +/* Ask for the passphrase using the supplied arguments. The returned + passphrase needs to be freed by the caller. */ +int +agent_get_passphrase (ctrl_t ctrl, + char **retpass, const char *desc, const char *prompt, + const char *errtext, int with_qualitybar) +{ + + int rc; + char line[ASSUAN_LINELENGTH]; + struct entry_parm_s parm; + int saveflag; + + *retpass = NULL; + if (opt.batch) + return gpg_error (GPG_ERR_BAD_PASSPHRASE); + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + if (!prompt) + prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase"); + + + if (desc) + snprintf (line, DIM(line)-1, "SETDESC %s", desc); + else + snprintf (line, DIM(line)-1, "RESET"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + if (with_qualitybar && opt.min_passphrase_len) + { + rc = setup_qualitybar (); + if (rc) + return unlock_pinentry (rc); + } + + if (errtext) + { + snprintf (line, DIM(line)-1, "SETERROR %s", errtext); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + } + + memset (&parm, 0, sizeof parm); + parm.size = ASSUAN_LINELENGTH/2 - 5; + parm.buffer = gcry_malloc_secure (parm.size+10); + if (!parm.buffer) + return unlock_pinentry (out_of_core ()); + + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (entry_ctx); + rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, + inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); + /* Most pinentries out in the wild return the old Assuan error code + for canceled which gets translated to an assuan Cancel error and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + if (rc) + xfree (parm.buffer); + else + *retpass = parm.buffer; + return unlock_pinentry (rc); +} + + + +/* Pop up the PIN-entry, display the text and the prompt and ask the + user to confirm this. We return 0 for success, ie. the user + confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an + other error. If WITH_CANCEL it true an extra cancel button is + displayed to allow the user to easily return a GPG_ERR_CANCELED. + if the Pinentry does not support this, the user can still cancel by + closing the Pinentry window. */ +int +agent_get_confirmation (ctrl_t ctrl, + const char *desc, const char *ok, + const char *notok, int with_cancel) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + if (desc) + snprintf (line, DIM(line)-1, "SETDESC %s", desc); + else + snprintf (line, DIM(line)-1, "RESET"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + /* Most pinentries out in the wild return the old Assuan error code + for canceled which gets translated to an assuan Cancel error and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + + if (rc) + return unlock_pinentry (rc); + + if (ok) + { + snprintf (line, DIM(line)-1, "SETOK %s", ok); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, + line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + } + if (notok) + { + /* Try to use the newer NOTOK feature if a cancel button is + requested. If no cancel button is requested we keep on using + the standard cancel. */ + if (with_cancel) + { + snprintf (line, DIM(line)-1, "SETNOTOK %s", notok); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, + line, NULL, NULL, NULL, NULL, NULL, NULL); + } + else + rc = GPG_ERR_ASS_UNKNOWN_CMD; + + if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + { + snprintf (line, DIM(line)-1, "SETCANCEL %s", notok); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + } + if (rc) + return unlock_pinentry (rc); + } + + rc = assuan_transact (entry_ctx, "CONFIRM", + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + + return unlock_pinentry (rc); +} + + + +/* Pop up the PINentry, display the text DESC and a button with the + text OK_BTN (which may be NULL to use the default of "OK") and waut + for the user to hit this button. The return value is not + relevant. */ +int +agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + if (desc) + snprintf (line, DIM(line)-1, "SETDESC %s", desc); + else + snprintf (line, DIM(line)-1, "RESET"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + /* Most pinentries out in the wild return the old Assuan error code + for canceled which gets translated to an assuan Cancel error and + not to the code for a user cancel. Fix this here. */ + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + + if (rc) + return unlock_pinentry (rc); + + if (ok_btn) + { + snprintf (line, DIM(line)-1, "SETOK %s", ok_btn); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, + NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + } + + rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL, + NULL, NULL, NULL); + if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED) + rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED); + + return unlock_pinentry (rc); +} + + +/* The thread running the popup message. */ +static void * +popup_message_thread (void *arg) +{ + (void)arg; + + /* We use the --one-button hack instead of the MESSAGE command to + allow the use of old Pinentries. Those old Pinentries will then + show an additional Cancel button but that is mostly a visual + annoyance. */ + assuan_transact (entry_ctx, "CONFIRM --one-button", + NULL, NULL, NULL, NULL, NULL, NULL); + popup_finished = 1; + return NULL; +} + + +/* Pop up a message window similar to the confirm one but keep it open + until agent_popup_message_stop has been called. It is crucial for + the caller to make sure that the stop function gets called as soon + as the message is not anymore required because the message is + system modal and all other attempts to use the pinentry will fail + (after a timeout). */ +int +agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + pth_attr_t tattr; + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + if (desc) + snprintf (line, DIM(line)-1, "SETDESC %s", desc); + else + snprintf (line, DIM(line)-1, "RESET"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (rc); + + if (ok_btn) + { + snprintf (line, DIM(line)-1, "SETOK %s", ok_btn); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL); + if (rc) + return unlock_pinentry (rc); + } + + tattr = pth_attr_new(); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); + pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message"); + + popup_finished = 0; + popup_tid = pth_spawn (tattr, popup_message_thread, NULL); + if (!popup_tid) + { + rc = gpg_error_from_syserror (); + log_error ("error spawning popup message handler: %s\n", + strerror (errno) ); + pth_attr_destroy (tattr); + return unlock_pinentry (rc); + } + pth_attr_destroy (tattr); + + return 0; +} + +/* Close a popup window. */ +void +agent_popup_message_stop (ctrl_t ctrl) +{ + int rc; + pid_t pid; + + (void)ctrl; + + if (!popup_tid || !entry_ctx) + { + log_debug ("agent_popup_message_stop called with no active popup\n"); + return; + } + + pid = assuan_get_pid (entry_ctx); + if (pid == (pid_t)(-1)) + ; /* No pid available can't send a kill. */ + else if (popup_finished) + ; /* Already finished and ready for joining. */ +#ifdef HAVE_W32_SYSTEM + /* Older versions of assuan set PID to 0 on Windows to indicate an + invalid value. */ + else if (pid != (pid_t) INVALID_HANDLE_VALUE + && pid != 0) + { + HANDLE process = (HANDLE) pid; + + /* Arbitrary error code. */ + TerminateProcess (process, 1); + } +#else + else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) + { /* The daemon already died. No need to send a kill. However + because we already waited for the process, we need to tell + assuan that it should not wait again (done by + unlock_pinentry). */ + if (rc == pid) + assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1); + } + else if (pid > 0) + kill (pid, SIGKILL); /* Need to use SIGKILL due to bad + interaction of SIGINT with Pth. */ +#endif + + /* Now wait for the thread to terminate. */ + rc = pth_join (popup_tid, NULL); + if (!rc) + log_debug ("agent_popup_message_stop: pth_join failed: %s\n", + strerror (errno)); + popup_tid = NULL; + entry_owner = NULL; + + /* Now we can close the connection. */ + unlock_pinentry (0); +} + + diff --git a/agent/call-scd.c b/agent/call-scd.c new file mode 100644 index 0000000..5a43377 --- /dev/null +++ b/agent/call-scd.c @@ -0,0 +1,1167 @@ +/* call-scd.c - fork of the scdaemon to do SC operations + * Copyright (C) 2001, 2002, 2005, 2007 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef HAVE_W32_SYSTEM +#include +#endif +#include + +#include "agent.h" +#include + +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#define MAX_OPEN_FDS 20 +#endif + +/* This Assuan flag is only available since libassuan 2.0.2. Because + comments lines are comments anyway we can use a replacement which + might not do anything. assuan_{g,s}et_flag don't return an error + thus there won't be any ABI problem. */ +#ifndef ASSUAN_CONVEY_COMMENTS +#define ASSUAN_CONVEY_COMMENTS 4 +#endif + + +/* Definition of module local data of the CTRL structure. */ +struct scd_local_s +{ + /* We keep a list of all allocated context with a an achnor at + SCD_LOCAL_LIST (see below). */ + struct scd_local_s *next_local; + + /* We need to get back to the ctrl object actually referencing this + structure. This is really an awkward way of enumerint the lcoal + contects. A much cleaner way would be to keep a global list of + ctrl objects to enumerate them. */ + ctrl_t ctrl_backlink; + + assuan_context_t ctx; /* NULL or session context for the SCdaemon + used with this connection. */ + int locked; /* This flag is used to assert proper use of + start_scd and unlock_scd. */ + +}; + + +/* Callback parameter for learn card */ +struct learn_parm_s +{ + void (*kpinfo_cb)(void*, const char *); + void *kpinfo_cb_arg; + void (*certinfo_cb)(void*, const char *); + void *certinfo_cb_arg; + void (*sinfo_cb)(void*, const char *, size_t, const char *); + void *sinfo_cb_arg; +}; + +struct inq_needpin_s +{ + assuan_context_t ctx; + int (*getpin_cb)(void *, const char *, char*, size_t); + void *getpin_cb_arg; + assuan_context_t passthru; /* If not NULL, pass unknown inquiries + up to the caller. */ +}; + + +/* To keep track of all active SCD contexts, we keep a linked list + anchored at this variable. */ +static struct scd_local_s *scd_local_list; + +/* A Mutex used inside the start_scd function. */ +static pth_mutex_t start_scd_lock; + +/* A malloced string with the name of the socket to be used for + additional connections. May be NULL if not provided by + SCdaemon. */ +static char *socket_name; + +/* The context of the primary connection. This is also used as a flag + to indicate whether the scdaemon has been started. */ +static assuan_context_t primary_scd_ctx; + +/* To allow reuse of the primary connection, the following flag is set + to true if the primary context has been reset and is not in use by + any connection. */ +static int primary_scd_ctx_reusable; + + + +/* Local prototypes. */ +static gpg_error_t membuf_data_cb (void *opaque, + const void *buffer, size_t length); + + + + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_call_scd (void) +{ + static int initialized; + + if (!initialized) + { + if (!pth_mutex_init (&start_scd_lock)) + log_fatal ("error initializing mutex: %s\n", strerror (errno)); + initialized = 1; + } +} + + +static void +dump_mutex_state (pth_mutex_t *m) +{ +#ifdef _W32_PTH_H + (void)m; + log_printf ("unknown under W32"); +#else + if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) + log_printf ("not_initialized"); + else if (!(m->mx_state & PTH_MUTEX_LOCKED)) + log_printf ("not_locked"); + else + log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); +#endif +} + + +/* This function may be called to print infromation pertaining to the + current state of this module to the log. */ +void +agent_scd_dump_state (void) +{ + log_info ("agent_scd_dump_state: scd_lock="); + dump_mutex_state (&start_scd_lock); + log_printf ("\n"); + log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n", + primary_scd_ctx, + (long)assuan_get_pid (primary_scd_ctx), + primary_scd_ctx_reusable); + if (socket_name) + log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name); +} + + +/* The unlock_scd function shall be called after having accessed the + SCD. It is currently not very useful but gives an opportunity to + keep track of connections currently calling SCD. Note that the + "lock" operation is done by the start_scd() function which must be + called and error checked before any SCD operation. CTRL is the + usual connection context and RC the error code to be passed trhough + the function. */ +static int +unlock_scd (ctrl_t ctrl, int rc) +{ + if (gpg_err_code (rc) == GPG_ERR_NOT_OPERATIONAL + && gpg_err_source (rc) == GPG_ERR_SOURCE_SCD) + { + /* If the SCdaemon returned this error, it detected a major + problem, like no reader connected. To finish this we need to + stop the connection. This simulates an explicit killing of + the SCdaemon. */ + assuan_transact (primary_scd_ctx, "BYE", + NULL, NULL, NULL, NULL, NULL, NULL); + } + + if (ctrl->scd_local->locked != 1) + { + log_error ("unlock_scd: invalid lock count (%d)\n", + ctrl->scd_local->locked); + if (!rc) + rc = gpg_error (GPG_ERR_INTERNAL); + } + ctrl->scd_local->locked = 0; + return rc; +} + +/* To make sure we leave no secrets in our image after forking of the + scdaemon, we use this callback. */ +static void +atfork_cb (void *opaque, int where) +{ + (void)opaque; + + if (!where) + gcry_control (GCRYCTL_TERM_SECMEM); +} + + +/* Fork off the SCdaemon if this has not already been done. Lock the + daemon and make sure that a proper context has been setup in CTRL. + This function might also lock the daemon, which means that the + caller must call unlock_scd after this fucntion has returned + success and the actual Assuan transaction been done. */ +static int +start_scd (ctrl_t ctrl) +{ + gpg_error_t err = 0; + const char *pgmname; + assuan_context_t ctx = NULL; + const char *argv[3]; + int no_close_list[3]; + int i; + int rc; + + if (opt.disable_scdaemon) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + /* If this is the first call for this session, setup the local data + structure. */ + if (!ctrl->scd_local) + { + ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local); + if (!ctrl->scd_local) + return gpg_error_from_syserror (); + ctrl->scd_local->ctrl_backlink = ctrl; + ctrl->scd_local->next_local = scd_local_list; + scd_local_list = ctrl->scd_local; + } + + + /* Assert that the lock count is as expected. */ + if (ctrl->scd_local->locked) + { + log_error ("start_scd: invalid lock count (%d)\n", + ctrl->scd_local->locked); + return gpg_error (GPG_ERR_INTERNAL); + } + ctrl->scd_local->locked++; + + if (ctrl->scd_local->ctx) + return 0; /* Okay, the context is fine. We used to test for an + alive context here and do an disconnect. Now that we + have a ticker function to check for it, it is easier + not to check here but to let the connection run on an + error instead. */ + + + /* We need to protect the following code. */ + if (!pth_mutex_acquire (&start_scd_lock, 0, NULL)) + { + log_error ("failed to acquire the start_scd lock: %s\n", + strerror (errno)); + return gpg_error (GPG_ERR_INTERNAL); + } + + /* Check whether the pipe server has already been started and in + this case either reuse a lingering pipe connection or establish a + new socket based one. */ + if (primary_scd_ctx && primary_scd_ctx_reusable) + { + ctx = primary_scd_ctx; + primary_scd_ctx_reusable = 0; + if (opt.verbose) + log_info ("new connection to SCdaemon established (reusing)\n"); + goto leave; + } + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); + err = rc; + goto leave; + } + + if (socket_name) + { + rc = assuan_socket_connect (ctx, socket_name, 0, 0); + if (rc) + { + log_error ("can't connect to socket `%s': %s\n", + socket_name, gpg_strerror (rc)); + err = gpg_error (GPG_ERR_NO_SCDAEMON); + goto leave; + } + + if (opt.verbose) + log_info ("new connection to SCdaemon established\n"); + goto leave; + } + + if (primary_scd_ctx) + { + log_info ("SCdaemon is running but won't accept further connections\n"); + err = gpg_error (GPG_ERR_NO_SCDAEMON); + goto leave; + } + + /* Nope, it has not been started. Fire it up now. */ + if (opt.verbose) + log_info ("no running SCdaemon - starting it\n"); + + if (fflush (NULL)) + { +#ifndef HAVE_W32_SYSTEM + err = gpg_error_from_syserror (); +#endif + log_error ("error flushing pending output: %s\n", strerror (errno)); + /* At least Windows XP fails here with EBADF. According to docs + and Wine an fflush(NULL) is the same as _flushall. However + the Wime implementaion does not flush stdin,stdout and stderr + - see above. Lets try to ignore the error. */ +#ifndef HAVE_W32_SYSTEM + goto leave; +#endif + } + + if (!opt.scdaemon_program || !*opt.scdaemon_program) + opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON); + if ( !(pgmname = strrchr (opt.scdaemon_program, '/'))) + pgmname = opt.scdaemon_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--multi-server"; + argv[2] = NULL; + + i=0; + if (!opt.running_detached) + { + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); + } + no_close_list[i] = -1; + + /* Connect to the pinentry and perform initial handshaking. Use + detached flag (128) so that under W32 SCDAEMON does not show up a + new window. */ + rc = assuan_pipe_connect (ctx, opt.scdaemon_program, argv, + no_close_list, atfork_cb, NULL, 128); + if (rc) + { + log_error ("can't connect to the SCdaemon: %s\n", + gpg_strerror (rc)); + err = gpg_error (GPG_ERR_NO_SCDAEMON); + goto leave; + } + + if (opt.verbose) + log_debug ("first connection to SCdaemon established\n"); + + if (DBG_ASSUAN) + assuan_set_log_stream (ctx, log_get_stream ()); + + /* Get the name of the additional socket opened by scdaemon. */ + { + membuf_t data; + unsigned char *databuf; + size_t datalen; + + xfree (socket_name); + socket_name = NULL; + init_membuf (&data, 256); + assuan_transact (ctx, "GETINFO socket_name", + membuf_data_cb, &data, NULL, NULL, NULL, NULL); + + databuf = get_membuf (&data, &datalen); + if (databuf && datalen) + { + socket_name = xtrymalloc (datalen + 1); + if (!socket_name) + log_error ("warning: can't store socket name: %s\n", + strerror (errno)); + else + { + memcpy (socket_name, databuf, datalen); + socket_name[datalen] = 0; + if (DBG_ASSUAN) + log_debug ("additional connections at `%s'\n", socket_name); + } + } + xfree (databuf); + } + + /* Tell the scdaemon we want him to send us an event signal. */ + if (opt.sigusr2_enabled) + { + char buf[100]; + +#ifdef HAVE_W32_SYSTEM + snprintf (buf, sizeof buf, "OPTION event-signal=%lx", + (unsigned long)get_agent_scd_notify_event ()); +#else + snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2); +#endif + assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); + } + + primary_scd_ctx = ctx; + primary_scd_ctx_reusable = 0; + + leave: + if (err) + { + unlock_scd (ctrl, err); + if (ctx) + assuan_release (ctx); + } + else + { + ctrl->scd_local->ctx = ctx; + } + if (!pth_mutex_release (&start_scd_lock)) + log_error ("failed to release the start_scd lock: %s\n", strerror (errno)); + return err; +} + + +/* Check whether the SCdaemon is active. This is a fast check without + any locking and might give a wrong result if another thread is about + to start the daemon or the daemon is about to be stopped.. */ +int +agent_scd_check_running (void) +{ + return !!primary_scd_ctx; +} + + +/* Check whether the Scdaemon is still alive and clean it up if not. */ +void +agent_scd_check_aliveness (void) +{ + pth_event_t evt; + pid_t pid; +#ifdef HAVE_W32_SYSTEM + DWORD rc; +#else + int rc; +#endif + + if (!primary_scd_ctx) + return; /* No scdaemon running. */ + + /* This is not a critical function so we use a short timeout while + acquiring the lock. */ + evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0)); + if (!pth_mutex_acquire (&start_scd_lock, 0, evt)) + { + if (pth_event_occurred (evt)) + { + if (opt.verbose > 1) + log_info ("failed to acquire the start_scd lock while" + " doing an aliveness check: %s\n", "timeout"); + } + else + log_error ("failed to acquire the start_scd lock while" + " doing an aliveness check: %s\n", strerror (errno)); + pth_event_free (evt, PTH_FREE_THIS); + return; + } + pth_event_free (evt, PTH_FREE_THIS); + + if (primary_scd_ctx) + { + pid = assuan_get_pid (primary_scd_ctx); +#ifdef HAVE_W32_SYSTEM + /* If we have a PID we disconnect if either GetExitProcessCode + fails or if ir returns the exit code of the scdaemon. 259 is + the error code for STILL_ALIVE. */ + if (pid != (pid_t)(void*)(-1) && pid + && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259)) +#else + if (pid != (pid_t)(-1) && pid + && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) +#endif + { + /* Okay, scdaemon died. Disconnect the primary connection + now but take care that it won't do another wait. Also + cleanup all other connections and release their + resources. The next use will start a new daemon then. + Due to the use of the START_SCD_LOCAL we are sure that + none of these context are actually in use. */ + struct scd_local_s *sl; + + assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1); + assuan_release (primary_scd_ctx); + + for (sl=scd_local_list; sl; sl = sl->next_local) + { + if (sl->ctx) + { + if (sl->ctx != primary_scd_ctx) + assuan_release (sl->ctx); + sl->ctx = NULL; + } + } + + primary_scd_ctx = NULL; + primary_scd_ctx_reusable = 0; + + xfree (socket_name); + socket_name = NULL; + } + } + + if (!pth_mutex_release (&start_scd_lock)) + log_error ("failed to release the start_scd lock while" + " doing the aliveness check: %s\n", strerror (errno)); +} + + + +/* Reset the SCD if it has been used. Actually it is not a reset but + a cleanup of resources used by the current connection. */ +int +agent_reset_scd (ctrl_t ctrl) +{ + if (ctrl->scd_local) + { + if (ctrl->scd_local->ctx) + { + /* We can't disconnect the primary context because libassuan + does a waitpid on it and thus the system would hang. + Instead we send a reset and keep that connection for + reuse. */ + if (ctrl->scd_local->ctx == primary_scd_ctx) + { + /* Send a RESTART to the SCD. This is required for the + primary connection as a kind of virtual EOF; we don't + have another way to tell it that the next command + should be viewed as if a new connection has been + made. For the non-primary connections this is not + needed as we simply close the socket. We don't check + for an error here because the RESTART may fail for + example if the scdaemon has already been terminated. + Anyway, we need to set the reusable flag to make sure + that the aliveness check can clean it up. */ + assuan_transact (primary_scd_ctx, "RESTART", + NULL, NULL, NULL, NULL, NULL, NULL); + primary_scd_ctx_reusable = 1; + } + else + assuan_release (ctrl->scd_local->ctx); + ctrl->scd_local->ctx = NULL; + } + + /* Remove the local context from our list and release it. */ + if (!scd_local_list) + BUG (); + else if (scd_local_list == ctrl->scd_local) + scd_local_list = ctrl->scd_local->next_local; + else + { + struct scd_local_s *sl; + + for (sl=scd_local_list; sl->next_local; sl = sl->next_local) + if (sl->next_local == ctrl->scd_local) + break; + if (!sl->next_local) + BUG (); + sl->next_local = ctrl->scd_local->next_local; + } + xfree (ctrl->scd_local); + ctrl->scd_local = NULL; + } + + return 0; +} + + + +static gpg_error_t +learn_status_cb (void *opaque, const char *line) +{ + struct learn_parm_s *parm = opaque; + const char *keyword = line; + int keywordlen; + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen)) + { + parm->certinfo_cb (parm->certinfo_cb_arg, line); + } + else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) + { + parm->kpinfo_cb (parm->kpinfo_cb_arg, line); + } + else if (keywordlen && *line) + { + parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line); + } + + return 0; +} + +/* Perform the LEARN command and return a list of all private keys + stored on the card. */ +int +agent_card_learn (ctrl_t ctrl, + void (*kpinfo_cb)(void*, const char *), + void *kpinfo_cb_arg, + void (*certinfo_cb)(void*, const char *), + void *certinfo_cb_arg, + void (*sinfo_cb)(void*, const char *, size_t, const char *), + void *sinfo_cb_arg) +{ + int rc; + struct learn_parm_s parm; + + rc = start_scd (ctrl); + if (rc) + return rc; + + memset (&parm, 0, sizeof parm); + parm.kpinfo_cb = kpinfo_cb; + parm.kpinfo_cb_arg = kpinfo_cb_arg; + parm.certinfo_cb = certinfo_cb; + parm.certinfo_cb_arg = certinfo_cb_arg; + parm.sinfo_cb = sinfo_cb; + parm.sinfo_cb_arg = sinfo_cb_arg; + rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force", + NULL, NULL, NULL, NULL, + learn_status_cb, &parm); + if (rc) + return unlock_scd (ctrl, rc); + + return unlock_scd (ctrl, 0); +} + + + +static gpg_error_t +get_serialno_cb (void *opaque, const char *line) +{ + char **serialno = opaque; + const char *keyword = line; + const char *s; + int keywordlen, n; + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + + if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) + { + if (*serialno) + return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */ + for (n=0,s=line; hexdigitp (s); s++, n++) + ; + if (!n || (n&1)|| !(spacep (s) || !*s) ) + return gpg_error (GPG_ERR_ASS_PARAMETER); + *serialno = xtrymalloc (n+1); + if (!*serialno) + return out_of_core (); + memcpy (*serialno, line, n); + (*serialno)[n] = 0; + } + + return 0; +} + +/* Return the serial number of the card or an appropriate error. The + serial number is returned as a hexstring. */ +int +agent_card_serialno (ctrl_t ctrl, char **r_serialno) +{ + int rc; + char *serialno = NULL; + + rc = start_scd (ctrl); + if (rc) + return rc; + + rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO", + NULL, NULL, NULL, NULL, + get_serialno_cb, &serialno); + if (rc) + { + xfree (serialno); + return unlock_scd (ctrl, rc); + } + *r_serialno = serialno; + return unlock_scd (ctrl, 0); +} + + + + +static gpg_error_t +membuf_data_cb (void *opaque, const void *buffer, size_t length) +{ + membuf_t *data = opaque; + + if (buffer) + put_membuf (data, buffer, length); + return 0; +} + +/* Handle the NEEDPIN inquiry. */ +static gpg_error_t +inq_needpin (void *opaque, const char *line) +{ + struct inq_needpin_s *parm = opaque; + char *pin; + size_t pinlen; + int rc; + + if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7])) + { + line += 7; + while (*line == ' ') + line++; + + pinlen = 90; + pin = gcry_malloc_secure (pinlen); + if (!pin) + return out_of_core (); + + rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); + if (!rc) + rc = assuan_send_data (parm->ctx, pin, pinlen); + xfree (pin); + } + else if (!strncmp (line, "POPUPKEYPADPROMPT", 17) + && (line[17] == ' ' || !line[17])) + { + line += 17; + while (*line == ' ') + line++; + + rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1); + } + else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19) + && (line[19] == ' ' || !line[19])) + { + rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0); + } + else if (parm->passthru) + { + unsigned char *value; + size_t valuelen; + int rest; + int needrest = !strncmp (line, "KEYDATA", 8); + + /* Pass the inquiry up to our caller. We limit the maximum + amount to an arbitrary value. As we know that the KEYDATA + enquiry is pretty sensitive we disable logging then */ + if ((rest = (needrest + && !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL)))) + assuan_begin_confidential (parm->passthru); + rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096); + if (rest) + assuan_end_confidential (parm->passthru); + if (!rc) + { + if ((rest = (needrest + && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL)))) + assuan_begin_confidential (parm->ctx); + rc = assuan_send_data (parm->ctx, value, valuelen); + if (rest) + assuan_end_confidential (parm->ctx); + xfree (value); + } + else + log_error ("error forwarding inquiry `%s': %s\n", + line, gpg_strerror (rc)); + } + else + { + log_error ("unsupported inquiry `%s'\n", line); + rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE); + } + + return rc; +} + + + +/* Create a signature using the current card */ +int +agent_card_pksign (ctrl_t ctrl, + const char *keyid, + int (*getpin_cb)(void *, const char *, char*, size_t), + void *getpin_cb_arg, + const unsigned char *indata, size_t indatalen, + unsigned char **r_buf, size_t *r_buflen) +{ + int rc, i; + char *p, line[ASSUAN_LINELENGTH]; + membuf_t data; + struct inq_needpin_s inqparm; + size_t len; + unsigned char *sigbuf; + size_t sigbuflen; + + *r_buf = NULL; + rc = start_scd (ctrl); + if (rc) + return rc; + + if (indatalen*2 + 50 > DIM(line)) + return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL)); + + sprintf (line, "SETDATA "); + p = line + strlen (line); + for (i=0; i < indatalen ; i++, p += 2 ) + sprintf (p, "%02X", indata[i]); + rc = assuan_transact (ctrl->scd_local->ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_scd (ctrl, rc); + + init_membuf (&data, 1024); + inqparm.ctx = ctrl->scd_local->ctx; + inqparm.getpin_cb = getpin_cb; + inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.passthru = 0; + snprintf (line, DIM(line)-1, + ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid); + line[DIM(line)-1] = 0; + rc = assuan_transact (ctrl->scd_local->ctx, line, + membuf_data_cb, &data, + inq_needpin, &inqparm, + NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return unlock_scd (ctrl, rc); + } + sigbuf = get_membuf (&data, &sigbuflen); + + /* Create an S-expression from it which is formatted like this: + "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */ + *r_buflen = 21 + 11 + sigbuflen + 4; + p = xtrymalloc (*r_buflen); + *r_buf = (unsigned char*)p; + if (!p) + return unlock_scd (ctrl, out_of_core ()); + p = stpcpy (p, "(7:sig-val(3:rsa(1:s" ); + sprintf (p, "%u:", (unsigned int)sigbuflen); + p += strlen (p); + memcpy (p, sigbuf, sigbuflen); + p += sigbuflen; + strcpy (p, ")))"); + xfree (sigbuf); + + assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)); + return unlock_scd (ctrl, 0); +} + +/* Decipher INDATA using the current card. Note that the returned value is */ +int +agent_card_pkdecrypt (ctrl_t ctrl, + const char *keyid, + int (*getpin_cb)(void *, const char *, char*, size_t), + void *getpin_cb_arg, + 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; + struct inq_needpin_s inqparm; + size_t len; + + *r_buf = NULL; + rc = start_scd (ctrl); + if (rc) + return rc; + + /* FIXME: use secure memory where appropriate */ + if (indatalen*2 + 50 > DIM(line)) + return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL)); + + sprintf (line, "SETDATA "); + p = line + strlen (line); + for (i=0; i < indatalen ; i++, p += 2 ) + sprintf (p, "%02X", indata[i]); + rc = assuan_transact (ctrl->scd_local->ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_scd (ctrl, rc); + + init_membuf (&data, 1024); + inqparm.ctx = ctrl->scd_local->ctx; + inqparm.getpin_cb = getpin_cb; + inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.passthru = 0; + snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid); + line[DIM(line)-1] = 0; + rc = assuan_transact (ctrl->scd_local->ctx, line, + membuf_data_cb, &data, + inq_needpin, &inqparm, + NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return unlock_scd (ctrl, rc); + } + *r_buf = get_membuf (&data, r_buflen); + if (!*r_buf) + return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM)); + + return unlock_scd (ctrl, 0); +} + + + +/* Read a certificate with ID into R_BUF and R_BUFLEN. */ +int +agent_card_readcert (ctrl_t ctrl, + const char *id, char **r_buf, size_t *r_buflen) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + membuf_t data; + size_t len; + + *r_buf = NULL; + rc = start_scd (ctrl); + if (rc) + return rc; + + init_membuf (&data, 1024); + snprintf (line, DIM(line)-1, "READCERT %s", id); + line[DIM(line)-1] = 0; + rc = assuan_transact (ctrl->scd_local->ctx, line, + membuf_data_cb, &data, + NULL, NULL, + NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return unlock_scd (ctrl, rc); + } + *r_buf = get_membuf (&data, r_buflen); + if (!*r_buf) + return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM)); + + return unlock_scd (ctrl, 0); +} + + + +/* Read a key with ID and return it in an allocate buffer pointed to + by r_BUF as a valid S-expression. */ +int +agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + membuf_t data; + size_t len, buflen; + + *r_buf = NULL; + rc = start_scd (ctrl); + if (rc) + return rc; + + init_membuf (&data, 1024); + snprintf (line, DIM(line)-1, "READKEY %s", id); + line[DIM(line)-1] = 0; + rc = assuan_transact (ctrl->scd_local->ctx, line, + membuf_data_cb, &data, + NULL, NULL, + NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return unlock_scd (ctrl, rc); + } + *r_buf = get_membuf (&data, &buflen); + if (!*r_buf) + return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM)); + + if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL)) + { + xfree (*r_buf); *r_buf = NULL; + return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE)); + } + + return unlock_scd (ctrl, 0); +} + + + +/* Type used with the card_getattr_cb. */ +struct card_getattr_parm_s { + const char *keyword; /* Keyword to look for. */ + size_t keywordlen; /* strlen of KEYWORD. */ + char *data; /* Malloced and unescaped data. */ + int error; /* ERRNO value or 0 on success. */ +}; + +/* Callback function for agent_card_getattr. */ +static gpg_error_t +card_getattr_cb (void *opaque, const char *line) +{ + struct card_getattr_parm_s *parm = opaque; + const char *keyword = line; + int keywordlen; + + if (parm->data) + return 0; /* We want only the first occurrence. */ + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + + if (keywordlen == parm->keywordlen + && !memcmp (keyword, parm->keyword, keywordlen)) + { + parm->data = percent_plus_unescape ((const unsigned char*)line, 0xff); + if (!parm->data) + parm->error = errno; + } + + return 0; +} + + +/* Call the agent to retrieve a single line data object. On success + the object is malloced and stored at RESULT; it is guaranteed that + NULL is never stored in this case. On error an error code is + returned and NULL stored at RESULT. */ +gpg_error_t +agent_card_getattr (ctrl_t ctrl, const char *name, char **result) +{ + int err; + struct card_getattr_parm_s parm; + char line[ASSUAN_LINELENGTH]; + + *result = NULL; + + if (!*name) + return gpg_error (GPG_ERR_INV_VALUE); + + memset (&parm, 0, sizeof parm); + parm.keyword = name; + parm.keywordlen = strlen (name); + + /* We assume that NAME does not need escaping. */ + if (8 + strlen (name) > DIM(line)-1) + return gpg_error (GPG_ERR_TOO_LARGE); + stpcpy (stpcpy (line, "GETATTR "), name); + + err = start_scd (ctrl); + if (err) + return err; + + err = assuan_transact (ctrl->scd_local->ctx, line, + NULL, NULL, NULL, NULL, + card_getattr_cb, &parm); + if (!err && parm.error) + err = gpg_error_from_errno (parm.error); + + if (!err && !parm.data) + err = gpg_error (GPG_ERR_NO_DATA); + + if (!err) + *result = parm.data; + else + xfree (parm.data); + + return unlock_scd (ctrl, err); +} + + + + +static gpg_error_t +pass_status_thru (void *opaque, const char *line) +{ + assuan_context_t ctx = opaque; + char keyword[200]; + int i; + + for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++) + keyword[i] = *line; + keyword[i] = 0; + /* truncate any remaining keyword stuff. */ + for (; *line && !spacep (line); line++) + ; + while (spacep (line)) + line++; + + assuan_write_status (ctx, keyword, line); + return 0; +} + +static gpg_error_t +pass_data_thru (void *opaque, const void *buffer, size_t length) +{ + assuan_context_t ctx = opaque; + + assuan_send_data (ctx, buffer, length); + return 0; +} + + +/* Send the line CMDLINE with command for the SCDdaemon to it and send + all status messages back. This command is used as a general quoting + mechanism to pass everything verbatim to SCDAEMON. The PIN + inquiry is handled inside gpg-agent. */ +int +agent_card_scd (ctrl_t ctrl, const char *cmdline, + int (*getpin_cb)(void *, const char *, char*, size_t), + void *getpin_cb_arg, void *assuan_context) +{ + int rc; + struct inq_needpin_s inqparm; + int saveflag; + + rc = start_scd (ctrl); + if (rc) + return rc; + + inqparm.ctx = ctrl->scd_local->ctx; + inqparm.getpin_cb = getpin_cb; + inqparm.getpin_cb_arg = getpin_cb_arg; + inqparm.passthru = assuan_context; + saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1); + rc = assuan_transact (ctrl->scd_local->ctx, cmdline, + pass_data_thru, assuan_context, + inq_needpin, &inqparm, + pass_status_thru, assuan_context); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag); + if (rc) + { + return unlock_scd (ctrl, rc); + } + + return unlock_scd (ctrl, 0); +} + + diff --git a/agent/command-ssh.c b/agent/command-ssh.c new file mode 100644 index 0000000..2f96ef5 --- /dev/null +++ b/agent/command-ssh.c @@ -0,0 +1,3089 @@ +/* command-ssh.c - gpg-agent's ssh-agent emulation layer + * Copyright (C) 2004, 2005, 2006, 2009 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 3 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, see . + */ + +/* Only v2 of the ssh-agent protocol is implemented. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" + +#include "estream.h" +#include "i18n.h" +#include "../common/ssh-utils.h" + + + + +/* Request types. */ +#define SSH_REQUEST_REQUEST_IDENTITIES 11 +#define SSH_REQUEST_SIGN_REQUEST 13 +#define SSH_REQUEST_ADD_IDENTITY 17 +#define SSH_REQUEST_REMOVE_IDENTITY 18 +#define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19 +#define SSH_REQUEST_LOCK 22 +#define SSH_REQUEST_UNLOCK 23 +#define SSH_REQUEST_ADD_ID_CONSTRAINED 25 + +/* Options. */ +#define SSH_OPT_CONSTRAIN_LIFETIME 1 +#define SSH_OPT_CONSTRAIN_CONFIRM 2 + +/* Response types. */ +#define SSH_RESPONSE_SUCCESS 6 +#define SSH_RESPONSE_FAILURE 5 +#define SSH_RESPONSE_IDENTITIES_ANSWER 12 +#define SSH_RESPONSE_SIGN_RESPONSE 14 + +/* Other constants. */ +#define SSH_DSA_SIGNATURE_PADDING 20 +#define SSH_DSA_SIGNATURE_ELEMS 2 +#define SPEC_FLAG_USE_PKCS1V2 (1 << 0) + + +/* The blurb we put into the header of a newly created control file. */ +static const char sshcontrolblurb[] = +"# List of allowed ssh keys. Only keys present in this file are used\n" +"# in the SSH protocol. The ssh-add tool may add new entries to this\n" +"# file to enable them; you may also add them manually. Comment\n" +"# lines, like this one, as well as empty lines are ignored. Lines do\n" +"# have a certain length limit but this is not serious limitation as\n" +"# the format of the entries is fixed and checked by gpg-agent. A\n" +"# non-comment line starts with optional white spaces, followed by the\n" +"# keygrip of the key given as 40 hex digits, optionally followed by a\n" +"# the caching TTL in seconds and another optional field for arbitrary\n" +"# flags. Prepend the keygrip with an '!' mark to disable it.\n" +"\n"; + + + +/* Macros. */ + +/* Return a new uint32 with b0 being the most significant byte and b3 + being the least significant byte. */ +#define uint32_construct(b0, b1, b2, b3) \ + ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3) + + + + +/* + * Basic types. + */ + +/* Type for a request handler. */ +typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl, + estream_t request, + estream_t response); + +/* Type, which is used for associating request handlers with the + appropriate request IDs. */ +typedef struct ssh_request_spec +{ + unsigned char type; + ssh_request_handler_t handler; + const char *identifier; + unsigned int secret_input; +} ssh_request_spec_t; + +/* Type for "key modifier functions", which are necessary since + OpenSSH and GnuPG treat key material slightly different. A key + modifier is called right after a new key identity has been received + in order to "sanitize" the material. */ +typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems, + gcry_mpi_t *mpis); + +/* The encoding of a generated signature is dependent on the + algorithm; therefore algorithm specific signature encoding + functions are necessary. */ +typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob, + gcry_mpi_t *mpis); + +/* Type, which is used for boundling all the algorithm specific + information together in a single object. */ +typedef struct ssh_key_type_spec +{ + /* Algorithm identifier as used by OpenSSH. */ + const char *ssh_identifier; + + /* Algorithm identifier as used by GnuPG. */ + const char *identifier; + + /* List of MPI names for secret keys; order matches the one of the + agent protocol. */ + const char *elems_key_secret; + + /* List of MPI names for public keys; order matches the one of the + agent protocol. */ + const char *elems_key_public; + + /* List of MPI names for signature data. */ + const char *elems_signature; + + /* List of MPI names for secret keys; order matches the one, which + is required by gpg-agent's key access layer. */ + const char *elems_sexp_order; + + /* Key modifier function. Key modifier functions are necessary in + order to fix any inconsistencies between the representation of + keys on the SSH and on the GnuPG side. */ + ssh_key_modifier_t key_modifier; + + /* Signature encoder function. Signature encoder functions are + necessary since the encoding of signatures depends on the used + algorithm. */ + ssh_signature_encoder_t signature_encoder; + + /* Misc flags. */ + unsigned int flags; +} ssh_key_type_spec_t; + + +/* Prototypes. */ +static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_lock (ctrl_t ctrl, + estream_t request, + estream_t response); +static gpg_error_t ssh_handler_unlock (ctrl_t ctrl, + estream_t request, + estream_t response); + +static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis); +static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob, + gcry_mpi_t *mpis); +static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob, + gcry_mpi_t *mpis); + + + +/* Global variables. */ + + +/* Associating request types with the corresponding request + handlers. */ + +static ssh_request_spec_t request_specs[] = + { +#define REQUEST_SPEC_DEFINE(id, name, secret_input) \ + { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input } + + REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1), + REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0), + REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1), + REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity, 1), + REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0), + REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0), + REQUEST_SPEC_DEFINE (LOCK, lock, 0), + REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0) +#undef REQUEST_SPEC_DEFINE + }; + + +/* Table holding key type specifications. */ +static ssh_key_type_spec_t ssh_key_types[] = + { + { + "ssh-rsa", "rsa", "nedupq", "en", "s", "nedpqu", + ssh_key_modifier_rsa, ssh_signature_encoder_rsa, + SPEC_FLAG_USE_PKCS1V2 + }, + { + "ssh-dss", "dsa", "pqgyx", "pqgy", "rs", "pqgyx", + NULL, ssh_signature_encoder_dsa, + 0 + }, + }; + + + + + +/* + General utility functions. + */ + +/* A secure realloc, i.e. it makes sure to allocate secure memory if A + is NULL. This is required because the standard gcry_realloc does + not know whether to allocate secure or normal if NULL is passed as + existing buffer. */ +static void * +realloc_secure (void *a, size_t n) +{ + void *p; + + if (a) + p = gcry_realloc (a, n); + else + p = gcry_malloc_secure (n); + + return p; +} + + +/* Create and return a new C-string from DATA/DATA_N (i.e.: add + NUL-termination); return NULL on OOM. */ +static char * +make_cstring (const char *data, size_t data_n) +{ + char *s; + + s = xtrymalloc (data_n + 1); + if (s) + { + memcpy (s, data, data_n); + s[data_n] = 0; + } + + return s; +} + + + + +/* + Primitive I/O functions. + */ + + +/* Read a byte from STREAM, store it in B. */ +static gpg_error_t +stream_read_byte (estream_t stream, unsigned char *b) +{ + gpg_error_t err; + int ret; + + ret = es_fgetc (stream); + if (ret == EOF) + { + if (es_ferror (stream)) + err = gpg_error_from_syserror (); + else + err = gpg_error (GPG_ERR_EOF); + *b = 0; + } + else + { + *b = ret & 0xFF; + err = 0; + } + + return err; +} + +/* Write the byte contained in B to STREAM. */ +static gpg_error_t +stream_write_byte (estream_t stream, unsigned char b) +{ + gpg_error_t err; + int ret; + + ret = es_fputc (b, stream); + if (ret == EOF) + err = gpg_error_from_syserror (); + else + err = 0; + + return err; +} + +/* Read a uint32 from STREAM, store it in UINT32. */ +static gpg_error_t +stream_read_uint32 (estream_t stream, u32 *uint32) +{ + unsigned char buffer[4]; + size_t bytes_read; + gpg_error_t err; + int ret; + + ret = es_read (stream, buffer, sizeof (buffer), &bytes_read); + if (ret) + err = gpg_error_from_syserror (); + else + { + if (bytes_read != sizeof (buffer)) + err = gpg_error (GPG_ERR_EOF); + else + { + u32 n; + + n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]); + *uint32 = n; + err = 0; + } + } + + return err; +} + +/* Write the uint32 contained in UINT32 to STREAM. */ +static gpg_error_t +stream_write_uint32 (estream_t stream, u32 uint32) +{ + unsigned char buffer[4]; + gpg_error_t err; + int ret; + + buffer[0] = uint32 >> 24; + buffer[1] = uint32 >> 16; + buffer[2] = uint32 >> 8; + buffer[3] = uint32 >> 0; + + ret = es_write (stream, buffer, sizeof (buffer), NULL); + if (ret) + err = gpg_error_from_syserror (); + else + err = 0; + + return err; +} + +/* Read SIZE bytes from STREAM into BUFFER. */ +static gpg_error_t +stream_read_data (estream_t stream, unsigned char *buffer, size_t size) +{ + gpg_error_t err; + size_t bytes_read; + int ret; + + ret = es_read (stream, buffer, size, &bytes_read); + if (ret) + err = gpg_error_from_syserror (); + else + { + if (bytes_read != size) + err = gpg_error (GPG_ERR_EOF); + else + err = 0; + } + + return err; +} + +/* Write SIZE bytes from BUFFER to STREAM. */ +static gpg_error_t +stream_write_data (estream_t stream, const unsigned char *buffer, size_t size) +{ + gpg_error_t err; + int ret; + + ret = es_write (stream, buffer, size, NULL); + if (ret) + err = gpg_error_from_syserror (); + else + err = 0; + + return err; +} + +/* Read a binary string from STREAM into STRING, store size of string + in STRING_SIZE; depending on SECURE use secure memory for + string. */ +static gpg_error_t +stream_read_string (estream_t stream, unsigned int secure, + unsigned char **string, u32 *string_size) +{ + gpg_error_t err; + unsigned char *buffer = NULL; + u32 length = 0; + + /* Read string length. */ + err = stream_read_uint32 (stream, &length); + if (err) + goto out; + + /* Allocate space. */ + if (secure) + buffer = xtrymalloc_secure (length + 1); + else + buffer = xtrymalloc (length + 1); + if (! buffer) + { + err = gpg_error_from_syserror (); + goto out; + } + + /* Read data. */ + err = stream_read_data (stream, buffer, length); + if (err) + goto out; + + /* Finalize string object. */ + buffer[length] = 0; + *string = buffer; + if (string_size) + *string_size = length; + + out: + + if (err) + xfree (buffer); + + return err; +} + +/* Read a C-string from STREAM, store copy in STRING. */ +static gpg_error_t +stream_read_cstring (estream_t stream, char **string) +{ + unsigned char *buffer; + gpg_error_t err; + + err = stream_read_string (stream, 0, &buffer, NULL); + if (err) + goto out; + + *string = (char *) buffer; + + out: + + return err; +} + + +/* Write a binary string from STRING of size STRING_N to STREAM. */ +static gpg_error_t +stream_write_string (estream_t stream, + const unsigned char *string, u32 string_n) +{ + gpg_error_t err; + + err = stream_write_uint32 (stream, string_n); + if (err) + goto out; + + err = stream_write_data (stream, string, string_n); + + out: + + return err; +} + +/* Write a C-string from STRING to STREAM. */ +static gpg_error_t +stream_write_cstring (estream_t stream, const char *string) +{ + gpg_error_t err; + + err = stream_write_string (stream, + (const unsigned char *) string, strlen (string)); + + return err; +} + +/* Read an MPI from STREAM, store it in MPINT. Depending on SECURE + use secure memory. */ +static gpg_error_t +stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint) +{ + unsigned char *mpi_data; + u32 mpi_data_size; + gpg_error_t err; + gcry_mpi_t mpi; + + mpi_data = NULL; + + err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size); + if (err) + goto out; + + /* To avoid excessive use of secure memory we check that an MPI is + not too large. */ + if (mpi_data_size > 520) + { + log_error (_("ssh keys greater than %d bits are not supported\n"), 4096); + err = GPG_ERR_TOO_LARGE; + goto out; + } + + err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL); + if (err) + goto out; + + *mpint = mpi; + + out: + + xfree (mpi_data); + + return err; +} + +/* Write the MPI contained in MPINT to STREAM. */ +static gpg_error_t +stream_write_mpi (estream_t stream, gcry_mpi_t mpint) +{ + unsigned char *mpi_buffer; + size_t mpi_buffer_n; + gpg_error_t err; + + mpi_buffer = NULL; + + err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint); + if (err) + goto out; + + err = stream_write_string (stream, mpi_buffer, mpi_buffer_n); + + out: + + xfree (mpi_buffer); + + return err; +} + +/* Copy data from SRC to DST until EOF is reached. */ +static gpg_error_t +stream_copy (estream_t dst, estream_t src) +{ + char buffer[BUFSIZ]; + size_t bytes_read; + gpg_error_t err; + int ret; + + err = 0; + while (1) + { + ret = es_read (src, buffer, sizeof (buffer), &bytes_read); + if (ret || (! bytes_read)) + { + if (ret) + err = gpg_error_from_syserror (); + break; + } + ret = es_write (dst, buffer, bytes_read, NULL); + if (ret) + { + err = gpg_error_from_syserror (); + break; + } + } + + return err; +} + + +/* Read the content of the file specified by FILENAME into a newly + create buffer, which is to be stored in BUFFER; store length of + buffer in BUFFER_N. */ +static gpg_error_t +file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) +{ + unsigned char *buffer_new; + struct stat statbuf; + estream_t stream; + gpg_error_t err; + int ret; + + *buffer = NULL; + *buffer_n = 0; + + buffer_new = NULL; + err = 0; + + stream = es_fopen (filename, "r"); + if (! stream) + { + err = gpg_error_from_syserror (); + goto out; + } + + ret = fstat (es_fileno (stream), &statbuf); + if (ret) + { + err = gpg_error_from_syserror (); + goto out; + } + + buffer_new = xtrymalloc (statbuf.st_size); + if (! buffer_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = stream_read_data (stream, buffer_new, statbuf.st_size); + if (err) + goto out; + + *buffer = buffer_new; + *buffer_n = statbuf.st_size; + + out: + + if (stream) + es_fclose (stream); + + if (err) + xfree (buffer_new); + + return err; +} + + + + +/* Open the ssh control file and create it if not available. With + APPEND passed as true the file will be opened in append mode, + otherwise in read only mode. On success a file pointer is stored + at the address of R_FP. */ +static gpg_error_t +open_control_file (FILE **r_fp, int append) +{ + gpg_error_t err; + char *fname; + FILE *fp; + + /* Note: As soon as we start to use non blocking functions here + (i.e. where Pth might switch threads) we need to employ a + mutex. */ + *r_fp = NULL; + fname = make_filename (opt.homedir, "sshcontrol", NULL); + /* FIXME: With "a+" we are not able to check whether this will will + be created and thus the blurb needs to be written first. */ + fp = fopen (fname, append? "a+":"r"); + if (!fp && errno == ENOENT) + { + /* Fixme: "x" is a GNU extension. We might want to use the es_ + functions here. */ + fp = fopen (fname, "wx"); + if (!fp) + { + err = gpg_error (gpg_err_code_from_errno (errno)); + log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err)); + xfree (fname); + return err; + } + fputs (sshcontrolblurb, fp); + fclose (fp); + fp = fopen (fname, append? "a+":"r"); + } + + if (!fp) + { + err = gpg_error (gpg_err_code_from_errno (errno)); + log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err)); + xfree (fname); + return err; + } + + *r_fp = fp; + + return 0; +} + + +/* Search the file at stream FP from the beginning until a matching + HEXGRIP is found; return success in this case and store true at + DISABLED if the found key has been disabled. If R_TTL is not NULL + a specified TTL for that key is stored there. If R_CONFIRM is not + NULL it is set to 1 if the key has the confirm flag set. */ +static gpg_error_t +search_control_file (FILE *fp, const char *hexgrip, + int *r_disabled, int *r_ttl, int *r_confirm) +{ + int c, i, n; + char *p, *pend, line[256]; + long ttl; + int lnr = 0; + const char fname[] = "sshcontrol"; + + assert (strlen (hexgrip) == 40 ); + + if (r_confirm) + *r_confirm = 0; + + fseek (fp, 0, SEEK_SET); + clearerr (fp); + *r_disabled = 0; + next_line: + do + { + if (!fgets (line, DIM(line)-1, fp) ) + { + if (feof (fp)) + return gpg_error (GPG_ERR_EOF); + return gpg_error (gpg_err_code_from_errno (errno)); + } + lnr++; + + if (!*line || line[strlen(line)-1] != '\n') + { + /* Eat until end of line */ + while ( (c=getc (fp)) != EOF && c != '\n') + ; + 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 == '#'); + + *r_disabled = 0; + if (*p == '!') + { + *r_disabled = 1; + for (p++; spacep (p); p++) + ; + } + + for (i=0; hexdigitp (p) && i < 40; p++, i++) + if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p)) + goto next_line; + if (i != 40 || !(spacep (p) || *p == '\n')) + { + log_error ("invalid formatted line in `%s', line %d\n", fname, lnr); + return gpg_error (GPG_ERR_BAD_DATA); + } + + ttl = strtol (p, &pend, 10); + p = pend; + if (!(spacep (p) || *p == '\n') || ttl < -1) + { + log_error ("invalid TTL value in `%s', line %d; assuming 0\n", + fname, lnr); + ttl = 0; + } + if (r_ttl) + *r_ttl = ttl; + + /* Now check for key-value pairs of the form NAME[=VALUE]. */ + while (*p) + { + for (; spacep (p) && *p != '\n'; p++) + ; + if (!*p || *p == '\n') + break; + n = strcspn (p, "= \t\n"); + if (p[n] == '=') + { + log_error ("assigning a value to a flag is not yet supported; " + "in `%s', line %d; flag ignored\n", fname, lnr); + p++; + } + else if (n == 7 && !memcmp (p, "confirm", 7)) + { + if (r_confirm) + *r_confirm = 1; + } + else + log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n", + n, p, fname, lnr); + p += n; + } + + return 0; /* Okay: found it. */ +} + + + +/* Add an entry to the control file to mark the key with the keygrip + HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks + for it. FMTFPR is the fingerprint string. This function is in + general used to add a key received through the ssh-add function. + We can assume that the user wants to allow ssh using this key. */ +static gpg_error_t +add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr, + int ttl, int confirm) +{ + gpg_error_t err; + FILE *fp; + int disabled; + + (void)ctrl; + + err = open_control_file (&fp, 1); + if (err) + return err; + + err = search_control_file (fp, hexgrip, &disabled, NULL, NULL); + if (err && gpg_err_code(err) == GPG_ERR_EOF) + { + struct tm *tp; + time_t atime = time (NULL); + + /* Not yet in the file - add it. Because the file has been + opened in append mode, we simply need to write to it. */ + tp = localtime (&atime); + fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n" + "# Fingerprint: %s\n" + "%s %d%s\n"), + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec, + fmtfpr, hexgrip, ttl, confirm? " confirm":""); + + } + fclose (fp); + return 0; +} + + +/* Scan the sshcontrol file and return the TTL. */ +static int +ttl_from_sshcontrol (const char *hexgrip) +{ + FILE *fp; + int disabled, ttl; + + if (!hexgrip || strlen (hexgrip) != 40) + return 0; /* Wrong input: Use global default. */ + + if (open_control_file (&fp, 0)) + return 0; /* Error: Use the global default TTL. */ + + if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL) + || disabled) + ttl = 0; /* Use the global default if not found or disabled. */ + + fclose (fp); + + return ttl; +} + + +/* Scan the sshcontrol file and return the confirm flag. */ +static int +confirm_flag_from_sshcontrol (const char *hexgrip) +{ + FILE *fp; + int disabled, confirm; + + if (!hexgrip || strlen (hexgrip) != 40) + return 1; /* Wrong input: Better ask for confirmation. */ + + if (open_control_file (&fp, 0)) + return 1; /* Error: Better ask for confirmation. */ + + if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm) + || disabled) + confirm = 0; /* If not found or disabled, there is no reason to + ask for confirmation. */ + + fclose (fp); + + return confirm; +} + + + + + +/* + + MPI lists. + + */ + +/* Free the list of MPIs MPI_LIST. */ +static void +mpint_list_free (gcry_mpi_t *mpi_list) +{ + if (mpi_list) + { + unsigned int i; + + for (i = 0; mpi_list[i]; i++) + gcry_mpi_release (mpi_list[i]); + xfree (mpi_list); + } +} + +/* Receive key material MPIs from STREAM according to KEY_SPEC; + depending on SECRET expect a public key or secret key. The newly + allocated list of MPIs is stored in MPI_LIST. Returns usual error + code. */ +static gpg_error_t +ssh_receive_mpint_list (estream_t stream, int secret, + ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list) +{ + const char *elems_public; + unsigned int elems_n; + const char *elems; + int elem_is_secret; + gcry_mpi_t *mpis; + gpg_error_t err; + unsigned int i; + + mpis = NULL; + err = 0; + + if (secret) + elems = key_spec.elems_key_secret; + else + elems = key_spec.elems_key_public; + elems_n = strlen (elems); + + elems_public = key_spec.elems_key_public; + + mpis = xtrycalloc (elems_n + 1, sizeof *mpis ); + if (!mpis) + { + err = gpg_error_from_syserror (); + goto out; + } + + elem_is_secret = 0; + for (i = 0; i < elems_n; i++) + { + if (secret) + elem_is_secret = ! strchr (elems_public, elems[i]); + err = stream_read_mpi (stream, elem_is_secret, &mpis[i]); + if (err) + break; + } + if (err) + goto out; + + *mpi_list = mpis; + + out: + + if (err) + mpint_list_free (mpis); + + return err; +} + + + +/* Key modifier function for RSA. */ +static gpg_error_t +ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis) +{ + gcry_mpi_t p; + gcry_mpi_t q; + gcry_mpi_t u; + + if (strcmp (elems, "nedupq")) + /* Modifying only necessary for secret keys. */ + goto out; + + u = mpis[3]; + p = mpis[4]; + q = mpis[5]; + + if (gcry_mpi_cmp (p, q) > 0) + { + /* P shall be smaller then Q! Swap primes. iqmp becomes u. */ + gcry_mpi_t tmp; + + tmp = mpis[4]; + mpis[4] = mpis[5]; + mpis[5] = tmp; + } + else + /* U needs to be recomputed. */ + gcry_mpi_invm (u, p, q); + + out: + + return 0; +} + +/* Signature encoder function for RSA. */ +static gpg_error_t +ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis) +{ + unsigned char *data; + size_t data_n; + gpg_error_t err; + gcry_mpi_t s; + + s = mpis[0]; + + err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s); + if (err) + goto out; + + err = stream_write_string (signature_blob, data, data_n); + xfree (data); + + out: + + return err; +} + + +/* Signature encoder function for DSA. */ +static gpg_error_t +ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis) +{ + unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS]; + unsigned char *data; + size_t data_n; + gpg_error_t err; + int i; + + data = NULL; + + for (i = 0; i < 2; i++) + { + err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]); + if (err) + break; + + if (data_n > SSH_DSA_SIGNATURE_PADDING) + { + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + break; + } + + memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0, + SSH_DSA_SIGNATURE_PADDING - data_n); + memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING) + + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n); + + xfree (data); + data = NULL; + } + if (err) + goto out; + + err = stream_write_string (signature_blob, buffer, sizeof (buffer)); + + out: + + xfree (data); + + return err; +} + +/* + S-Expressions. + */ + + +/* This function constructs a new S-Expression for the key identified + by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in + *SEXP. Returns usual error code. */ +static gpg_error_t +sexp_key_construct (gcry_sexp_t *sexp, + ssh_key_type_spec_t key_spec, int secret, + gcry_mpi_t *mpis, const char *comment) +{ + const char *key_identifier[] = { "public-key", "private-key" }; + gcry_sexp_t sexp_new; + char *sexp_template; + size_t sexp_template_n; + gpg_error_t err; + const char *elems; + size_t elems_n; + unsigned int i; + unsigned int j; + void **arg_list; + + err = 0; + sexp_new = NULL; + arg_list = NULL; + if (secret) + elems = key_spec.elems_sexp_order; + else + elems = key_spec.elems_key_public; + elems_n = strlen (elems); + + /* + Calculate size for sexp_template_n: + + "(%s(%s)(comment%s))" -> 20 + sizeof (). + + mpi: (X%m) -> 5. + + */ + sexp_template_n = 20 + (elems_n * 5); + sexp_template = xtrymalloc (sexp_template_n); + if (! sexp_template) + { + err = gpg_error_from_syserror (); + goto out; + } + + /* Key identifier, algorithm identifier, mpis, comment. */ + arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1)); + if (! arg_list) + { + err = gpg_error_from_syserror (); + goto out; + } + + i = 0; + arg_list[i++] = &key_identifier[secret]; + arg_list[i++] = &key_spec.identifier; + + *sexp_template = 0; + sexp_template_n = 0; + sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s"); + for (i = 0; i < elems_n; i++) + { + sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)", + elems[i]); + if (secret) + { + for (j = 0; j < elems_n; j++) + if (key_spec.elems_key_secret[j] == elems[i]) + break; + } + else + j = i; + arg_list[i + 2] = &mpis[j]; + } + sexp_template_n += sprintf (sexp_template + sexp_template_n, + ")(comment%%s))"); + + arg_list[i + 2] = &comment; + + err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list); + if (err) + goto out; + + *sexp = sexp_new; + + out: + + xfree (arg_list); + xfree (sexp_template); + + return err; +} + +/* This functions breaks up the key contained in the S-Expression SEXP + according to KEY_SPEC. The MPIs are bundled in a newly create + list, which is to be stored in MPIS; a newly allocated string + holding the comment will be stored in COMMENT; SECRET will be + filled with a boolean flag specifying what kind of key it is. + Returns usual error code. */ +static gpg_error_t +sexp_key_extract (gcry_sexp_t sexp, + ssh_key_type_spec_t key_spec, int *secret, + gcry_mpi_t **mpis, char **comment) +{ + gpg_error_t err; + gcry_sexp_t value_list; + gcry_sexp_t value_pair; + gcry_sexp_t comment_list; + unsigned int i; + char *comment_new; + const char *data; + size_t data_n; + int is_secret; + size_t elems_n; + const char *elems; + gcry_mpi_t *mpis_new; + gcry_mpi_t mpi; + + err = 0; + value_list = NULL; + value_pair = NULL; + comment_list = NULL; + comment_new = NULL; + mpis_new = NULL; + + data = gcry_sexp_nth_data (sexp, 0, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + if ((data_n == 10 && !strncmp (data, "public-key", 10)) + || (data_n == 21 && !strncmp (data, "protected-private-key", 21)) + || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20))) + { + is_secret = 0; + elems = key_spec.elems_key_public; + } + else if (data_n == 11 && !strncmp (data, "private-key", 11)) + { + is_secret = 1; + elems = key_spec.elems_key_secret; + } + else + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + elems_n = strlen (elems); + mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new ); + if (!mpis_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0); + if (! value_list) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + for (i = 0; i < elems_n; i++) + { + value_pair = gcry_sexp_find_token (value_list, elems + i, 1); + if (! value_pair) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + + /* Note that we need to use STD format; i.e. prepend a 0x00 to + indicate a positive number if the high bit is set. */ + mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD); + if (! mpi) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + mpis_new[i] = mpi; + gcry_sexp_release (value_pair); + value_pair = NULL; + } + if (err) + goto out; + + /* We do not require a comment sublist to be present here. */ + data = NULL; + data_n = 0; + + comment_list = gcry_sexp_find_token (sexp, "comment", 0); + if (comment_list) + data = gcry_sexp_nth_data (comment_list, 1, &data_n); + if (! data) + { + data = "(none)"; + data_n = 6; + } + + comment_new = make_cstring (data, data_n); + if (! comment_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + if (secret) + *secret = is_secret; + *mpis = mpis_new; + *comment = comment_new; + + out: + + gcry_sexp_release (value_list); + gcry_sexp_release (value_pair); + gcry_sexp_release (comment_list); + + if (err) + { + xfree (comment_new); + mpint_list_free (mpis_new); + } + + return err; +} + +/* Extract the car from SEXP, and create a newly created C-string + which is to be stored in IDENTIFIER. */ +static gpg_error_t +sexp_extract_identifier (gcry_sexp_t sexp, char **identifier) +{ + char *identifier_new; + gcry_sexp_t sublist; + const char *data; + size_t data_n; + gpg_error_t err; + + identifier_new = NULL; + err = 0; + + sublist = gcry_sexp_nth (sexp, 1); + if (! sublist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + data = gcry_sexp_nth_data (sublist, 0, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + identifier_new = make_cstring (data, data_n); + if (! identifier_new) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + + *identifier = identifier_new; + + out: + + gcry_sexp_release (sublist); + + return err; +} + + + +/* + + Key I/O. + +*/ + +/* Search for a key specification entry. If SSH_NAME is not NULL, + search for an entry whose "ssh_name" is equal to SSH_NAME; + otherwise, search for an entry whose "name" is equal to NAME. + Store found entry in SPEC on success, return error otherwise. */ +static gpg_error_t +ssh_key_type_lookup (const char *ssh_name, const char *name, + ssh_key_type_spec_t *spec) +{ + gpg_error_t err; + unsigned int i; + + for (i = 0; i < DIM (ssh_key_types); i++) + if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier))) + || (name && (! strcmp (name, ssh_key_types[i].identifier)))) + break; + + if (i == DIM (ssh_key_types)) + err = gpg_error (GPG_ERR_NOT_FOUND); + else + { + *spec = ssh_key_types[i]; + err = 0; + } + + return err; +} + +/* Receive a key from STREAM, according to the key specification given + as KEY_SPEC. Depending on SECRET, receive a secret or a public + key. If READ_COMMENT is true, receive a comment string as well. + Constructs a new S-Expression from received data and stores it in + KEY_NEW. Returns zero on success or an error code. */ +static gpg_error_t +ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret, + int read_comment, ssh_key_type_spec_t *key_spec) +{ + gpg_error_t err; + char *key_type = NULL; + char *comment = NULL; + gcry_sexp_t key = NULL; + ssh_key_type_spec_t spec; + gcry_mpi_t *mpi_list = NULL; + const char *elems; + + + err = stream_read_cstring (stream, &key_type); + if (err) + goto out; + + err = ssh_key_type_lookup (key_type, NULL, &spec); + if (err) + goto out; + + err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list); + if (err) + goto out; + + if (read_comment) + { + err = stream_read_cstring (stream, &comment); + if (err) + goto out; + } + + if (secret) + elems = spec.elems_key_secret; + else + elems = spec.elems_key_public; + + if (spec.key_modifier) + { + err = (*spec.key_modifier) (elems, mpi_list); + if (err) + goto out; + } + + err = sexp_key_construct (&key, spec, secret, mpi_list, comment? comment:""); + if (err) + goto out; + + if (key_spec) + *key_spec = spec; + *key_new = key; + + out: + + mpint_list_free (mpi_list); + xfree (key_type); + xfree (comment); + + return err; +} + +/* Converts a key of type TYPE, whose key material is given in MPIS, + into a newly created binary blob, which is to be stored in + BLOB/BLOB_SIZE. Returns zero on success or an error code. */ +static gpg_error_t +ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, + const char *type, gcry_mpi_t *mpis) +{ + unsigned char *blob_new; + long int blob_size_new; + estream_t stream; + gpg_error_t err; + unsigned int i; + + *blob = NULL; + *blob_size = 0; + + blob_new = NULL; + stream = NULL; + err = 0; + + stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! stream) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = stream_write_cstring (stream, type); + if (err) + goto out; + + for (i = 0; mpis[i] && (! err); i++) + err = stream_write_mpi (stream, mpis[i]); + if (err) + goto out; + + blob_size_new = es_ftell (stream); + if (blob_size_new == -1) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = es_fseek (stream, 0, SEEK_SET); + if (err) + goto out; + + blob_new = xtrymalloc (blob_size_new); + if (! blob_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = stream_read_data (stream, blob_new, blob_size_new); + if (err) + goto out; + + *blob = blob_new; + *blob_size = blob_size_new; + + out: + + if (stream) + es_fclose (stream); + if (err) + xfree (blob_new); + + return err; +} + + +/* Write the public key KEY_PUBLIC to STREAM in SSH key format. If + OVERRIDE_COMMENT is not NULL, it will be used instead of the + comment stored in the key. */ +static gpg_error_t +ssh_send_key_public (estream_t stream, gcry_sexp_t key_public, + const char *override_comment) +{ + ssh_key_type_spec_t spec; + gcry_mpi_t *mpi_list; + char *key_type; + char *comment; + unsigned char *blob; + size_t blob_n; + gpg_error_t err; + + key_type = NULL; + mpi_list = NULL; + comment = NULL; + blob = NULL; + + err = sexp_extract_identifier (key_public, &key_type); + if (err) + goto out; + + err = ssh_key_type_lookup (NULL, key_type, &spec); + if (err) + goto out; + + err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment); + if (err) + goto out; + + err = ssh_convert_key_to_blob (&blob, &blob_n, + spec.ssh_identifier, mpi_list); + if (err) + goto out; + + err = stream_write_string (stream, blob, blob_n); + if (err) + goto out; + + err = stream_write_cstring (stream, + override_comment? override_comment : comment); + + out: + + mpint_list_free (mpi_list); + xfree (key_type); + xfree (comment); + xfree (blob); + + return err; +} + +/* Read a public key out of BLOB/BLOB_SIZE according to the key + specification given as KEY_SPEC, storing the new key in KEY_PUBLIC. + Returns zero on success or an error code. */ +static gpg_error_t +ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, + gcry_sexp_t *key_public, + ssh_key_type_spec_t *key_spec) +{ + estream_t blob_stream; + gpg_error_t err; + + err = 0; + + blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! blob_stream) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = stream_write_data (blob_stream, blob, blob_size); + if (err) + goto out; + + err = es_fseek (blob_stream, 0, SEEK_SET); + if (err) + goto out; + + err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec); + + out: + + if (blob_stream) + es_fclose (blob_stream); + + return err; +} + + + +/* This function calculates the key grip for the key contained in the + S-Expression KEY and writes it to BUFFER, which must be large + enough to hold it. Returns usual error code. */ +static gpg_error_t +ssh_key_grip (gcry_sexp_t key, unsigned char *buffer) +{ + if (!gcry_pk_get_keygrip (key, buffer)) + return gpg_error (GPG_ERR_INTERNAL); + + return 0; +} + + +/* Converts the secret key KEY_SECRET into a public key, storing it in + KEY_PUBLIC. SPEC is the according key specification. Returns zero + on success or an error code. */ +static gpg_error_t +key_secret_to_public (gcry_sexp_t *key_public, + ssh_key_type_spec_t spec, gcry_sexp_t key_secret) +{ + char *comment; + gcry_mpi_t *mpis; + gpg_error_t err; + int is_secret; + + comment = NULL; + mpis = NULL; + + err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment); + if (err) + goto out; + + err = sexp_key_construct (key_public, spec, 0, mpis, comment); + + out: + + mpint_list_free (mpis); + xfree (comment); + + return err; +} + + +/* Check whether a smartcard is available and whether it has a usable + key. Store a copy of that key at R_PK and return 0. If no key is + available store NULL at R_PK and return an error code. If CARDSN + is not NULL, a string with the serial number of the card will be + a malloced and stored there. */ +static gpg_error_t +card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) +{ + gpg_error_t err; + char *authkeyid; + char *serialno = NULL; + unsigned char *pkbuf; + size_t pkbuflen; + gcry_sexp_t s_pk; + unsigned char grip[20]; + + *r_pk = NULL; + if (cardsn) + *cardsn = NULL; + + /* First see whether a card is available and whether the application + is supported. */ + err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid); + if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED ) + { + /* Ask for the serial number to reset the card. */ + err = agent_card_serialno (ctrl, &serialno); + if (err) + { + if (opt.verbose) + log_info (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + return err; + } + log_info (_("detected card with S/N: %s\n"), serialno); + err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid); + } + if (err) + { + log_error (_("error getting default authentication keyID of card: %s\n"), + gpg_strerror (err)); + xfree (serialno); + return err; + } + + /* Get the S/N if we don't have it yet. Use the fast getattr method. */ + if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) ) + { + log_error (_("error getting serial number of card: %s\n"), + gpg_strerror (err)); + xfree (authkeyid); + return err; + } + + /* Read the public key. */ + err = agent_card_readkey (ctrl, authkeyid, &pkbuf); + if (err) + { + if (opt.verbose) + log_info (_("no suitable card key found: %s\n"), gpg_strerror (err)); + xfree (serialno); + xfree (authkeyid); + return err; + } + + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen); + if (err) + { + log_error ("failed to build S-Exp from received card key: %s\n", + gpg_strerror (err)); + xfree (pkbuf); + xfree (serialno); + xfree (authkeyid); + return err; + } + + err = ssh_key_grip (s_pk, grip); + if (err) + { + log_debug ("error computing keygrip from received card key: %s\n", + gcry_strerror (err)); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + xfree (authkeyid); + return err; + } + + if ( agent_key_available (grip) ) + { + /* (Shadow)-key is not available in our key storage. */ + unsigned char *shadow_info; + unsigned char *tmp; + + shadow_info = make_shadow_info (serialno, authkeyid); + if (!shadow_info) + { + err = gpg_error_from_syserror (); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + xfree (authkeyid); + return err; + } + err = agent_shadow_key (pkbuf, shadow_info, &tmp); + xfree (shadow_info); + if (err) + { + log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err)); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + xfree (authkeyid); + return err; + } + xfree (pkbuf); + pkbuf = tmp; + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + assert (pkbuflen); + + err = agent_write_private_key (grip, pkbuf, pkbuflen, 0); + if (err) + { + log_error (_("error writing key: %s\n"), gpg_strerror (err)); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + xfree (authkeyid); + return err; + } + } + + if (cardsn) + { + char *dispsn; + + /* If the card handler is able to return a short serialnumber, + use that one, else use the complete serialno. */ + if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn)) + { + *cardsn = xtryasprintf ("cardno:%s", dispsn); + xfree (dispsn); + } + else + *cardsn = xtryasprintf ("cardno:%s", serialno); + if (!*cardsn) + { + err = gpg_error_from_syserror (); + xfree (pkbuf); + gcry_sexp_release (s_pk); + xfree (serialno); + xfree (authkeyid); + return err; + } + } + + xfree (pkbuf); + xfree (serialno); + xfree (authkeyid); + *r_pk = s_pk; + return 0; +} + + + + +/* + + Request handler. Each handler is provided with a CTRL context, a + REQUEST object and a RESPONSE object. The actual request is to be + read from REQUEST, the response needs to be written to RESPONSE. + +*/ + + +/* Handler for the "request_identities" command. */ +static gpg_error_t +ssh_handler_request_identities (ctrl_t ctrl, + estream_t request, estream_t response) +{ + char *key_type; + ssh_key_type_spec_t spec; + struct dirent *dir_entry; + char *key_directory; + size_t key_directory_n; + char *key_path; + unsigned char *buffer; + size_t buffer_n; + u32 key_counter; + estream_t key_blobs; + gcry_sexp_t key_secret; + gcry_sexp_t key_public; + DIR *dir; + gpg_error_t err; + int ret; + FILE *ctrl_fp = NULL; + char *cardsn; + gpg_error_t ret_err; + + (void)request; + + /* Prepare buffer stream. */ + + key_directory = NULL; + key_secret = NULL; + key_public = NULL; + key_type = NULL; + key_path = NULL; + key_counter = 0; + buffer = NULL; + dir = NULL; + err = 0; + + key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! key_blobs) + { + err = gpg_error_from_syserror (); + goto out; + } + + /* Open key directory. */ + key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL); + if (! key_directory) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + key_directory_n = strlen (key_directory); + + key_path = xtrymalloc (key_directory_n + 46); + if (! key_path) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + + sprintf (key_path, "%s/", key_directory); + sprintf (key_path + key_directory_n + 41, ".key"); + + dir = opendir (key_directory); + if (! dir) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + + + + /* First check whether a key is currently available in the card + reader - this should be allowed even without being listed in + sshcontrol. */ + + if (!card_key_available (ctrl, &key_public, &cardsn)) + { + err = ssh_send_key_public (key_blobs, key_public, cardsn); + gcry_sexp_release (key_public); + key_public = NULL; + xfree (cardsn); + if (err) + goto out; + + key_counter++; + } + + + /* Then look at all the registered an allowed keys. */ + + + /* Fixme: We should better iterate over the control file and check + whether the key file is there. This is better in resepct to + performance if tehre are a lot of key sin our key storage. */ + /* FIXME: make sure that buffer gets deallocated properly. */ + err = open_control_file (&ctrl_fp, 0); + if (err) + goto out; + + while ( (dir_entry = readdir (dir)) ) + { + if ((strlen (dir_entry->d_name) == 44) + && (! strncmp (dir_entry->d_name + 40, ".key", 4))) + { + char hexgrip[41]; + int disabled; + + /* We do only want to return keys listed in our control + file. */ + strncpy (hexgrip, dir_entry->d_name, 40); + hexgrip[40] = 0; + if ( strlen (hexgrip) != 40 ) + continue; + if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL) + || disabled) + continue; + + strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40); + + /* Read file content. */ + err = file_to_buffer (key_path, &buffer, &buffer_n); + if (err) + goto out; + + err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); + if (err) + goto out; + + xfree (buffer); + buffer = NULL; + + err = sexp_extract_identifier (key_secret, &key_type); + if (err) + goto out; + + err = ssh_key_type_lookup (NULL, key_type, &spec); + if (err) + goto out; + + xfree (key_type); + key_type = NULL; + + err = key_secret_to_public (&key_public, spec, key_secret); + if (err) + goto out; + + gcry_sexp_release (key_secret); + key_secret = NULL; + + err = ssh_send_key_public (key_blobs, key_public, NULL); + if (err) + goto out; + + gcry_sexp_release (key_public); + key_public = NULL; + + key_counter++; + } + } + + ret = es_fseek (key_blobs, 0, SEEK_SET); + if (ret) + { + err = gpg_error_from_syserror (); + goto out; + } + + out: + + /* Send response. */ + + gcry_sexp_release (key_secret); + gcry_sexp_release (key_public); + + if (! err) + { + ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER); + if (ret_err) + goto leave; + ret_err = stream_write_uint32 (response, key_counter); + if (ret_err) + goto leave; + ret_err = stream_copy (response, key_blobs); + if (ret_err) + goto leave; + } + else + { + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + goto leave; + }; + + leave: + + if (key_blobs) + es_fclose (key_blobs); + if (dir) + closedir (dir); + + if (ctrl_fp) + fclose (ctrl_fp); + + xfree (key_directory); + xfree (key_path); + xfree (buffer); + xfree (key_type); + + return ret_err; +} + + +/* This function hashes the data contained in DATA of size DATA_N + according to the message digest algorithm specified by MD_ALGORITHM + and writes the message digest to HASH, which needs to large enough + for the digest. */ +static gpg_error_t +data_hash (unsigned char *data, size_t data_n, + int md_algorithm, unsigned char *hash) +{ + gcry_md_hash_buffer (md_algorithm, hash, data, data_n); + + return 0; +} + +/* This function signs the data contained in CTRL, stores the created + signature in newly allocated memory in SIG and it's size in SIG_N; + SIG_ENCODER is the signature encoder to use. */ +static gpg_error_t +data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, + unsigned char **sig, size_t *sig_n) +{ + gpg_error_t err; + gcry_sexp_t signature_sexp = NULL; + estream_t stream = NULL; + gcry_sexp_t valuelist = NULL; + gcry_sexp_t sublist = NULL; + gcry_mpi_t sig_value = NULL; + unsigned char *sig_blob = NULL; + size_t sig_blob_n = 0; + char *identifier = NULL; + const char *identifier_raw; + size_t identifier_n; + ssh_key_type_spec_t spec; + int ret; + unsigned int i; + const char *elems; + size_t elems_n; + gcry_mpi_t *mpis = NULL; + char hexgrip[40+1]; + + *sig = NULL; + *sig_n = 0; + + /* Quick check to see whether we have a valid keygrip and convert it + to hex. */ + if (!ctrl->have_keygrip) + { + err = gpg_error (GPG_ERR_NO_SECKEY); + goto out; + } + bin2hex (ctrl->keygrip, 20, hexgrip); + + /* Ask for confirmation if needed. */ + if (confirm_flag_from_sshcontrol (hexgrip)) + { + gcry_sexp_t key; + char *fpr, *prompt; + char *comment = NULL; + + err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key); + if (err) + goto out; + err = ssh_get_fingerprint_string (key, &fpr); + if (!err) + { + gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0); + if (tmpsxp) + comment = gcry_sexp_nth_string (tmpsxp, 1); + gcry_sexp_release (tmpsxp); + } + gcry_sexp_release (key); + if (err) + goto out; + prompt = xtryasprintf (_("An ssh process requested the use of key%%0A" + " %s%%0A" + " (%s)%%0A" + "Do you want to allow this?"), + fpr, comment? comment:""); + xfree (fpr); + gcry_free (comment); + err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0); + xfree (prompt); + if (err) + goto out; + } + + /* Create signature. */ + ctrl->use_auth_call = 1; + err = agent_pksign_do (ctrl, + _("Please enter the passphrase " + "for the ssh key%%0A %F%%0A (%c)"), + &signature_sexp, + CACHE_MODE_SSH, ttl_from_sshcontrol); + ctrl->use_auth_call = 0; + if (err) + goto out; + + valuelist = gcry_sexp_nth (signature_sexp, 1); + if (! valuelist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! stream) + { + err = gpg_error_from_syserror (); + goto out; + } + + identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n); + if (! identifier_raw) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + identifier = make_cstring (identifier_raw, identifier_n); + if (! identifier) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = ssh_key_type_lookup (NULL, identifier, &spec); + if (err) + goto out; + + err = stream_write_cstring (stream, spec.ssh_identifier); + if (err) + goto out; + + elems = spec.elems_signature; + elems_n = strlen (elems); + + mpis = xtrycalloc (elems_n + 1, sizeof *mpis); + if (!mpis) + { + err = gpg_error_from_syserror (); + goto out; + } + + for (i = 0; i < elems_n; i++) + { + sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1); + if (! sublist) + { + err = gpg_error (GPG_ERR_INV_SEXP); + break; + } + + sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG); + if (! sig_value) + { + err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ + break; + } + gcry_sexp_release (sublist); + sublist = NULL; + + mpis[i] = sig_value; + } + if (err) + goto out; + + err = (*sig_encoder) (stream, mpis); + if (err) + goto out; + + sig_blob_n = es_ftell (stream); + if (sig_blob_n == -1) + { + err = gpg_error_from_syserror (); + goto out; + } + + sig_blob = xtrymalloc (sig_blob_n); + if (! sig_blob) + { + err = gpg_error_from_syserror (); + goto out; + } + + ret = es_fseek (stream, 0, SEEK_SET); + if (ret) + { + err = gpg_error_from_syserror (); + goto out; + } + + err = stream_read_data (stream, sig_blob, sig_blob_n); + if (err) + goto out; + + *sig = sig_blob; + *sig_n = sig_blob_n; + + out: + + if (err) + xfree (sig_blob); + + if (stream) + es_fclose (stream); + gcry_sexp_release (valuelist); + gcry_sexp_release (signature_sexp); + gcry_sexp_release (sublist); + mpint_list_free (mpis); + xfree (identifier); + + return err; +} + +/* Handler for the "sign_request" command. */ +static gpg_error_t +ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response) +{ + gcry_sexp_t key; + ssh_key_type_spec_t spec; + unsigned char hash[MAX_DIGEST_LEN]; + unsigned int hash_n; + unsigned char key_grip[20]; + unsigned char *key_blob; + u32 key_blob_size; + unsigned char *data; + unsigned char *sig; + size_t sig_n; + u32 data_size; + u32 flags; + gpg_error_t err; + gpg_error_t ret_err; + + key_blob = NULL; + data = NULL; + sig = NULL; + key = NULL; + + /* Receive key. */ + + err = stream_read_string (request, 0, &key_blob, &key_blob_size); + if (err) + goto out; + + err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec); + if (err) + goto out; + + /* Receive data to sign. */ + err = stream_read_string (request, 0, &data, &data_size); + if (err) + goto out; + + /* FIXME? */ + err = stream_read_uint32 (request, &flags); + if (err) + goto out; + + /* Hash data. */ + hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1); + if (! hash_n) + { + err = gpg_error (GPG_ERR_INTERNAL); + goto out; + } + err = data_hash (data, data_size, GCRY_MD_SHA1, hash); + if (err) + goto out; + + /* Calculate key grip. */ + err = ssh_key_grip (key, key_grip); + if (err) + goto out; + + /* Sign data. */ + + ctrl->digest.algo = GCRY_MD_SHA1; + memcpy (ctrl->digest.value, hash, hash_n); + ctrl->digest.valuelen = hash_n; + ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2); + ctrl->have_keygrip = 1; + memcpy (ctrl->keygrip, key_grip, 20); + + err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n); + + out: + + /* Done. */ + + if (! err) + { + ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE); + if (ret_err) + goto leave; + ret_err = stream_write_string (response, sig, sig_n); + if (ret_err) + goto leave; + } + else + { + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + if (ret_err) + goto leave; + } + + leave: + + gcry_sexp_release (key); + xfree (key_blob); + xfree (data); + xfree (sig); + + return ret_err; +} + +/* This function extracts the comment contained in the key + S-Expression KEY and stores a copy in COMMENT. Returns usual error + code. */ +static gpg_error_t +ssh_key_extract_comment (gcry_sexp_t key, char **comment) +{ + gcry_sexp_t comment_list; + char *comment_new; + const char *data; + size_t data_n; + gpg_error_t err; + + comment_list = gcry_sexp_find_token (key, "comment", 0); + if (! comment_list) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + data = gcry_sexp_nth_data (comment_list, 1, &data_n); + if (! data) + { + err = gpg_error (GPG_ERR_INV_SEXP); + goto out; + } + + comment_new = make_cstring (data, data_n); + if (! comment_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + *comment = comment_new; + err = 0; + + out: + + gcry_sexp_release (comment_list); + + return err; +} + +/* This function converts the key contained in the S-Expression KEY + into a buffer, which is protected by the passphrase PASSPHRASE. + Returns usual error code. */ +static gpg_error_t +ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase, + unsigned char **buffer, size_t *buffer_n) +{ + unsigned char *buffer_new; + unsigned int buffer_new_n; + gpg_error_t err; + + err = 0; + buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0); + buffer_new = xtrymalloc_secure (buffer_new_n); + if (! buffer_new) + { + err = gpg_error_from_syserror (); + goto out; + } + + gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n); + /* FIXME: guarantee? */ + + err = agent_protect (buffer_new, passphrase, buffer, buffer_n); + + out: + + xfree (buffer_new); + + return err; +} + + + +/* Callback function to compare the first entered PIN with the one + currently being entered. */ +static int +reenter_compare_cb (struct pin_entry_info_s *pi) +{ + const char *pin1 = pi->check_cb_arg; + + if (!strcmp (pin1, pi->pin)) + return 0; /* okay */ + return -1; +} + +/* Store the ssh KEY into our local key storage and protect it after + asking for a passphrase. Cache that passphrase. TTL is the + maximum caching time for that key. If the key already exists in + our key storage, don't do anything. When entering a new key also + add an entry to the sshcontrol file. */ +static gpg_error_t +ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm) +{ + gpg_error_t err; + unsigned char key_grip_raw[20]; + char key_grip[41]; + unsigned char *buffer = NULL; + size_t buffer_n; + char *description = NULL; + const char *description2 = _("Please re-enter this passphrase"); + char *comment = NULL; + char *key_fpr = NULL; + const char *initial_errtext = NULL; + unsigned int i; + struct pin_entry_info_s *pi = NULL, *pi2; + + err = ssh_key_grip (key, key_grip_raw); + if (err) + goto out; + + /* Check whether the key is already in our key storage. Don't do + anything then. */ + if ( !agent_key_available (key_grip_raw) ) + goto out; /* Yes, key is available. */ + + err = ssh_get_fingerprint_string (key, &key_fpr); + if (err) + goto out; + + err = ssh_key_extract_comment (key, &comment); + if (err) + goto out; + + if ( asprintf (&description, + _("Please enter a passphrase to protect" + " the received secret key%%0A" + " %s%%0A" + " %s%%0A" + "within gpg-agent's key storage"), + key_fpr, comment ? comment : "") < 0) + { + err = gpg_error_from_syserror (); + goto out; + } + + + pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1); + if (!pi) + { + err = gpg_error_from_syserror (); + goto out; + } + pi2 = pi + (sizeof *pi + 100 + 1); + pi->max_length = 100; + pi->max_tries = 1; + pi2->max_length = 100; + pi2->max_tries = 1; + pi2->check_cb = reenter_compare_cb; + pi2->check_cb_arg = pi->pin; + + next_try: + err = agent_askpin (ctrl, description, NULL, initial_errtext, pi); + initial_errtext = NULL; + if (err) + goto out; + + /* Unless the passphrase is empty, ask to confirm it. */ + if (pi->pin && *pi->pin) + { + err = agent_askpin (ctrl, description2, NULL, NULL, pi2); + if (err == -1) + { /* The re-entered one did not match and the user did not + hit cancel. */ + initial_errtext = _("does not match - try again"); + goto next_try; + } + } + + err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n); + if (err) + goto out; + + /* Store this key to our key storage. */ + err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0); + if (err) + goto out; + + /* Cache this passphrase. */ + for (i = 0; i < 20; i++) + sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]); + + err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl); + if (err) + goto out; + + /* And add an entry to the sshcontrol file. */ + err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm); + + + out: + if (pi && pi->max_length) + wipememory (pi->pin, pi->max_length); + xfree (pi); + xfree (buffer); + xfree (comment); + xfree (key_fpr); + xfree (description); + + return err; +} + + +/* This function removes the key contained in the S-Expression KEY + from the local key storage, in case it exists there. Returns usual + error code. FIXME: this function is a stub. */ +static gpg_error_t +ssh_identity_drop (gcry_sexp_t key) +{ + unsigned char key_grip[21] = { 0 }; + gpg_error_t err; + + err = ssh_key_grip (key, key_grip); + if (err) + goto out; + + key_grip[sizeof (key_grip) - 1] = 0; + + /* FIXME: What to do here - forgetting the passphrase or deleting + the key from key cache? */ + + out: + + return err; +} + +/* Handler for the "add_identity" command. */ +static gpg_error_t +ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t ret_err; + gpg_error_t err; + gcry_sexp_t key; + unsigned char b; + int confirm; + int ttl; + + confirm = 0; + key = NULL; + ttl = 0; + + /* FIXME? */ + err = ssh_receive_key (request, &key, 1, 1, NULL); + if (err) + goto out; + + while (1) + { + err = stream_read_byte (request, &b); + if (gpg_err_code (err) == GPG_ERR_EOF) + { + err = 0; + break; + } + + switch (b) + { + case SSH_OPT_CONSTRAIN_LIFETIME: + { + u32 n = 0; + + err = stream_read_uint32 (request, &n); + if (! err) + ttl = n; + break; + } + + case SSH_OPT_CONSTRAIN_CONFIRM: + { + confirm = 1; + break; + } + + default: + /* FIXME: log/bad? */ + break; + } + } + if (err) + goto out; + + err = ssh_identity_register (ctrl, key, ttl, confirm); + + out: + + gcry_sexp_release (key); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + + return ret_err; +} + +/* Handler for the "remove_identity" command. */ +static gpg_error_t +ssh_handler_remove_identity (ctrl_t ctrl, + estream_t request, estream_t response) +{ + unsigned char *key_blob; + u32 key_blob_size; + gcry_sexp_t key; + gpg_error_t ret_err; + gpg_error_t err; + + (void)ctrl; + + /* Receive key. */ + + key_blob = NULL; + key = NULL; + + err = stream_read_string (request, 0, &key_blob, &key_blob_size); + if (err) + goto out; + + err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL); + if (err) + goto out; + + err = ssh_identity_drop (key); + + out: + + xfree (key_blob); + gcry_sexp_release (key); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + + return ret_err; +} + +/* FIXME: stub function. Actually useful? */ +static gpg_error_t +ssh_identities_remove_all (void) +{ + gpg_error_t err; + + err = 0; + + /* FIXME: shall we remove _all_ cache entries or only those + registered through the ssh emulation? */ + + return err; +} + +/* Handler for the "remove_all_identities" command. */ +static gpg_error_t +ssh_handler_remove_all_identities (ctrl_t ctrl, + estream_t request, estream_t response) +{ + gpg_error_t ret_err; + gpg_error_t err; + + (void)ctrl; + (void)request; + + err = ssh_identities_remove_all (); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + + return ret_err; +} + +/* Lock agent? FIXME: stub function. */ +static gpg_error_t +ssh_lock (void) +{ + gpg_error_t err; + + /* FIXME */ + log_error ("ssh-agent's lock command is not implemented\n"); + err = 0; + + return err; +} + +/* Unock agent? FIXME: stub function. */ +static gpg_error_t +ssh_unlock (void) +{ + gpg_error_t err; + + log_error ("ssh-agent's unlock command is not implemented\n"); + err = 0; + + return err; +} + +/* Handler for the "lock" command. */ +static gpg_error_t +ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t ret_err; + gpg_error_t err; + + (void)ctrl; + (void)request; + + err = ssh_lock (); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + + return ret_err; +} + +/* Handler for the "unlock" command. */ +static gpg_error_t +ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response) +{ + gpg_error_t ret_err; + gpg_error_t err; + + (void)ctrl; + (void)request; + + err = ssh_unlock (); + + if (! err) + ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS); + else + ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE); + + return ret_err; +} + + + +/* Return the request specification for the request identified by TYPE + or NULL in case the requested request specification could not be + found. */ +static ssh_request_spec_t * +request_spec_lookup (int type) +{ + ssh_request_spec_t *spec; + unsigned int i; + + for (i = 0; i < DIM (request_specs); i++) + if (request_specs[i].type == type) + break; + if (i == DIM (request_specs)) + { + if (opt.verbose) + log_info ("ssh request %u is not supported\n", type); + spec = NULL; + } + else + spec = request_specs + i; + + return spec; +} + +/* Process a single request. The request is read from and the + response is written to STREAM_SOCK. Uses CTRL as context. Returns + zero in case of success, non zero in case of failure. */ +static int +ssh_request_process (ctrl_t ctrl, estream_t stream_sock) +{ + ssh_request_spec_t *spec; + estream_t response; + estream_t request; + unsigned char request_type; + gpg_error_t err; + int send_err; + int ret; + unsigned char *request_data; + u32 request_data_size; + u32 response_size; + + request_data = NULL; + response = NULL; + request = NULL; + send_err = 0; + + /* Create memory streams for request/response data. The entire + request will be stored in secure memory, since it might contain + secret key material. The response does not have to be stored in + secure memory, since we never give out secret keys. + + Note: we only have little secure memory, but there is NO + possibility of DoS here; only trusted clients are allowed to + connect to the agent. What could happen is that the agent + returns out-of-secure-memory errors on requests in case the + agent's owner floods his own agent with many large messages. + -moritz */ + + /* Retrieve request. */ + err = stream_read_string (stream_sock, 1, &request_data, &request_data_size); + if (err) + goto out; + + if (opt.verbose > 1) + log_info ("received ssh request of length %u\n", + (unsigned int)request_data_size); + + if (! request_data_size) + { + send_err = 1; + goto out; + /* Broken request; FIXME. */ + } + + request_type = request_data[0]; + spec = request_spec_lookup (request_type); + if (! spec) + { + send_err = 1; + goto out; + /* Unknown request; FIXME. */ + } + + if (spec->secret_input) + request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+"); + else + request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+"); + if (! request) + { + err = gpg_error_from_syserror (); + goto out; + } + ret = es_setvbuf (request, NULL, _IONBF, 0); + if (ret) + { + err = gpg_error_from_syserror (); + goto out; + } + err = stream_write_data (request, request_data + 1, request_data_size - 1); + if (err) + goto out; + es_rewind (request); + + response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + if (! response) + { + err = gpg_error_from_syserror (); + goto out; + } + + if (opt.verbose) + log_info ("ssh request handler for %s (%u) started\n", + spec->identifier, spec->type); + + err = (*spec->handler) (ctrl, request, response); + + if (opt.verbose) + { + if (err) + log_info ("ssh request handler for %s (%u) failed: %s\n", + spec->identifier, spec->type, gpg_strerror (err)); + else + log_info ("ssh request handler for %s (%u) ready\n", + spec->identifier, spec->type); + } + + if (err) + { + send_err = 1; + goto out; + } + + response_size = es_ftell (response); + if (opt.verbose > 1) + log_info ("sending ssh response of length %u\n", + (unsigned int)response_size); + + err = es_fseek (response, 0, SEEK_SET); + if (err) + { + send_err = 1; + goto out; + } + + err = stream_write_uint32 (stream_sock, response_size); + if (err) + { + send_err = 1; + goto out; + } + + err = stream_copy (stream_sock, response); + if (err) + goto out; + + err = es_fflush (stream_sock); + if (err) + goto out; + + out: + + if (err && es_feof (stream_sock)) + log_error ("error occured while processing request: %s\n", + gpg_strerror (err)); + + if (send_err) + { + if (opt.verbose > 1) + log_info ("sending ssh error response\n"); + err = stream_write_uint32 (stream_sock, 1); + if (err) + goto leave; + err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE); + if (err) + goto leave; + } + + leave: + + if (request) + es_fclose (request); + if (response) + es_fclose (response); + xfree (request_data); /* FIXME? */ + + return !!err; +} + +/* Start serving client on SOCK_CLIENT. */ +void +start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) +{ + estream_t stream_sock = NULL; + gpg_error_t err = 0; + int ret; + + /* Because the ssh protocol does not send us information about the + the current TTY setting, we resort here to use those from startup + or those explictly set. */ + { + static const char *names[] = + {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; + int idx; + const char *value; + + for (idx=0; !err && names[idx]; idx++) + if (!session_env_getenv (ctrl->session_env, names[idx]) + && (value = session_env_getenv (opt.startup_env, names[idx]))) + err = session_env_setenv (ctrl->session_env, names[idx], value); + + if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) + if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) + err = gpg_error_from_syserror (); + + if (!err && !ctrl->lc_messages && opt.startup_lc_messages) + if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages))) + err = gpg_error_from_syserror (); + + if (err) + { + log_error ("error setting default session environment: %s\n", + gpg_strerror (err)); + goto out; + } + } + + + /* Create stream from socket. */ + stream_sock = es_fdopen (FD2INT(sock_client), "r+"); + if (!stream_sock) + { + err = gpg_error_from_syserror (); + log_error (_("failed to create stream from socket: %s\n"), + gpg_strerror (err)); + goto out; + } + /* We have to disable the estream buffering, because the estream + core doesn't know about secure memory. */ + ret = es_setvbuf (stream_sock, NULL, _IONBF, 0); + if (ret) + { + err = gpg_error_from_syserror (); + log_error ("failed to disable buffering " + "on socket stream: %s\n", gpg_strerror (err)); + goto out; + } + + /* Main processing loop. */ + while ( !ssh_request_process (ctrl, stream_sock) ) + { + /* Check wether we have reached EOF before trying to read + another request. */ + int c; + + c = es_fgetc (stream_sock); + if (c == EOF) + break; + es_ungetc (c, stream_sock); + } + + /* Reset the SCD in case it has been used. */ + agent_reset_scd (ctrl); + + + out: + if (stream_sock) + es_fclose (stream_sock); +} diff --git a/agent/command.c b/agent/command.c new file mode 100644 index 0000000..97cf507 --- /dev/null +++ b/agent/command.c @@ -0,0 +1,2073 @@ +/* command.c - gpg-agent command handler + * Copyright (C) 2001, 2002, 2003, 2004, 2005, + * 2006, 2008, 2009 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 3 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, see . + */ + +/* FIXME: we should not use the default assuan buffering but setup + some buffering in secure mempory to protect session keys etc. */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include +#include "i18n.h" +#include "../common/ssh-utils.h" + +/* maximum allowed size of the inquired ciphertext */ +#define MAXLEN_CIPHERTEXT 4096 +/* maximum allowed size of the key parameters */ +#define MAXLEN_KEYPARAM 1024 + +#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) + + +#if MAX_DIGEST_LEN < 20 +#error MAX_DIGEST_LEN shorter than keygrip +#endif + +/* Data used to associate an Assuan context with local server data */ +struct server_local_s +{ + assuan_context_t assuan_ctx; + int message_fd; + int use_cache_for_signing; + char *keydesc; /* Allocated description for the next key + operation. */ + int pause_io_logging; /* Used to suppress I/O logging during a command */ + int stopme; /* If set to true the agent will be terminated after + the end of this session. */ + int allow_pinentry_notify; /* Set if pinentry notifications should + be done. */ +}; + + +/* An entry for the getval/putval commands. */ +struct putval_item_s +{ + struct putval_item_s *next; + size_t off; /* Offset to the value into DATA. */ + size_t len; /* Length of the value. */ + char d[1]; /* Key | Nul | value. */ +}; + + +/* A list of key value pairs fpr the getval/putval commands. */ +static struct putval_item_s *putval_list; + + + +/* To help polling clients, we keep track of the number of certain + events. This structure keeps those counters. The counters are + integers and there should be no problem if they are overflowing as + callers need to check only whether a counter changed. The actual + values are not meaningful. */ +struct +{ + /* Incremented if any of the other counters below changed. */ + unsigned int any; + + /* Incremented if a key is added or removed from the internal privat + key database. */ + unsigned int key; + + /* Incremented if a change of the card readers stati has been + detected. */ + unsigned int card; + +} eventcounter; + + + +/* Local prototypes. */ +static int command_has_option (const char *cmd, const char *cmdopt); + + + + +/* Release the memory buffer MB but first wipe out the used memory. */ +static void +clear_outbuf (membuf_t *mb) +{ + void *p; + size_t n; + + p = get_membuf (mb, &n); + if (p) + { + memset (p, 0, n); + xfree (p); + } +} + + +/* Write the content of memory buffer MB as assuan data to CTX and + wipe the buffer out afterwards. */ +static gpg_error_t +write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb) +{ + gpg_error_t ae; + void *p; + size_t n; + + p = get_membuf (mb, &n); + if (!p) + return out_of_core (); + ae = assuan_send_data (ctx, p, n); + memset (p, 0, n); + xfree (p); + return ae; +} + + +static gpg_error_t +reset_notify (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + + (void) line; + + memset (ctrl->keygrip, 0, 20); + ctrl->have_keygrip = 0; + ctrl->digest.valuelen = 0; + + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; + return 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))); +} + +/* Same as has_option but does only test for the name of the option + and ignores an argument, i.e. with NAME being "--hash" it would + return true for "--hash" as well as for "--hash=foo". */ +static int +has_option_name (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) || s[n] == '=')); +} + +/* Return a pointer to the argument of the option with NAME. If such + an option is not given, it returns NULL. */ +static char * +option_value (const char *line, const char *name) +{ + char *s; + int n = strlen (name); + + s = strstr (line, name); + if (s && (s == line || spacep (s-1)) + && s[n] && (spacep (s+n) || s[n] == '=')) + { + s += n + 1; + s += strspn (s, " "); + if (*s && !spacep(s)) + return s; + } + return NULL; +} + + +/* Skip over options. It is assumed that leading spaces have been + removed (this is the case for lines passed to a handler from + assuan). Blanks after the options are also removed. */ +static char * +skip_options (char *line) +{ + while ( *line == '-' && line[1] == '-' ) + { + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + } + return line; +} + + +/* Replace all '+' by a blank. */ +static void +plus_to_blank (char *s) +{ + for (; *s; s++) + { + if (*s == '+') + *s = ' '; + } +} + + +/* Parse a hex string. Return an Assuan error code or 0 on success and the + length of the parsed string in LEN. */ +static int +parse_hexstring (assuan_context_t ctx, const char *string, size_t *len) +{ + const char *p; + size_t n; + + /* parse the hash value */ + for (p=string, n=0; hexdigitp (p); p++, n++) + ; + if (*p != ' ' && *p != '\t' && *p) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring"); + if ((n&1)) + return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits"); + *len = n; + return 0; +} + +/* Parse the keygrip in STRING into the provided buffer BUF. BUF must + provide space for 20 bytes. BUF is not changed if the function + returns an error. */ +static int +parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) +{ + int rc; + size_t n = 0; + + rc = parse_hexstring (ctx, string, &n); + if (rc) + return rc; + n /= 2; + if (n != 20) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip"); + + if (hex2bin (string, buf, 20) < 0) + return set_error (GPG_ERR_BUG, "hex2bin"); + + return 0; +} + + +/* Write an assuan status line. */ +gpg_error_t +agent_write_status (ctrl_t ctrl, const char *keyword, ...) +{ + gpg_error_t err = 0; + va_list arg_ptr; + const char *text; + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + char buf[950], *p; + size_t n; + + va_start (arg_ptr, keyword); + + p = buf; + n = 0; + while ( (text = va_arg (arg_ptr, const char *)) ) + { + if (n) + { + *p++ = ' '; + n++; + } + for ( ; *text && n < DIM (buf)-3; n++, text++) + { + if (*text == '\n') + { + *p++ = '\\'; + *p++ = 'n'; + } + else if (*text == '\r') + { + *p++ = '\\'; + *p++ = 'r'; + } + else + *p++ = *text; + } + } + *p = 0; + err = assuan_write_status (ctx, keyword, buf); + + va_end (arg_ptr); + return err; +} + + +/* Helper to notify the client about a launched Pinentry. Because + that might disturb some older clients, this is only done if enabled + via an option. Returns an gpg error code. */ +gpg_error_t +agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid) +{ + char line[100]; + + if (!ctrl || !ctrl->server_local + || !ctrl->server_local->allow_pinentry_notify) + return 0; + snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid); + return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0); +} + + + +static const char hlp_geteventcounter[] = + "GETEVENTCOUNTER\n" + "\n" + "Return a a status line named EVENTCOUNTER with the current values\n" + "of all event counters. The values are decimal numbers in the range\n" + "0 to UINT_MAX and wrapping around to 0. The actual values should\n" + "not be relied upon, they shall only be used to detect a change.\n" + "\n" + "The currently defined counters are:\n" + "\n" + "ANY - Incremented with any change of any of the other counters.\n" + "KEY - Incremented for added or removed private keys.\n" + "CARD - Incremented for changes of the card readers stati."; +static gpg_error_t +cmd_geteventcounter (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + char any_counter[25]; + char key_counter[25]; + char card_counter[25]; + + (void)line; + + snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any); + snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key); + snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card); + + return agent_write_status (ctrl, "EVENTCOUNTER", + any_counter, + key_counter, + card_counter, + NULL); +} + + +/* This function should be called once for all key removals or + additions. This function is assured not to do any context + switches. */ +void +bump_key_eventcounter (void) +{ + eventcounter.key++; + eventcounter.any++; +} + +/* This function should be called for all card reader status + changes. This function is assured not to do any context + switches. */ +void +bump_card_eventcounter (void) +{ + eventcounter.card++; + eventcounter.any++; +} + + + + +static const char hlp_istrusted[] = + "ISTRUSTED \n" + "\n" + "Return OK when we have an entry with this fingerprint in our\n" + "trustlist"; +static gpg_error_t +cmd_istrusted (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc, n, i; + char *p; + char fpr[41]; + + /* Parse the fingerprint value. */ + for (p=line,n=0; hexdigitp (p); p++, n++) + ; + if (*p || !(n == 40 || n == 32)) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint"); + i = 0; + if (n==32) + { + strcpy (fpr, "00000000"); + i += 8; + } + for (p=line; i < 40; p++, i++) + fpr[i] = *p >= 'a'? (*p & 0xdf): *p; + fpr[i] = 0; + rc = agent_istrusted (ctrl, fpr, NULL); + if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) + return rc; + else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF ) + return gpg_error (GPG_ERR_NOT_TRUSTED); + else + { + log_error ("command is_trusted failed: %s\n", gpg_strerror (rc)); + return rc; + } +} + + +static const char hlp_listtrusted[] = + "LISTTRUSTED\n" + "\n" + "List all entries from the trustlist."; +static gpg_error_t +cmd_listtrusted (assuan_context_t ctx, char *line) +{ + int rc; + + (void)line; + + rc = agent_listtrusted (ctx); + if (rc) + log_error ("command listtrusted failed: %s\n", gpg_strerror (rc)); + return rc; +} + + +static const char hlp_martrusted[] = + "MARKTRUSTED \n" + "\n" + "Store a new key in into the trustlist."; +static gpg_error_t +cmd_marktrusted (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc, n, i; + char *p; + char fpr[41]; + int flag; + + /* parse the fingerprint value */ + for (p=line,n=0; hexdigitp (p); p++, n++) + ; + if (!spacep (p) || !(n == 40 || n == 32)) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint"); + i = 0; + if (n==32) + { + strcpy (fpr, "00000000"); + i += 8; + } + for (p=line; i < 40; p++, i++) + fpr[i] = *p >= 'a'? (*p & 0xdf): *p; + fpr[i] = 0; + + while (spacep (p)) + p++; + flag = *p++; + if ( (flag != 'S' && flag != 'P') || !spacep (p) ) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S"); + while (spacep (p)) + p++; + + rc = agent_marktrusted (ctrl, p, fpr, flag); + if (rc) + log_error ("command marktrusted failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + + +static const char hlp_havekey[] = + "HAVEKEY \n" + "\n" + "Return success when the secret key is available."; +static gpg_error_t +cmd_havekey (assuan_context_t ctx, char *line) +{ + int rc; + unsigned char buf[20]; + + rc = parse_keygrip (ctx, line, buf); + if (rc) + return rc; + + if (agent_key_available (buf)) + return gpg_error (GPG_ERR_NO_SECKEY); + + return 0; +} + + +static const char hlp_sigkey[] = + "SIGKEY \n" + "SETKEY \n" + "\n" + "Set the key used for a sign or decrypt operation."; +static gpg_error_t +cmd_sigkey (assuan_context_t ctx, char *line) +{ + int rc; + ctrl_t ctrl = assuan_get_pointer (ctx); + + rc = parse_keygrip (ctx, line, ctrl->keygrip); + if (rc) + return rc; + ctrl->have_keygrip = 1; + return 0; +} + + +static const char hlp_setkeydesc[] = + "SETKEYDESC plus_percent_escaped_string\n" + "\n" + "Set a description to be used for the next PKSIGN or PKDECRYPT\n" + "operation if this operation requires the entry of a passphrase. If\n" + "this command is not used a default text will be used. Note, that\n" + "this description implictly selects the label used for the entry\n" + "box; if the string contains the string PIN (which in general will\n" + "not be translated), \"PIN\" is used, otherwise the translation of\n" + "\"passphrase\" is used. The description string should not contain\n" + "blanks unless they are percent or '+' escaped.\n" + "\n" + "The description is only valid for the next PKSIGN or PKDECRYPT\n" + "operation."; +static gpg_error_t +cmd_setkeydesc (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + char *desc, *p; + + for (p=line; *p == ' '; p++) + ; + desc = p; + p = strchr (desc, ' '); + if (p) + *p = 0; /* We ignore any garbage; we might late use it for other args. */ + + if (!desc || !*desc) + return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); + + /* Note, that we only need to replace the + characters and should + leave the other escaping in place because the escaped string is + send verbatim to the pinentry which does the unescaping (but not + the + replacing) */ + plus_to_blank (desc); + + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = xtrystrdup (desc); + if (!ctrl->server_local->keydesc) + return out_of_core (); + return 0; +} + + +static const char hlp_sethash[] = + "SETHASH --hash=| \n" + "\n" + "The client can use this command to tell the server about the data\n" + "(which usually is a hash) to be signed."; +static gpg_error_t +cmd_sethash (assuan_context_t ctx, char *line) +{ + int rc; + size_t n; + char *p; + ctrl_t ctrl = assuan_get_pointer (ctx); + unsigned char *buf; + char *endp; + int algo; + + /* Parse the alternative hash options which may be used instead of + the algo number. */ + if (has_option_name (line, "--hash")) + { + if (has_option (line, "--hash=sha1")) + algo = GCRY_MD_SHA1; + else if (has_option (line, "--hash=sha224")) + algo = GCRY_MD_SHA224; + else if (has_option (line, "--hash=sha256")) + algo = GCRY_MD_SHA256; + else if (has_option (line, "--hash=sha384")) + algo = GCRY_MD_SHA384; + else if (has_option (line, "--hash=sha512")) + algo = GCRY_MD_SHA512; + else if (has_option (line, "--hash=rmd160")) + algo = GCRY_MD_RMD160; + else if (has_option (line, "--hash=md5")) + algo = GCRY_MD_MD5; + else if (has_option (line, "--hash=tls-md5sha1")) + algo = MD_USER_TLS_MD5SHA1; + else + return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm"); + } + else + algo = 0; + + line = skip_options (line); + + if (!algo) + { + /* No hash option has been given: require an algo number instead */ + algo = (int)strtoul (line, &endp, 10); + for (line = endp; *line == ' ' || *line == '\t'; line++) + ; + if (!algo || gcry_md_test_algo (algo)) + return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL); + } + ctrl->digest.algo = algo; + + /* Parse the hash value. */ + n = 0; + rc = parse_hexstring (ctx, line, &n); + if (rc) + return rc; + n /= 2; + if (algo == MD_USER_TLS_MD5SHA1 && n == 36) + ; + else if (n != 16 && n != 20 && n != 24 + && n != 28 && n != 32 && n != 48 && n != 64) + return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash"); + + if (n > MAX_DIGEST_LEN) + return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long"); + + buf = ctrl->digest.value; + ctrl->digest.valuelen = n; + for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++) + buf[n] = xtoi_2 (p); + for (; n < ctrl->digest.valuelen; n++) + buf[n] = 0; + return 0; +} + + +static const char hlp_pksign[] = + "PKSIGN [options]\n" + "\n" + "Perform the actual sign operation. Neither input nor output are\n" + "sensitive to eavesdropping."; +static gpg_error_t +cmd_pksign (assuan_context_t ctx, char *line) +{ + int rc; + cache_mode_t cache_mode = CACHE_MODE_NORMAL; + ctrl_t ctrl = assuan_get_pointer (ctx); + membuf_t outbuf; + + (void)line; + + if (opt.ignore_cache_for_signing) + cache_mode = CACHE_MODE_IGNORE; + else if (!ctrl->server_local->use_cache_for_signing) + cache_mode = CACHE_MODE_IGNORE; + + init_membuf (&outbuf, 512); + + rc = agent_pksign (ctrl, ctrl->server_local->keydesc, + &outbuf, cache_mode); + if (rc) + clear_outbuf (&outbuf); + else + rc = write_and_clear_outbuf (ctx, &outbuf); + if (rc) + log_error ("command pksign failed: %s\n", gpg_strerror (rc)); + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; + return rc; +} + + +static const char hlp_pkdecrypt[] = + "PKDECRYPT \n" + "\n" + "Perform the actual decrypt operation. Input is not\n" + "sensitive to eavesdropping."; +static gpg_error_t +cmd_pkdecrypt (assuan_context_t ctx, char *line) +{ + int rc; + ctrl_t ctrl = assuan_get_pointer (ctx); + unsigned char *value; + size_t valuelen; + membuf_t outbuf; + + (void)line; + + /* First inquire the data to decrypt */ + rc = assuan_inquire (ctx, "CIPHERTEXT", + &value, &valuelen, MAXLEN_CIPHERTEXT); + if (rc) + return rc; + + init_membuf (&outbuf, 512); + + rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc, + value, valuelen, &outbuf); + xfree (value); + if (rc) + clear_outbuf (&outbuf); + else + rc = write_and_clear_outbuf (ctx, &outbuf); + if (rc) + log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc)); + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; + return rc; +} + + +static const char hlp_genkey[] = + "GENKEY\n" + "\n" + "Generate a new key, store the secret part and return the public\n" + "part. Here is an example transaction:\n" + "\n" + " C: GENKEY\n" + " S: INQUIRE KEYPARAM\n" + " C: D (genkey (rsa (nbits 1024)))\n" + " C: END\n" + " S: D (public-key\n" + " S: D (rsa (n 326487324683264) (e 10001)))\n" + " S: OK key created\n" + "\n"; +static gpg_error_t +cmd_genkey (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + unsigned char *value; + size_t valuelen; + membuf_t outbuf; + + (void)line; + + /* First inquire the parameters */ + rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM); + if (rc) + return rc; + + init_membuf (&outbuf, 512); + + rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf); + xfree (value); + if (rc) + clear_outbuf (&outbuf); + else + rc = write_and_clear_outbuf (ctx, &outbuf); + if (rc) + log_error ("command genkey failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + + +static const char hlp_readkey[] = + "READKEY \n" + "\n" + "Return the public key for the given keygrip."; +static gpg_error_t +cmd_readkey (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + unsigned char grip[20]; + gcry_sexp_t s_pkey = NULL; + + rc = parse_keygrip (ctx, line, grip); + if (rc) + return rc; /* Return immediately as this is already an Assuan error code.*/ + + rc = agent_public_key_from_file (ctrl, grip, &s_pkey); + if (!rc) + { + size_t len; + unsigned char *buf; + + len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = xtrymalloc (len); + if (!buf) + rc = gpg_error_from_syserror (); + else + { + len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + rc = assuan_send_data (ctx, buf, len); + xfree (buf); + } + gcry_sexp_release (s_pkey); + } + + if (rc) + log_error ("command readkey failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + +static const char hlp_keyinfo[] = + "KEYINFO [--list] [--data] [--ssh-fpr] \n" + "\n" + "Return information about the key specified by the KEYGRIP. If the\n" + "key is not available GPG_ERR_NOT_FOUND is returned. If the option\n" + "--list is given the keygrip is ignored and information about all\n" + "available keys are returned. The information is returned as a\n" + "status line unless --data was specified, with this format:\n" + "\n" + " KEYINFO - - \n" + "\n" + "KEYGRIP is the keygrip.\n" + "\n" + "TYPE is describes the type of the key:\n" + " 'D' - Regular key stored on disk,\n" + " 'T' - Key is stored on a smartcard (token).\n" + " '-' - Unknown type.\n" + "\n" + "SERIALNO is an ASCII string with the serial number of the\n" + " smartcard. If the serial number is not known a single\n" + " dash '-' is used instead.\n" + "\n" + "IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n" + " is not known a dash is used instead.\n" + "\n" + "FPR returns the formatted ssh-style fingerprint of the key. It is only\n" + " print if the option --ssh-fpr has been used. '-' is printed if the\n" + " fingerprint is not available.\n" + "\n" + "More information may be added in the future."; +static gpg_error_t +do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, + int data, int with_ssh_fpr) +{ + gpg_error_t err; + char hexgrip[40+1]; + char *fpr = NULL; + int keytype; + unsigned char *shadow_info = NULL; + char *serialno = NULL; + char *idstr = NULL; + const char *keytypestr; + + err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info); + if (err) + goto leave; + + /* Reformat the grip so that we use uppercase as good style. */ + bin2hex (grip, 20, hexgrip); + + if (keytype == PRIVATE_KEY_CLEAR + || keytype == PRIVATE_KEY_PROTECTED) + keytypestr = "D"; + else if (keytype == PRIVATE_KEY_SHADOWED) + keytypestr = "T"; + else + keytypestr = "-"; + + /* Compute the ssh fingerprint if requested. */ + if (with_ssh_fpr) + { + gcry_sexp_t key; + + if (!agent_raw_key_from_file (ctrl, grip, &key)) + { + ssh_get_fingerprint_string (key, &fpr); + gcry_sexp_release (key); + } + } + + if (shadow_info) + { + err = parse_shadow_info (shadow_info, &serialno, &idstr); + if (err) + goto leave; + } + + /* Note that we don't support the CACHED and PROTECTION values as + gnupg 2.1 does. We print '-' instead. However we support the + ssh fingerprint. */ + if (!data) + err = agent_write_status (ctrl, "KEYINFO", + hexgrip, + keytypestr, + serialno? serialno : "-", + idstr? idstr : "-", + "-", + "-", + fpr? fpr : "-", + NULL); + else + { + char *string; + + string = xtryasprintf ("%s %s %s %s - - %s\n", + hexgrip, keytypestr, + serialno? serialno : "-", + idstr? idstr : "-", + fpr? fpr : "-"); + if (!string) + err = gpg_error_from_syserror (); + else + err = assuan_send_data (ctx, string, strlen(string)); + xfree (string); + } + + leave: + xfree (fpr); + xfree (shadow_info); + xfree (serialno); + xfree (idstr); + return err; +} + + +static gpg_error_t +cmd_keyinfo (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int err; + unsigned char grip[20]; + DIR *dir = NULL; + int list_mode; + int opt_data, opt_ssh_fpr; + + list_mode = has_option (line, "--list"); + opt_data = has_option (line, "--data"); + opt_ssh_fpr = has_option (line, "--ssh-fpr"); + line = skip_options (line); + + if (list_mode) + { + char *dirname; + struct dirent *dir_entry; + char hexgrip[41]; + + dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL); + if (!dirname) + { + err = gpg_error_from_syserror (); + goto leave; + } + dir = opendir (dirname); + if (!dir) + { + err = gpg_error_from_syserror (); + xfree (dirname); + goto leave; + } + xfree (dirname); + + while ( (dir_entry = readdir (dir)) ) + { + if (strlen (dir_entry->d_name) != 44 + || strcmp (dir_entry->d_name + 40, ".key")) + continue; + strncpy (hexgrip, dir_entry->d_name, 40); + hexgrip[40] = 0; + + if ( hex2bin (hexgrip, grip, 20) < 0 ) + continue; /* Bad hex string. */ + + err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr); + if (err) + goto leave; + } + err = 0; + } + else + { + err = parse_keygrip (ctx, line, grip); + if (err) + goto leave; + err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr); + } + + leave: + if (dir) + closedir (dir); + if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) + log_error ("command keyinfo failed: %s\n", gpg_strerror (err)); + return err; +} + + + +static int +send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw) +{ + size_t n; + int rc; + + assuan_begin_confidential (ctx); + n = strlen (pw); + if (via_data) + rc = assuan_send_data (ctx, pw, n); + else + { + char *p = xtrymalloc_secure (n*2+1); + if (!p) + rc = gpg_error_from_syserror (); + else + { + bin2hex (pw, n, p); + rc = assuan_set_okay_line (ctx, p); + xfree (p); + } + } + return rc; +} + + +static const char hlp_get_passphrase[] = + "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n" + " [--qualitybar] \n" + " [ ]\n" + "\n" + "This function is usually used to ask for a passphrase to be used\n" + "for conventional encryption, but may also be used by programs which\n" + "need specal handling of passphrases. This command uses a syntax\n" + "which helps clients to use the agent with minimum effort. The\n" + "agent either returns with an error or with a OK followed by the hex\n" + "encoded passphrase. Note that the length of the strings is\n" + "implicitly limited by the maximum length of a command.\n" + "\n" + "If the option \"--data\" is used the passphrase is returned by usual\n" + "data lines and not on the okay line.\n" + "\n" + "If the option \"--check\" is used the passphrase constraints checks as\n" + "implemented by gpg-agent are applied. A check is not done if the\n" + "passphrase has been found in the cache.\n" + "\n" + "If the option \"--no-ask\" is used and the passphrase is not in the\n" + "cache the user will not be asked to enter a passphrase but the error\n" + "code GPG_ERR_NO_DATA is returned. \n" + "\n" + "If the option \"--qualitybar\" is used a visual indication of the\n" + "entered passphrase quality is shown. (Unless no minimum passphrase\n" + "length has been configured.)"; +static gpg_error_t +cmd_get_passphrase (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + const char *pw; + char *response; + char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL; + const char *desc2 = _("Please re-enter this passphrase"); + char *p; + void *cache_marker; + int opt_data, opt_check, opt_no_ask, opt_qualbar; + int opt_repeat = 0; + char *repeat_errtext = NULL; + + opt_data = has_option (line, "--data"); + opt_check = has_option (line, "--check"); + opt_no_ask = has_option (line, "--no-ask"); + if (has_option_name (line, "--repeat")) + { + p = option_value (line, "--repeat"); + if (p) + opt_repeat = atoi (p); + else + opt_repeat = 1; + } + opt_qualbar = has_option (line, "--qualitybar"); + line = skip_options (line); + + cacheid = line; + p = strchr (cacheid, ' '); + if (p) + { + *p++ = 0; + while (*p == ' ') + p++; + errtext = p; + p = strchr (errtext, ' '); + if (p) + { + *p++ = 0; + while (*p == ' ') + p++; + prompt = p; + p = strchr (prompt, ' '); + if (p) + { + *p++ = 0; + while (*p == ' ') + p++; + desc = p; + p = strchr (desc, ' '); + if (p) + *p = 0; /* Ignore trailing garbage. */ + } + } + } + if (!cacheid || !*cacheid || strlen (cacheid) > 50) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); + if (!desc) + return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); + + if (!strcmp (cacheid, "X")) + cacheid = NULL; + if (!strcmp (errtext, "X")) + errtext = NULL; + if (!strcmp (prompt, "X")) + prompt = NULL; + if (!strcmp (desc, "X")) + desc = NULL; + + pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker) + : NULL; + if (pw) + { + rc = send_back_passphrase (ctx, opt_data, pw); + agent_unlock_cache_entry (&cache_marker); + } + else if (opt_no_ask) + rc = gpg_error (GPG_ERR_NO_DATA); + else + { + /* Note, that we only need to replace the + characters and + should leave the other escaping in place because the escaped + string is send verbatim to the pinentry which does the + unescaping (but not the + replacing) */ + if (errtext) + plus_to_blank (errtext); + if (prompt) + plus_to_blank (prompt); + if (desc) + plus_to_blank (desc); + + next_try: + rc = agent_get_passphrase (ctrl, &response, desc, prompt, + repeat_errtext? repeat_errtext:errtext, + opt_qualbar); + xfree (repeat_errtext); + repeat_errtext = NULL; + if (!rc) + { + int i; + + if (opt_check && check_passphrase_constraints (ctrl, response, 0)) + { + xfree (response); + goto next_try; + } + for (i = 0; i < opt_repeat; i++) + { + char *response2; + + rc = agent_get_passphrase (ctrl, &response2, desc2, prompt, + errtext, 0); + if (rc) + break; + if (strcmp (response2, response)) + { + xfree (response2); + xfree (response); + repeat_errtext = try_percent_escape + (_("does not match - try again"), NULL); + if (!repeat_errtext) + { + rc = gpg_error_from_syserror (); + break; + } + goto next_try; + } + xfree (response2); + } + if (!rc) + { + if (cacheid) + agent_put_cache (cacheid, CACHE_MODE_USER, response, 0); + rc = send_back_passphrase (ctx, opt_data, response); + } + xfree (response); + } + } + + if (rc) + log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc)); + return rc; +} + + +static const char hlp_clear_passphrase[] = + "CLEAR_PASSPHRASE \n" + "\n" + "may be used to invalidate the cache entry for a passphrase. The\n" + "function returns with OK even when there is no cached passphrase."; +static gpg_error_t +cmd_clear_passphrase (assuan_context_t ctx, char *line) +{ + char *cacheid = NULL; + char *p; + + /* parse the stuff */ + for (p=line; *p == ' '; p++) + ; + cacheid = p; + p = strchr (cacheid, ' '); + if (p) + *p = 0; /* ignore garbage */ + if (!cacheid || !*cacheid || strlen (cacheid) > 50) + return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); + + agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0); + return 0; +} + + +static const char hlp_get_confirmation[] = + "GET_CONFIRMATION \n" + "\n" + "This command may be used to ask for a simple confirmation.\n" + "DESCRIPTION is displayed along with a Okay and Cancel button. This\n" + "command uses a syntax which helps clients to use the agent with\n" + "minimum effort. The agent either returns with an error or with a\n" + "OK. Note, that the length of DESCRIPTION is implicitly limited by\n" + "the maximum length of a command. DESCRIPTION should not contain\n" + "any spaces, those must be encoded either percent escaped or simply\n" + "as '+'."; +static gpg_error_t +cmd_get_confirmation (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + char *desc = NULL; + char *p; + + /* parse the stuff */ + for (p=line; *p == ' '; p++) + ; + desc = p; + p = strchr (desc, ' '); + if (p) + *p = 0; /* We ignore any garbage -may be later used for other args. */ + + if (!desc || !*desc) + return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); + + if (!strcmp (desc, "X")) + desc = NULL; + + /* Note, that we only need to replace the + characters and should + leave the other escaping in place because the escaped string is + send verbatim to the pinentry which does the unescaping (but not + the + replacing) */ + if (desc) + plus_to_blank (desc); + + rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0); + if (rc) + log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + +static const char hlp_learn[] = + "LEARN [--send]\n" + "\n" + "Learn something about the currently inserted smartcard. With\n" + "--send the new certificates are send back."; +static gpg_error_t +cmd_learn (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + + rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL); + if (rc) + log_error ("command learn failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + +static const char hlp_passwd[] = + "PASSWD \n" + "\n" + "Change the passphrase/PIN for the key identified by keygrip in LINE."; +static gpg_error_t +cmd_passwd (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + unsigned char grip[20]; + gcry_sexp_t s_skey = NULL; + unsigned char *shadow_info = NULL; + + rc = parse_keygrip (ctx, line, grip); + if (rc) + goto leave; + + ctrl->in_passwd++; + rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc, + grip, &shadow_info, CACHE_MODE_IGNORE, NULL, + &s_skey); + if (rc) + ; + else if (!s_skey) + { + log_error ("changing a smartcard PIN is not yet supported\n"); + rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + else + rc = agent_protect_and_store (ctrl, s_skey); + ctrl->in_passwd--; + + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; + + leave: + gcry_sexp_release (s_skey); + xfree (shadow_info); + if (rc) + log_error ("command passwd failed: %s\n", gpg_strerror (rc)); + return rc; +} + + +static const char hlp_preset_passphrase[] = + "PRESET_PASSPHRASE \n" + "\n" + "Set the cached passphrase/PIN for the key identified by the keygrip\n" + "to passwd for the given time, where -1 means infinite and 0 means\n" + "the default (currently only a timeout of -1 is allowed, which means\n" + "to never expire it). If passwd is not provided, ask for it via the\n" + "pinentry module."; +static gpg_error_t +cmd_preset_passphrase (assuan_context_t ctx, char *line) +{ + int rc; + char *grip_clear = NULL; + char *passphrase = NULL; + int ttl; + size_t len; + + if (!opt.allow_preset_passphrase) + return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase"); + + grip_clear = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + return gpg_error (GPG_ERR_MISSING_VALUE); + *line = '\0'; + line++; + while (*line && (*line == ' ' || *line == '\t')) + line++; + + /* Currently, only infinite timeouts are allowed. */ + ttl = -1; + if (line[0] != '-' || line[1] != '1') + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + line++; + line++; + while (!(*line != ' ' && *line != '\t')) + line++; + + /* Syntax check the hexstring. */ + len = 0; + rc = parse_hexstring (ctx, line, &len); + if (rc) + return rc; + line[len] = '\0'; + + /* If there is a passphrase, use it. Currently, a passphrase is + required. */ + if (*line) + { + /* Do in-place conversion. */ + passphrase = line; + if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL)) + rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring"); + } + else + rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required"); + + if (!rc) + rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); + + if (rc) + log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc)); + + return rc; +} + + + +static const char hlp_scd[] = + "SCD \n" + " \n" + "This is a general quote command to redirect everything to the\n" + "SCdaemon."; +static gpg_error_t +cmd_scd (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + + rc = divert_generic_cmd (ctrl, line, ctx); + + return rc; +} + + + +static const char hlp_getval[] = + "GETVAL \n" + "\n" + "Return the value for KEY from the special environment as created by\n" + "PUTVAL."; +static gpg_error_t +cmd_getval (assuan_context_t ctx, char *line) +{ + int rc = 0; + char *key = NULL; + char *p; + struct putval_item_s *vl; + + for (p=line; *p == ' '; p++) + ; + key = p; + p = strchr (key, ' '); + if (p) + { + *p++ = 0; + for (; *p == ' '; p++) + ; + if (*p) + return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments"); + } + if (!key || !*key) + return set_error (GPG_ERR_ASS_PARAMETER, "no key given"); + + + for (vl=putval_list; vl; vl = vl->next) + if ( !strcmp (vl->d, key) ) + break; + + if (vl) /* Got an entry. */ + rc = assuan_send_data (ctx, vl->d+vl->off, vl->len); + else + return gpg_error (GPG_ERR_NO_DATA); + + if (rc) + log_error ("command getval failed: %s\n", gpg_strerror (rc)); + return rc; +} + + +static const char hlp_putval[] = + "PUTVAL []\n" + "\n" + "The gpg-agent maintains a kind of environment which may be used to\n" + "store key/value pairs in it, so that they can be retrieved later.\n" + "This may be used by helper daemons to daemonize themself on\n" + "invocation and register them with gpg-agent. Callers of the\n" + "daemon's service may now first try connect to get the information\n" + "for that service from gpg-agent through the GETVAL command and then\n" + "try to connect to that daemon. Only if that fails they may start\n" + "an own instance of the service daemon. \n" + "\n" + "KEY is an an arbitrary symbol with the same syntax rules as keys\n" + "for shell environment variables. PERCENT_ESCAPED_VALUE is the\n" + "corresponsing value; they should be similar to the values of\n" + "envronment variables but gpg-agent does not enforce any\n" + "restrictions. If that value is not given any value under that KEY\n" + "is removed from this special environment."; +static gpg_error_t +cmd_putval (assuan_context_t ctx, char *line) +{ + int rc = 0; + char *key = NULL; + char *value = NULL; + size_t valuelen = 0; + char *p; + struct putval_item_s *vl, *vlprev; + + for (p=line; *p == ' '; p++) + ; + key = p; + p = strchr (key, ' '); + if (p) + { + *p++ = 0; + for (; *p == ' '; p++) + ; + if (*p) + { + value = p; + p = strchr (value, ' '); + if (p) + *p = 0; + valuelen = percent_plus_unescape_inplace (value, 0); + } + } + if (!key || !*key) + return set_error (GPG_ERR_ASS_PARAMETER, "no key given"); + + + for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next) + if ( !strcmp (vl->d, key) ) + break; + + if (vl) /* Delete old entry. */ + { + if (vlprev) + vlprev->next = vl->next; + else + putval_list = vl->next; + xfree (vl); + } + + if (valuelen) /* Add entry. */ + { + vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen); + if (!vl) + rc = gpg_error_from_syserror (); + else + { + vl->len = valuelen; + vl->off = strlen (key) + 1; + strcpy (vl->d, key); + memcpy (vl->d + vl->off, value, valuelen); + vl->next = putval_list; + putval_list = vl; + } + } + + if (rc) + log_error ("command putval failed: %s\n", gpg_strerror (rc)); + return rc; +} + + + + +static const char hlp_updatestartuptty[] = + "UPDATESTARTUPTTY\n" + "\n" + "Set startup TTY and X11 DISPLAY variables to the values of this\n" + "session. This command is useful to pull future pinentries to\n" + "another screen. It is only required because there is no way in the\n" + "ssh-agent protocol to convey this information."; +static gpg_error_t +cmd_updatestartuptty (assuan_context_t ctx, char *line) +{ + static const char *names[] = + { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL }; + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + session_env_t se; + int idx; + char *lc_ctype = NULL; + char *lc_messages = NULL; + + (void)line; + + se = session_env_new (); + if (!se) + err = gpg_error_from_syserror (); + + for (idx=0; !err && names[idx]; idx++) + { + const char *value = session_env_getenv (ctrl->session_env, names[idx]); + if (value) + err = session_env_setenv (se, names[idx], value); + } + + if (!err && ctrl->lc_ctype) + if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype))) + err = gpg_error_from_syserror (); + + if (!err && ctrl->lc_messages) + if (!(lc_messages = xtrystrdup (ctrl->lc_messages))) + err = gpg_error_from_syserror (); + + if (err) + { + session_env_release (se); + xfree (lc_ctype); + xfree (lc_messages); + } + else + { + session_env_release (opt.startup_env); + opt.startup_env = se; + xfree (opt.startup_lc_ctype); + opt.startup_lc_ctype = lc_ctype; + xfree (opt.startup_lc_messages); + opt.startup_lc_messages = lc_messages; + } + + return err; +} + + + +static const char hlp_killagent[] = + "KILLAGENT\n" + "\n" + "If the agent has been started using a standard socket\n" + "we allow a client to stop the agent."; +static gpg_error_t +cmd_killagent (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + + (void)line; + + if (!opt.use_standard_socket) + return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket"); + + ctrl->server_local->stopme = 1; + return gpg_error (GPG_ERR_EOF); +} + + +static const char hlp_reloadagent[] = + "RELOADAGENT\n" + "\n" + "This command is an alternative to SIGHUP\n" + "to reload the configuration."; +static gpg_error_t +cmd_reloadagent (assuan_context_t ctx, char *line) +{ + (void)ctx; + (void)line; + + agent_sighup_action (); + return 0; +} + + + +static const char hlp_getinfo[] = + "GETINFO \n" + "\n" + "Multipurpose function to return a variety of information.\n" + "Supported values for WHAT are:\n" + "\n" + " version - Return the version of the program.\n" + " pid - Return the process id of the server.\n" + " socket_name - Return the name of the socket.\n" + " ssh_socket_name - Return the name of the ssh socket.\n" + " scd_running - Return OK if the SCdaemon is already running.\n" + " std_session_env - List the standard session environment.\n" + " std_startup_env - List the standard startup environment.\n" + " cmd_has_option\n" + " - Returns OK if the command CMD implements the option OPT."; +static gpg_error_t +cmd_getinfo (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc = 0; + + if (!strcmp (line, "version")) + { + const char *s = VERSION; + rc = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "pid")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else if (!strcmp (line, "socket_name")) + { + const char *s = get_agent_socket_name (); + + if (s) + rc = assuan_send_data (ctx, s, strlen (s)); + else + rc = gpg_error (GPG_ERR_NO_DATA); + } + else if (!strcmp (line, "ssh_socket_name")) + { + const char *s = get_agent_ssh_socket_name (); + + if (s) + rc = assuan_send_data (ctx, s, strlen (s)); + else + rc = gpg_error (GPG_ERR_NO_DATA); + } + else if (!strcmp (line, "scd_running")) + { + rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL); + } + else if (!strcmp (line, "s2k_count")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else if (!strcmp (line, "std_session_env") + || !strcmp (line, "std_startup_env")) + { + int iterator; + const char *name, *value; + char *string; + + iterator = 0; + while ((name = session_env_list_stdenvnames (&iterator, NULL))) + { + value = session_env_getenv_or_default + (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL); + if (value) + { + string = xtryasprintf ("%s=%s", name, value); + if (!string) + rc = gpg_error_from_syserror (); + else + { + rc = assuan_send_data (ctx, string, strlen (string)+1); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); + } + if (rc) + break; + } + } + } + else if (!strncmp (line, "cmd_has_option", 14) + && (line[14] == ' ' || line[14] == '\t' || !line[14])) + { + char *cmd, *cmdopt; + line += 14; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmd = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + *line++ = 0; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmdopt = line; + if (!command_has_option (cmd, cmdopt)) + rc = gpg_error (GPG_ERR_GENERAL); + } + } + } + } + else + rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + return rc; +} + + + +static gpg_error_t +option_handler (assuan_context_t ctx, const char *key, const char *value) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + + if (!strcmp (key, "putenv")) + { + /* Change the session's environment to be used for the + Pinentry. Valid values are: + Delete envvar NAME + = Set envvar NAME to the empty string + = Set envvar NAME to VALUE + */ + err = session_env_putenv (ctrl->session_env, value); + } + else if (!strcmp (key, "display")) + { + err = session_env_setenv (ctrl->session_env, "DISPLAY", value); + } + else if (!strcmp (key, "ttyname")) + { + if (!opt.keep_tty) + err = session_env_setenv (ctrl->session_env, "GPG_TTY", value); + } + else if (!strcmp (key, "ttytype")) + { + if (!opt.keep_tty) + err = session_env_setenv (ctrl->session_env, "TERM", value); + } + else if (!strcmp (key, "lc-ctype")) + { + if (ctrl->lc_ctype) + xfree (ctrl->lc_ctype); + ctrl->lc_ctype = xtrystrdup (value); + if (!ctrl->lc_ctype) + return out_of_core (); + } + else if (!strcmp (key, "lc-messages")) + { + if (ctrl->lc_messages) + xfree (ctrl->lc_messages); + ctrl->lc_messages = xtrystrdup (value); + if (!ctrl->lc_messages) + return out_of_core (); + } + else if (!strcmp (key, "xauthority")) + { + err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value); + } + else if (!strcmp (key, "pinentry-user-data")) + { + err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value); + } + else if (!strcmp (key, "use-cache-for-signing")) + ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; + else if (!strcmp (key, "allow-pinentry-notify")) + ctrl->server_local->allow_pinentry_notify = 1; + else + err = gpg_error (GPG_ERR_UNKNOWN_OPTION); + + return err; +} + + + + +/* Called by libassuan after all commands. ERR is the error from the + last assuan operation and not the one returned from the command. */ +static void +post_cmd_notify (assuan_context_t ctx, gpg_error_t err) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + + (void)err; + + /* Switch off any I/O monitor controlled logging pausing. */ + ctrl->server_local->pause_io_logging = 0; +} + + +/* This function is called by libassuan for all I/O. We use it here + to disable logging for the GETEVENTCOUNTER commands. This is so + that the debug output won't get cluttered by this primitive + command. */ +static unsigned int +io_monitor (assuan_context_t ctx, void *hook, int direction, + const char *line, size_t linelen) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + + (void) hook; + + /* Note that we only check for the uppercase name. This allows to + see the logging for debugging if using a non-upercase command + name. */ + if (ctx && direction == ASSUAN_IO_FROM_PEER + && linelen >= 15 + && !strncmp (line, "GETEVENTCOUNTER", 15) + && (linelen == 15 || spacep (line+15))) + { + ctrl->server_local->pause_io_logging = 1; + } + + return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0; +} + + +/* Return true if the command CMD implements the option OPT. */ +static int +command_has_option (const char *cmd, const char *cmdopt) +{ + if (!strcmp (cmd, "GET_PASSPHRASE")) + { + if (!strcmp (cmdopt, "repeat")) + return 1; + } + + return 0; +} + + +/* Tell the assuan library about our commands */ +static int +register_commands (assuan_context_t ctx) +{ + static struct { + const char *name; + assuan_handler_t handler; + const char * const help; + } table[] = { + { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter }, + { "ISTRUSTED", cmd_istrusted, hlp_istrusted }, + { "HAVEKEY", cmd_havekey, hlp_havekey }, + { "KEYINFO", cmd_keyinfo, hlp_keyinfo }, + { "SIGKEY", cmd_sigkey, hlp_sigkey }, + { "SETKEY", cmd_sigkey, hlp_sigkey }, + { "SETKEYDESC", cmd_setkeydesc,hlp_setkeydesc }, + { "SETHASH", cmd_sethash, hlp_sethash }, + { "PKSIGN", cmd_pksign, hlp_pksign }, + { "PKDECRYPT", cmd_pkdecrypt, hlp_pkdecrypt }, + { "GENKEY", cmd_genkey, hlp_genkey }, + { "READKEY", cmd_readkey, hlp_readkey }, + { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase }, + { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase }, + { "CLEAR_PASSPHRASE", cmd_clear_passphrase, hlp_clear_passphrase }, + { "GET_CONFIRMATION", cmd_get_confirmation, hlp_get_confirmation }, + { "LISTTRUSTED", cmd_listtrusted, hlp_listtrusted }, + { "MARKTRUSTED", cmd_marktrusted, hlp_martrusted }, + { "LEARN", cmd_learn, hlp_learn }, + { "PASSWD", cmd_passwd, hlp_passwd }, + { "INPUT", NULL }, + { "OUTPUT", NULL }, + { "SCD", cmd_scd, hlp_scd }, + { "GETVAL", cmd_getval, hlp_getval }, + { "PUTVAL", cmd_putval, hlp_putval }, + { "UPDATESTARTUPTTY", cmd_updatestartuptty, hlp_updatestartuptty }, + { "KILLAGENT", cmd_killagent, hlp_killagent }, + { "RELOADAGENT", cmd_reloadagent,hlp_reloadagent }, + { "GETINFO", cmd_getinfo, hlp_getinfo }, + { NULL } + }; + int i, rc; + + for (i=0; table[i].name; i++) + { + rc = assuan_register_command (ctx, table[i].name, table[i].handler, + table[i].help); + if (rc) + return rc; + } + assuan_register_post_cmd_notify (ctx, post_cmd_notify); + assuan_register_reset_notify (ctx, reset_notify); + assuan_register_option_handler (ctx, option_handler); + return 0; +} + + +/* Startup the server. If LISTEN_FD and FD is given as -1, this is a + simple piper server, otherwise it is a regular server. CTRL is the + control structure for this connection; it has only the basic + intialization. */ +void +start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) +{ + int rc; + assuan_context_t ctx = NULL; + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc)); + agent_exit (2); + } + + if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD) + { + assuan_fd_t filedes[2]; + + filedes[0] = assuan_fdopen (0); + filedes[1] = assuan_fdopen (1); + rc = assuan_init_pipe_server (ctx, filedes); + } + else if (listen_fd != GNUPG_INVALID_FD) + { + rc = assuan_init_socket_server (ctx, listen_fd, 0); + /* FIXME: Need to call assuan_sock_set_nonce for Windows. But + this branch is currently not used. */ + } + else + { + rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED); + } + if (rc) + { + log_error ("failed to initialize the server: %s\n", + gpg_strerror(rc)); + agent_exit (2); + } + rc = register_commands (ctx); + if (rc) + { + log_error ("failed to register commands with Assuan: %s\n", + gpg_strerror(rc)); + agent_exit (2); + } + + 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->use_cache_for_signing = 1; + ctrl->digest.raw_value = 0; + + assuan_set_io_monitor (ctx, io_monitor, NULL); + + for (;;) + { + rc = assuan_accept (ctx); + if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1) + { + break; + } + else if (rc) + { + log_info ("Assuan accept problem: %s\n", gpg_strerror (rc)); + break; + } + + rc = assuan_process (ctx); + if (rc) + { + log_info ("Assuan processing failed: %s\n", gpg_strerror (rc)); + continue; + } + } + + /* Reset the SCD if needed. */ + agent_reset_scd (ctrl); + + /* Reset the pinentry (in case of popup messages). */ + agent_reset_query (ctrl); + + /* Cleanup. */ + assuan_release (ctx); + if (ctrl->server_local->stopme) + agent_exit (0); + xfree (ctrl->server_local); + ctrl->server_local = NULL; +} + diff --git a/agent/divert-scd.c b/agent/divert-scd.c new file mode 100644 index 0000000..bf07d07 --- /dev/null +++ b/agent/divert-scd.c @@ -0,0 +1,451 @@ +/* divert-scd.c - divert operations to the scdaemon + * Copyright (C) 2002, 2003, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include "i18n.h" +#include "sexp-parse.h" + + +static int +ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid) +{ + int rc, i; + char *serialno; + int no_card = 0; + char *desc; + char *want_sn, *want_kid; + int want_sn_displen; + + *r_kid = NULL; + + rc = parse_shadow_info (shadow_info, &want_sn, &want_kid); + if (rc) + return rc; + + /* We assume that a 20 byte serial number is a standard one which + has the property to have a zero in the last nibble (Due to BCD + representation). We don't display this '0' because it may + confuse the user. */ + want_sn_displen = strlen (want_sn); + if (want_sn_displen == 20 && want_sn[19] == '0') + want_sn_displen--; + + for (;;) + { + rc = agent_card_serialno (ctrl, &serialno); + if (!rc) + { + log_debug ("detected card with S/N %s\n", serialno); + i = strcmp (serialno, want_sn); + xfree (serialno); + serialno = NULL; + if (!i) + { + xfree (want_sn); + *r_kid = want_kid; + return 0; /* yes, we have the correct card */ + } + } + else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT) + { + log_debug ("no card present\n"); + rc = 0; + no_card = 1; + } + else + { + log_error ("error accessing card: %s\n", gpg_strerror (rc)); + } + + if (!rc) + { + if (asprintf (&desc, + "%s:%%0A%%0A" + " \"%.*s\"", + no_card + ? _("Please insert the card with serial number") + : _("Please remove the current card and " + "insert the one with serial number"), + want_sn_displen, want_sn) < 0) + { + rc = out_of_core (); + } + else + { + rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0); + xfree (desc); + } + } + if (rc) + { + xfree (want_sn); + xfree (want_kid); + return rc; + } + } +} + + +/* Put the DIGEST into an DER encoded container and return it in R_VAL. */ +static int +encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, + unsigned char **r_val, size_t *r_len) +{ + unsigned char *frame; + unsigned char asn[100]; + size_t asnlen; + + *r_val = NULL; + *r_len = 0; + + asnlen = DIM(asn); + if (!algo || gcry_md_test_algo (algo)) + return gpg_error (GPG_ERR_DIGEST_ALGO); + 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); + } + + frame = xtrymalloc (asnlen + digestlen); + if (!frame) + return out_of_core (); + memcpy (frame, asn, asnlen); + memcpy (frame+asnlen, digest, digestlen); + if (DBG_CRYPTO) + log_printhex ("encoded hash:", frame, asnlen+digestlen); + + *r_val = frame; + *r_len = asnlen+digestlen; + return 0; +} + + +/* Callback used to ask for the PIN which should be set into BUF. The + buf has been allocated by the caller and is of size MAXBUF which + includes the terminating null. The function should return an UTF-8 + string with the passphrase, the buffer may optionally be padded + with arbitrary characters. + + INFO gets displayed as part of a generic string. However if the + first character of INFO is a vertical bar all up to the next + verical bar are considered flags and only everything after the + second vertical bar gets displayed as the full prompt. + + Flags: + + 'N' = New PIN, this requests a second prompt to repeat the + PIN. If the PIN is not correctly repeated it starts from + all over. + 'A' = The PIN is an Admin PIN, SO-PIN or alike. + 'P' = The PIN is a PUK (Personal Unblocking Key). + 'R' = The PIN is a Reset Code. + + Example: + + "|AN|Please enter the new security officer's PIN" + + The text "Please ..." will get displayed and the flags 'A' and 'N' + are considered. + */ +static int +getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) +{ + struct pin_entry_info_s *pi; + int rc; + ctrl_t ctrl = opaque; + const char *ends, *s; + int any_flags = 0; + int newpin = 0; + int resetcode = 0; + int is_puk = 0; + const char *again_text = NULL; + const char *prompt = "PIN"; + + if (buf && maxbuf < 2) + return gpg_error (GPG_ERR_INV_VALUE); + + /* Parse the flags. */ + if (info && *info =='|' && (ends=strchr (info+1, '|'))) + { + for (s=info+1; s < ends; s++) + { + if (*s == 'A') + prompt = _("Admin PIN"); + else if (*s == 'P') + { + /* TRANSLATORS: A PUK is the Personal Unblocking Code + used to unblock a PIN. */ + prompt = _("PUK"); + is_puk = 1; + } + else if (*s == 'N') + newpin = 1; + else if (*s == 'R') + { + prompt = _("Reset Code"); + resetcode = 1; + } + } + info = ends+1; + any_flags = 1; + } + else if (info && *info == '|') + log_debug ("pin_cb called without proper PIN info hack\n"); + + /* If BUF has been passed as NULL, we are in keypad mode: The + callback opens the popup and immediatley returns. */ + if (!buf) + { + if (maxbuf == 0) /* Close the pinentry. */ + { + agent_popup_message_stop (ctrl); + rc = 0; + } + else if (maxbuf == 1) /* Open the pinentry. */ + { + if (info) + { + char *desc; + + if ( asprintf (&desc, + _("%s%%0A%%0AUse the reader's keypad for input."), + info) < 0 ) + rc = gpg_error_from_syserror (); + else + { + rc = agent_popup_message_start (ctrl, desc, NULL); + xfree (desc); + } + } + else + rc = agent_popup_message_start (ctrl, NULL, NULL); + } + else + rc = gpg_error (GPG_ERR_INV_VALUE); + return rc; + } + + /* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole + mess because we should call the card's verify function from the + pinentry check pin CB. */ + again: + pi = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10); + if (!pi) + return gpg_error_from_syserror (); + pi->max_length = maxbuf-1; + pi->min_digits = 0; /* we want a real passphrase */ + pi->max_digits = 16; + pi->max_tries = 3; + + if (any_flags) + { + rc = agent_askpin (ctrl, info, prompt, again_text, pi); + again_text = NULL; + if (!rc && newpin) + { + struct pin_entry_info_s *pi2; + pi2 = gcry_calloc_secure (1, sizeof (*pi) + maxbuf + 10); + if (!pi2) + { + rc = gpg_error_from_syserror (); + xfree (pi); + return rc; + } + pi2->max_length = maxbuf-1; + pi2->min_digits = 0; + pi2->max_digits = 16; + pi2->max_tries = 1; + rc = agent_askpin (ctrl, + (resetcode? + _("Repeat this Reset Code"): + is_puk? + _("Repeat this PUK"): + _("Repeat this PIN")), + prompt, NULL, pi2); + if (!rc && strcmp (pi->pin, pi2->pin)) + { + again_text = (resetcode? + N_("Reset Code not correctly repeated; try again"): + is_puk? + N_("PUK not correctly repeated; try again"): + N_("PIN not correctly repeated; try again")); + xfree (pi2); + xfree (pi); + goto again; + } + xfree (pi2); + } + } + else + { + char *desc; + if ( asprintf (&desc, + _("Please enter the PIN%s%s%s to unlock the card"), + info? " (`":"", + info? info:"", + info? "')":"") < 0) + desc = NULL; + rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi); + xfree (desc); + } + + if (!rc) + { + strncpy (buf, pi->pin, maxbuf-1); + buf[maxbuf-1] = 0; + } + xfree (pi); + return rc; +} + + + + +int +divert_pksign (ctrl_t ctrl, + const unsigned char *digest, size_t digestlen, int algo, + const unsigned char *shadow_info, unsigned char **r_sig) +{ + int rc; + char *kid; + size_t siglen; + unsigned char *sigval = NULL; + + rc = ask_for_card (ctrl, shadow_info, &kid); + if (rc) + return rc; + + if (algo == MD_USER_TLS_MD5SHA1) + { + int save = ctrl->use_auth_call; + ctrl->use_auth_call = 1; + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + digest, digestlen, &sigval, &siglen); + ctrl->use_auth_call = save; + } + else + { + unsigned char *data; + size_t ndata; + + rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata); + if (!rc) + { + rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, + data, ndata, &sigval, &siglen); + xfree (data); + } + } + + if (!rc) + *r_sig = sigval; + + xfree (kid); + + return rc; +} + + +/* Decrypt the the value given asn an S-expression in CIPHER using the + key identified by SHADOW_INFO and return the plaintext in an + allocated buffer in R_BUF. */ +int +divert_pkdecrypt (ctrl_t ctrl, + const unsigned char *cipher, + const unsigned char *shadow_info, + char **r_buf, size_t *r_len) +{ + int rc; + char *kid; + const unsigned char *s; + size_t n; + const unsigned char *ciphertext; + size_t ciphertextlen; + char *plaintext; + size_t plaintextlen; + + s = cipher; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "enc-val")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "rsa")) + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "a")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + ciphertext = s; + ciphertextlen = n; + + rc = ask_for_card (ctrl, shadow_info, &kid); + if (rc) + return rc; + + rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, + ciphertext, ciphertextlen, + &plaintext, &plaintextlen); + if (!rc) + { + *r_buf = plaintext; + *r_len = plaintextlen; + } + xfree (kid); + return rc; +} + + +int +divert_generic_cmd (ctrl_t ctrl, const char *cmdline, void *assuan_context) +{ + return agent_card_scd (ctrl, cmdline, getpin_cb, ctrl, assuan_context); +} + + + + + diff --git a/agent/findkey.c b/agent/findkey.c new file mode 100644 index 0000000..800db88 --- /dev/null +++ b/agent/findkey.c @@ -0,0 +1,952 @@ +/* findkey.c - Locate the secret key + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, + * 2010, 2011 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* (we use pth_sleep) */ + +#include "agent.h" +#include "i18n.h" +#include "../common/ssh-utils.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* Helper to pass data to the check callback of the unprotect function. */ +struct try_unprotect_arg_s +{ + ctrl_t ctrl; + const unsigned char *protected_key; + unsigned char *unprotected_key; + int change_required; /* Set by the callback to indicate that the + user should chnage the passphrase. */ +}; + + +/* Write an S-expression formatted key to our key storage. With FORCE + passed as true an existing key with the given GRIP will get + overwritten. */ +int +agent_write_private_key (const unsigned char *grip, + const void *buffer, size_t length, int force) +{ + char *fname; + FILE *fp; + char hexgrip[40+4+1]; + int fd; + + bin2hex (grip, 20, hexgrip); + strcpy (hexgrip+40, ".key"); + + fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); + + if (!force && !access (fname, F_OK)) + { + log_error ("secret key file `%s' already exists\n", fname); + xfree (fname); + return gpg_error (GPG_ERR_GENERAL); + } + + /* In FORCE mode we would like to create FNAME but only if it does + not already exist. We cannot make this guarantee just using + POSIX (GNU provides the "x" opentype for fopen, however, this is + not portable). Thus, we use the more flexible open function and + then use fdopen to obtain a stream. */ + fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY | O_BINARY) + : (O_CREAT | O_EXCL | O_WRONLY | O_BINARY), + S_IRUSR | S_IWUSR +#ifndef HAVE_W32_SYSTEM + | S_IRGRP +#endif + ); + if (fd < 0) + fp = NULL; + else + { + fp = fdopen (fd, "wb"); + if (!fp) + { + int save_e = errno; + close (fd); + errno = save_e; + } + } + + if (!fp) + { + gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); + log_error ("can't create `%s': %s\n", fname, strerror (errno)); + xfree (fname); + return tmperr; + } + + if (fwrite (buffer, length, 1, fp) != 1) + { + gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); + log_error ("error writing `%s': %s\n", fname, strerror (errno)); + fclose (fp); + remove (fname); + xfree (fname); + return tmperr; + } + if ( fclose (fp) ) + { + gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); + log_error ("error closing `%s': %s\n", fname, strerror (errno)); + remove (fname); + xfree (fname); + return tmperr; + } + bump_key_eventcounter (); + xfree (fname); + return 0; +} + + +/* Callback function to try the unprotection from the passpharse query + code. */ +static int +try_unprotect_cb (struct pin_entry_info_s *pi) +{ + struct try_unprotect_arg_s *arg = pi->check_cb_arg; + size_t dummy; + gpg_error_t err; + gnupg_isotime_t now, protected_at, tmptime; + char *desc = NULL; + + assert (!arg->unprotected_key); + + arg->change_required = 0; + err = agent_unprotect (arg->protected_key, pi->pin, protected_at, + &arg->unprotected_key, &dummy); + if (err) + return err; + if (!opt.max_passphrase_days || arg->ctrl->in_passwd) + return 0; /* No regular passphrase change required. */ + + if (!*protected_at) + { + /* No protection date known - must force passphrase change. */ + desc = xtrystrdup (_("Note: This passphrase has never been changed.%0A" + "Please change it now.")); + if (!desc) + return gpg_error_from_syserror (); + } + else + { + gnupg_get_isotime (now); + gnupg_copy_time (tmptime, protected_at); + err = add_days_to_isotime (tmptime, opt.max_passphrase_days); + if (err) + return err; + if (strcmp (now, tmptime) > 0 ) + { + /* Passphrase "expired". */ + desc = xtryasprintf + (_("This passphrase has not been changed%%0A" + "since %.4s-%.2s-%.2s. Please change it now."), + protected_at, protected_at+4, protected_at+6); + if (!desc) + return gpg_error_from_syserror (); + } + } + + if (desc) + { + /* Change required. */ + if (opt.enforce_passphrase_constraints) + { + err = agent_get_confirmation (arg->ctrl, desc, + _("Change passphrase"), NULL, 0); + if (!err) + arg->change_required = 1; + } + else + { + err = agent_get_confirmation (arg->ctrl, desc, + _("Change passphrase"), + _("I'll change it later"), 0); + if (!err) + arg->change_required = 1; + else if (gpg_err_code (err) == GPG_ERR_CANCELED) + err = 0; + } + xfree (desc); + } + + return 0; +} + + +/* Modify a Key description, replacing certain special format + characters. List of currently supported replacements: + + %% - Replaced by a single % + %c - Replaced by the content of COMMENT. + %F - Replaced by an ssh style fingerprint computed from KEY. + + The functions returns 0 on success or an error code. On success a + newly allocated string is stored at the address of RESULT. + */ +static gpg_error_t +modify_description (const char *in, const char *comment, const gcry_sexp_t key, + char **result) +{ + size_t comment_length; + size_t in_len; + size_t out_len; + char *out; + size_t i; + int special, pass; + char *ssh_fpr = NULL; + + comment_length = strlen (comment); + in_len = strlen (in); + + /* First pass calculates the length, second pass does the actual + copying. */ + out = NULL; + out_len = 0; + for (pass=0; pass < 2; pass++) + { + special = 0; + for (i = 0; i < in_len; i++) + { + if (special) + { + special = 0; + switch (in[i]) + { + case '%': + if (out) + *out++ = '%'; + else + out_len++; + break; + + case 'c': /* Comment. */ + if (out) + { + memcpy (out, comment, comment_length); + out += comment_length; + } + else + out_len += comment_length; + break; + + case 'F': /* SSH style fingerprint. */ + if (!ssh_fpr && key) + ssh_get_fingerprint_string (key, &ssh_fpr); + if (ssh_fpr) + { + if (out) + out = stpcpy (out, ssh_fpr); + else + out_len += strlen (ssh_fpr); + } + break; + + default: /* Invalid special sequences are kept as they are. */ + if (out) + { + *out++ = '%'; + *out++ = in[i]; + } + else + out_len+=2; + break; + } + } + else if (in[i] == '%') + special = 1; + else + { + if (out) + *out++ = in[i]; + else + out_len++; + } + } + + if (!pass) + { + *result = out = xtrymalloc (out_len + 1); + if (!out) + { + xfree (ssh_fpr); + return gpg_error_from_syserror (); + } + } + } + + *out = 0; + assert (*result + out_len == out); + xfree (ssh_fpr); + return 0; +} + + + +/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP + should be the hex encoded keygrip of that key to be used with the + caching mechanism. DESC_TEXT may be set to override the default + description used for the pinentry. If LOOKUP_TTL is given this + function is used to lookup the default ttl. */ +static int +unprotect (ctrl_t ctrl, const char *desc_text, + unsigned char **keybuf, const unsigned char *grip, + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl) +{ + struct pin_entry_info_s *pi; + struct try_unprotect_arg_s arg; + int rc; + unsigned char *result; + size_t resultlen; + char hexgrip[40+1]; + + bin2hex (grip, 20, hexgrip); + + /* First try to get it from the cache - if there is none or we can't + unprotect it, we fall back to ask the user */ + if (cache_mode != CACHE_MODE_IGNORE) + { + void *cache_marker; + const char *pw; + + retry: + pw = agent_get_cache (hexgrip, cache_mode, &cache_marker); + if (pw) + { + rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen); + agent_unlock_cache_entry (&cache_marker); + if (!rc) + { + xfree (*keybuf); + *keybuf = result; + return 0; + } + rc = 0; + } + + /* If the pinentry is currently in use, we wait up to 60 seconds + for it to close and check the cache again. This solves a common + situation where several requests for unprotecting a key have + been made but the user is still entering the passphrase for + the first request. Because all requests to agent_askpin are + serialized they would then pop up one after the other to + request the passphrase - despite that the user has already + entered it and is then available in the cache. This + implementation is not race free but in the worst case the + user has to enter the passphrase only once more. */ + if (pinentry_active_p (ctrl, 0)) + { + /* Active - wait */ + if (!pinentry_active_p (ctrl, 60)) + { + /* We need to give the other thread a chance to actually put + it into the cache. */ + pth_sleep (1); + goto retry; + } + /* Timeout - better call pinentry now the plain way. */ + } + } + + pi = gcry_calloc_secure (1, sizeof (*pi) + 100); + if (!pi) + return gpg_error_from_syserror (); + pi->max_length = 100; + pi->min_digits = 0; /* we want a real passphrase */ + pi->max_digits = 16; + pi->max_tries = 3; + pi->check_cb = try_unprotect_cb; + arg.ctrl = ctrl; + arg.protected_key = *keybuf; + arg.unprotected_key = NULL; + arg.change_required = 0; + pi->check_cb_arg = &arg; + + rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi); + if (!rc) + { + assert (arg.unprotected_key); + if (arg.change_required) + { + size_t canlen, erroff; + gcry_sexp_t s_skey; + + assert (arg.unprotected_key); + canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL); + rc = gcry_sexp_sscan (&s_skey, &erroff, + (char*)arg.unprotected_key, canlen); + if (rc) + { + log_error ("failed to build S-Exp (off=%u): %s\n", + (unsigned int)erroff, gpg_strerror (rc)); + wipememory (arg.unprotected_key, canlen); + xfree (arg.unprotected_key); + xfree (pi); + return rc; + } + rc = agent_protect_and_store (ctrl, s_skey); + gcry_sexp_release (s_skey); + if (rc) + { + log_error ("changing the passphrase failed: %s\n", + gpg_strerror (rc)); + wipememory (arg.unprotected_key, canlen); + xfree (arg.unprotected_key); + xfree (pi); + return rc; + } + } + else + agent_put_cache (hexgrip, cache_mode, pi->pin, + lookup_ttl? lookup_ttl (hexgrip) : 0); + xfree (*keybuf); + *keybuf = arg.unprotected_key; + } + xfree (pi); + return rc; +} + + +/* Read the key identified by GRIP from the private key directory and + return it as an gcrypt S-expression object in RESULT. On failure + returns an error code and stores NULL at RESULT. */ +static gpg_error_t +read_key_file (const unsigned char *grip, gcry_sexp_t *result) +{ + int rc; + char *fname; + FILE *fp; + struct stat st; + unsigned char *buf; + size_t buflen, erroff; + gcry_sexp_t s_skey; + char hexgrip[40+4+1]; + + *result = NULL; + + bin2hex (grip, 20, hexgrip); + strcpy (hexgrip+40, ".key"); + + fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); + fp = fopen (fname, "rb"); + if (!fp) + { + rc = gpg_error_from_syserror (); + if (gpg_err_code (rc) != GPG_ERR_ENOENT) + log_error ("can't open `%s': %s\n", fname, strerror (errno)); + xfree (fname); + return rc; + } + + if (fstat (fileno(fp), &st)) + { + rc = gpg_error_from_syserror (); + log_error ("can't stat `%s': %s\n", fname, strerror (errno)); + xfree (fname); + fclose (fp); + return rc; + } + + buflen = st.st_size; + buf = xtrymalloc (buflen+1); + if (!buf || fread (buf, buflen, 1, fp) != 1) + { + rc = gpg_error_from_syserror (); + log_error ("error reading `%s': %s\n", fname, strerror (errno)); + xfree (fname); + fclose (fp); + xfree (buf); + return rc; + } + + /* Convert the file into a gcrypt S-expression object. */ + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); + xfree (fname); + fclose (fp); + xfree (buf); + if (rc) + { + log_error ("failed to build S-Exp (off=%u): %s\n", + (unsigned int)erroff, gpg_strerror (rc)); + return rc; + } + *result = s_skey; + return 0; +} + + +/* Return the secret key as an S-Exp in RESULT after locating it using + the GRIP. Stores NULL at RESULT if the operation shall be diverted + to a token; in this case an allocated S-expression with the + shadow_info part from the file is stored at SHADOW_INFO. + CACHE_MODE defines now the cache shall be used. DESC_TEXT may be + set to present a custom description for the pinentry. LOOKUP_TTL + is an optional function to convey a TTL to the cache manager; we do + not simply pass the TTL value because the value is only needed if an + unprotect action was needed and looking up the TTL may have some + overhead (e.g. scanning the sshcontrol file). */ +gpg_error_t +agent_key_from_file (ctrl_t ctrl, const char *desc_text, + const unsigned char *grip, unsigned char **shadow_info, + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl, + gcry_sexp_t *result) +{ + int rc; + unsigned char *buf; + size_t len, buflen, erroff; + gcry_sexp_t s_skey; + int got_shadow_info = 0; + + *result = NULL; + if (shadow_info) + *shadow_info = NULL; + + rc = read_key_file (grip, &s_skey); + if (rc) + return rc; + + /* For use with the protection functions we also need the key as an + canonical encoded S-expression in a buffer. Create this buffer + now. */ + rc = make_canon_sexp (s_skey, &buf, &len); + if (rc) + return rc; + + switch (agent_private_key_type (buf)) + { + case PRIVATE_KEY_CLEAR: + break; /* no unprotection needed */ + case PRIVATE_KEY_PROTECTED: + { + char *desc_text_final; + char *comment = NULL; + + /* Note, that we will take the comment as a C string for + display purposes; i.e. all stuff beyond a Nul character is + ignored. */ + { + gcry_sexp_t comment_sexp; + + comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0); + if (comment_sexp) + comment = gcry_sexp_nth_string (comment_sexp, 1); + gcry_sexp_release (comment_sexp); + } + + desc_text_final = NULL; + if (desc_text) + rc = modify_description (desc_text, comment? comment:"", s_skey, + &desc_text_final); + gcry_free (comment); + + if (!rc) + { + rc = unprotect (ctrl, desc_text_final, &buf, grip, + cache_mode, lookup_ttl); + if (rc) + log_error ("failed to unprotect the secret key: %s\n", + gpg_strerror (rc)); + } + + xfree (desc_text_final); + } + break; + case PRIVATE_KEY_SHADOWED: + if (shadow_info) + { + const unsigned char *s; + size_t n; + + rc = agent_get_shadow_info (buf, &s); + if (!rc) + { + n = gcry_sexp_canon_len (s, 0, NULL,NULL); + assert (n); + *shadow_info = xtrymalloc (n); + if (!*shadow_info) + rc = out_of_core (); + else + { + memcpy (*shadow_info, s, n); + rc = 0; + got_shadow_info = 1; + } + } + if (rc) + log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc)); + } + else + rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY); + break; + default: + log_error ("invalid private key format\n"); + rc = gpg_error (GPG_ERR_BAD_SECKEY); + break; + } + gcry_sexp_release (s_skey); + s_skey = NULL; + if (rc || got_shadow_info) + { + xfree (buf); + return rc; + } + + buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL); + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); + wipememory (buf, buflen); + xfree (buf); + if (rc) + { + log_error ("failed to build S-Exp (off=%u): %s\n", + (unsigned int)erroff, gpg_strerror (rc)); + return rc; + } + + *result = s_skey; + return 0; +} + + +/* Return the key for the keygrip GRIP. The result is stored at + RESULT. This function extracts the key from the private key + database and returns it as an S-expression object as it is. On + failure an error code is returned and NULL stored at RESULT. */ +gpg_error_t +agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t *result) +{ + gpg_error_t err; + gcry_sexp_t s_skey; + + (void)ctrl; + + *result = NULL; + + err = read_key_file (grip, &s_skey); + if (!err) + *result = s_skey; + return err; +} + + +/* Return the public key for the keygrip GRIP. The result is stored + at RESULT. This function extracts the public key from the private + key database. On failure an error code is returned and NULL stored + at RESULT. */ +gpg_error_t +agent_public_key_from_file (ctrl_t ctrl, + const unsigned char *grip, + gcry_sexp_t *result) +{ + int i, idx, rc; + gcry_sexp_t s_skey; + const char *algoname; + gcry_sexp_t uri_sexp, comment_sexp; + const char *uri, *comment; + size_t uri_length, comment_length; + char *format, *p; + void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2 + for comment + end-of-list. */ + int argidx; + gcry_sexp_t list, l2; + const char *name; + const char *s; + size_t n; + const char *elems; + gcry_mpi_t *array; + + (void)ctrl; + + *result = NULL; + + rc = read_key_file (grip, &s_skey); + if (rc) + return rc; + + list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 ); + if (!list) + list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 ); + if (!list) + list = gcry_sexp_find_token (s_skey, "private-key", 0 ); + if (!list) + { + log_error ("invalid private key format\n"); + gcry_sexp_release (s_skey); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + name = gcry_sexp_nth_data (list, 0, &n); + if (n==3 && !memcmp (name, "rsa", 3)) + { + algoname = "rsa"; + elems = "ne"; + } + else if (n==3 && !memcmp (name, "dsa", 3)) + { + algoname = "dsa"; + elems = "pqgy"; + } + else if (n==3 && !memcmp (name, "elg", 3)) + { + algoname = "elg"; + elems = "pgy"; + } + else + { + log_error ("unknown private key algorithm\n"); + gcry_sexp_release (list); + gcry_sexp_release (s_skey); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + /* Allocate an array for the parameters and copy them out of the + secret key. FIXME: We should have a generic copy function. */ + array = xtrycalloc (strlen(elems) + 1, sizeof *array); + if (!array) + { + rc = gpg_error_from_syserror (); + gcry_sexp_release (list); + gcry_sexp_release (s_skey); + return rc; + } + + for (idx=0, s=elems; *s; s++, idx++ ) + { + l2 = gcry_sexp_find_token (list, s, 1); + if (!l2) + { + /* Required parameter not found. */ + for (i=0; i. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include "i18n.h" +#include "exechelp.h" +#include "sysutils.h" + +static int +store_key (gcry_sexp_t private, const char *passphrase, int force) +{ + int rc; + unsigned char *buf; + size_t len; + unsigned char grip[20]; + + if ( !gcry_pk_get_keygrip (private, grip) ) + { + log_error ("can't calculate keygrip\n"); + return gpg_error (GPG_ERR_GENERAL); + } + + len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = gcry_malloc_secure (len); + if (!buf) + return out_of_core (); + len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + + if (passphrase) + { + unsigned char *p; + + rc = agent_protect (buf, passphrase, &p, &len); + if (rc) + { + xfree (buf); + return rc; + } + xfree (buf); + buf = p; + } + + rc = agent_write_private_key (grip, buf, len, force); + xfree (buf); + return rc; +} + + +/* Count the number of non-alpha characters in S. Control characters + and non-ascii characters are not considered. */ +static size_t +nonalpha_count (const char *s) +{ + size_t n; + + for (n=0; *s; s++) + if (isascii (*s) && ( isdigit (*s) || ispunct (*s) )) + n++; + + return n; +} + + +/* Check PW against a list of pattern. Return 0 if PW does not match + these pattern. */ +static int +check_passphrase_pattern (ctrl_t ctrl, const char *pw) +{ + gpg_error_t err = 0; + const char *pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CHECK_PATTERN); + FILE *infp; + const char *argv[10]; + pid_t pid; + int result, i; + + (void)ctrl; + + infp = gnupg_tmpfile (); + if (!infp) + { + err = gpg_error_from_syserror (); + log_error (_("error creating temporary file: %s\n"), gpg_strerror (err)); + return 1; /* Error - assume password should not be used. */ + } + + if (fwrite (pw, strlen (pw), 1, infp) != 1) + { + err = gpg_error_from_syserror (); + log_error (_("error writing to temporary file: %s\n"), + gpg_strerror (err)); + fclose (infp); + return 1; /* Error - assume password should not be used. */ + } + rewind (infp); + + i = 0; + argv[i++] = "--null"; + argv[i++] = "--", + argv[i++] = opt.check_passphrase_pattern, + argv[i] = NULL; + assert (i < sizeof argv); + + if (gnupg_spawn_process_fd (pgmname, argv, fileno (infp), -1, -1, &pid)) + result = 1; /* Execute error - assume password should no be used. */ + else if (gnupg_wait_process (pgmname, pid, NULL)) + result = 1; /* Helper returned an error - probably a match. */ + else + result = 0; /* Success; i.e. no match. */ + + /* Overwrite our temporary file. */ + rewind (infp); + for (i=((strlen (pw)+99)/100)*100; i > 0; i--) + putc ('\xff', infp); + fflush (infp); + fclose (infp); + return result; +} + + +static int +take_this_one_anyway2 (ctrl_t ctrl, const char *desc, const char *anyway_btn) +{ + gpg_error_t err; + + if (opt.enforce_passphrase_constraints) + { + err = agent_show_message (ctrl, desc, _("Enter new passphrase")); + if (!err) + err = gpg_error (GPG_ERR_CANCELED); + } + else + err = agent_get_confirmation (ctrl, desc, + anyway_btn, _("Enter new passphrase"), 0); + return err; +} + + +static int +take_this_one_anyway (ctrl_t ctrl, const char *desc) +{ + return take_this_one_anyway2 (ctrl, desc, _("Take this one anyway")); +} + + +/* Check whether the passphrase PW is suitable. Returns 0 if the + passphrase is suitable and true if it is not and the user should be + asked to provide a different one. If SILENT is set, no message are + displayed. */ +int +check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent) +{ + gpg_error_t err; + unsigned int minlen = opt.min_passphrase_len; + unsigned int minnonalpha = opt.min_passphrase_nonalpha; + + if (!pw) + pw = ""; + + if (utf8_charcount (pw) < minlen ) + { + char *desc; + + if (silent) + return gpg_error (GPG_ERR_INV_PASSPHRASE); + + desc = xtryasprintf + ( ngettext ("Warning: You have entered an insecure passphrase.%%0A" + "A passphrase should be at least %u character long.", + "Warning: You have entered an insecure passphrase.%%0A" + "A passphrase should be at least %u characters long.", + minlen), minlen ); + if (!desc) + return gpg_error_from_syserror (); + err = take_this_one_anyway (ctrl, desc); + xfree (desc); + if (err) + return err; + } + + if (nonalpha_count (pw) < minnonalpha ) + { + char *desc; + + if (silent) + return gpg_error (GPG_ERR_INV_PASSPHRASE); + + desc = xtryasprintf + ( ngettext ("Warning: You have entered an insecure passphrase.%%0A" + "A passphrase should contain at least %u digit or%%0A" + "special character.", + "Warning: You have entered an insecure passphrase.%%0A" + "A passphrase should contain at least %u digits or%%0A" + "special characters.", + minnonalpha), minnonalpha ); + if (!desc) + return gpg_error_from_syserror (); + err = take_this_one_anyway (ctrl, desc); + xfree (desc); + if (err) + return err; + } + + /* If configured check the passphrase against a list of know words + and pattern. The actual test is done by an external program. + The warning message is generic to give the user no hint on how to + circumvent this list. */ + if (*pw && opt.check_passphrase_pattern && + check_passphrase_pattern (ctrl, pw)) + { + const char *desc = + /* */ _("Warning: You have entered an insecure passphrase.%%0A" + "A passphrase may not be a known term or match%%0A" + "certain pattern."); + + if (silent) + return gpg_error (GPG_ERR_INV_PASSPHRASE); + + err = take_this_one_anyway (ctrl, desc); + if (err) + return err; + } + + /* The final check is to warn about an empty passphrase. */ + if (!*pw) + { + const char *desc = (opt.enforce_passphrase_constraints? + _("You have not entered a passphrase!%0A" + "An empty passphrase is not allowed.") : + _("You have not entered a passphrase - " + "this is in general a bad idea!%0A" + "Please confirm that you do not want to " + "have any protection on your key.")); + + if (silent) + return gpg_error (GPG_ERR_INV_PASSPHRASE); + + err = take_this_one_anyway2 (ctrl, desc, + _("Yes, protection is not needed")); + if (err) + return err; + } + + return 0; +} + + +/* Callback function to compare the first entered PIN with the one + currently being entered. */ +static int +reenter_compare_cb (struct pin_entry_info_s *pi) +{ + const char *pin1 = pi->check_cb_arg; + + if (!strcmp (pin1, pi->pin)) + return 0; /* okay */ + return -1; +} + + + +/* Generate a new keypair according to the parameters given in + KEYPARAM */ +int +agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparamlen, + membuf_t *outbuf) +{ + gcry_sexp_t s_keyparam, s_key, s_private, s_public; + struct pin_entry_info_s *pi, *pi2; + int rc; + size_t len; + char *buf; + + rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen); + if (rc) + { + log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc)); + return gpg_error (GPG_ERR_INV_DATA); + } + + /* Get the passphrase now, cause key generation may take a while. */ + { + const char *text1 = _("Please enter the passphrase to%0A" + "to protect your new key"); + const char *text2 = _("Please re-enter this passphrase"); + const char *initial_errtext = NULL; + + pi = gcry_calloc_secure (2, sizeof (*pi) + 100); + pi2 = pi + (sizeof *pi + 100); + pi->max_length = 100; + pi->max_tries = 3; + pi->with_qualitybar = 1; + pi2->max_length = 100; + pi2->max_tries = 3; + pi2->check_cb = reenter_compare_cb; + pi2->check_cb_arg = pi->pin; + + next_try: + rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi); + initial_errtext = NULL; + if (!rc) + { + if (check_passphrase_constraints (ctrl, pi->pin, 0)) + { + pi->failed_tries = 0; + pi2->failed_tries = 0; + goto next_try; + } + if (pi->pin && *pi->pin) + { + rc = agent_askpin (ctrl, text2, NULL, NULL, pi2); + if (rc == -1) + { /* The re-entered one did not match and the user did not + hit cancel. */ + initial_errtext = _("does not match - try again"); + goto next_try; + } + } + } + if (rc) + { + xfree (pi); + return rc; + } + + if (!*pi->pin) + { + xfree (pi); + pi = NULL; /* User does not want a passphrase. */ + } + } + + rc = gcry_pk_genkey (&s_key, s_keyparam ); + gcry_sexp_release (s_keyparam); + if (rc) + { + log_error ("key generation failed: %s\n", gpg_strerror (rc)); + xfree (pi); + return rc; + } + + /* break out the parts */ + s_private = gcry_sexp_find_token (s_key, "private-key", 0); + if (!s_private) + { + log_error ("key generation failed: invalid return value\n"); + gcry_sexp_release (s_key); + xfree (pi); + return gpg_error (GPG_ERR_INV_DATA); + } + s_public = gcry_sexp_find_token (s_key, "public-key", 0); + if (!s_public) + { + log_error ("key generation failed: invalid return value\n"); + gcry_sexp_release (s_private); + gcry_sexp_release (s_key); + xfree (pi); + return gpg_error (GPG_ERR_INV_DATA); + } + gcry_sexp_release (s_key); s_key = NULL; + + /* store the secret key */ + if (DBG_CRYPTO) + log_debug ("storing private key\n"); + rc = store_key (s_private, pi? pi->pin:NULL, 0); + xfree (pi); pi = NULL; + gcry_sexp_release (s_private); + if (rc) + { + gcry_sexp_release (s_public); + return rc; + } + + /* return the public key */ + if (DBG_CRYPTO) + log_debug ("returning public key\n"); + len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = xtrymalloc (len); + if (!buf) + { + gpg_error_t tmperr = out_of_core (); + gcry_sexp_release (s_private); + gcry_sexp_release (s_public); + return tmperr; + } + len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + put_membuf (outbuf, buf, len); + gcry_sexp_release (s_public); + xfree (buf); + + return 0; +} + + + +/* Apply a new passpahrse to the key S_SKEY and store it. */ +int +agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey) +{ + struct pin_entry_info_s *pi, *pi2; + int rc; + + { + const char *text1 = _("Please enter the new passphrase"); + const char *text2 = _("Please re-enter this passphrase"); + const char *initial_errtext = NULL; + + pi = gcry_calloc_secure (2, sizeof (*pi) + 100); + pi2 = pi + (sizeof *pi + 100); + pi->max_length = 100; + pi->max_tries = 3; + pi->with_qualitybar = 1; + pi2->max_length = 100; + pi2->max_tries = 3; + pi2->check_cb = reenter_compare_cb; + pi2->check_cb_arg = pi->pin; + + next_try: + rc = agent_askpin (ctrl, text1, NULL, initial_errtext, pi); + initial_errtext = NULL; + if (!rc) + { + if (check_passphrase_constraints (ctrl, pi->pin, 0)) + { + pi->failed_tries = 0; + pi2->failed_tries = 0; + goto next_try; + } + /* Unless the passphrase is empty, ask to confirm it. */ + if (pi->pin && *pi->pin) + { + rc = agent_askpin (ctrl, text2, NULL, NULL, pi2); + if (rc == -1) + { /* The re-entered one did not match and the user did not + hit cancel. */ + initial_errtext = _("does not match - try again"); + goto next_try; + } + } + } + if (rc) + { + xfree (pi); + return rc; + } + + if (!*pi->pin) + { + xfree (pi); + pi = NULL; /* User does not want a passphrase. */ + } + } + + rc = store_key (s_skey, pi? pi->pin:NULL, 1); + xfree (pi); + return rc; +} diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c new file mode 100644 index 0000000..b00d899 --- /dev/null +++ b/agent/gpg-agent.c @@ -0,0 +1,2291 @@ +/* gpg-agent.c - The GnuPG Agent + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2009, 2010 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 3 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, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef HAVE_W32_SYSTEM +# include +# include +#endif /*!HAVE_W32_SYSTEM*/ +#include +#include +#include + +#define JNLIB_NEED_LOG_LOGV +#define JNLIB_NEED_AFLOCAL +#include "agent.h" +#include /* Malloc hooks and socket wrappers. */ + +#include "i18n.h" +#include "mkdtemp.h" /* Gnulib replacement. */ +#include "sysutils.h" +#include "setenv.h" +#include "gc-opt-flags.h" +#include "exechelp.h" +#include "../common/estream.h" + +enum cmd_and_opt_values +{ aNull = 0, + oCsh = 'c', + oQuiet = 'q', + oSh = 's', + oVerbose = 'v', + + oNoVerbose = 500, + aGPGConfList, + aGPGConfTest, + aUseStandardSocketP, + oOptions, + oDebug, + oDebugAll, + oDebugLevel, + oDebugWait, + oNoGreeting, + oNoOptions, + oHomedir, + oNoDetach, + oNoGrab, + oLogFile, + oServer, + oDaemon, + oBatch, + + oPinentryProgram, + oPinentryTouchFile, + oDisplay, + oTTYname, + oTTYtype, + oLCctype, + oLCmessages, + oXauthority, + oScdaemonProgram, + oDefCacheTTL, + oDefCacheTTLSSH, + oMaxCacheTTL, + oMaxCacheTTLSSH, + oEnforcePassphraseConstraints, + oMinPassphraseLen, + oMinPassphraseNonalpha, + oCheckPassphrasePattern, + oMaxPassphraseDays, + oEnablePassphraseHistory, + oUseStandardSocket, + oNoUseStandardSocket, + oFakedSystemTime, + + oIgnoreCacheForSigning, + oAllowMarkTrusted, + oAllowPresetPassphrase, + oKeepTTY, + oKeepDISPLAY, + oSSHSupport, + oDisableScdaemon, + oWriteEnvFile +}; + + + +static ARGPARSE_OPTS opts[] = { + + { aGPGConfList, "gpgconf-list", 256, "@" }, + { aGPGConfTest, "gpgconf-test", 256, "@" }, + { aUseStandardSocketP, "use-standard-socket-p", 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_("|FILE|read options from FILE")}, + { oDebug, "debug" ,4|16, "@"}, + { oDebugAll, "debug-all" ,0, "@"}, + { oDebugLevel, "debug-level" ,2, "@"}, + { oDebugWait,"debug-wait",1, "@"}, + { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, + { oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")}, + { oLogFile, "log-file" ,2, N_("use a log file for the server")}, + { oUseStandardSocket, "use-standard-socket", 0, + N_("use a standard location for the socket")}, + { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, + { oPinentryProgram, "pinentry-program", 2 , + N_("|PGM|use PGM as the PIN-Entry program") }, + { oPinentryTouchFile, "pinentry-touch-file", 2 , "@" }, + { oScdaemonProgram, "scdaemon-program", 2 , + N_("|PGM|use PGM as the SCdaemon program") }, + { oDisableScdaemon, "disable-scdaemon", 0, N_("do not use the SCdaemon") }, + { oFakedSystemTime, "faked-system-time", 2, "@" }, /* (epoch time) */ + + { oBatch, "batch", 0, "@" }, + { oHomedir, "homedir", 2, "@"}, + + { oDisplay, "display", 2, "@" }, + { oTTYname, "ttyname", 2, "@" }, + { oTTYtype, "ttytype", 2, "@" }, + { oLCctype, "lc-ctype", 2, "@" }, + { oLCmessages, "lc-messages", 2, "@" }, + { oXauthority, "xauthority", 2, "@" }, + { oKeepTTY, "keep-tty", 0, N_("ignore requests to change the TTY")}, + { oKeepDISPLAY, "keep-display", + 0, N_("ignore requests to change the X display")}, + + { oDefCacheTTL, "default-cache-ttl", 4, + N_("|N|expire cached PINs after N seconds")}, + { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" }, + { oMaxCacheTTL, "max-cache-ttl", 4, "@" }, + { oMaxCacheTTLSSH, "max-cache-ttl-ssh", 4, "@" }, + + { oEnforcePassphraseConstraints, "enforce-passphrase-constraints", 0, "@"}, + { oMinPassphraseLen, "min-passphrase-len", 4, "@" }, + { oMinPassphraseNonalpha, "min-passphrase-nonalpha", 4, "@" }, + { oCheckPassphrasePattern, "check-passphrase-pattern", 2, "@" }, + { oMaxPassphraseDays, "max-passphrase-days", 4, "@" }, + { oEnablePassphraseHistory, "enable-passphrase-history", 0, "@" }, + + { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, + N_("do not use the PIN cache when signing")}, + { oAllowMarkTrusted, "allow-mark-trusted", 0, + N_("allow clients to mark keys as \"trusted\"")}, + { oAllowPresetPassphrase, "allow-preset-passphrase", 0, + N_("allow presetting passphrase")}, + { oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") }, + { oWriteEnvFile, "write-env-file", 2|8, + N_("|FILE|write environment settings also to FILE")}, + {0} +}; + + +#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */ +#define DEFAULT_CACHE_TTL_SSH (30*60) /* 30 minutes */ +#define MAX_CACHE_TTL (120*60) /* 2 hours */ +#define MAX_CACHE_TTL_SSH (120*60) /* 2 hours */ +#define MIN_PASSPHRASE_LEN (8) +#define MIN_PASSPHRASE_NONALPHA (1) +#define MAX_PASSPHRASE_DAYS (0) + +/* The timer tick used for housekeeping stuff. For Windows we use a + longer period as the SetWaitableTimer seems to signal earlier than + the 2 seconds. */ +#ifdef HAVE_W32_SYSTEM +#define TIMERTICK_INTERVAL (4) +#else +#define TIMERTICK_INTERVAL (2) /* Seconds. */ +#endif + + +/* The list of open file descriptors at startup. Note that this list + has been allocated using the standard malloc. */ +static int *startup_fd_list; + +/* The signal mask at startup and a flag telling whether it is valid. */ +#ifdef HAVE_SIGPROCMASK +static sigset_t startup_signal_mask; +static int startup_signal_mask_valid; +#endif + +/* Flag to indicate that a shutdown was requested. */ +static int shutdown_pending; + +/* Counter for the currently running own socket checks. */ +static int check_own_socket_running; + +/* It is possible that we are currently running under setuid permissions */ +static int maybe_setuid = 1; + +/* Name of the communication socket used for native gpg-agent requests. */ +static char *socket_name; + +/* Name of the communication socket used for ssh-agent-emulation. */ +static char *socket_name_ssh; + +/* We need to keep track of the server's nonces (these are dummies for + POSIX systems). */ +static assuan_sock_nonce_t socket_nonce; +static assuan_sock_nonce_t socket_nonce_ssh; + + +/* Default values for options passed to the pinentry. */ +static char *default_display; +static char *default_ttyname; +static char *default_ttytype; +static char *default_lc_ctype; +static char *default_lc_messages; +static char *default_xauthority; + +/* Name of a config file, which will be reread on a HUP if it is not NULL. */ +static char *config_filename; + +/* Helper to implement --debug-level */ +static const char *debug_level; + +/* Keep track of the current log file so that we can avoid updating + the log file after a SIGHUP if it didn't changed. Malloced. */ +static char *current_logfile; + +/* The handle_tick() function may test whether a parent is still + running. We record the PID of the parent here or -1 if it should be + watched. */ +static pid_t parent_pid = (pid_t)(-1); + + +/* + Local prototypes. + */ + +static char *create_socket_name (char *standard_name, char *template); +static gnupg_fd_t create_server_socket (char *name, int is_ssh, + assuan_sock_nonce_t *nonce); +static void create_directories (void); + +static void agent_init_default_ctrl (ctrl_t ctrl); +static void agent_deinit_default_ctrl (ctrl_t ctrl); + +static void handle_connections (gnupg_fd_t listen_fd, + gnupg_fd_t listen_fd_ssh); +static void check_own_socket (void); +static int check_for_running_agent (int silent, int mode); + +/* Pth wrapper function definitions. */ +ASSUAN_SYSTEM_PTH_IMPL; + +GCRY_THREAD_OPTION_PTH_IMPL; +static int fixed_gcry_pth_init (void) +{ + return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; +} + + +#ifndef PTH_HAVE_PTH_THREAD_ID +static unsigned long pth_thread_id (void) +{ + return (unsigned long)pth_self (); +} +#endif + + + +/* + Functions. + */ + +static char * +make_libversion (const char *libname, const char *(*getfnc)(const char*)) +{ + const char *s; + char *result; + + if (maybe_setuid) + { + gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* Drop setuid. */ + maybe_setuid = 0; + } + s = getfnc (NULL); + result = xmalloc (strlen (libname) + 1 + strlen (s) + 1); + strcpy (stpcpy (stpcpy (result, libname), " "), s); + return result; +} + + +static const char * +my_strusage (int level) +{ + static char *ver_gcry; + const char *p; + + switch (level) + { + case 11: p = "gpg-agent (GnuPG)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug + reporting address. This is so that we can change the + reporting address without breaking the translations. */ + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + + case 20: + if (!ver_gcry) + ver_gcry = make_libversion ("libgcrypt", gcry_check_version); + p = ver_gcry; + break; + + case 1: + case 40: p = _("Usage: gpg-agent [options] (-h for help)"); + break; + case 41: p = _("Syntax: gpg-agent [options] [command [args]]\n" + "Secret key management for GnuPG\n"); + break; + + default: p = NULL; + } + return p; +} + + + +/* Setup the debugging. With the global variable DEBUG_LEVEL set to NULL + only the active debug flags are propagated to the subsystems. With + DEBUG_LEVEL set, a specific set of debug flags is set; thus overriding + all flags already set. Note that we don't fail here, because it is + important to keep gpg-agent running even after re-reading the + options due to a SIGHUP. */ +static void +set_debug (void) +{ + int numok = (debug_level && digitp (debug_level)); + int numlvl = numok? atoi (debug_level) : 0; + + if (!debug_level) + ; + else if (!strcmp (debug_level, "none") || (numok && numlvl < 1)) + opt.debug = 0; + else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2)) + opt.debug = DBG_ASSUAN_VALUE; + else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5)) + opt.debug = DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE; + else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8)) + opt.debug = (DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE + |DBG_CACHE_VALUE); + else if (!strcmp (debug_level, "guru") || numok) + { + opt.debug = ~0; + /* Unless the "guru" string has been used we don't want to allow + hashing debugging. The rationale is that people tend to + select the highest debug value and would then clutter their + disk with debug files which may reveal confidential data. */ + if (numok) + opt.debug &= ~(DBG_HASHING_VALUE); + } + else + { + log_error (_("invalid debug-level `%s' given\n"), debug_level); + opt.debug = 0; /* Reset debugging, so that prior debug + statements won't have an undesired effect. */ + } + + 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); + + if (opt.debug) + log_info ("enabled debug flags:%s%s%s%s%s%s%s%s\n", + (opt.debug & DBG_COMMAND_VALUE)? " command":"", + (opt.debug & DBG_MPI_VALUE )? " mpi":"", + (opt.debug & DBG_CRYPTO_VALUE )? " crypto":"", + (opt.debug & DBG_MEMORY_VALUE )? " memory":"", + (opt.debug & DBG_CACHE_VALUE )? " cache":"", + (opt.debug & DBG_MEMSTAT_VALUE)? " memstat":"", + (opt.debug & DBG_HASHING_VALUE)? " hashing":"", + (opt.debug & DBG_ASSUAN_VALUE )? " assuan":""); +} + + +/* Helper for cleanup to remove one socket with NAME. */ +static void +remove_socket (char *name) +{ + if (name && *name) + { + char *p; + + remove (name); + p = strrchr (name, '/'); + if (p) + { + *p = 0; + rmdir (name); + *p = '/'; + } + *name = 0; + } +} + +static void +cleanup (void) +{ + remove_socket (socket_name); + remove_socket (socket_name_ssh); +} + + + +/* Handle options which are allowed to be reset after program start. + Return true when the current option in PARGS could be handled and + false if not. As a special feature, passing a value of NULL for + PARGS, resets the options to the default. REREAD should be set + true if it is not the initial option parsing. */ +static int +parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) +{ + if (!pargs) + { /* reset mode */ + opt.quiet = 0; + opt.verbose = 0; + opt.debug = 0; + opt.no_grab = 0; + opt.pinentry_program = NULL; + opt.pinentry_touch_file = NULL; + opt.scdaemon_program = NULL; + opt.def_cache_ttl = DEFAULT_CACHE_TTL; + opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH; + opt.max_cache_ttl = MAX_CACHE_TTL; + opt.max_cache_ttl_ssh = MAX_CACHE_TTL_SSH; + opt.enforce_passphrase_constraints = 0; + opt.min_passphrase_len = MIN_PASSPHRASE_LEN; + opt.min_passphrase_nonalpha = MIN_PASSPHRASE_NONALPHA; + opt.check_passphrase_pattern = NULL; + opt.max_passphrase_days = MAX_PASSPHRASE_DAYS; + opt.enable_passhrase_history = 0; + opt.ignore_cache_for_signing = 0; + opt.allow_mark_trusted = 0; + opt.disable_scdaemon = 0; + return 1; + } + + switch (pargs->r_opt) + { + case oQuiet: opt.quiet = 1; break; + case oVerbose: opt.verbose++; 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 oLogFile: + if (!reread) + return 0; /* not handeld */ + if (!current_logfile || !pargs->r.ret_str + || strcmp (current_logfile, pargs->r.ret_str)) + { + log_set_file (pargs->r.ret_str); + if (DBG_ASSUAN) + assuan_set_assuan_log_stream (log_get_stream ()); + xfree (current_logfile); + current_logfile = xtrystrdup (pargs->r.ret_str); + } + break; + + case oNoGrab: opt.no_grab = 1; break; + + case oPinentryProgram: opt.pinentry_program = pargs->r.ret_str; break; + case oPinentryTouchFile: opt.pinentry_touch_file = pargs->r.ret_str; break; + case oScdaemonProgram: opt.scdaemon_program = pargs->r.ret_str; break; + case oDisableScdaemon: opt.disable_scdaemon = 1; break; + + case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break; + case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break; + case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break; + case oMaxCacheTTLSSH: opt.max_cache_ttl_ssh = pargs->r.ret_ulong; break; + + case oEnforcePassphraseConstraints: + opt.enforce_passphrase_constraints=1; + break; + case oMinPassphraseLen: opt.min_passphrase_len = pargs->r.ret_ulong; break; + case oMinPassphraseNonalpha: + opt.min_passphrase_nonalpha = pargs->r.ret_ulong; + break; + case oCheckPassphrasePattern: + opt.check_passphrase_pattern = pargs->r.ret_str; + break; + case oMaxPassphraseDays: + opt.max_passphrase_days = pargs->r.ret_ulong; + break; + case oEnablePassphraseHistory: + opt.enable_passhrase_history = 1; + break; + + case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; + + case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break; + + case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break; + + default: + return 0; /* not handled */ + } + + return 1; /* handled */ +} + + +/* The main entry point. */ +int +main (int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + int orig_argc; + char **orig_argv; + FILE *configfp = NULL; + char *configname = NULL; + const char *shell; + unsigned configlineno; + int parse_debug = 0; + 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; + gpg_error_t err; + const char *env_file_name = NULL; + struct assuan_malloc_hooks malloc_hooks; + + /* Before we do anything else we save the list of currently open + file descriptors and the signal mask. This info is required to + do the exec call properly. */ + startup_fd_list = get_all_open_fds (); +#ifdef HAVE_SIGPROCMASK + if (!sigprocmask (SIG_UNBLOCK, NULL, &startup_signal_mask)) + startup_signal_mask_valid = 1; +#endif /*HAVE_SIGPROCMASK*/ + + /* Set program name etc. */ + 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 ("gpg-agent", JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID); + + /* Make sure that our subsystems are ready. */ + i18n_init (); + init_common_subsystems (); + + + /* Libgcrypt requires us to register the threading model first. + Note that this will also do the pth_init. */ + gcry_threads_pth.init = fixed_gcry_pth_init; + 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)); + } + + + /* 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( _("%s is too old (need %s, have %s)\n"), "libgcrypt", + NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); + } + + malloc_hooks.malloc = gcry_malloc; + malloc_hooks.realloc = gcry_realloc; + malloc_hooks.free = gcry_free; + assuan_set_malloc_hooks (&malloc_hooks); + assuan_set_assuan_log_prefix (log_get_prefix (NULL)); + assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_sock_init (); + + setup_libgcrypt_logging (); + gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); + + disable_core_dumps (); + + /* Set default options. */ + parse_rereadable_options (NULL, 0); /* Reset them to default values. */ +#ifdef USE_STANDARD_SOCKET + opt.use_standard_socket = 1; /* Under Windows we always use a standard + socket. */ +#endif + + shell = getenv ("SHELL"); + if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) + csh_style = 1; + + opt.homedir = default_homedir (); + + /* Record some of the original environment strings. */ + { + const char *s; + int idx; + static const char *names[] = + { "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL }; + + err = 0; + opt.startup_env = session_env_new (); + if (!opt.startup_env) + err = gpg_error_from_syserror (); + for (idx=0; !err && names[idx]; idx++) + { + s = getenv (names[idx]); + if (s) + err = session_env_setenv (opt.startup_env, names[idx], s); + } + if (!err) + { + s = ttyname (0); + if (s) + err = session_env_setenv (opt.startup_env, "GPG_TTY", s); + } + if (err) + log_fatal ("error recording startup environment: %s\n", + gpg_strerror (err)); + + /* Fixme: Better use the locale function here. */ + opt.startup_lc_ctype = getenv ("LC_CTYPE"); + if (opt.startup_lc_ctype) + opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype); + opt.startup_lc_messages = getenv ("LC_MESSAGES"); + if (opt.startup_lc_messages) + opt.startup_lc_messages = xstrdup (opt.startup_lc_messages); + } + + /* 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, 32768, 0); + maybe_setuid = 0; + + /* + Now we are now working under our real uid + */ + + if (default_config) + configname = make_filename (opt.homedir, "gpg-agent.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 ); + /* Save the default conf file name so that + reread_configuration is able to test whether the + config file has been created in the meantime. */ + xfree (config_filename); + config_filename = configname; + configname = NULL; + } + 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) ) + { + if (parse_rereadable_options (&pargs, 0)) + continue; /* Already handled */ + switch (pargs.r_opt) + { + case aGPGConfList: gpgconf_list = 1; break; + case aGPGConfTest: gpgconf_list = 2; break; + case aUseStandardSocketP: gpgconf_list = 3; break; + case oBatch: opt.batch=1; break; + + case oDebugWait: debug_wait = 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 oDisplay: default_display = xstrdup (pargs.r.ret_str); break; + case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break; + case oTTYtype: default_ttytype = xstrdup (pargs.r.ret_str); break; + case oLCctype: default_lc_ctype = xstrdup (pargs.r.ret_str); break; + case oLCmessages: default_lc_messages = xstrdup (pargs.r.ret_str); + case oXauthority: default_xauthority = xstrdup (pargs.r.ret_str); + break; + + case oUseStandardSocket: opt.use_standard_socket = 1; break; + case oNoUseStandardSocket: opt.use_standard_socket = 0; break; + + case oFakedSystemTime: + { + time_t faked_time = isotime2epoch (pargs.r.ret_str); + if (faked_time == (time_t)(-1)) + faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10); + gnupg_set_time (faked_time, 0); + } + break; + + case oKeepTTY: opt.keep_tty = 1; break; + case oKeepDISPLAY: opt.keep_display = 1; break; + + case oSSHSupport: opt.ssh_support = 1; break; + case oWriteEnvFile: + if (pargs.r_type) + env_file_name = pargs.r.ret_str; + else + env_file_name = make_filename ("~/.gpg-agent-info", NULL); + break; + + default : pargs.err = configfp? 1:2; break; + } + } + if (configfp) + { + fclose( configfp ); + configfp = NULL; + /* Keep a copy of the name so that it can be read on SIGHUP. */ + if (config_filename != configname) + { + xfree (config_filename); + 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 + /* We don't want to print it here because gpg-agent is useful of its + own and quite matured. */ + /*log_info ("NOTE: this is a development version!\n");*/ +#endif + + set_debug (); + + if (atexit (cleanup)) + { + log_error ("atexit failed\n"); + cleanup (); + exit (1); + } + + initialize_module_call_pinentry (); + initialize_module_call_scd (); + initialize_module_trustlist (); + + /* Try to create missing directories. */ + create_directories (); + + if (debug_wait && pipe_server) + { + log_debug ("waiting for debugger - my pid is %u .....\n", + (unsigned int)getpid()); + gnupg_sleep (debug_wait); + log_debug ("... okay\n"); + } + + if (gpgconf_list == 3) + agent_exit (!opt.use_standard_socket); + if (gpgconf_list == 2) + agent_exit (0); + if (gpgconf_list) + { + char *filename; + char *filename_esc; + + /* List options and default values in the GPG Conf format. */ + filename = make_filename (opt.homedir, "gpg-agent.conf", NULL ); + filename_esc = percent_escape (filename, NULL); + + printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", + GC_OPT_FLAG_DEFAULT, filename_esc); + xfree (filename); + xfree (filename_esc); + + printf ("verbose:%lu:\n" + "quiet:%lu:\n" + "debug-level:%lu:\"none:\n" + "log-file:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME ); + printf ("default-cache-ttl:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL ); + printf ("default-cache-ttl-ssh:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL_SSH ); + printf ("max-cache-ttl:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL ); + printf ("max-cache-ttl-ssh:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL_SSH ); + printf ("enforce-passphrase-constraints:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("min-passphrase-len:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MIN_PASSPHRASE_LEN ); + printf ("min-passphrase-nonalpha:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, + MIN_PASSPHRASE_NONALPHA); + printf ("check-passphrase-pattern:%lu:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME); + printf ("max-passphrase-days:%lu:%d:\n", + GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, + MAX_PASSPHRASE_DAYS); + printf ("enable-passphrase-history:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("no-grab:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("ignore-cache-for-signing:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("allow-mark-trusted:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("disable-scdaemon:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + + agent_exit (0); + } + + /* If this has been called without any options, we merely check + whether an agent is already running. We do this here so that we + don't clobber a logfile but print it directly to stderr. */ + if (!pipe_server && !is_daemon) + { + log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX); + check_for_running_agent (0, 0); + agent_exit (0); + } + +#ifdef ENABLE_NLS + /* gpg-agent usually does not output any messages because it runs in + the background. For log files it is acceptable to have messages + always encoded in utf-8. We switch here to utf-8, so that + commands like --help still give native messages. It is far + easier to switch only once instead of for every message and it + actually helps when more then one thread is active (avoids an + extra copy step). */ + bind_textdomain_codeset (PACKAGE_GT, "UTF-8"); +#endif + + /* Now start with logging to a file if this is desired. */ + if (logfile) + { + log_set_file (logfile); + log_set_prefix (NULL, (JNLIB_LOG_WITH_PREFIX + |JNLIB_LOG_WITH_TIME + |JNLIB_LOG_WITH_PID)); + current_logfile = xstrdup (logfile); + } + if (DBG_ASSUAN) + assuan_set_assuan_log_stream (log_get_stream ()); + + /* Make sure that we have a default ttyname. */ + if (!default_ttyname && ttyname (1)) + default_ttyname = xstrdup (ttyname (1)); + if (!default_ttytype && getenv ("TERM")) + default_ttytype = xstrdup (getenv ("TERM")); + + + if (pipe_server) + { + /* This is the simple pipe based server */ + ctrl_t ctrl; + + ctrl = xtrycalloc (1, sizeof *ctrl); + if (!ctrl) + { + log_error ("error allocating connection control data: %s\n", + strerror (errno) ); + agent_exit (1); + } + ctrl->session_env = session_env_new (); + if (!ctrl->session_env) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + agent_exit (1); + } + agent_init_default_ctrl (ctrl); + start_command_handler (ctrl, GNUPG_INVALID_FD, GNUPG_INVALID_FD); + agent_deinit_default_ctrl (ctrl); + xfree (ctrl); + } + else if (!is_daemon) + ; /* NOTREACHED */ + else + { /* Regular server mode */ + gnupg_fd_t fd; + gnupg_fd_t fd_ssh; + pid_t pid; + + /* Remove the DISPLAY variable so that a pinentry does not + default to a specific display. There is still a default + display when gpg-agent was started using --display or a + client requested this using an OPTION command. Note, that we + don't do this when running in reverse daemon mode (i.e. when + exec the program given as arguments). */ +#ifndef HAVE_W32_SYSTEM + if (!opt.keep_display && !argc) + unsetenv ("DISPLAY"); +#endif + + + /* Create the sockets. */ + socket_name = create_socket_name + ("S.gpg-agent", "/tmp/gpg-XXXXXX/S.gpg-agent"); + if (opt.ssh_support) + socket_name_ssh = create_socket_name + ("S.gpg-agent.ssh", "/tmp/gpg-XXXXXX/S.gpg-agent.ssh"); + + fd = create_server_socket (socket_name, 0, &socket_nonce); + if (opt.ssh_support) + fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh); + else + fd_ssh = GNUPG_INVALID_FD; + + /* If we are going to exec a program in the parent, we record + the PID, so that the child may check whether the program is + still alive. */ + if (argc) + parent_pid = getpid (); + + fflush (NULL); +#ifdef HAVE_W32_SYSTEM + pid = getpid (); + printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); +#else /*!HAVE_W32_SYSTEM*/ + 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, *infostr_ssh_sock, *infostr_ssh_pid; + + /* Close the socket FD. */ + close (fd); + + /* Note that we used a standard fork so that Pth runs in + both the parent and the child. The pth_fork would + terminate Pth in the child but that is not the way we + want it. Thus we use a plain fork and terminate Pth here + in the parent. The pth_kill may or may not work reliable + but it should not harm to call it. Because Pth fiddles + with the signal mask the signal mask might not be correct + right now and thus we restore it. That is not strictly + necessary but some programs falsely assume a cleared + signal mask. es_pth_kill is a wrapper around pth_kill to + take care not to use any Pth functions in the estream + code after Pth has been killed. */ + if ( !es_pth_kill () ) + log_error ("pth_kill failed in forked process\n"); + +#ifdef HAVE_SIGPROCMASK + if (startup_signal_mask_valid) + { + if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL)) + log_error ("error restoring signal mask: %s\n", + strerror (errno)); + } + else + log_info ("no saved signal mask\n"); +#endif /*HAVE_SIGPROCMASK*/ + + /* Create the info string: :: */ + if (asprintf (&infostr, "GPG_AGENT_INFO=%s:%lu:1", + socket_name, (ulong)pid ) < 0) + { + log_error ("out of core\n"); + kill (pid, SIGTERM); + exit (1); + } + if (opt.ssh_support) + { + if (asprintf (&infostr_ssh_sock, "SSH_AUTH_SOCK=%s", + socket_name_ssh) < 0) + { + log_error ("out of core\n"); + kill (pid, SIGTERM); + exit (1); + } + if (asprintf (&infostr_ssh_pid, "SSH_AGENT_PID=%u", + 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 (opt.ssh_support) + *socket_name_ssh = 0; + + if (env_file_name) + { + FILE *fp; + + fp = fopen (env_file_name, "w"); + if (!fp) + log_error (_("error creating `%s': %s\n"), + env_file_name, strerror (errno)); + else + { + fputs (infostr, fp); + putc ('\n', fp); + if (opt.ssh_support) + { + fputs (infostr_ssh_sock, fp); + putc ('\n', fp); + fputs (infostr_ssh_pid, fp); + putc ('\n', fp); + } + fclose (fp); + } + } + + + 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); + } + if (opt.ssh_support && putenv (infostr_ssh_sock)) + { + log_error ("failed to set environment: %s\n", + strerror (errno) ); + kill (pid, SIGTERM ); + exit (1); + } + if (opt.ssh_support && putenv (infostr_ssh_pid)) + { + log_error ("failed to set environment: %s\n", + strerror (errno) ); + kill (pid, SIGTERM ); + exit (1); + } + + /* Close all the file descriptors except the standard + ones and those open at startup. We explicitly don't + close 0,1,2 in case something went wrong collecting + them at startup. */ + close_all_fds (3, startup_fd_list); + + /* Run the command. */ + 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); + if (opt.ssh_support) + { + *strchr (infostr_ssh_sock, '=') = ' '; + printf ("setenv %s;\n", infostr_ssh_sock); + *strchr (infostr_ssh_pid, '=') = ' '; + printf ("setenv %s;\n", infostr_ssh_pid); + } + } + else + { + printf ( "%s; export GPG_AGENT_INFO;\n", infostr); + if (opt.ssh_support) + { + printf ("%s; export SSH_AUTH_SOCK;\n", infostr_ssh_sock); + printf ("%s; export SSH_AGENT_PID;\n", infostr_ssh_pid); + } + } + xfree (infostr); + if (opt.ssh_support) + { + xfree (infostr_ssh_sock); + xfree (infostr_ssh_pid); + } + exit (0); + } + /*NOTREACHED*/ + } /* End parent */ + + /* + This is the child + */ + + /* Detach from tty and put process into a new session */ + if (!nodetach ) + { + int i; + unsigned int oldflags; + + /* Close stdin, stdout and stderr unless it is the log stream */ + for (i=0; i <= 2; i++) + { + if (!log_test_fd (i) && i != fd ) + { + if ( ! close (i) + && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1) + { + log_error ("failed to open `%s': %s\n", + "/dev/null", strerror (errno)); + cleanup (); + exit (1); + } + } + } + if (setsid() == -1) + { + log_error ("setsid() failed: %s\n", strerror(errno) ); + cleanup (); + exit (1); + } + + log_get_prefix (&oldflags); + log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED); + opt.running_detached = 1; + } + + if (chdir("/")) + { + log_error ("chdir to / failed: %s\n", strerror (errno)); + exit (1); + } + + { + struct sigaction sa; + + sa.sa_handler = SIG_IGN; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (SIGPIPE, &sa, NULL); + } +#endif /*!HAVE_W32_SYSTEM*/ + + log_info ("%s %s started\n", strusage(11), strusage(13) ); + handle_connections (fd, opt.ssh_support ? fd_ssh : GNUPG_INVALID_FD); + assuan_sock_close (fd); + } + + return 0; +} + + +void +agent_exit (int rc) +{ + /*FIXME: update_random_seed_file();*/ +#if 1 + /* 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); +} + + +static void +agent_init_default_ctrl (ctrl_t ctrl) +{ + /* Note we ignore malloc errors because we can't do much about it + and the request will fail anyway shortly after this + initialization. */ + session_env_setenv (ctrl->session_env, "DISPLAY", default_display); + session_env_setenv (ctrl->session_env, "GPG_TTY", default_ttyname); + session_env_setenv (ctrl->session_env, "TERM", default_ttytype); + session_env_setenv (ctrl->session_env, "XAUTHORITY", default_xauthority); + session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", NULL); + + if (ctrl->lc_ctype) + xfree (ctrl->lc_ctype); + ctrl->lc_ctype = default_lc_ctype? xtrystrdup (default_lc_ctype) : NULL; + + if (ctrl->lc_messages) + xfree (ctrl->lc_messages); + ctrl->lc_messages = default_lc_messages? xtrystrdup (default_lc_messages) + /**/ : NULL; + +} + + +static void +agent_deinit_default_ctrl (ctrl_t ctrl) +{ + session_env_release (ctrl->session_env); + + if (ctrl->lc_ctype) + xfree (ctrl->lc_ctype); + if (ctrl->lc_messages) + xfree (ctrl->lc_messages); +} + + +/* Reread parts of the configuration. Note, that this function is + obviously not thread-safe and should only be called from the PTH + signal handler. + + Fixme: Due to the way the argument parsing works, we create a + memory leak here for all string type arguments. There is currently + no clean way to tell whether the memory for the argument has been + allocated or points into the process' original arguments. Unless + we have a mechanism to tell this, we need to live on with this. */ +static void +reread_configuration (void) +{ + ARGPARSE_ARGS pargs; + FILE *fp; + unsigned int configlineno = 0; + int dummy; + + if (!config_filename) + return; /* No config file. */ + + fp = fopen (config_filename, "r"); + if (!fp) + { + log_info (_("option file `%s': %s\n"), + config_filename, strerror(errno) ); + return; + } + + parse_rereadable_options (NULL, 1); /* Start from the default values. */ + + memset (&pargs, 0, sizeof pargs); + dummy = 0; + pargs.argc = &dummy; + pargs.flags = 1; /* do not remove the args */ + while (optfile_parse (fp, config_filename, &configlineno, &pargs, opts) ) + { + if (pargs.r_opt < -1) + pargs.err = 1; /* Print a warning. */ + else /* Try to parse this option - ignore unchangeable ones. */ + parse_rereadable_options (&pargs, 1); + } + fclose (fp); + set_debug (); +} + + +/* Return the file name of the socket we are using for native + requests. */ +const char * +get_agent_socket_name (void) +{ + const char *s = socket_name; + + return (s && *s)? s : NULL; +} + +/* Return the file name of the socket we are using for SSH + requests. */ +const char * +get_agent_ssh_socket_name (void) +{ + const char *s = socket_name_ssh; + + return (s && *s)? s : NULL; +} + + +/* Under W32, this function returns the handle of the scdaemon + notification event. Calling it the first time creates that + event. */ +#ifdef HAVE_W32_SYSTEM +void * +get_agent_scd_notify_event (void) +{ + static HANDLE the_event; + + if (!the_event) + { + HANDLE h, h2; + SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; + + /* We need to use manual reset evet object due to the way our + w32-pth wait function works: If we would use an automatic + reset event we are not able to figure out which handle has + been signaled because at the time we single out the signaled + handles using WFSO the event has already been reset due to + the WFMO. */ + h = CreateEvent (&sa, TRUE, FALSE, NULL); + if (!h) + log_error ("can't create scd notify event: %s\n", w32_strerror (-1) ); + else if (!DuplicateHandle (GetCurrentProcess(), h, + GetCurrentProcess(), &h2, + EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0)) + { + log_error ("setting syncronize for scd notify event failed: %s\n", + w32_strerror (-1) ); + CloseHandle (h); + } + else + { + CloseHandle (h); + the_event = h2; + } + } + + log_debug ("returning notify handle %p\n", the_event); + return the_event; +} +#endif /*HAVE_W32_SYSTEM*/ + + + +/* Create a name for the socket. With USE_STANDARD_SOCKET given as + true using STANDARD_NAME in the home directory or if given as + false from the mkdir type name TEMPLATE. In the latter case a + unique name in a unique new directory will be created. In both + cases check for valid characters as well as against a maximum + allowed length for a unix domain socket is done. The function + terminates the process in case of an error. Returns: Pointer to an + allocated string with the absolute name of the socket used. */ +static char * +create_socket_name (char *standard_name, char *template) +{ + char *name, *p; + + if (opt.use_standard_socket) + name = make_filename (opt.homedir, standard_name, NULL); + else + { + name = xstrdup (template); + p = strrchr (name, '/'); + if (!p) + BUG (); + *p = 0; + if (!mkdtemp (name)) + { + log_error (_("can't create directory `%s': %s\n"), + name, strerror (errno)); + agent_exit (2); + } + *p = '/'; + } + + if (strchr (name, PATHSEP_C)) + { + log_error (("`%s' are not allowed in the socket name\n"), PATHSEP_S); + agent_exit (2); + } + if (strlen (name) + 1 >= DIMof (struct sockaddr_un, sun_path) ) + { + log_error (_("name of socket too long\n")); + agent_exit (2); + } + return name; +} + + + +/* Create a Unix domain socket with NAME. Returns the file descriptor + or terminates the process in case of an error. Not that this + function needs to be used for the regular socket first and only + then for the ssh socket. */ +static gnupg_fd_t +create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce) +{ + struct sockaddr_un *serv_addr; + socklen_t len; + gnupg_fd_t fd; + int rc; + + fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0); + if (fd == ASSUAN_INVALID_FD) + { + log_error (_("can't create socket: %s\n"), strerror (errno)); + agent_exit (2); + } + + serv_addr = xmalloc (sizeof (*serv_addr)); + memset (serv_addr, 0, sizeof *serv_addr); + serv_addr->sun_family = AF_UNIX; + if (strlen (name) + 1 >= sizeof (serv_addr->sun_path)) + { + log_error (_("socket name `%s' is too long\n"), name); + agent_exit (2); + } + strcpy (serv_addr->sun_path, name); + len = SUN_LEN (serv_addr); + rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); + if (opt.use_standard_socket && rc == -1 && errno == EADDRINUSE) + { + /* Check whether a gpg-agent is already running on the standard + socket. We do this test only if this is not the ssh socket. + For ssh we assume that a test for gpg-agent has already been + done and reuse the requested ssh socket. Testing the + ssh-socket is not possible because at this point, though we + know the new Assuan socket, the Assuan server and thus the + ssh-agent server is not yet operational. This would lead to + a hang. */ + if (!is_ssh && !check_for_running_agent (1, 1)) + { + log_error (_("a gpg-agent is already running - " + "not starting a new one\n")); + *name = 0; /* Inhibit removal of the socket by cleanup(). */ + assuan_sock_close (fd); + agent_exit (2); + } + remove (name); + rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); + } + if (rc != -1 + && (rc=assuan_sock_get_nonce ((struct sockaddr*)serv_addr, len, nonce))) + log_error (_("error getting nonce for the socket\n")); + if (rc == -1) + { + /* We use gpg_strerror here because it allows us to get strings + for some W32 socket error codes. */ + log_error (_("error binding socket to `%s': %s\n"), + serv_addr->sun_path, + gpg_strerror (gpg_error_from_errno (errno))); + + assuan_sock_close (fd); + if (opt.use_standard_socket) + *name = 0; /* Inhibit removal of the socket by cleanup(). */ + agent_exit (2); + } + + if (listen (FD2INT(fd), 5 ) == -1) + { + log_error (_("listen() failed: %s\n"), strerror (errno)); + assuan_sock_close (fd); + agent_exit (2); + } + + if (opt.verbose) + log_info (_("listening on socket `%s'\n"), serv_addr->sun_path); + + return fd; +} + + +/* Check that the directory for storing the private keys exists and + create it if not. This function won't fail as it is only a + convenience function and not strictly necessary. */ +static void +create_private_keys_directory (const char *home) +{ + char *fname; + struct stat statbuf; + + fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL); + if (stat (fname, &statbuf) && errno == ENOENT) + { +#ifdef HAVE_W32_SYSTEM /*FIXME: Setup proper permissions. */ + if (!CreateDirectory (fname, NULL)) + log_error (_("can't create directory `%s': %s\n"), + fname, w32_strerror (-1) ); +#else + if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR )) + log_error (_("can't create directory `%s': %s\n"), + fname, strerror (errno) ); +#endif + else if (!opt.quiet) + log_info (_("directory `%s' created\n"), fname); + } + xfree (fname); +} + +/* 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 home directory is used. To cope + with HOME, we compare only the suffix if we see that the default + homedir does start with a tilde. We don't stop here in case of + problems because other functions will throw an error anyway.*/ +static void +create_directories (void) +{ + struct stat statbuf; + const char *defhome = standard_homedir (); + char *home; + + home = make_filename (opt.homedir, NULL); + if ( stat (home, &statbuf) ) + { + if (errno == ENOENT) + { + if ( +#ifdef HAVE_W32_SYSTEM + ( !compare_filenames (home, defhome) ) +#else + (*defhome == '~' + && (strlen (home) >= strlen (defhome+1) + && !strcmp (home + strlen(home) + - strlen (defhome+1), defhome+1))) + || (*defhome != '~' && !strcmp (home, defhome) ) +#endif + ) + { +#ifdef HAVE_W32_SYSTEM + if (!CreateDirectory (home, NULL)) + log_error (_("can't create directory `%s': %s\n"), + home, w32_strerror (-1) ); +#else + if (mkdir (home, S_IRUSR|S_IWUSR|S_IXUSR )) + log_error (_("can't create directory `%s': %s\n"), + home, strerror (errno) ); +#endif + else + { + if (!opt.quiet) + log_info (_("directory `%s' created\n"), home); + create_private_keys_directory (home); + } + } + } + else + log_error (_("stat() failed for `%s': %s\n"), home, strerror (errno)); + } + else if ( !S_ISDIR(statbuf.st_mode)) + { + log_error (_("can't use `%s' as home directory\n"), home); + } + else /* exists and is a directory. */ + { + create_private_keys_directory (home); + } + xfree (home); +} + + + +/* This is the worker for the ticker. It is called every few seconds + and may only do fast operations. */ +static void +handle_tick (void) +{ + static time_t last_minute; + + if (!last_minute) + last_minute = time (NULL); + + /* Check whether the scdaemon has died and cleanup in this case. */ + agent_scd_check_aliveness (); + + /* If we are running as a child of another process, check whether + the parent is still alive and shutdown if not. */ +#ifndef HAVE_W32_SYSTEM + if (parent_pid != (pid_t)(-1)) + { + if (kill (parent_pid, 0)) + { + shutdown_pending = 2; + if (!opt.quiet) + { + log_info ("parent process died - shutting down\n"); + log_info ("%s %s stopped\n", strusage(11), strusage(13) ); + } + cleanup (); + agent_exit (0); + } + } +#endif /*HAVE_W32_SYSTEM*/ + + /* Code to be run every minute. */ + if (last_minute + 60 <= time (NULL)) + { + check_own_socket (); + last_minute = time (NULL); + } + +} + + +/* A global function which allows us to call the reload stuff from + other places too. This is only used when build for W32. */ +void +agent_sighup_action (void) +{ + log_info ("SIGHUP received - " + "re-reading configuration and flushing cache\n"); + agent_flush_cache (); + reread_configuration (); + agent_reload_trustlist (); +} + + +static void +agent_sigusr2_action (void) +{ + if (opt.verbose) + log_info ("SIGUSR2 received - updating card event counter\n"); + /* Nothing to check right now. We only increment a counter. */ + bump_card_eventcounter (); +} + + +static void +handle_signal (int signo) +{ + switch (signo) + { +#ifndef HAVE_W32_SYSTEM + case SIGHUP: + agent_sighup_action (); + break; + + case SIGUSR1: + log_info ("SIGUSR1 received - printing internal information:\n"); + pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); + agent_query_dump_state (); + agent_scd_dump_state (); + break; + + case SIGUSR2: + agent_sigusr2_action (); + 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 (); + agent_exit (0); + } + break; + + case SIGINT: + log_info ("SIGINT received - immediate shutdown\n"); + log_info( "%s %s stopped\n", strusage(11), strusage(13)); + cleanup (); + agent_exit (0); + break; +#endif + default: + log_info ("signal %d received - no action defined\n", signo); + } +} + + +/* Check the nonce on a new connection. This is a NOP unless we we + are using our Unix domain socket emulation under Windows. */ +static int +check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce) +{ + if (assuan_sock_check_nonce (ctrl->thread_startup.fd, nonce)) + { + log_info (_("error reading nonce on fd %d: %s\n"), + FD2INT(ctrl->thread_startup.fd), strerror (errno)); + assuan_sock_close (ctrl->thread_startup.fd); + xfree (ctrl); + return -1; + } + else + return 0; +} + + +/* This is the standard connection thread's main function. */ +static void * +start_connection_thread (void *arg) +{ + ctrl_t ctrl = arg; + + if (check_nonce (ctrl, &socket_nonce)) + return NULL; + + agent_init_default_ctrl (ctrl); + if (opt.verbose) + log_info (_("handler 0x%lx for fd %d started\n"), + pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + + start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd); + if (opt.verbose) + log_info (_("handler 0x%lx for fd %d terminated\n"), + pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + + agent_deinit_default_ctrl (ctrl); + xfree (ctrl); + return NULL; +} + + +/* This is the ssh connection thread's main function. */ +static void * +start_connection_thread_ssh (void *arg) +{ + ctrl_t ctrl = arg; + + if (check_nonce (ctrl, &socket_nonce_ssh)) + return NULL; + + agent_init_default_ctrl (ctrl); + if (opt.verbose) + log_info (_("ssh handler 0x%lx for fd %d started\n"), + pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + + start_command_handler_ssh (ctrl, ctrl->thread_startup.fd); + if (opt.verbose) + log_info (_("ssh handler 0x%lx for fd %d terminated\n"), + pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + + agent_deinit_default_ctrl (ctrl); + xfree (ctrl); + return NULL; +} + + +/* Connection handler loop. Wait for connection requests and spawn a + thread after accepting a connection. */ +static void +handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) +{ + pth_attr_t tattr; + pth_event_t ev, time_ev; + sigset_t sigs; + int signo; + struct sockaddr_un paddr; + socklen_t plen; + fd_set fdset, read_fdset; + int ret; + gnupg_fd_t fd; + int nfd; + + tattr = pth_attr_new(); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); + +#ifndef HAVE_W32_SYSTEM /* fixme */ + /* Make sure that the signals we are going to handle are not blocked + and create an event object for them. We also set the default + action to ignore because we use an Pth event to get notified + about signals. This avoids that the default action is taken in + case soemthing goes wrong within Pth. The problem might also be + a Pth bug. */ + sigemptyset (&sigs ); + { + static const int mysigs[] = { SIGHUP, SIGUSR1, SIGUSR2, SIGINT, SIGTERM }; + struct sigaction sa; + int i; + + for (i=0; i < DIM (mysigs); i++) + { + sigemptyset (&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigaction (mysigs[i], &sa, NULL); + + sigaddset (&sigs, mysigs[i]); + } + } + + pth_sigmask (SIG_UNBLOCK, &sigs, NULL); + ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +#else +# ifdef PTH_EVENT_HANDLE + sigs = 0; + ev = pth_event (PTH_EVENT_HANDLE, get_agent_scd_notify_event ()); + signo = 0; +# else + /* Use a dummy event. */ + sigs = 0; + ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +# endif +#endif + time_ev = NULL; + + /* Set a flag to tell call-scd.c that it may enable event + notifications. */ + opt.sigusr2_enabled = 1; + + FD_ZERO (&fdset); + FD_SET (FD2INT (listen_fd), &fdset); + nfd = FD2INT (listen_fd); + if (listen_fd_ssh != GNUPG_INVALID_FD) + { + FD_SET ( FD2INT(listen_fd_ssh), &fdset); + if (FD2INT (listen_fd_ssh) > nfd) + nfd = FD2INT (listen_fd_ssh); + } + + for (;;) + { + /* Make sure that our signals are not blocked. */ + pth_sigmask (SIG_UNBLOCK, &sigs, NULL); + + /* Shutdown test. */ + if (shutdown_pending) + { + if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) + break; /* ready */ + + /* Do not accept new connections but keep on running the + loop to cope with the timer events. */ + FD_ZERO (&fdset); + } + + /* Create a timeout event if needed. To help with power saving + we syncronize the ticks to the next full second. */ + if (!time_ev) + { + pth_time_t nexttick; + + nexttick = pth_timeout (TIMERTICK_INTERVAL, 0); + if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */ + { + nexttick.tv_sec++; + nexttick.tv_usec = 0; + } + time_ev = pth_event (PTH_EVENT_TIME, nexttick); + } + + /* POSIX says that fd_set should be implemented as a structure, + thus a simple assignment is fine to copy the entire set. */ + read_fdset = fdset; + + if (time_ev) + pth_event_concat (ev, time_ev, NULL); + ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev); + if (time_ev) + pth_event_isolate (time_ev); + + if (ret == -1) + { + if (pth_event_occurred (ev) + || (time_ev && pth_event_occurred (time_ev))) + { + if (pth_event_occurred (ev)) + { +#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE) + agent_sigusr2_action (); +#else + handle_signal (signo); +#endif + } + if (time_ev && pth_event_occurred (time_ev)) + { + pth_event_free (time_ev, PTH_FREE_ALL); + time_ev = NULL; + handle_tick (); + } + continue; + } + log_error (_("pth_select failed: %s - waiting 1s\n"), + strerror (errno)); + pth_sleep (1); + continue; + } + + if (pth_event_occurred (ev)) + { +#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE) + agent_sigusr2_action (); +#else + handle_signal (signo); +#endif + } + + if (time_ev && pth_event_occurred (time_ev)) + { + pth_event_free (time_ev, PTH_FREE_ALL); + time_ev = NULL; + handle_tick (); + } + + + /* We now might create new threads and because we don't want any + signals (as we are handling them here) to be delivered to a + new thread. Thus we need to block those signals. */ + pth_sigmask (SIG_BLOCK, &sigs, NULL); + + if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset)) + { + ctrl_t ctrl; + + plen = sizeof paddr; + fd = INT2FD (pth_accept (FD2INT(listen_fd), + (struct sockaddr *)&paddr, &plen)); + if (fd == GNUPG_INVALID_FD) + { + log_error ("accept failed: %s\n", strerror (errno)); + } + else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) ) + { + log_error ("error allocating connection control data: %s\n", + strerror (errno) ); + assuan_sock_close (fd); + } + else if ( !(ctrl->session_env = session_env_new ()) ) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + assuan_sock_close (fd); + } + else + { + char threadname[50]; + + snprintf (threadname, sizeof threadname-1, + "conn fd=%d (gpg)", FD2INT(fd)); + threadname[sizeof threadname -1] = 0; + pth_attr_set (tattr, PTH_ATTR_NAME, threadname); + ctrl->thread_startup.fd = fd; + if (!pth_spawn (tattr, start_connection_thread, ctrl)) + { + log_error ("error spawning connection handler: %s\n", + strerror (errno) ); + assuan_sock_close (fd); + xfree (ctrl); + } + } + fd = GNUPG_INVALID_FD; + } + + if (!shutdown_pending && listen_fd_ssh != GNUPG_INVALID_FD + && FD_ISSET ( FD2INT (listen_fd_ssh), &read_fdset)) + { + ctrl_t ctrl; + + plen = sizeof paddr; + fd = INT2FD(pth_accept (FD2INT(listen_fd_ssh), + (struct sockaddr *)&paddr, &plen)); + if (fd == GNUPG_INVALID_FD) + { + log_error ("accept failed for ssh: %s\n", strerror (errno)); + } + else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) ) + { + log_error ("error allocating connection control data: %s\n", + strerror (errno) ); + assuan_sock_close (fd); + } + else if ( !(ctrl->session_env = session_env_new ()) ) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + assuan_sock_close (fd); + } + else + { + char threadname[50]; + + agent_init_default_ctrl (ctrl); + snprintf (threadname, sizeof threadname-1, + "conn fd=%d (ssh)", FD2INT(fd)); + threadname[sizeof threadname -1] = 0; + pth_attr_set (tattr, PTH_ATTR_NAME, threadname); + ctrl->thread_startup.fd = fd; + if (!pth_spawn (tattr, start_connection_thread_ssh, ctrl) ) + { + log_error ("error spawning ssh connection handler: %s\n", + strerror (errno) ); + assuan_sock_close (fd); + xfree (ctrl); + } + } + fd = GNUPG_INVALID_FD; + } + } + + pth_event_free (ev, PTH_FREE_ALL); + if (time_ev) + pth_event_free (time_ev, PTH_FREE_ALL); + cleanup (); + log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); +} + + + +/* Helper for check_own_socket. */ +static gpg_error_t +check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length) +{ + membuf_t *mb = opaque; + put_membuf (mb, buffer, length); + return 0; +} + + +/* The thread running the actual check. We need to run this in a + separate thread so that check_own_thread can be called from the + timer tick. */ +static void * +check_own_socket_thread (void *arg) +{ + int rc; + char *sockname = arg; + assuan_context_t ctx = NULL; + membuf_t mb; + char *buffer; + + check_own_socket_running++; + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); + goto leave; + } + + rc = assuan_socket_connect (ctx, sockname, (pid_t)(-1), 0); + if (rc) + { + log_error ("can't connect my own socket: %s\n", gpg_strerror (rc)); + goto leave; + } + + init_membuf (&mb, 100); + rc = assuan_transact (ctx, "GETINFO pid", check_own_socket_pid_cb, &mb, + NULL, NULL, NULL, NULL); + put_membuf (&mb, "", 1); + buffer = get_membuf (&mb, NULL); + if (rc || !buffer) + { + log_error ("sending command \"%s\" to my own socket failed: %s\n", + "GETINFO pid", gpg_strerror (rc)); + rc = 1; + } + else if ( (pid_t)strtoul (buffer, NULL, 10) != getpid ()) + { + log_error ("socket is now serviced by another server\n"); + rc = 1; + } + else if (opt.verbose > 1) + log_error ("socket is still served by this server\n"); + + xfree (buffer); + + leave: + xfree (sockname); + if (ctx) + assuan_release (ctx); + if (rc) + { + /* We may not remove the socket as it is now in use by another + server. Setting the name to empty does this. */ + if (socket_name) + *socket_name = 0; + if (socket_name_ssh) + *socket_name_ssh = 0; + shutdown_pending = 2; + log_info ("this process is useless - shutting down\n"); + } + check_own_socket_running--; + return NULL; +} + + +/* Check whether we are still listening on our own socket. In case + another gpg-agent process started after us has taken ownership of + our socket, we woul linger around without any real taks. Thus we + better check once in a while whether we are really needed. */ +static void +check_own_socket (void) +{ + char *sockname; + pth_attr_t tattr; + + if (!opt.use_standard_socket) + return; /* This check makes only sense in standard socket mode. */ + + if (check_own_socket_running || shutdown_pending) + return; /* Still running or already shutting down. */ + + sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); + if (!sockname) + return; /* Out of memory. */ + + tattr = pth_attr_new(); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); + pth_attr_set (tattr, PTH_ATTR_NAME, "check-own-socket"); + + if (!pth_spawn (tattr, check_own_socket_thread, sockname)) + log_error ("error spawning check_own_socket_thread: %s\n", + strerror (errno) ); + pth_attr_destroy (tattr); +} + + + +/* Figure out whether an agent is available and running. Prints an + error if not. If SILENT is true, no messages are printed. Usually + started with MODE 0. Returns 0 if the agent is running. */ +static int +check_for_running_agent (int silent, int mode) +{ + int rc; + char *infostr, *p; + assuan_context_t ctx = NULL; + int prot, pid; + + if (!mode) + { + infostr = getenv ("GPG_AGENT_INFO"); + if (!infostr || !*infostr) + { + if (!check_for_running_agent (silent, 1)) + return 0; /* Okay, its running on the standard socket. */ + if (!silent) + log_error (_("no gpg-agent running in this session\n")); + return -1; + } + + infostr = xstrdup (infostr); + if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) + { + xfree (infostr); + if (!check_for_running_agent (silent, 1)) + return 0; /* Okay, its running on the standard socket. */ + if (!silent) + log_error (_("malformed GPG_AGENT_INFO environment variable\n")); + return -1; + } + + *p++ = 0; + pid = atoi (p); + while (*p && *p != PATHSEP_C) + p++; + prot = *p? atoi (p+1) : 0; + if (prot != 1) + { + xfree (infostr); + if (!silent) + log_error (_("gpg-agent protocol version %d is not supported\n"), + prot); + if (!check_for_running_agent (silent, 1)) + return 0; /* Okay, its running on the standard socket. */ + return -1; + } + } + else /* MODE != 0 */ + { + infostr = make_filename (opt.homedir, "S.gpg-agent", NULL); + pid = (pid_t)(-1); + } + + rc = assuan_new (&ctx); + if (! rc) + rc = assuan_socket_connect (ctx, infostr, pid, 0); + xfree (infostr); + if (rc) + { + if (!mode && !check_for_running_agent (silent, 1)) + return 0; /* Okay, its running on the standard socket. */ + + if (!mode && !silent) + log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); + + if (ctx) + assuan_release (ctx); + return -1; + } + + if (!opt.quiet && !silent) + log_info ("gpg-agent running and available\n"); + + assuan_release (ctx); + return 0; +} diff --git a/agent/learncard.c b/agent/learncard.c new file mode 100644 index 0000000..77f2bb0 --- /dev/null +++ b/agent/learncard.c @@ -0,0 +1,472 @@ +/* learncard.c - Handle the LEARN command + * Copyright (C) 2002, 2003, 2004, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include + +/* Structures used by the callback mechanism to convey information + pertaining to key pairs. */ +struct keypair_info_s +{ + struct keypair_info_s *next; + int no_cert; + char *id; /* points into grip */ + char hexgrip[1]; /* The keygrip (i.e. a hash over the public key + parameters) formatted as a hex string. + Allocated somewhat large to also act as + memeory for the above ID field. */ +}; +typedef struct keypair_info_s *KEYPAIR_INFO; + +struct kpinfo_cb_parm_s +{ + ctrl_t ctrl; + int error; + KEYPAIR_INFO info; +}; + + +/* Structures used by the callback mechanism to convey information + pertaining to certificates. */ +struct certinfo_s { + struct certinfo_s *next; + int type; + int done; + char id[1]; +}; +typedef struct certinfo_s *CERTINFO; + +struct certinfo_cb_parm_s +{ + ctrl_t ctrl; + int error; + CERTINFO info; +}; + + +/* Structures used by the callback mechanism to convey assuan status + lines. */ +struct sinfo_s { + struct sinfo_s *next; + char *data; /* Points into keyword. */ + char keyword[1]; +}; +typedef struct sinfo_s *SINFO; + +struct sinfo_cb_parm_s { + int error; + SINFO info; +}; + + +/* Destructor for key information objects. */ +static void +release_keypair_info (KEYPAIR_INFO info) +{ + while (info) + { + KEYPAIR_INFO tmp = info->next; + xfree (info); + info = tmp; + } +} + +/* Destructor for certificate information objects. */ +static void +release_certinfo (CERTINFO info) +{ + while (info) + { + CERTINFO tmp = info->next; + xfree (info); + info = tmp; + } +} + +/* Destructor for status information objects. */ +static void +release_sinfo (SINFO info) +{ + while (info) + { + SINFO tmp = info->next; + xfree (info); + info = tmp; + } +} + + + +/* This callback is used by agent_card_learn and passed the content of + all KEYPAIRINFO lines. It merely stores this data away */ +static void +kpinfo_cb (void *opaque, const char *line) +{ + struct kpinfo_cb_parm_s *parm = opaque; + KEYPAIR_INFO item; + char *p; + + if (parm->error) + return; /* no need to gather data after an error coccured */ + + if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS", + "learncard", "k", "0", "0", NULL))) + return; + + item = xtrycalloc (1, sizeof *item + strlen (line)); + if (!item) + { + parm->error = out_of_core (); + return; + } + strcpy (item->hexgrip, line); + for (p = item->hexgrip; hexdigitp (p); p++) + ; + if (p == item->hexgrip && *p == 'X' && spacep (p+1)) + { + item->no_cert = 1; + p++; + } + else if ((p - item->hexgrip) != 40 || !spacep (p)) + { /* not a 20 byte hex keygrip or not followed by a space */ + parm->error = gpg_error (GPG_ERR_INV_RESPONSE); + xfree (item); + return; + } + *p++ = 0; + while (spacep (p)) + p++; + item->id = p; + while (*p && !spacep (p)) + p++; + if (p == item->id) + { /* invalid ID string */ + parm->error = gpg_error (GPG_ERR_INV_RESPONSE); + xfree (item); + return; + } + *p = 0; /* ignore trailing stuff */ + + /* store it */ + item->next = parm->info; + parm->info = item; +} + + +/* This callback is used by agent_card_learn and passed the content of + all CERTINFO lines. It merely stores this data away */ +static void +certinfo_cb (void *opaque, const char *line) +{ + struct certinfo_cb_parm_s *parm = opaque; + CERTINFO item; + int type; + char *p, *pend; + + if (parm->error) + return; /* no need to gather data after an error coccured */ + + if ((parm->error = agent_write_status (parm->ctrl, "PROGRESS", + "learncard", "c", "0", "0", NULL))) + return; + + type = strtol (line, &p, 10); + while (spacep (p)) + p++; + for (pend = p; *pend && !spacep (pend); pend++) + ; + if (p == pend || !*p) + { + parm->error = gpg_error (GPG_ERR_INV_RESPONSE); + return; + } + *pend = 0; /* ignore trailing stuff */ + + item = xtrycalloc (1, sizeof *item + strlen (p)); + if (!item) + { + parm->error = out_of_core (); + return; + } + item->type = type; + strcpy (item->id, p); + /* store it */ + item->next = parm->info; + parm->info = item; +} + + +/* This callback is used by agent_card_learn and passed the content of + all SINFO lines. It merely stores this data away */ +static void +sinfo_cb (void *opaque, const char *keyword, size_t keywordlen, + const char *data) +{ + struct sinfo_cb_parm_s *sparm = opaque; + SINFO item; + + if (sparm->error) + return; /* no need to gather data after an error coccured */ + + item = xtrycalloc (1, sizeof *item + keywordlen + 1 + strlen (data)); + if (!item) + { + sparm->error = out_of_core (); + return; + } + memcpy (item->keyword, keyword, keywordlen); + item->data = item->keyword + keywordlen; + *item->data = 0; + item->data++; + strcpy (item->data, data); + /* store it */ + item->next = sparm->info; + sparm->info = item; +} + + + +static int +send_cert_back (ctrl_t ctrl, const char *id, void *assuan_context) +{ + int rc; + char *derbuf; + size_t derbuflen; + + rc = agent_card_readcert (ctrl, id, &derbuf, &derbuflen); + if (rc) + { + const char *action; + + switch (gpg_err_code (rc)) + { + case GPG_ERR_INV_ID: + case GPG_ERR_NOT_FOUND: + action = " - ignored"; + break; + default: + action = ""; + break; + } + if (opt.verbose || !*action) + log_info ("error reading certificate `%s': %s%s\n", + id? id:"?", gpg_strerror (rc), action); + + return *action? 0 : rc; + } + + rc = assuan_send_data (assuan_context, derbuf, derbuflen); + xfree (derbuf); + if (!rc) + rc = assuan_send_data (assuan_context, NULL, 0); + if (!rc) + rc = assuan_write_line (assuan_context, "END"); + if (rc) + { + log_error ("sending certificate failed: %s\n", + gpg_strerror (rc)); + return rc; + } + return 0; +} + +/* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new + certificates are send back via Assuan. */ +int +agent_handle_learn (ctrl_t ctrl, void *assuan_context) +{ + int rc; + + struct kpinfo_cb_parm_s parm; + struct certinfo_cb_parm_s cparm; + struct sinfo_cb_parm_s sparm; + char *serialno = NULL; + KEYPAIR_INFO item; + SINFO sitem; + unsigned char grip[20]; + char *p; + int i; + static int certtype_list[] = { + 111, /* Root CA */ + 101, /* trusted */ + 102, /* useful */ + 100, /* regular */ + /* We don't include 110 here because gpgsm can't handle that + special root CA format. */ + -1 /* end of list */ + }; + + + memset (&parm, 0, sizeof parm); + memset (&cparm, 0, sizeof cparm); + memset (&sparm, 0, sizeof sparm); + parm.ctrl = ctrl; + cparm.ctrl = ctrl; + + /* Check whether a card is present and get the serial number */ + rc = agent_card_serialno (ctrl, &serialno); + if (rc) + goto leave; + + /* Now gather all the available info. */ + rc = agent_card_learn (ctrl, kpinfo_cb, &parm, certinfo_cb, &cparm, + sinfo_cb, &sparm); + if (!rc && (parm.error || cparm.error || sparm.error)) + rc = parm.error? parm.error : cparm.error? cparm.error : sparm.error; + if (rc) + { + log_debug ("agent_card_learn failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + log_info ("card has S/N: %s\n", serialno); + + /* Pass on all the collected status information. */ + if (assuan_context) + { + for (sitem = sparm.info; sitem; sitem = sitem->next) + { + assuan_write_status (assuan_context, sitem->keyword, sitem->data); + } + } + + /* Write out the certificates in a standard order. */ + for (i=0; certtype_list[i] != -1; i++) + { + CERTINFO citem; + for (citem = cparm.info; citem; citem = citem->next) + { + if (certtype_list[i] != citem->type) + continue; + + if (opt.verbose) + log_info (" id: %s (type=%d)\n", + citem->id, citem->type); + + if (assuan_context) + { + rc = send_cert_back (ctrl, citem->id, assuan_context); + if (rc) + goto leave; + citem->done = 1; + } + } + } + + for (item = parm.info; item; item = item->next) + { + unsigned char *pubkey, *shdkey; + size_t n; + + if (opt.verbose) + log_info (" id: %s (grip=%s)\n", item->id, item->hexgrip); + + if (item->no_cert) + continue; /* No public key yet available. */ + + if (assuan_context) + { + agent_write_status (ctrl, "KEYPAIRINFO", + item->hexgrip, item->id, NULL); + } + + for (p=item->hexgrip, i=0; i < 20; p += 2, i++) + grip[i] = xtoi_2 (p); + + if (!agent_key_available (grip)) + continue; /* The key is already available. */ + + /* Unknown key - store it. */ + rc = agent_card_readkey (ctrl, item->id, &pubkey); + if (rc) + { + log_debug ("agent_card_readkey failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + { + unsigned char *shadow_info = make_shadow_info (serialno, item->id); + if (!shadow_info) + { + rc = gpg_error (GPG_ERR_ENOMEM); + xfree (pubkey); + goto leave; + } + rc = agent_shadow_key (pubkey, shadow_info, &shdkey); + xfree (shadow_info); + } + xfree (pubkey); + if (rc) + { + log_error ("shadowing the key failed: %s\n", gpg_strerror (rc)); + goto leave; + } + n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); + assert (n); + + rc = agent_write_private_key (grip, shdkey, n, 0); + xfree (shdkey); + if (rc) + { + log_error ("error writing key: %s\n", gpg_strerror (rc)); + goto leave; + } + + if (opt.verbose) + log_info ("stored\n"); + + if (assuan_context) + { + CERTINFO citem; + + /* only send the certificate if we have not done so before */ + for (citem = cparm.info; citem; citem = citem->next) + { + if (!strcmp (citem->id, item->id)) + break; + } + if (!citem) + { + rc = send_cert_back (ctrl, item->id, assuan_context); + if (rc) + goto leave; + } + } + } + + + leave: + xfree (serialno); + release_keypair_info (parm.info); + release_certinfo (cparm.info); + release_sinfo (sparm.info); + return rc; +} + + diff --git a/agent/minip12.c b/agent/minip12.c new file mode 100644 index 0000000..2471717 --- /dev/null +++ b/agent/minip12.c @@ -0,0 +1,2360 @@ +/* minip12.c - A minimal pkcs-12 implementation. + * Copyright (C) 2002, 2003, 2004, 2006 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 3 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, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include + +#ifdef TEST +#include +#include +#endif + +#include "../jnlib/logging.h" +#include "../jnlib/utf8conv.h" +#include "minip12.h" + +#ifndef DIM +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#endif + + +enum +{ + UNIVERSAL = 0, + APPLICATION = 1, + ASNCONTEXT = 2, + PRIVATE = 3 +}; + + +enum +{ + 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 +}; + + +static unsigned char const oid_data[9] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 }; +static unsigned char const oid_encryptedData[9] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 }; +static unsigned char const oid_pkcs_12_keyBag[11] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x01 }; +static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 }; +static unsigned char const oid_pkcs_12_CertBag[11] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 }; +static unsigned char const oid_pkcs_12_CrlBag[11] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 }; + +static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 }; +static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 }; +static unsigned char const oid_x509Certificate_for_pkcs_12[10] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 }; + + +static unsigned char const oid_rsaEncryption[9] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; + + +static unsigned char const data_3desiter2048[30] = { + 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, + 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 }; +#define DATA_3DESITER2048_SALT_OFF 18 + +static unsigned char const data_rc2iter2048[30] = { + 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E, + 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 }; +#define DATA_RC2ITER2048_SALT_OFF 18 + +static unsigned char const data_mactemplate[51] = { + 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, + 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, + 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, + 0x02, 0x08, 0x00 }; +#define DATA_MACTEMPLATE_MAC_OFF 17 +#define DATA_MACTEMPLATE_SALT_OFF 39 + +static unsigned char const data_attrtemplate[106] = { + 0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, + 0x48, 0x1e, 0x46, 0x00, 0x47, 0x00, 0x6e, 0x00, + 0x75, 0x00, 0x50, 0x00, 0x47, 0x00, 0x20, 0x00, + 0x65, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, + 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x20, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, + 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, + 0x66, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, + 0x04, 0x14 }; /* Need to append SHA-1 digest. */ +#define DATA_ATTRTEMPLATE_KEYID_OFF 73 + +struct buffer_s +{ + unsigned char *buffer; + size_t length; +}; + + +struct tag_info +{ + int class; + int is_constructed; + unsigned long tag; + unsigned long length; /* length part of the TLV */ + int nhdr; + int ndef; /* It is an indefinite length */ +}; + + +/* Parse the buffer at the address BUFFER which is of SIZE and return + the tag and the length part from the TLV triplet. Update BUFFER + and SIZE on success. Checks that the encoded length does not + exhaust the length of the provided buffer. */ +static int +parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) +{ + int c; + unsigned long tag; + const unsigned char *buf = *buffer; + size_t length = *size; + + ti->length = 0; + ti->ndef = 0; + ti->nhdr = 0; + + /* Get the tag */ + if (!length) + return -1; /* premature eof */ + c = *buf++; length--; + ti->nhdr++; + + ti->class = (c & 0xc0) >> 6; + ti->is_constructed = !!(c & 0x20); + tag = c & 0x1f; + + if (tag == 0x1f) + { + tag = 0; + do + { + tag <<= 7; + if (!length) + return -1; /* premature eof */ + c = *buf++; length--; + ti->nhdr++; + tag |= c & 0x7f; + } + while (c & 0x80); + } + ti->tag = tag; + + /* Get the length */ + if (!length) + return -1; /* prematureeof */ + c = *buf++; length--; + ti->nhdr++; + + if ( !(c & 0x80) ) + ti->length = c; + else if (c == 0x80) + ti->ndef = 1; + else if (c == 0xff) + return -1; /* forbidden length value */ + else + { + unsigned long len = 0; + int count = c & 0x7f; + + for (; count; count--) + { + len <<= 8; + if (!length) + return -1; /* premature_eof */ + c = *buf++; length--; + ti->nhdr++; + len |= c & 0xff; + } + ti->length = len; + } + + if (ti->class == UNIVERSAL && !ti->tag) + ti->length = 0; + + if (ti->length > length) + return -1; /* data larger than buffer. */ + + *buffer = buf; + *size = length; + return 0; +} + + +/* Given an ASN.1 chunk of a structure like: + + 24 NDEF: OCTET STRING -- This is not passed to us + 04 1: OCTET STRING -- INPUT point s to here + : 30 + 04 1: OCTET STRING + : 80 + [...] + 04 2: OCTET STRING + : 00 00 + : } -- This denotes a Null tag and are the last + -- two bytes in INPUT. + + Create a new buffer with the content of that octet string. INPUT + is the orginal buffer with a length as stored at LENGTH. Returns + NULL on error or a new malloced buffer with the length of this new + buffer stored at LENGTH and the number of bytes parsed from input + are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is + allowed to be passed as NULL if the caller is not interested in + this value. */ +static unsigned char * +cram_octet_string (const unsigned char *input, size_t *length, + size_t *input_consumed) +{ + const unsigned char *s = input; + size_t n = *length; + unsigned char *output, *d; + struct tag_info ti; + + /* Allocate output buf. We know that it won't be longer than the + input buffer. */ + d = output = gcry_malloc (n); + if (!output) + goto bailout; + + for (;;) + { + if (parse_tag (&s, &n, &ti)) + goto bailout; + if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING + && !ti.ndef && !ti.is_constructed) + { + memcpy (d, s, ti.length); + s += ti.length; + d += ti.length; + n -= ti.length; + } + else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed) + break; /* Ready */ + else + goto bailout; + } + + + *length = d - output; + if (input_consumed) + *input_consumed += s - input; + return output; + + bailout: + if (input_consumed) + *input_consumed += s - input; + gcry_free (output); + return NULL; +} + + + +static int +string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw, + int req_keylen, unsigned char *keybuf) +{ + int rc, i, j; + gcry_md_hd_t md; + gcry_mpi_t num_b1 = NULL; + int pwlen; + unsigned char hash[20], buf_b[64], buf_i[128], *p; + size_t cur_keylen; + size_t n; + + cur_keylen = 0; + pwlen = strlen (pw); + if (pwlen > 63/2) + { + log_error ("password too long\n"); + return -1; + } + + if (saltlen < 8) + { + log_error ("salt too short\n"); + return -1; + } + + /* Store salt and password in BUF_I */ + p = buf_i; + for(i=0; i < 64; i++) + *p++ = salt [i%saltlen]; + for(i=j=0; i < 64; i += 2) + { + *p++ = 0; + *p++ = pw[j]; + if (++j > pwlen) /* Note, that we include the trailing zero */ + j = 0; + } + + for (;;) + { + rc = gcry_md_open (&md, GCRY_MD_SHA1, 0); + if (rc) + { + log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc)); + return rc; + } + for(i=0; i < 64; i++) + gcry_md_putc (md, id); + gcry_md_write (md, buf_i, 128); + memcpy (hash, gcry_md_read (md, 0), 20); + gcry_md_close (md); + for (i=1; i < iter; i++) + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20); + + for (i=0; i < 20 && cur_keylen < req_keylen; i++) + keybuf[cur_keylen++] = hash[i]; + if (cur_keylen == req_keylen) + { + gcry_mpi_release (num_b1); + return 0; /* ready */ + } + + /* need more bytes. */ + for(i=0; i < 64; i++) + buf_b[i] = hash[i % 20]; + rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n); + if (rc) + { + log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc)); + return -1; + } + gcry_mpi_add_ui (num_b1, num_b1, 1); + for (i=0; i < 128; i += 64) + { + gcry_mpi_t num_ij; + + rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n); + if (rc) + { + log_error ( "gcry_mpi_scan failed: %s\n", + gpg_strerror (rc)); + return -1; + } + gcry_mpi_add (num_ij, num_ij, num_b1); + gcry_mpi_clear_highbit (num_ij, 64*8); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij); + if (rc) + { + log_error ( "gcry_mpi_print failed: %s\n", + gpg_strerror (rc)); + return -1; + } + gcry_mpi_release (num_ij); + } + } +} + + +static int +set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, + const char *pw, int keybytes) +{ + unsigned char keybuf[24]; + int rc; + + assert (keybytes == 5 || keybytes == 24); + if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf)) + return -1; + rc = gcry_cipher_setkey (chd, keybuf, keybytes); + if (rc) + { + log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc)); + return -1; + } + + if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf)) + return -1; + rc = gcry_cipher_setiv (chd, keybuf, 8); + if (rc) + { + log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc)); + return -1; + } + return 0; +} + + +static void +crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, + int iter, const char *pw, int cipher_algo, int encrypt) +{ + gcry_cipher_hd_t chd; + int rc; + + rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); + if (rc) + { + log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc)); + wipememory (buffer, length); + return; + } + if (set_key_iv (chd, salt, saltlen, iter, pw, + cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24)) + { + wipememory (buffer, length); + goto leave; + } + + rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0) + : gcry_cipher_decrypt (chd, buffer, length, NULL, 0); + + if (rc) + { + wipememory (buffer, length); + log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + leave: + gcry_cipher_close (chd); +} + + +/* Decrypt a block of data and try several encodings of the key. + CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is + a buffer of the same size to receive the decryption result. SALT, + SALTLEN, ITER and PW are the information required for decryption + and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a + function called with the plaintext and used to check whether the + decryption succeeded; i.e. that a correct passphrase has been + given. That function shall return true if the decryption has likely + succeeded. */ +static void +decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, + char *salt, size_t saltlen, + int iter, const char *pw, int cipher_algo, + int (*check_fnc) (const void *, size_t)) +{ + static const char * const charsets[] = { + "", /* No conversion - use the UTF-8 passphrase direct. */ + "ISO-8859-1", + "ISO-8859-15", + "ISO-8859-2", + "ISO-8859-3", + "ISO-8859-4", + "ISO-8859-5", + "ISO-8859-6", + "ISO-8859-7", + "ISO-8859-8", + "ISO-8859-9", + "KOI8-R", + "IBM437", + "IBM850", + "EUC-JP", + "BIG5", + NULL + }; + int charsetidx = 0; + char *convertedpw = NULL; /* Malloced and converted password or NULL. */ + size_t convertedpwsize = 0; /* Allocated length. */ + + for (charsetidx=0; charsets[charsetidx]; charsetidx++) + { + if (*charsets[charsetidx]) + { + jnlib_iconv_t cd; + const char *inptr; + char *outptr; + size_t inbytes, outbytes; + + if (!convertedpw) + { + /* We assume one byte encodings. Thus we can allocate + the buffer of the same size as the original + passphrase; the result will actually be shorter + then. */ + convertedpwsize = strlen (pw) + 1; + convertedpw = gcry_malloc_secure (convertedpwsize); + if (!convertedpw) + { + log_info ("out of secure memory while" + " converting passphrase\n"); + break; /* Give up. */ + } + } + + cd = jnlib_iconv_open (charsets[charsetidx], "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) + continue; + + inptr = pw; + inbytes = strlen (pw); + outptr = convertedpw; + outbytes = convertedpwsize - 1; + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, + &outptr, &outbytes) == (size_t)-1) + { + jnlib_iconv_close (cd); + continue; + } + *outptr = 0; + jnlib_iconv_close (cd); + log_info ("decryption failed; trying charset `%s'\n", + charsets[charsetidx]); + } + memcpy (plaintext, ciphertext, length); + crypt_block (plaintext, length, salt, saltlen, iter, + convertedpw? convertedpw:pw, cipher_algo, 0); + if (check_fnc (plaintext, length)) + break; /* Decryption succeeded. */ + } + gcry_free (convertedpw); +} + + +/* Return true if the decryption of an bag_encrypted_data object has + likely succeeded. */ +static int +bag_decrypted_data_p (const void *plaintext, size_t length) +{ + struct tag_info ti; + const unsigned char *p = plaintext; + size_t n = length; + + /* { */ + /* # warning debug code is enabled */ + /* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */ + /* if (!fp || fwrite (p, n, 1, fp) != 1) */ + /* exit (2); */ + /* fclose (fp); */ + /* } */ + + if (parse_tag (&p, &n, &ti)) + return 0; + if (ti.class || ti.tag != TAG_SEQUENCE) + return 0; + if (parse_tag (&p, &n, &ti)) + return 0; + + return 1; +} + +/* Note: If R_RESULT is passed as NULL, a key object as already be + processed and thus we need to skip it here. */ +static int +parse_bag_encrypted_data (const unsigned char *buffer, size_t length, + int startoffset, size_t *r_consumed, const char *pw, + void (*certcb)(void*, const unsigned char*, size_t), + void *certcbarg, gcry_mpi_t **r_result) +{ + struct tag_info ti; + const unsigned char *p = buffer; + const unsigned char *p_start = buffer; + size_t n = length; + const char *where; + char salt[20]; + size_t saltlen; + unsigned int iter; + unsigned char *plain = NULL; + int bad_pass = 0; + unsigned char *cram_buffer = NULL; + size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */ + int is_3des = 0; + gcry_mpi_t *result = NULL; + int result_count; + + if (r_result) + *r_result = NULL; + where = "start"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_SEQUENCE) + goto bailout; + + where = "bag.encryptedData.version"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0) + goto bailout; + p++; n--; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_SEQUENCE) + goto bailout; + + where = "bag.encryptedData.data"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) + || memcmp (p, oid_data, DIM(oid_data))) + goto bailout; + p += DIM(oid_data); + n -= DIM(oid_data); + + where = "bag.encryptedData.keyinfo"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC) + && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC, + DIM(oid_pbeWithSHAAnd40BitRC2_CBC))) + { + p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC); + n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC); + } + else if (!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) + && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, + DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) + { + p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + is_3des = 1; + } + else + goto bailout; + + where = "rc2or3des-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING + || ti.length < 8 || ti.length > 20 ) + goto bailout; + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) + goto bailout; + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } + + where = "rc2or3des-ciphertext"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + + consumed = p - p_start; + if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef) + { + /* Mozilla exported certs now come with single byte chunks of + octect strings. (Mozilla Firefox 1.0.4). Arghh. */ + where = "cram-rc2or3des-ciphertext"; + cram_buffer = cram_octet_string ( p, &n, &consumed); + if (!cram_buffer) + goto bailout; + p = p_start = cram_buffer; + if (r_consumed) + *r_consumed = consumed; + r_consumed = NULL; /* Ugly hack to not update that value any further. */ + ti.length = n; + } + else if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.length ) + ; + else + goto bailout; + + log_info ("%lu bytes of %s encrypted text\n",ti.length,is_3des?"3DES":"RC2"); + + plain = gcry_malloc_secure (ti.length); + if (!plain) + { + log_error ("error allocating decryption buffer\n"); + goto bailout; + } + decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, + is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, + bag_decrypted_data_p); + n = ti.length; + startoffset = 0; + p_start = p = plain; + + where = "outer.outer.seq"; + if (parse_tag (&p, &n, &ti)) + { + bad_pass = 1; + goto bailout; + } + if (ti.class || ti.tag != TAG_SEQUENCE) + { + bad_pass = 1; + goto bailout; + } + + if (parse_tag (&p, &n, &ti)) + { + bad_pass = 1; + goto bailout; + } + + /* Loop over all certificates inside the bag. */ + while (n) + { + int iscrlbag = 0; + int iskeybag = 0; + + where = "certbag.nextcert"; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + + where = "certbag.objectidentifier"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OBJECT_ID) + goto bailout; + if ( ti.length == DIM(oid_pkcs_12_CertBag) + && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag))) + { + p += DIM(oid_pkcs_12_CertBag); + n -= DIM(oid_pkcs_12_CertBag); + } + else if ( ti.length == DIM(oid_pkcs_12_CrlBag) + && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag))) + { + p += DIM(oid_pkcs_12_CrlBag); + n -= DIM(oid_pkcs_12_CrlBag); + iscrlbag = 1; + } + else if ( ti.length == DIM(oid_pkcs_12_keyBag) + && !memcmp (p, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag))) + { + /* The TrustedMIME plugin for MS Outlook started to create + files with just one outer 3DES encrypted container and + inside the certificates as well as the key. */ + p += DIM(oid_pkcs_12_keyBag); + n -= DIM(oid_pkcs_12_keyBag); + iskeybag = 1; + } + else + goto bailout; + + where = "certbag.before.certheader"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (iscrlbag) + { + log_info ("skipping unsupported crlBag\n"); + p += ti.length; + n -= ti.length; + } + else if (iskeybag && (result || !r_result)) + { + log_info ("one keyBag already processed; skipping this one\n"); + p += ti.length; + n -= ti.length; + } + else if (iskeybag) + { + int len; + + log_info ("processing simple keyBag\n"); + + /* Fixme: This code is duplicated from parse_bag_data. */ + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER + || ti.length != 1 || *p) + goto bailout; + p++; n--; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + len = ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (len < ti.nhdr) + goto bailout; + len -= ti.nhdr; + if (ti.class || ti.tag != TAG_OBJECT_ID + || ti.length != DIM(oid_rsaEncryption) + || memcmp (p, oid_rsaEncryption, + DIM(oid_rsaEncryption))) + goto bailout; + p += DIM (oid_rsaEncryption); + n -= DIM (oid_rsaEncryption); + if (len < ti.length) + goto bailout; + len -= ti.length; + if (n < len) + goto bailout; + p += len; + n -= len; + if ( parse_tag (&p, &n, &ti) + || ti.class || ti.tag != TAG_OCTET_STRING) + goto bailout; + if ( parse_tag (&p, &n, &ti) + || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + len = ti.length; + + result = gcry_calloc (10, sizeof *result); + if (!result) + { + log_error ( "error allocating result array\n"); + goto bailout; + } + result_count = 0; + + where = "reading.keybag.key-parameters"; + for (result_count = 0; len && result_count < 9;) + { + if ( parse_tag (&p, &n, &ti) + || ti.class || ti.tag != TAG_INTEGER) + goto bailout; + if (len < ti.nhdr) + goto bailout; + len -= ti.nhdr; + if (len < ti.length) + goto bailout; + len -= ti.length; + if (!result_count && ti.length == 1 && !*p) + ; /* ignore the very first one if it is a 0 */ + else + { + int rc; + + rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p, + ti.length, NULL); + if (rc) + { + log_error ("error parsing key parameter: %s\n", + gpg_strerror (rc)); + goto bailout; + } + result_count++; + } + p += ti.length; + n -= ti.length; + } + if (len) + goto bailout; + } + else + { + log_info ("processing certBag\n"); + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OBJECT_ID + || ti.length != DIM(oid_x509Certificate_for_pkcs_12) + || memcmp (p, oid_x509Certificate_for_pkcs_12, + DIM(oid_x509Certificate_for_pkcs_12))) + goto bailout; + p += DIM(oid_x509Certificate_for_pkcs_12); + n -= DIM(oid_x509Certificate_for_pkcs_12); + + where = "certbag.before.octetstring"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef) + goto bailout; + + /* Return the certificate. */ + if (certcb) + certcb (certcbarg, p, ti.length); + + p += ti.length; + n -= ti.length; + } + + /* Ugly hack to cope with the padding: Forget about the rest if + that is less or equal to the cipher's block length. We can + reasonable assume that all valid data will be longer than + just one block. */ + if (n <= 8) + n = 0; + + /* Skip the optional SET with the pkcs12 cert attributes. */ + if (n) + { + where = "bag.attributes"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!ti.class && ti.tag == TAG_SEQUENCE) + ; /* No attributes. */ + else if (!ti.class && ti.tag == TAG_SET && !ti.ndef) + { /* The optional SET. */ + p += ti.length; + n -= ti.length; + if (n <= 8) + n = 0; + if (n && parse_tag (&p, &n, &ti)) + goto bailout; + } + else + goto bailout; + } + } + + if (r_consumed) + *r_consumed = consumed; + gcry_free (plain); + gcry_free (cram_buffer); + if (r_result) + *r_result = result; + return 0; + + bailout: + if (result) + { + int i; + + for (i=0; result[i]; i++) + gcry_mpi_release (result[i]); + gcry_free (result); + } + if (r_consumed) + *r_consumed = consumed; + gcry_free (plain); + gcry_free (cram_buffer); + log_error ("encryptedData error at \"%s\", offset %u\n", + where, (unsigned int)((p - p_start)+startoffset)); + if (bad_pass) + { + /* Note, that the following string might be used by other programs + to check for a bad passphrase; it should therefore not be + translated or changed. */ + log_error ("possibly bad passphrase given\n"); + } + return -1; +} + + +/* Return true if the decryption of a bag_data object has likely + succeeded. */ +static int +bag_data_p (const void *plaintext, size_t length) +{ + struct tag_info ti; + const unsigned char *p = plaintext; + size_t n = length; + +/* { */ +/* # warning debug code is enabled */ +/* FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */ +/* if (!fp || fwrite (p, n, 1, fp) != 1) */ +/* exit (2); */ +/* fclose (fp); */ +/* } */ + + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + return 0; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER + || ti.length != 1 || *p) + return 0; + + return 1; +} + + +static gcry_mpi_t * +parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, + size_t *r_consumed, const char *pw) +{ + int rc; + struct tag_info ti; + const unsigned char *p = buffer; + const unsigned char *p_start = buffer; + size_t n = length; + const char *where; + char salt[20]; + size_t saltlen; + unsigned int iter; + int len; + unsigned char *plain = NULL; + gcry_mpi_t *result = NULL; + int result_count, i; + unsigned char *cram_buffer = NULL; + size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */ + + where = "start"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING) + goto bailout; + + consumed = p - p_start; + if (ti.is_constructed && ti.ndef) + { + /* Mozilla exported certs now come with single byte chunks of + octect strings. (Mozilla Firefox 1.0.4). Arghh. */ + where = "cram-data.outersegs"; + cram_buffer = cram_octet_string ( p, &n, &consumed); + if (!cram_buffer) + goto bailout; + p = p_start = cram_buffer; + if (r_consumed) + *r_consumed = consumed; + r_consumed = NULL; /* Ugly hack to not update that value any further. */ + } + + + where = "data.outerseqs"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + + where = "data.objectidentifier"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OBJECT_ID + || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag) + || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag, + DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag))) + goto bailout; + p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); + n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); + + where = "shrouded,outerseqs"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OBJECT_ID + || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) + || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, + DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) + goto bailout; + p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + + where = "3des-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING + || ti.length < 8 || ti.length > 20) + goto bailout; + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) + goto bailout; + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } + + where = "3des-ciphertext"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length ) + goto bailout; + + log_info ("%lu bytes of 3DES encrypted text\n", ti.length); + + plain = gcry_malloc_secure (ti.length); + if (!plain) + { + log_error ("error allocating decryption buffer\n"); + goto bailout; + } + consumed += p - p_start + ti.length; + decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, + GCRY_CIPHER_3DES, + bag_data_p); + n = ti.length; + startoffset = 0; + p_start = p = plain; + + where = "decrypted-text"; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER + || ti.length != 1 || *p) + goto bailout; + p++; n--; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + len = ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (len < ti.nhdr) + goto bailout; + len -= ti.nhdr; + if (ti.class || ti.tag != TAG_OBJECT_ID + || ti.length != DIM(oid_rsaEncryption) + || memcmp (p, oid_rsaEncryption, + DIM(oid_rsaEncryption))) + goto bailout; + p += DIM (oid_rsaEncryption); + n -= DIM (oid_rsaEncryption); + if (len < ti.length) + goto bailout; + len -= ti.length; + if (n < len) + goto bailout; + p += len; + n -= len; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING) + goto bailout; + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + len = ti.length; + + result = gcry_calloc (10, sizeof *result); + if (!result) + { + log_error ( "error allocating result array\n"); + goto bailout; + } + result_count = 0; + + where = "reading.key-parameters"; + for (result_count=0; len && result_count < 9;) + { + if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER) + goto bailout; + if (len < ti.nhdr) + goto bailout; + len -= ti.nhdr; + if (len < ti.length) + goto bailout; + len -= ti.length; + if (!result_count && ti.length == 1 && !*p) + ; /* ignore the very first one if it is a 0 */ + else + { + rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p, + ti.length, NULL); + if (rc) + { + log_error ("error parsing key parameter: %s\n", + gpg_strerror (rc)); + goto bailout; + } + result_count++; + } + p += ti.length; + n -= ti.length; + } + if (len) + goto bailout; + + gcry_free (cram_buffer); + if (r_consumed) + *r_consumed = consumed; + return result; + + bailout: + gcry_free (plain); + if (result) + { + for (i=0; result[i]; i++) + gcry_mpi_release (result[i]); + gcry_free (result); + } + gcry_free (cram_buffer); + log_error ( "data error at \"%s\", offset %u\n", + where, (unsigned int)((p - buffer) + startoffset)); + if (r_consumed) + *r_consumed = consumed; + return NULL; +} + + +/* Parse a PKCS12 object and return an array of MPI representing the + secret key parameters. This is a very limited implementation in + that it is only able to look for 3DES encoded encryptedData and + tries to extract the first private key object it finds. In case of + an error NULL is returned. CERTCB and CERRTCBARG are used to pass + X.509 certificates back to the caller. */ +gcry_mpi_t * +p12_parse (const unsigned char *buffer, size_t length, const char *pw, + void (*certcb)(void*, const unsigned char*, size_t), + void *certcbarg) +{ + struct tag_info ti; + const unsigned char *p = buffer; + const unsigned char *p_start = buffer; + size_t n = length; + const char *where; + int bagseqlength, len; + int bagseqndef, lenndef; + gcry_mpi_t *result = NULL; + unsigned char *cram_buffer = NULL; + + where = "pfx"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_SEQUENCE) + goto bailout; + + where = "pfxVersion"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3) + goto bailout; + p++; n--; + + where = "authSave"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) + || memcmp (p, oid_data, DIM(oid_data))) + goto bailout; + p += DIM(oid_data); + n -= DIM(oid_data); + + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != ASNCONTEXT || ti.tag) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING) + goto bailout; + + if (ti.is_constructed && ti.ndef) + { + /* Mozilla exported certs now come with single byte chunks of + octect strings. (Mozilla Firefox 1.0.4). Arghh. */ + where = "cram-bags"; + cram_buffer = cram_octet_string ( p, &n, NULL); + if (!cram_buffer) + goto bailout; + p = p_start = cram_buffer; + } + + where = "bags"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE) + goto bailout; + bagseqndef = ti.ndef; + bagseqlength = ti.length; + while (bagseqlength || bagseqndef) + { +/* log_debug ( "at offset %u\n", (p - p_start)); */ + where = "bag-sequence"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed) + break; /* Ready */ + if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE) + goto bailout; + + if (!bagseqndef) + { + if (bagseqlength < ti.nhdr) + goto bailout; + bagseqlength -= ti.nhdr; + if (bagseqlength < ti.length) + goto bailout; + bagseqlength -= ti.length; + } + lenndef = ti.ndef; + len = ti.length; + + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (lenndef) + len = ti.nhdr; + else + len -= ti.nhdr; + + if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData) + && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData))) + { + size_t consumed = 0; + + p += DIM(oid_encryptedData); + n -= DIM(oid_encryptedData); + if (!lenndef) + len -= DIM(oid_encryptedData); + where = "bag.encryptedData"; + if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw, + certcb, certcbarg, + result? NULL : &result)) + goto bailout; + if (lenndef) + len += consumed; + } + else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data) + && !memcmp (p, oid_data, DIM(oid_data))) + { + if (result) + { + log_info ("already got an key object, skipping this one\n"); + p += ti.length; + n -= ti.length; + } + else + { + size_t consumed = 0; + + p += DIM(oid_data); + n -= DIM(oid_data); + if (!lenndef) + len -= DIM(oid_data); + result = parse_bag_data (p, n, (p - p_start), &consumed, pw); + if (!result) + goto bailout; + if (lenndef) + len += consumed; + } + } + else + { + log_info ("unknown bag type - skipped\n"); + p += ti.length; + n -= ti.length; + } + + if (len < 0 || len > n) + goto bailout; + p += len; + n -= len; + if (lenndef) + { + /* Need to skip the Null Tag. */ + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)) + goto bailout; + } + } + + gcry_free (cram_buffer); + return result; + bailout: + log_error ("error at \"%s\", offset %u\n", + where, (unsigned int)(p - p_start)); + if (result) + { + int i; + + for (i=0; result[i]; i++) + gcry_mpi_release (result[i]); + gcry_free (result); + } + gcry_free (cram_buffer); + return NULL; +} + + + +static size_t +compute_tag_length (size_t n) +{ + int needed = 0; + + if (n < 128) + needed += 2; /* tag and one length byte */ + else if (n < 256) + needed += 3; /* tag, number of length bytes, 1 length byte */ + else if (n < 65536) + needed += 4; /* tag, number of length bytes, 2 length bytes */ + else + { + log_error ("object too larger to encode\n"); + return 0; + } + return needed; +} + +static unsigned char * +store_tag_length (unsigned char *p, int tag, size_t n) +{ + if (tag == TAG_SEQUENCE) + tag |= 0x20; /* constructed */ + + *p++ = tag; + if (n < 128) + *p++ = n; + else if (n < 256) + { + *p++ = 0x81; + *p++ = n; + } + else if (n < 65536) + { + *p++ = 0x82; + *p++ = n >> 8; + *p++ = n; + } + + return p; +} + + +/* Create the final PKCS-12 object from the sequences contained in + SEQLIST. PW is the password. That array is terminated with an NULL + object. */ +static unsigned char * +create_final (struct buffer_s *sequences, const char *pw, size_t *r_length) +{ + int i; + size_t needed = 0; + size_t len[8], n; + unsigned char *macstart; + size_t maclen; + unsigned char *result, *p; + size_t resultlen; + char salt[8]; + unsigned char keybuf[20]; + gcry_md_hd_t md; + int rc; + int with_mac = 1; + + + /* 9 steps to create the pkcs#12 Krampf. */ + + /* 8. The MAC. */ + /* We add this at step 0. */ + + /* 7. All the buffers. */ + for (i=0; sequences[i].buffer; i++) + needed += sequences[i].length; + + /* 6. This goes into a sequences. */ + len[6] = needed; + n = compute_tag_length (needed); + needed += n; + + /* 5. Encapsulate all in an octet string. */ + len[5] = needed; + n = compute_tag_length (needed); + needed += n; + + /* 4. And tag it with [0]. */ + len[4] = needed; + n = compute_tag_length (needed); + needed += n; + + /* 3. Prepend an data OID. */ + needed += 2 + DIM (oid_data); + + /* 2. Put all into a sequences. */ + len[2] = needed; + n = compute_tag_length (needed); + needed += n; + + /* 1. Prepend the version integer 3. */ + needed += 3; + + /* 0. And the final outer sequence. */ + if (with_mac) + needed += DIM (data_mactemplate); + len[0] = needed; + n = compute_tag_length (needed); + needed += n; + + /* Allocate a buffer. */ + result = gcry_malloc (needed); + if (!result) + { + log_error ("error allocating buffer\n"); + return NULL; + } + p = result; + + /* 0. Store the very outer sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[0]); + + /* 1. Store the version integer 3. */ + *p++ = TAG_INTEGER; + *p++ = 1; + *p++ = 3; + + /* 2. Store another sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[2]); + + /* 3. Store the data OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data)); + memcpy (p, oid_data, DIM (oid_data)); + p += DIM (oid_data); + + /* 4. Next comes a context tag. */ + p = store_tag_length (p, 0xa0, len[4]); + + /* 5. And an octet string. */ + p = store_tag_length (p, TAG_OCTET_STRING, len[5]); + + /* 6. And the inner sequence. */ + macstart = p; + p = store_tag_length (p, TAG_SEQUENCE, len[6]); + + /* 7. Append all the buffers. */ + for (i=0; sequences[i].buffer; i++) + { + memcpy (p, sequences[i].buffer, sequences[i].length); + p += sequences[i].length; + } + + if (with_mac) + { + /* Intermezzo to compute the MAC. */ + maclen = p - macstart; + gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); + if (string_to_key (3, salt, 8, 2048, pw, 20, keybuf)) + { + gcry_free (result); + return NULL; + } + rc = gcry_md_open (&md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + if (rc) + { + log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc)); + gcry_free (result); + return NULL; + } + rc = gcry_md_setkey (md, keybuf, 20); + if (rc) + { + log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc)); + gcry_md_close (md); + gcry_free (result); + return NULL; + } + gcry_md_write (md, macstart, maclen); + + /* 8. Append the MAC template and fix it up. */ + memcpy (p, data_mactemplate, DIM (data_mactemplate)); + memcpy (p + DATA_MACTEMPLATE_SALT_OFF, salt, 8); + memcpy (p + DATA_MACTEMPLATE_MAC_OFF, gcry_md_read (md, 0), 20); + p += DIM (data_mactemplate); + gcry_md_close (md); + } + + /* Ready. */ + resultlen = p - result; + if (needed != resultlen) + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)resultlen); + + *r_length = resultlen; + return result; +} + + +/* Build a DER encoded SEQUENCE with the key: + + SEQUENCE { + INTEGER 0 + SEQUENCE { + OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) + NULL + } + OCTET STRING, encapsulates { + SEQUENCE { + INTEGER 0 + INTEGER + INTEGER + INTEGER + INTEGER + INTEGER + INTEGER + INTEGER + INTEGER + } + } + } +*/ + +static unsigned char * +build_key_sequence (gcry_mpi_t *kparms, size_t *r_length) +{ + int rc, i; + size_t needed, n; + unsigned char *plain, *p; + size_t plainlen; + size_t outseqlen, oidseqlen, octstrlen, inseqlen; + + needed = 3; /* The version(?) integer of value 0. */ + for (i=0; kparms[i]; i++) + { + n = 0; + rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]); + if (rc) + { + log_error ("error formatting parameter: %s\n", gpg_strerror (rc)); + return NULL; + } + needed += n; + n = compute_tag_length (n); + if (!n) + return NULL; + needed += n; + } + if (i != 8) + { + log_error ("invalid parameters for p12_build\n"); + return NULL; + } + /* Now this all goes into a sequence. */ + inseqlen = needed; + n = compute_tag_length (needed); + if (!n) + return NULL; + needed += n; + /* Encapsulate all into an octet string. */ + octstrlen = needed; + n = compute_tag_length (needed); + if (!n) + return NULL; + needed += n; + /* Prepend the object identifier sequence. */ + oidseqlen = 2 + DIM (oid_rsaEncryption) + 2; + needed += 2 + oidseqlen; + /* The version number. */ + needed += 3; + /* And finally put the whole thing into a sequence. */ + outseqlen = needed; + n = compute_tag_length (needed); + if (!n) + return NULL; + needed += n; + + /* allocate 8 extra bytes for padding */ + plain = gcry_malloc_secure (needed+8); + if (!plain) + { + log_error ("error allocating encryption buffer\n"); + return NULL; + } + + /* And now fill the plaintext buffer. */ + p = plain; + p = store_tag_length (p, TAG_SEQUENCE, outseqlen); + /* Store version. */ + *p++ = TAG_INTEGER; + *p++ = 1; + *p++ = 0; + /* Store object identifier sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, oidseqlen); + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption)); + memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); + p += DIM (oid_rsaEncryption); + *p++ = TAG_NULL; + *p++ = 0; + /* Start with the octet string. */ + p = store_tag_length (p, TAG_OCTET_STRING, octstrlen); + p = store_tag_length (p, TAG_SEQUENCE, inseqlen); + /* Store the key parameters. */ + *p++ = TAG_INTEGER; + *p++ = 1; + *p++ = 0; + for (i=0; kparms[i]; i++) + { + n = 0; + rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]); + if (rc) + { + log_error ("oops: error formatting parameter: %s\n", + gpg_strerror (rc)); + gcry_free (plain); + return NULL; + } + p = store_tag_length (p, TAG_INTEGER, n); + + n = plain + needed - p; + rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]); + if (rc) + { + log_error ("oops: error storing parameter: %s\n", + gpg_strerror (rc)); + gcry_free (plain); + return NULL; + } + p += n; + } + + plainlen = p - plain; + assert (needed == plainlen); + /* Append some pad characters; we already allocated extra space. */ + n = 8 - plainlen % 8; + for (i=0; i < n; i++, plainlen++) + *p++ = n; + + *r_length = plainlen; + return plain; +} + + + +static unsigned char * +build_key_bag (unsigned char *buffer, size_t buflen, char *salt, + const unsigned char *sha1hash, const char *keyidstr, + size_t *r_length) +{ + size_t len[11], needed; + unsigned char *p, *keybag; + size_t keybaglen; + + /* Walk 11 steps down to collect the info: */ + + /* 10. The data goes into an octet string. */ + needed = compute_tag_length (buflen); + needed += buflen; + + /* 9. Prepend the algorithm identifier. */ + needed += DIM (data_3desiter2048); + + /* 8. Put a sequence around. */ + len[8] = needed; + needed += compute_tag_length (needed); + + /* 7. Prepend a [0] tag. */ + len[7] = needed; + needed += compute_tag_length (needed); + + /* 6b. The attributes which are appended at the end. */ + if (sha1hash) + needed += DIM (data_attrtemplate) + 20; + + /* 6. Prepend the shroudedKeyBag OID. */ + needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); + + /* 5+4. Put all into two sequences. */ + len[5] = needed; + needed += compute_tag_length ( needed); + len[4] = needed; + needed += compute_tag_length (needed); + + /* 3. This all goes into an octet string. */ + len[3] = needed; + needed += compute_tag_length (needed); + + /* 2. Prepend another [0] tag. */ + len[2] = needed; + needed += compute_tag_length (needed); + + /* 1. Prepend the data OID. */ + needed += 2 + DIM (oid_data); + + /* 0. Prepend another sequence. */ + len[0] = needed; + needed += compute_tag_length (needed); + + /* Now that we have all length information, allocate a buffer. */ + p = keybag = gcry_malloc (needed); + if (!keybag) + { + log_error ("error allocating buffer\n"); + return NULL; + } + + /* Walk 11 steps up to store the data. */ + + /* 0. Store the first sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[0]); + + /* 1. Store the data OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data)); + memcpy (p, oid_data, DIM (oid_data)); + p += DIM (oid_data); + + /* 2. Store a [0] tag. */ + p = store_tag_length (p, 0xa0, len[2]); + + /* 3. And an octet string. */ + p = store_tag_length (p, TAG_OCTET_STRING, len[3]); + + /* 4+5. Two sequences. */ + p = store_tag_length (p, TAG_SEQUENCE, len[4]); + p = store_tag_length (p, TAG_SEQUENCE, len[5]); + + /* 6. Store the shroudedKeyBag OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); + memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag, + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); + p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); + + /* 7. Store a [0] tag. */ + p = store_tag_length (p, 0xa0, len[7]); + + /* 8. Store a sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[8]); + + /* 9. Now for the pre-encoded algorithm identifier and the salt. */ + memcpy (p, data_3desiter2048, DIM (data_3desiter2048)); + memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8); + p += DIM (data_3desiter2048); + + /* 10. And the octet string with the encrypted data. */ + p = store_tag_length (p, TAG_OCTET_STRING, buflen); + memcpy (p, buffer, buflen); + p += buflen; + + /* Append the attributes whose length we calculated at step 2b. */ + if (sha1hash) + { + int i; + + memcpy (p, data_attrtemplate, DIM (data_attrtemplate)); + for (i=0; i < 8; i++) + p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i]; + p += DIM (data_attrtemplate); + memcpy (p, sha1hash, 20); + p += 20; + } + + + keybaglen = p - keybag; + if (needed != keybaglen) + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)keybaglen); + + *r_length = keybaglen; + return keybag; +} + + +static unsigned char * +build_cert_bag (unsigned char *buffer, size_t buflen, char *salt, + size_t *r_length) +{ + size_t len[9], needed; + unsigned char *p, *certbag; + size_t certbaglen; + + /* Walk 9 steps down to collect the info: */ + + /* 8. The data goes into an octet string. */ + needed = compute_tag_length (buflen); + needed += buflen; + + /* 7. The algorithm identifier. */ + needed += DIM (data_rc2iter2048); + + /* 6. The data OID. */ + needed += 2 + DIM (oid_data); + + /* 5. A sequence. */ + len[5] = needed; + needed += compute_tag_length ( needed); + + /* 4. An integer. */ + needed += 3; + + /* 3. A sequence. */ + len[3] = needed; + needed += compute_tag_length (needed); + + /* 2. A [0] tag. */ + len[2] = needed; + needed += compute_tag_length (needed); + + /* 1. The encryptedData OID. */ + needed += 2 + DIM (oid_encryptedData); + + /* 0. The first sequence. */ + len[0] = needed; + needed += compute_tag_length (needed); + + /* Now that we have all length information, allocate a buffer. */ + p = certbag = gcry_malloc (needed); + if (!certbag) + { + log_error ("error allocating buffer\n"); + return NULL; + } + + /* Walk 9 steps up to store the data. */ + + /* 0. Store the first sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[0]); + + /* 1. Store the encryptedData OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData)); + memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); + p += DIM (oid_encryptedData); + + /* 2. Store a [0] tag. */ + p = store_tag_length (p, 0xa0, len[2]); + + /* 3. Store a sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[3]); + + /* 4. Store the integer 0. */ + *p++ = TAG_INTEGER; + *p++ = 1; + *p++ = 0; + + /* 5. Store a sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[5]); + + /* 6. Store the data OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data)); + memcpy (p, oid_data, DIM (oid_data)); + p += DIM (oid_data); + + /* 7. Now for the pre-encoded algorithm identifier and the salt. */ + memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048)); + memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8); + p += DIM (data_rc2iter2048); + + /* 8. And finally the [0] tag with the encrypted data. */ + p = store_tag_length (p, 0x80, buflen); + memcpy (p, buffer, buflen); + p += buflen; + certbaglen = p - certbag; + + if (needed != certbaglen) + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)certbaglen); + + *r_length = certbaglen; + return certbag; +} + + +static unsigned char * +build_cert_sequence (unsigned char *buffer, size_t buflen, + const unsigned char *sha1hash, const char *keyidstr, + size_t *r_length) +{ + size_t len[8], needed, n; + unsigned char *p, *certseq; + size_t certseqlen; + int i; + + assert (strlen (keyidstr) == 8); + + /* Walk 8 steps down to collect the info: */ + + /* 7. The data goes into an octet string. */ + needed = compute_tag_length (buflen); + needed += buflen; + + /* 6. A [0] tag. */ + len[6] = needed; + needed += compute_tag_length (needed); + + /* 5. An OID. */ + needed += 2 + DIM (oid_x509Certificate_for_pkcs_12); + + /* 4. A sequence. */ + len[4] = needed; + needed += compute_tag_length (needed); + + /* 3. A [0] tag. */ + len[3] = needed; + needed += compute_tag_length (needed); + + /* 2b. The attributes which are appended at the end. */ + if (sha1hash) + needed += DIM (data_attrtemplate) + 20; + + /* 2. An OID. */ + needed += 2 + DIM (oid_pkcs_12_CertBag); + + /* 1. A sequence. */ + len[1] = needed; + needed += compute_tag_length (needed); + + /* 0. The first sequence. */ + len[0] = needed; + needed += compute_tag_length (needed); + + /* Now that we have all length information, allocate a buffer. */ + p = certseq = gcry_malloc (needed + 8 /*(for padding)*/); + if (!certseq) + { + log_error ("error allocating buffer\n"); + return NULL; + } + + /* Walk 8 steps up to store the data. */ + + /* 0. Store the first sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[0]); + + /* 1. Store the second sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[1]); + + /* 2. Store the pkcs12-cert-bag OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag)); + memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); + p += DIM (oid_pkcs_12_CertBag); + + /* 3. Store a [0] tag. */ + p = store_tag_length (p, 0xa0, len[3]); + + /* 4. Store a sequence. */ + p = store_tag_length (p, TAG_SEQUENCE, len[4]); + + /* 5. Store the x509Certificate OID. */ + p = store_tag_length (p, TAG_OBJECT_ID, + DIM (oid_x509Certificate_for_pkcs_12)); + memcpy (p, oid_x509Certificate_for_pkcs_12, + DIM (oid_x509Certificate_for_pkcs_12)); + p += DIM (oid_x509Certificate_for_pkcs_12); + + /* 6. Store a [0] tag. */ + p = store_tag_length (p, 0xa0, len[6]); + + /* 7. And the octet string with the actual certificate. */ + p = store_tag_length (p, TAG_OCTET_STRING, buflen); + memcpy (p, buffer, buflen); + p += buflen; + + /* Append the attributes whose length we calculated at step 2b. */ + if (sha1hash) + { + memcpy (p, data_attrtemplate, DIM (data_attrtemplate)); + for (i=0; i < 8; i++) + p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i]; + p += DIM (data_attrtemplate); + memcpy (p, sha1hash, 20); + p += 20; + } + + certseqlen = p - certseq; + if (needed != certseqlen) + log_debug ("length mismatch: %lu, %lu\n", + (unsigned long)needed, (unsigned long)certseqlen); + + /* Append some pad characters; we already allocated extra space. */ + n = 8 - certseqlen % 8; + for (i=0; i < n; i++, certseqlen++) + *p++ = n; + + *r_length = certseqlen; + return certseq; +} + + +/* Expect the RSA key parameters in KPARMS and a password in PW. + Create a PKCS structure from it and return it as well as the length + in R_LENGTH; return NULL in case of an error. If CHARSET is not + NULL, re-encode PW to that character set. */ +unsigned char * +p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, + const char *pw, const char *charset, size_t *r_length) +{ + unsigned char *buffer = NULL; + size_t n, buflen; + char salt[8]; + struct buffer_s seqlist[3]; + int seqlistidx = 0; + unsigned char sha1hash[20]; + char keyidstr[8+1]; + char *pwbuf = NULL; + size_t pwbufsize = 0; + + n = buflen = 0; /* (avoid compiler warning). */ + memset (sha1hash, 0, 20); + *keyidstr = 0; + + if (charset && pw && *pw) + { + jnlib_iconv_t cd; + const char *inptr; + char *outptr; + size_t inbytes, outbytes; + + /* We assume that the converted passphrase is at max 2 times + longer than its utf-8 encoding. */ + pwbufsize = strlen (pw)*2 + 1; + pwbuf = gcry_malloc_secure (pwbufsize); + if (!pwbuf) + { + log_error ("out of secure memory while converting passphrase\n"); + goto failure; + } + + cd = jnlib_iconv_open (charset, "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) + { + log_error ("can't convert passphrase to" + " requested charset `%s': %s\n", + charset, strerror (errno)); + gcry_free (pwbuf); + goto failure; + } + + inptr = pw; + inbytes = strlen (pw); + outptr = pwbuf; + outbytes = pwbufsize - 1; + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, + &outptr, &outbytes) == (size_t)-1) + { + log_error ("error converting passphrase to" + " requested charset `%s': %s\n", + charset, strerror (errno)); + gcry_free (pwbuf); + jnlib_iconv_close (cd); + goto failure; + } + *outptr = 0; + jnlib_iconv_close (cd); + pw = pwbuf; + } + + + if (cert && certlen) + { + /* Calculate the hash value we need for the bag attributes. */ + gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, cert, certlen); + sprintf (keyidstr, "%02x%02x%02x%02x", + sha1hash[16], sha1hash[17], sha1hash[18], sha1hash[19]); + + /* Encode the certificate. */ + buffer = build_cert_sequence (cert, certlen, sha1hash, keyidstr, + &buflen); + if (!buffer) + goto failure; + + /* Encrypt it. */ + gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); + crypt_block (buffer, buflen, salt, 8, 2048, pw, + GCRY_CIPHER_RFC2268_40, 1); + + /* Encode the encrypted stuff into a bag. */ + seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n); + seqlist[seqlistidx].length = n; + gcry_free (buffer); + buffer = NULL; + if (!seqlist[seqlistidx].buffer) + goto failure; + seqlistidx++; + } + + + if (kparms) + { + /* Encode the key. */ + buffer = build_key_sequence (kparms, &buflen); + if (!buffer) + goto failure; + + /* Encrypt it. */ + gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); + crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1); + + /* Encode the encrypted stuff into a bag. */ + if (cert && certlen) + seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, + sha1hash, keyidstr, &n); + else + seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, + NULL, NULL, &n); + seqlist[seqlistidx].length = n; + gcry_free (buffer); + buffer = NULL; + if (!seqlist[seqlistidx].buffer) + goto failure; + seqlistidx++; + } + + seqlist[seqlistidx].buffer = NULL; + seqlist[seqlistidx].length = 0; + + buffer = create_final (seqlist, pw, &buflen); + + failure: + if (pwbuf) + { + wipememory (pwbuf, pwbufsize); + gcry_free (pwbuf); + } + for ( ; seqlistidx; seqlistidx--) + gcry_free (seqlist[seqlistidx].buffer); + + *r_length = buffer? buflen : 0; + return buffer; +} + + +#ifdef TEST + +static void +cert_cb (void *opaque, const unsigned char *cert, size_t certlen) +{ + printf ("got a certificate of %u bytes length\n", certlen); +} + +int +main (int argc, char **argv) +{ + FILE *fp; + struct stat st; + unsigned char *buf; + size_t buflen; + gcry_mpi_t *result; + + if (argc != 3) + { + fprintf (stderr, "usage: testp12 file passphrase\n"); + return 1; + } + + gcry_control (GCRYCTL_DISABLE_SECMEM, NULL); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL); + + fp = fopen (argv[1], "rb"); + if (!fp) + { + fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno)); + return 1; + } + + if (fstat (fileno(fp), &st)) + { + fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno)); + return 1; + } + + buflen = st.st_size; + buf = gcry_malloc (buflen+1); + if (!buf || fread (buf, buflen, 1, fp) != 1) + { + fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno)); + return 1; + } + fclose (fp); + + result = p12_parse (buf, buflen, argv[2], cert_cb, NULL); + if (result) + { + int i, rc; + unsigned char *tmpbuf; + + for (i=0; result[i]; i++) + { + rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf, + NULL, result[i]); + if (rc) + printf ("%d: [error printing number: %s]\n", + i, gpg_strerror (rc)); + else + { + printf ("%d: %s\n", i, tmpbuf); + gcry_free (tmpbuf); + } + } + } + + return 0; + +} + +/* +Local Variables: +compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error" +End: +*/ +#endif /* TEST */ diff --git a/agent/minip12.h b/agent/minip12.h new file mode 100644 index 0000000..998f82f --- /dev/null +++ b/agent/minip12.h @@ -0,0 +1,36 @@ +/* minip12.h - Global definitions for the minimal pkcs-12 implementation. + * 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 3 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, see . + */ + +#ifndef MINIP12_H +#define MINIP12_H + +#include + +gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length, + const char *pw, + void (*certcb)(void*, const unsigned char*, size_t), + void *certcbarg); + +unsigned char *p12_build (gcry_mpi_t *kparms, + unsigned char *cert, size_t certlen, + const char *pw, const char *charset, + size_t *r_length); + + +#endif /*MINIP12_H*/ diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c new file mode 100644 index 0000000..9e1c47d --- /dev/null +++ b/agent/pkdecrypt.c @@ -0,0 +1,151 @@ +/* pkdecrypt.c - public key decryption (well, acually using a secret key) + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" + + +/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp. + Try to get the key from CTRL and write the decoded stuff back to + OUTFP. */ +int +agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *ciphertext, size_t ciphertextlen, + membuf_t *outbuf) +{ + gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL; + unsigned char *shadow_info = NULL; + int rc; + char *buf = NULL; + size_t len; + + if (!ctrl->have_keygrip) + { + log_error ("speculative decryption not yet supported\n"); + rc = gpg_error (GPG_ERR_NO_SECKEY); + goto leave; + } + + rc = gcry_sexp_sscan (&s_cipher, NULL, (char*)ciphertext, ciphertextlen); + if (rc) + { + log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc)); + rc = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + + if (DBG_CRYPTO) + { + log_printhex ("keygrip:", ctrl->keygrip, 20); + log_printhex ("cipher: ", ciphertext, ciphertextlen); + } + rc = agent_key_from_file (ctrl, desc_text, + ctrl->keygrip, &shadow_info, + CACHE_MODE_NORMAL, NULL, &s_skey); + if (rc) + { + if (gpg_err_code (rc) == GPG_ERR_ENOENT) + rc = gpg_error (GPG_ERR_NO_SECKEY); + else + log_error ("failed to read the secret key\n"); + goto leave; + } + + if (!s_skey) + { /* divert operation to the smartcard */ + + if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL)) + { + rc = gpg_error (GPG_ERR_INV_SEXP); + goto leave; + } + + rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len ); + if (rc) + { + log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + { + char tmpbuf[60]; + + sprintf (tmpbuf, "(5:value%u:", (unsigned int)len); + put_membuf (outbuf, tmpbuf, strlen (tmpbuf)); + put_membuf (outbuf, buf, len); + put_membuf (outbuf, ")", 2); + } + } + else + { /* No smartcard, but a private key */ +/* if (DBG_CRYPTO ) */ +/* { */ +/* log_debug ("skey: "); */ +/* gcry_sexp_dump (s_skey); */ +/* } */ + + rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey); + if (rc) + { + log_error ("decryption failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + if (DBG_CRYPTO) + { + log_debug ("plain: "); + gcry_sexp_dump (s_plain); + } + len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = xmalloc (len); + len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + if (*buf == '(') + put_membuf (outbuf, buf, len); + else + { + /* Old style libgcrypt: This is only an S-expression + part. Turn it into a complete S-expression. */ + put_membuf (outbuf, "(5:value", 8); + put_membuf (outbuf, buf, len); + put_membuf (outbuf, ")", 2); + } + } + + + leave: + gcry_sexp_release (s_skey); + gcry_sexp_release (s_plain); + gcry_sexp_release (s_cipher); + xfree (buf); + xfree (shadow_info); + return rc; +} + + diff --git a/agent/pksign.c b/agent/pksign.c new file mode 100644 index 0000000..25cadb2 --- /dev/null +++ b/agent/pksign.c @@ -0,0 +1,261 @@ +/* pksign.c - public key signing (well, actually using a secret key) + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" + + +static int +do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash, + int raw_value) +{ + gcry_sexp_t hash; + int rc; + + if (!raw_value) + { + const char *s; + char tmp[16+1]; + int i; + + s = gcry_md_algo_name (algo); + if (s && strlen (s) < 16) + { + for (i=0; i < strlen (s); i++) + tmp[i] = tolower (s[i]); + tmp[i] = '\0'; + } + + rc = gcry_sexp_build (&hash, NULL, + "(data (flags pkcs1) (hash %s %b))", + tmp, (int)mdlen, md); + } + else + { + gcry_mpi_t mpi; + + rc = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL); + if (! rc) + { + rc = gcry_sexp_build (&hash, NULL, + "(data (flags raw) (value %m))", + mpi); + gcry_mpi_release (mpi); + } + + } + + *r_hash = hash; + return rc; +} + + +/* Special version of do_encode_md to take care of pkcs#1 padding. + For TLS-MD5SHA1 we need to do the padding ourself as Libgrypt does + not know about this special scheme. Fixme: We should have a + pkcs1-only-padding flag for Libgcrypt. */ +static int +do_encode_raw_pkcs1 (const byte *md, size_t mdlen, unsigned int nbits, + gcry_sexp_t *r_hash) +{ + int rc; + gcry_sexp_t hash; + unsigned char *frame; + size_t i, n, nframe; + + nframe = (nbits+7) / 8; + if ( !mdlen || mdlen + 8 + 4 > nframe ) + { + /* Can't encode this hash into a frame of size NFRAME. */ + return gpg_error (GPG_ERR_TOO_SHORT); + } + + frame = xtrymalloc (nframe); + if (!frame) + return gpg_error_from_syserror (); + + /* Assemble the pkcs#1 block type 1. */ + n = 0; + frame[n++] = 0; + frame[n++] = 1; /* Block type. */ + i = nframe - mdlen - 3 ; + assert (i >= 8); /* At least 8 bytes of padding. */ + memset (frame+n, 0xff, i ); + n += i; + frame[n++] = 0; + memcpy (frame+n, md, mdlen ); + n += mdlen; + assert (n == nframe); + + /* Create the S-expression. */ + rc = gcry_sexp_build (&hash, NULL, + "(data (flags raw) (value %b))", + (int)nframe, frame); + xfree (frame); + + *r_hash = hash; + return rc; +} + + + +/* SIGN whatever information we have accumulated in CTRL and return + the signature S-expression. LOOKUP is an optional function to + provide a way for lower layers to ask for the caching TTL. */ +int +agent_pksign_do (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t *signature_sexp, + cache_mode_t cache_mode, lookup_ttl_t lookup_ttl) +{ + gcry_sexp_t s_skey = NULL, s_sig = NULL; + unsigned char *shadow_info = NULL; + unsigned int rc = 0; /* FIXME: gpg-error? */ + + if (! ctrl->have_keygrip) + return gpg_error (GPG_ERR_NO_SECKEY); + + rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip, + &shadow_info, cache_mode, lookup_ttl, + &s_skey); + if (rc) + { + log_error ("failed to read the secret key\n"); + goto leave; + } + + if (!s_skey) + { + /* Divert operation to the smartcard */ + + unsigned char *buf = NULL; + size_t len = 0; + + rc = divert_pksign (ctrl, + ctrl->digest.value, + ctrl->digest.valuelen, + ctrl->digest.algo, + shadow_info, &buf); + if (rc) + { + log_error ("smartcard signing failed: %s\n", gpg_strerror (rc)); + goto leave; + } + len = gcry_sexp_canon_len (buf, 0, NULL, NULL); + assert (len); + + rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len); + xfree (buf); + if (rc) + { + log_error ("failed to convert sigbuf returned by divert_pksign " + "into S-Exp: %s", gpg_strerror (rc)); + goto leave; + } + } + else + { + /* No smartcard, but a private key */ + + gcry_sexp_t s_hash = NULL; + + /* Put the hash into a sexp */ + if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1) + rc = do_encode_raw_pkcs1 (ctrl->digest.value, + ctrl->digest.valuelen, + gcry_pk_get_nbits (s_skey), + &s_hash); + else + rc = do_encode_md (ctrl->digest.value, + ctrl->digest.valuelen, + ctrl->digest.algo, + &s_hash, + ctrl->digest.raw_value); + if (rc) + goto leave; + + if (DBG_CRYPTO) + { + log_debug ("skey: "); + gcry_sexp_dump (s_skey); + } + + /* sign */ + rc = gcry_pk_sign (&s_sig, s_hash, s_skey); + gcry_sexp_release (s_hash); + if (rc) + { + log_error ("signing failed: %s\n", gpg_strerror (rc)); + goto leave; + } + + if (DBG_CRYPTO) + { + log_debug ("result: "); + gcry_sexp_dump (s_sig); + } + } + + leave: + + *signature_sexp = s_sig; + + gcry_sexp_release (s_skey); + xfree (shadow_info); + + return rc; +} + +/* SIGN whatever information we have accumulated in CTRL and write it + back to OUTFP. */ +int +agent_pksign (ctrl_t ctrl, const char *desc_text, + membuf_t *outbuf, cache_mode_t cache_mode) +{ + gcry_sexp_t s_sig = NULL; + char *buf = NULL; + size_t len = 0; + int rc = 0; + + rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode, NULL); + if (rc) + goto leave; + + len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + buf = xmalloc (len); + len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len); + assert (len); + + put_membuf (outbuf, buf, len); + + leave: + gcry_sexp_release (s_sig); + xfree (buf); + + return rc; +} diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c new file mode 100644 index 0000000..72de91b --- /dev/null +++ b/agent/preset-passphrase.c @@ -0,0 +1,270 @@ +/* preset-passphrase.c - A tool to preset a passphrase. + * 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 3 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, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif +#ifdef HAVE_LANGINFO_CODESET +#include +#endif +#ifdef HAVE_DOSISH_SYSTEM +#include /* for setmode() */ +#endif +#ifdef HAVE_W32_SYSTEM +#include /* To initialize the sockets. fixme */ +#endif + +#define JNLIB_NEED_LOG_LOGV +#include "agent.h" +#include "minip12.h" +#include "simple-pwquery.h" +#include "i18n.h" +#include "sysutils.h" + + +enum cmd_and_opt_values +{ aNull = 0, + oVerbose = 'v', + oPassphrase = 'P', + + oPreset = 'c', + oForget = 'f', + + oNoVerbose = 500, + + oHomedir, + +aTest }; + + +static const char *opt_homedir; +static const char *opt_passphrase; + +static ARGPARSE_OPTS opts[] = { + + { 301, NULL, 0, N_("@Options:\n ") }, + + { oVerbose, "verbose", 0, "verbose" }, + { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" }, + { oPreset, "preset", 256, "preset passphrase"}, + { oForget, "forget", 256, "forget passphrase"}, + + { oHomedir, "homedir", 2, "@" }, + {0} +}; + + +static const char * +my_strusage (int level) +{ + const char *p; + switch (level) + { + case 11: p = "gpg-preset-passphrase (GnuPG)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + + case 1: + case 40: + p = _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"); + break; + case 41: + p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n" + "Password cache maintenance\n"); + break; + + default: p = NULL; + } + return p; +} + + + + +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL + + +static void +preset_passphrase (const char *keygrip) +{ + int rc; + char *line; + /* FIXME: Use secure memory. */ + char passphrase[500]; + char *passphrase_esc; + + if (!opt_passphrase) + { + rc = read (0, passphrase, sizeof (passphrase) - 1); + if (rc < 0) + { + log_error ("reading passphrase failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return; + } + passphrase[rc] = '\0'; + line = strchr (passphrase, '\n'); + if (line) + { + if (line > passphrase && line[-1] == '\r') + line--; + *line = '\0'; + } + + /* FIXME: How to handle empty passwords? */ + } + + { + const char *s = opt_passphrase ? opt_passphrase : passphrase; + passphrase_esc = bin2hex (s, strlen (s), NULL); + } + if (!passphrase_esc) + { + log_error ("can not escape string: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return; + } + + rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip, + passphrase_esc); + wipememory (passphrase_esc, strlen (passphrase_esc)); + xfree (passphrase_esc); + + if (rc < 0) + { + log_error ("caching passphrase failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return; + } + if (!opt_passphrase) + wipememory (passphrase, sizeof (passphrase)); + + rc = map_spwq_error (simple_query (line)); + if (rc) + { + log_error ("caching passphrase failed: %s\n", gpg_strerror (rc)); + return; + } + + wipememory (line, strlen (line)); + xfree (line); +} + + +static void +forget_passphrase (const char *keygrip) +{ + int rc; + char *line; + + rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip); + if (rc < 0) + rc = gpg_error_from_syserror (); + else + rc = map_spwq_error (simple_query (line)); + if (rc) + { + log_error ("clearing passphrase failed: %s\n", gpg_strerror (rc)); + return; + } + + xfree (line); +} + + +int +main (int argc, char **argv) +{ + ARGPARSE_ARGS pargs; + int cmd = 0; + const char *keygrip = NULL; + + set_strusage (my_strusage); + log_set_prefix ("gpg-preset-passphrase", 1); + + /* Make sure that our subsystems are ready. */ + i18n_init (); + init_common_subsystems (); + + opt_homedir = default_homedir (); + + 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 oHomedir: opt_homedir = pargs.r.ret_str; break; + + case oPreset: cmd = oPreset; break; + case oForget: cmd = oForget; break; + case oPassphrase: opt_passphrase = pargs.r.ret_str; break; + + default : pargs.err = 2; break; + } + } + if (log_get_errorcount(0)) + exit(2); + + if (argc == 1) + keygrip = *argv; + else + usage (1); + + /* Tell simple-pwquery about the the standard socket name. */ + { + char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL); + simple_pw_set_socket (tmp); + xfree (tmp); + } + + if (cmd == oPreset) + preset_passphrase (keygrip); + else if (cmd == oForget) + forget_passphrase (keygrip); + else + log_error ("one of the options --preset or --forget must be given\n"); + + agent_exit (0); + return 8; /*NOTREACHED*/ +} + + +void +agent_exit (int rc) +{ + rc = rc? rc : log_get_errorcount(0)? 2 : 0; + exit (rc); +} diff --git a/agent/protect-tool.c b/agent/protect-tool.c new file mode 100644 index 0000000..dc040f9 --- /dev/null +++ b/agent/protect-tool.c @@ -0,0 +1,1271 @@ +/* protect-tool.c - A tool to test the secret key protection + * Copyright (C) 2002, 2003, 2004, 2006 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 3 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, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif +#ifdef HAVE_LANGINFO_CODESET +#include +#endif +#ifdef HAVE_DOSISH_SYSTEM +#include /* for setmode() */ +#endif + +#define JNLIB_NEED_LOG_LOGV +#include "agent.h" +#include "minip12.h" +#include "i18n.h" +#include "get-passphrase.h" +#include "sysutils.h" +#include "estream.h" + + +enum cmd_and_opt_values +{ + aNull = 0, + oVerbose = 'v', + oArmor = 'a', + oPassphrase = 'P', + + oProtect = 'p', + oUnprotect = 'u', + + oNoVerbose = 500, + oShadow, + oShowShadowInfo, + oShowKeygrip, + oS2Kcalibration, + oCanonical, + + oP12Import, + oP12Export, + oP12Charset, + oStore, + oForce, + oHaveCert, + oNoFailOnExist, + oHomedir, + oPrompt, + oStatusMsg, + + oAgentProgram +}; + + +struct rsa_secret_key_s +{ + gcry_mpi_t n; /* public modulus */ + gcry_mpi_t e; /* public exponent */ + gcry_mpi_t d; /* exponent */ + gcry_mpi_t p; /* prime p. */ + gcry_mpi_t q; /* prime q. */ + gcry_mpi_t u; /* inverse of p mod q. */ +}; + + +static const char *opt_homedir; +static int opt_armor; +static int opt_canonical; +static int opt_store; +static int opt_force; +static int opt_no_fail_on_exist; +static int opt_have_cert; +static const char *opt_passphrase; +static char *opt_prompt; +static int opt_status_msg; +static const char *opt_p12_charset; +static const char *opt_agent_program; + +static char *get_passphrase (int promptno); +static void release_passphrase (char *pw); +static int store_private_key (const unsigned char *grip, + const void *buffer, size_t length, int force); + + +static ARGPARSE_OPTS opts[] = { + ARGPARSE_group (300, N_("@Commands:\n ")), + + ARGPARSE_c (oProtect, "protect", "protect a private key"), + ARGPARSE_c (oUnprotect, "unprotect", "unprotect a private key"), + ARGPARSE_c (oShadow, "shadow", "create a shadow entry for a public key"), + ARGPARSE_c (oShowShadowInfo, "show-shadow-info", "return the shadow info"), + ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""), + ARGPARSE_c (oP12Import, "p12-import", + "import a pkcs#12 encoded private key"), + ARGPARSE_c (oP12Export, "p12-export", + "export a private key pkcs#12 encoded"), + + ARGPARSE_c (oS2Kcalibration, "s2k-calibration", "@"), + + ARGPARSE_group (301, N_("@\nOptions:\n ")), + + ARGPARSE_s_n (oVerbose, "verbose", "verbose"), + ARGPARSE_s_n (oArmor, "armor", "write output in advanced format"), + ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"), + + ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"), + ARGPARSE_s_s (oP12Charset,"p12-charset", + "|NAME|set charset for a new PKCS#12 passphrase to NAME"), + ARGPARSE_s_n (oHaveCert, "have-cert", + "certificate to export provided on STDIN"), + ARGPARSE_s_n (oStore, "store", + "store the created key in the appropriate place"), + ARGPARSE_s_n (oForce, "force", + "force overwriting"), + ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"), + ARGPARSE_s_s (oHomedir, "homedir", "@"), + ARGPARSE_s_s (oPrompt, "prompt", + "|ESCSTRING|use ESCSTRING as prompt in pinentry"), + ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"), + + ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), + + ARGPARSE_end () +}; + +static const char * +my_strusage (int level) +{ + const char *p; + switch (level) + { + case 11: p = "gpg-protect-tool (GnuPG)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + + case 1: + case 40: p = _("Usage: gpg-protect-tool [options] (-h for help)\n"); + break; + case 41: p = _("Syntax: gpg-protect-tool [options] [args]\n" + "Secret key maintenance tool\n"); + break; + + default: p = NULL; + } + return p; +} + + +/* static void */ +/* print_mpi (const char *text, gcry_mpi_t a) */ +/* { */ +/* char *buf; */ +/* void *bufaddr = &buf; */ +/* int rc; */ + +/* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */ +/* if (rc) */ +/* log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */ +/* else */ +/* { */ +/* log_info ("%s: %s\n", text, buf); */ +/* gcry_free (buf); */ +/* } */ +/* } */ + + + +static unsigned char * +make_canonical (const char *fname, const char *buf, size_t buflen) +{ + int rc; + size_t erroff, len; + gcry_sexp_t sexp; + unsigned char *result; + + rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); + if (rc) + { + log_error ("invalid S-Expression in `%s' (off=%u): %s\n", + fname, (unsigned int)erroff, gpg_strerror (rc)); + return NULL; + } + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); + assert (len); + result = xmalloc (len); + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, result, len); + assert (len); + gcry_sexp_release (sexp); + return result; +} + +static char * +make_advanced (const unsigned char *buf, size_t buflen) +{ + int rc; + size_t erroff, len; + gcry_sexp_t sexp; + char *result; + + rc = gcry_sexp_sscan (&sexp, &erroff, (const char*)buf, buflen); + if (rc) + { + log_error ("invalid canonical S-Expression (off=%u): %s\n", + (unsigned int)erroff, gpg_strerror (rc)); + return NULL; + } + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); + assert (len); + result = xmalloc (len); + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len); + assert (len); + gcry_sexp_release (sexp); + return result; +} + + +static char * +read_file (const char *fname, size_t *r_length) +{ + FILE *fp; + char *buf; + size_t buflen; + + if (!strcmp (fname, "-")) + { + size_t nread, bufsize = 0; + + fp = stdin; +#ifdef HAVE_DOSISH_SYSTEM + setmode ( fileno(fp) , O_BINARY ); +#endif + buf = NULL; + buflen = 0; +#define NCHUNK 8192 + do + { + bufsize += NCHUNK; + if (!buf) + buf = xmalloc (bufsize); + else + buf = xrealloc (buf, bufsize); + + nread = fread (buf+buflen, 1, NCHUNK, fp); + if (nread < NCHUNK && ferror (fp)) + { + log_error ("error reading `[stdin]': %s\n", strerror (errno)); + xfree (buf); + return NULL; + } + buflen += nread; + } + while (nread == NCHUNK); +#undef NCHUNK + + } + else + { + struct stat st; + + fp = fopen (fname, "rb"); + if (!fp) + { + log_error ("can't open `%s': %s\n", fname, strerror (errno)); + return NULL; + } + + if (fstat (fileno(fp), &st)) + { + log_error ("can't stat `%s': %s\n", fname, strerror (errno)); + 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, strerror (errno)); + fclose (fp); + xfree (buf); + return NULL; + } + fclose (fp); + } + + *r_length = buflen; + return buf; +} + + +static unsigned char * +read_key (const char *fname) +{ + char *buf; + size_t buflen; + unsigned char *key; + + buf = read_file (fname, &buflen); + if (!buf) + return NULL; + key = make_canonical (fname, buf, buflen); + xfree (buf); + return key; +} + + + +static void +read_and_protect (const char *fname) +{ + int rc; + unsigned char *key; + unsigned char *result; + size_t resultlen; + char *pw; + + key = read_key (fname); + if (!key) + return; + + pw = get_passphrase (1); + rc = agent_protect (key, pw, &result, &resultlen); + release_passphrase (pw); + xfree (key); + if (rc) + { + log_error ("protecting the key failed: %s\n", gpg_strerror (rc)); + return; + } + + if (opt_armor) + { + char *p = make_advanced (result, resultlen); + xfree (result); + if (!p) + return; + result = (unsigned char*)p; + resultlen = strlen (p); + } + + fwrite (result, resultlen, 1, stdout); + xfree (result); +} + + +static void +read_and_unprotect (const char *fname) +{ + int rc; + unsigned char *key; + unsigned char *result; + size_t resultlen; + char *pw; + gnupg_isotime_t protected_at; + + key = read_key (fname); + if (!key) + return; + + rc = agent_unprotect (key, (pw=get_passphrase (1)), + protected_at, &result, &resultlen); + release_passphrase (pw); + xfree (key); + if (rc) + { + if (opt_status_msg) + log_info ("[PROTECT-TOOL:] bad-passphrase\n"); + log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc)); + return; + } + if (opt.verbose) + log_info ("key protection done at %.4s-%.2s-%.2s %.2s:%.2s:%s\n", + protected_at, protected_at+4, protected_at+6, + protected_at+9, protected_at+11, protected_at+13); + + + if (opt_armor) + { + char *p = make_advanced (result, resultlen); + xfree (result); + if (!p) + return; + result = (unsigned char*)p; + resultlen = strlen (p); + } + + fwrite (result, resultlen, 1, stdout); + xfree (result); +} + + + +static void +read_and_shadow (const char *fname) +{ + int rc; + unsigned char *key; + unsigned char *result; + size_t resultlen; + unsigned char dummy_info[] = "(8:313233342:43)"; + + key = read_key (fname); + if (!key) + return; + + rc = agent_shadow_key (key, dummy_info, &result); + xfree (key); + if (rc) + { + log_error ("shadowing the key failed: %s\n", gpg_strerror (rc)); + return; + } + resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL); + assert (resultlen); + + if (opt_armor) + { + char *p = make_advanced (result, resultlen); + xfree (result); + if (!p) + return; + result = (unsigned char*)p; + resultlen = strlen (p); + } + + fwrite (result, resultlen, 1, stdout); + xfree (result); +} + +static void +show_shadow_info (const char *fname) +{ + int rc; + unsigned char *key; + const unsigned char *info; + size_t infolen; + + key = read_key (fname); + if (!key) + return; + + rc = agent_get_shadow_info (key, &info); + xfree (key); + if (rc) + { + log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc)); + return; + } + infolen = gcry_sexp_canon_len (info, 0, NULL,NULL); + assert (infolen); + + if (opt_armor) + { + char *p = make_advanced (info, infolen); + if (!p) + return; + fwrite (p, strlen (p), 1, stdout); + xfree (p); + } + else + fwrite (info, infolen, 1, stdout); +} + + +static void +show_file (const char *fname) +{ + unsigned char *key; + size_t keylen; + char *p; + + key = read_key (fname); + if (!key) + return; + + keylen = gcry_sexp_canon_len (key, 0, NULL,NULL); + assert (keylen); + + if (opt_canonical) + { + fwrite (key, keylen, 1, stdout); + } + else + { + p = make_advanced (key, keylen); + if (p) + { + fwrite (p, strlen (p), 1, stdout); + xfree (p); + } + } + xfree (key); +} + +static void +show_keygrip (const char *fname) +{ + unsigned char *key; + gcry_sexp_t private; + unsigned char grip[20]; + int i; + + key = read_key (fname); + if (!key) + return; + + if (gcry_sexp_new (&private, key, 0, 0)) + { + log_error ("gcry_sexp_new failed\n"); + return; + } + xfree (key); + + if (!gcry_pk_get_keygrip (private, grip)) + { + log_error ("can't calculate keygrip\n"); + return; + } + gcry_sexp_release (private); + + for (i=0; i < 20; i++) + printf ("%02X", grip[i]); + putchar ('\n'); +} + + +static int +rsa_key_check (struct rsa_secret_key_s *skey) +{ + int err = 0; + gcry_mpi_t t = gcry_mpi_snew (0); + gcry_mpi_t t1 = gcry_mpi_snew (0); + gcry_mpi_t t2 = gcry_mpi_snew (0); + gcry_mpi_t phi = gcry_mpi_snew (0); + + /* check that n == p * q */ + gcry_mpi_mul (t, skey->p, skey->q); + if (gcry_mpi_cmp( t, skey->n) ) + { + log_error ("RSA oops: n != p * q\n"); + err++; + } + + /* check that p is less than q */ + if (gcry_mpi_cmp (skey->p, skey->q) > 0) + { + gcry_mpi_t tmp; + + log_info ("swapping secret primes\n"); + tmp = gcry_mpi_copy (skey->p); + gcry_mpi_set (skey->p, skey->q); + gcry_mpi_set (skey->q, tmp); + gcry_mpi_release (tmp); + /* and must recompute u of course */ + gcry_mpi_invm (skey->u, skey->p, skey->q); + } + + /* check that e divides neither p-1 nor q-1 */ + gcry_mpi_sub_ui (t, skey->p, 1 ); + gcry_mpi_div (NULL, t, t, skey->e, 0); + if (!gcry_mpi_cmp_ui( t, 0) ) + { + log_error ("RSA oops: e divides p-1\n"); + err++; + } + gcry_mpi_sub_ui (t, skey->q, 1); + gcry_mpi_div (NULL, t, t, skey->e, 0); + if (!gcry_mpi_cmp_ui( t, 0)) + { + log_info ( "RSA oops: e divides q-1\n" ); + err++; + } + + /* check that d is correct. */ + gcry_mpi_sub_ui (t1, skey->p, 1); + gcry_mpi_sub_ui (t2, skey->q, 1); + gcry_mpi_mul (phi, t1, t2); + gcry_mpi_invm (t, skey->e, phi); + if (gcry_mpi_cmp (t, skey->d)) + { /* no: try universal exponent. */ + gcry_mpi_gcd (t, t1, t2); + gcry_mpi_div (t, NULL, phi, t, 0); + gcry_mpi_invm (t, skey->e, t); + if (gcry_mpi_cmp (t, skey->d)) + { + log_error ("RSA oops: bad secret exponent\n"); + err++; + } + } + + /* check for correctness of u */ + gcry_mpi_invm (t, skey->p, skey->q); + if (gcry_mpi_cmp (t, skey->u)) + { + log_info ( "RSA oops: bad u parameter\n"); + err++; + } + + if (err) + log_info ("RSA secret key check failed\n"); + + gcry_mpi_release (t); + gcry_mpi_release (t1); + gcry_mpi_release (t2); + gcry_mpi_release (phi); + + return err? -1:0; +} + + +/* A callback used by p12_parse to return a certificate. */ +static void +import_p12_cert_cb (void *opaque, const unsigned char *cert, size_t certlen) +{ + struct b64state state; + gpg_error_t err, err2; + + (void)opaque; + + err = b64enc_start (&state, stdout, "CERTIFICATE"); + if (!err) + err = b64enc_write (&state, cert, certlen); + err2 = b64enc_finish (&state); + if (!err) + err = err2; + if (err) + log_error ("error writing armored certificate: %s\n", gpg_strerror (err)); +} + +static void +import_p12_file (const char *fname) +{ + char *buf; + unsigned char *result; + size_t buflen, resultlen, buf_off; + int i; + int rc; + gcry_mpi_t *kparms; + struct rsa_secret_key_s sk; + gcry_sexp_t s_key; + unsigned char *key; + unsigned char grip[20]; + char *pw; + + /* fixme: we should release some stuff on error */ + + buf = read_file (fname, &buflen); + if (!buf) + return; + + /* GnuPG 2.0.4 accidently created binary P12 files with the string + "The passphrase is %s encoded.\n\n" prepended to the ASN.1 data. + We fix that here. */ + if (buflen > 29 && !memcmp (buf, "The passphrase is ", 18)) + { + for (buf_off=18; buf_off < buflen && buf[buf_off] != '\n'; buf_off++) + ; + buf_off++; + if (buf_off < buflen && buf[buf_off] == '\n') + buf_off++; + } + else + buf_off = 0; + + kparms = p12_parse ((unsigned char*)buf+buf_off, buflen-buf_off, + (pw=get_passphrase (2)), + import_p12_cert_cb, NULL); + release_passphrase (pw); + xfree (buf); + if (!kparms) + { + log_error ("error parsing or decrypting the PKCS-12 file\n"); + return; + } + for (i=0; kparms[i]; i++) + ; + if (i != 8) + { + log_error ("invalid structure of private key\n"); + return; + } + + +/* print_mpi (" n", kparms[0]); */ +/* print_mpi (" e", kparms[1]); */ +/* print_mpi (" d", kparms[2]); */ +/* print_mpi (" p", kparms[3]); */ +/* print_mpi (" q", kparms[4]); */ +/* print_mpi ("dmp1", kparms[5]); */ +/* print_mpi ("dmq1", kparms[6]); */ +/* print_mpi (" u", kparms[7]); */ + + sk.n = kparms[0]; + sk.e = kparms[1]; + sk.d = kparms[2]; + sk.q = kparms[3]; + sk.p = kparms[4]; + sk.u = kparms[7]; + if (rsa_key_check (&sk)) + return; +/* print_mpi (" n", sk.n); */ +/* print_mpi (" e", sk.e); */ +/* print_mpi (" d", sk.d); */ +/* print_mpi (" p", sk.p); */ +/* print_mpi (" q", sk.q); */ +/* print_mpi (" u", sk.u); */ + + /* Create an S-expresion from the parameters. */ + rc = gcry_sexp_build (&s_key, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); + for (i=0; i < 8; i++) + gcry_mpi_release (kparms[i]); + gcry_free (kparms); + if (rc) + { + log_error ("failed to created S-expression from key: %s\n", + gpg_strerror (rc)); + return; + } + + /* Compute the keygrip. */ + if (!gcry_pk_get_keygrip (s_key, grip)) + { + log_error ("can't calculate keygrip\n"); + return; + } + log_info ("keygrip: "); + for (i=0; i < 20; i++) + log_printf ("%02X", grip[i]); + log_printf ("\n"); + + /* Convert to canonical encoding. */ + buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, NULL, 0); + assert (buflen); + key = gcry_xmalloc_secure (buflen); + buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, key, buflen); + assert (buflen); + gcry_sexp_release (s_key); + + pw = get_passphrase (4); + rc = agent_protect (key, pw, &result, &resultlen); + release_passphrase (pw); + xfree (key); + if (rc) + { + log_error ("protecting the key failed: %s\n", gpg_strerror (rc)); + return; + } + + if (opt_armor) + { + char *p = make_advanced (result, resultlen); + xfree (result); + if (!p) + return; + result = (unsigned char*)p; + resultlen = strlen (p); + } + + if (opt_store) + store_private_key (grip, result, resultlen, opt_force); + else + fwrite (result, resultlen, 1, stdout); + + xfree (result); +} + + + +static gcry_mpi_t * +sexp_to_kparms (gcry_sexp_t sexp) +{ + gcry_sexp_t list, l2; + const char *name; + const char *s; + size_t n; + int i, idx; + const char *elems; + gcry_mpi_t *array; + + list = gcry_sexp_find_token (sexp, "private-key", 0 ); + if(!list) + return NULL; + 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 1) + usage (1); + + /* Set the information which can't be taken from envvars. */ + gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT, + opt.verbose, + opt_homedir, + opt_agent_program, + NULL, NULL, NULL); + + if (opt_prompt) + opt_prompt = percent_plus_unescape (opt_prompt, 0); + + if (cmd == oProtect) + read_and_protect (fname); + else if (cmd == oUnprotect) + read_and_unprotect (fname); + else if (cmd == oShadow) + read_and_shadow (fname); + else if (cmd == oShowShadowInfo) + show_shadow_info (fname); + else if (cmd == oShowKeygrip) + show_keygrip (fname); + else if (cmd == oP12Import) + import_p12_file (fname); + else if (cmd == oP12Export) + export_p12_file (fname); + else if (cmd == oS2Kcalibration) + { + if (!opt.verbose) + opt.verbose++; /* We need to see something. */ + get_standard_s2k_count (); + } + else + show_file (fname); + + agent_exit (0); + return 8; /*NOTREACHED*/ +} + +void +agent_exit (int rc) +{ + rc = rc? rc : log_get_errorcount(0)? 2 : 0; + exit (rc); +} + + +/* Return the passphrase string and ask the agent if it has not been + set from the command line PROMPTNO select the prompt to display: + 0 = default + 1 = taken from the option --prompt + 2 = for unprotecting a pkcs#12 object + 3 = for protecting a new pkcs#12 object + 4 = for protecting an imported pkcs#12 in our system +*/ +static char * +get_passphrase (int promptno) +{ + char *pw; + int err; + const char *desc; + char *orig_codeset; + int repeat = 0; + + if (opt_passphrase) + return xstrdup (opt_passphrase); + + orig_codeset = i18n_switchto_utf8 (); + + if (promptno == 1 && opt_prompt) + { + desc = opt_prompt; + } + else if (promptno == 2) + { + desc = _("Please enter the passphrase to unprotect the " + "PKCS#12 object."); + } + else if (promptno == 3) + { + desc = _("Please enter the passphrase to protect the " + "new PKCS#12 object."); + repeat = 1; + } + else if (promptno == 4) + { + desc = _("Please enter the passphrase to protect the " + "imported object within the GnuPG system."); + repeat = 1; + } + else + desc = _("Please enter the passphrase or the PIN\n" + "needed to complete this operation."); + + i18n_switchback (orig_codeset); + + err = gnupg_get_passphrase (NULL, NULL, _("Passphrase:"), desc, + repeat, repeat, 1, &pw); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_CANCELED) + log_info (_("cancelled\n")); + else + log_error (_("error while asking for the passphrase: %s\n"), + gpg_strerror (err)); + agent_exit (0); + } + assert (pw); + + return pw; +} + + +static void +release_passphrase (char *pw) +{ + if (pw) + { + wipememory (pw, strlen (pw)); + xfree (pw); + } +} + +static int +store_private_key (const unsigned char *grip, + const void *buffer, size_t length, int force) +{ + char *fname; + estream_t fp; + char hexgrip[40+4+1]; + + bin2hex (grip, 20, hexgrip); + strcpy (hexgrip+40, ".key"); + + fname = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); + if (force) + fp = es_fopen (fname, "wb"); + else + { + if (!access (fname, F_OK)) + { + if (opt_status_msg) + log_info ("[PROTECT-TOOL:] secretkey-exists\n"); + if (opt_no_fail_on_exist) + log_info ("secret key file `%s' already exists\n", fname); + else + log_error ("secret key file `%s' already exists\n", fname); + xfree (fname); + return opt_no_fail_on_exist? 0 : -1; + } + /* FWIW: Under Windows Vista the standard fopen in the msvcrt + fails if the "x" GNU extension is used. */ + fp = es_fopen (fname, "wbx"); + } + + if (!fp) + { + log_error ("can't create `%s': %s\n", fname, strerror (errno)); + xfree (fname); + return -1; + } + + if (es_fwrite (buffer, length, 1, fp) != 1) + { + log_error ("error writing `%s': %s\n", fname, strerror (errno)); + es_fclose (fp); + remove (fname); + xfree (fname); + return -1; + } + if (es_fclose (fp)) + { + log_error ("error closing `%s': %s\n", fname, strerror (errno)); + remove (fname); + xfree (fname); + return -1; + } + log_info ("secret key stored as `%s'\n", fname); + + if (opt_status_msg) + log_info ("[PROTECT-TOOL:] secretkey-stored\n"); + + xfree (fname); + return 0; +} diff --git a/agent/protect.c b/agent/protect.c new file mode 100644 index 0000000..d6c9641 --- /dev/null +++ b/agent/protect.c @@ -0,0 +1,1321 @@ +/* protect.c - Un/Protect a secret key + * Copyright (C) 1998, 1999, 2000, 2001, 2002, + * 2003, 2007, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_W32_SYSTEM +# include +#else +# include +#endif + +#include "agent.h" + +#include "sexp-parse.h" + +#define PROT_CIPHER GCRY_CIPHER_AES +#define PROT_CIPHER_STRING "aes" +#define PROT_CIPHER_KEYLEN (128/8) + + +/* A table containing the information needed to create a protected + private key */ +static struct { + const char *algo; + const char *parmlist; + int prot_from, prot_to; +} protect_info[] = { + { "rsa", "nedpqu", 2, 5 }, + { "dsa", "pqgyx", 4, 4 }, + { "elg", "pgyx", 3, 3 }, + { NULL } +}; + + +/* A helper object for time measurement. */ +struct calibrate_time_s +{ +#ifdef HAVE_W32_SYSTEM + FILETIME creation_time, exit_time, kernel_time, user_time; +#else + clock_t ticks; +#endif +}; + + +static int +hash_passphrase (const char *passphrase, int hashalgo, + int s2kmode, + const unsigned char *s2ksalt, unsigned long s2kcount, + unsigned char *key, size_t keylen); + +/* Get the process time and store it in DATA. */ +static void +calibrate_get_time (struct calibrate_time_s *data) +{ +#ifdef HAVE_W32_SYSTEM + GetProcessTimes (GetCurrentProcess (), + &data->creation_time, &data->exit_time, + &data->kernel_time, &data->user_time); +#else + struct tms tmp; + + times (&tmp); + data->ticks = tmp.tms_utime; +#endif +} + + +static unsigned long +calibrate_elapsed_time (struct calibrate_time_s *starttime) +{ + struct calibrate_time_s stoptime; + + calibrate_get_time (&stoptime); +#ifdef HAVE_W32_SYSTEM + { + unsigned long long t1, t2; + + t1 = (((unsigned long long)starttime->kernel_time.dwHighDateTime << 32) + + starttime->kernel_time.dwLowDateTime); + t1 += (((unsigned long long)starttime->user_time.dwHighDateTime << 32) + + starttime->user_time.dwLowDateTime); + t2 = (((unsigned long long)stoptime.kernel_time.dwHighDateTime << 32) + + stoptime.kernel_time.dwLowDateTime); + t2 += (((unsigned long long)stoptime.user_time.dwHighDateTime << 32) + + stoptime.user_time.dwLowDateTime); + return (unsigned long)((t2 - t1)/10000); + } +#else + return (unsigned long)((((double) (stoptime.ticks - starttime->ticks)) + /CLOCKS_PER_SEC)*10000000); +#endif +} + + +/* Run a test hashing for COUNT and return the time required in + milliseconds. */ +static unsigned long +calibrate_s2k_count_one (unsigned long count) +{ + int rc; + char keybuf[PROT_CIPHER_KEYLEN]; + struct calibrate_time_s starttime; + + calibrate_get_time (&starttime); + rc = hash_passphrase ("123456789abcdef0", GCRY_MD_SHA1, + 3, "saltsalt", count, keybuf, sizeof keybuf); + if (rc) + BUG (); + return calibrate_elapsed_time (&starttime); +} + + +/* Measure the time we need to do the hash operations and deduce an + S2K count which requires about 100ms of time. */ +static unsigned long +calibrate_s2k_count (void) +{ + unsigned long count; + unsigned long ms; + + for (count = 65536; count; count *= 2) + { + ms = calibrate_s2k_count_one (count); + if (opt.verbose > 1) + log_info ("S2K calibration: %lu -> %lums\n", count, ms); + if (ms > 100) + break; + } + + count = (unsigned long)(((double)count / ms) * 100); + count /= 1024; + count *= 1024; + if (count < 65536) + count = 65536; + + if (opt.verbose) + { + ms = calibrate_s2k_count_one (count); + log_info ("S2K calibration: %lu iterations for %lums\n", count, ms); + } + + return count; +} + + + +/* Return the standard S2K count. */ +unsigned long +get_standard_s2k_count (void) +{ + static unsigned long count; + + if (!count) + count = calibrate_s2k_count (); + + /* Enforce a lower limit. */ + return count < 65536 ? 65536 : count; +} + + + + +/* Calculate the MIC for a private key S-Exp. SHA1HASH should point to + a 20 byte buffer. This function is suitable for any algorithms. */ +static int +calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) +{ + const unsigned char *hash_begin, *hash_end; + const unsigned char *s; + size_t n; + + s = plainkey; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "private-key")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + hash_begin = s; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; /* skip over the algorithm name */ + + while (*s == '(') + { + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; + if ( *s != ')' ) + return gpg_error (GPG_ERR_INV_SEXP); + s++; + } + if (*s != ')') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + hash_end = s; + + gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, + hash_begin, hash_end - hash_begin); + + return 0; +} + + + +/* Encrypt the parameter block starting at PROTBEGIN with length + PROTLEN using the utf8 encoded key PASSPHRASE and return the entire + encrypted block in RESULT or return with an error code. SHA1HASH + is the 20 byte SHA-1 hash required for the integrity code. + + The parameter block is expected to be an incomplete S-Expression of + the form (example in advanced format): + + (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#) + + the returned block is the S-Expression: + + (protected mode (parms) encrypted_octet_string) + +*/ +static int +do_encryption (const unsigned char *protbegin, size_t protlen, + const char *passphrase, const unsigned char *sha1hash, + unsigned char **result, size_t *resultlen) +{ + gcry_cipher_hd_t hd; + const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; + int blklen, enclen, outlen; + unsigned char *iv = NULL; + int rc; + char *outbuf = NULL; + char *p; + int saltpos, ivpos, encpos; + + *resultlen = 0; + *result = NULL; + + rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC, + GCRY_CIPHER_SECURE); + if (rc) + return rc; + + + /* We need to work on a copy of the data because this makes it + easier to add the trailer and the padding and more important we + have to prefix the text with 2 parenthesis, so we have to + allocate enough space for: + + (()(4:hash4:sha120:)) + padding + + We always append a full block of random bytes as padding but + encrypt only what is needed for a full blocksize. */ + blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER); + outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen; + enclen = outlen/blklen * blklen; + outbuf = gcry_malloc_secure (outlen); + if (!outbuf) + rc = out_of_core (); + if (!rc) + { + /* Allocate random bytes to be used as IV, padding and s2k salt. */ + iv = xtrymalloc (blklen*2+8); + if (!iv) + rc = gpg_error (GPG_ERR_ENOMEM); + else + { + gcry_create_nonce (iv, blklen*2+8); + rc = gcry_cipher_setiv (hd, iv, blklen); + } + } + if (!rc) + { + unsigned char *key; + size_t keylen = PROT_CIPHER_KEYLEN; + + key = gcry_malloc_secure (keylen); + if (!key) + rc = out_of_core (); + else + { + rc = hash_passphrase (passphrase, GCRY_MD_SHA1, + 3, iv+2*blklen, + get_standard_s2k_count (), key, keylen); + if (!rc) + rc = gcry_cipher_setkey (hd, key, keylen); + xfree (key); + } + } + if (!rc) + { + p = outbuf; + *p++ = '('; + *p++ = '('; + memcpy (p, protbegin, protlen); + p += protlen; + memcpy (p, ")(4:hash4:sha120:", 17); + p += 17; + memcpy (p, sha1hash, 20); + p += 20; + *p++ = ')'; + *p++ = ')'; + memcpy (p, iv+blklen, blklen); + p += blklen; + assert ( p - outbuf == outlen); + rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0); + } + gcry_cipher_close (hd); + if (rc) + { + xfree (iv); + xfree (outbuf); + return rc; + } + + /* Now allocate the buffer we want to return. This is + + (protected openpgp-s2k3-sha1-aes-cbc + ((sha1 salt no_of_iterations) 16byte_iv) + encrypted_octet_string) + + in canoncical format of course. We use asprintf and %n modifier + and dummy values as placeholders. */ + { + char countbuf[35]; + + snprintf (countbuf, sizeof countbuf, "%lu", get_standard_s2k_count ()); + p = xtryasprintf + ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)", + (int)strlen (modestr), modestr, + &saltpos, + (unsigned int)strlen (countbuf), countbuf, + blklen, &ivpos, blklen, "", + enclen, &encpos, enclen, ""); + if (!p) + { + gpg_error_t tmperr = out_of_core (); + xfree (iv); + xfree (outbuf); + return tmperr; + } + } + *resultlen = strlen (p); + *result = (unsigned char*)p; + memcpy (p+saltpos, iv+2*blklen, 8); + memcpy (p+ivpos, iv, blklen); + memcpy (p+encpos, outbuf, enclen); + xfree (iv); + xfree (outbuf); + return 0; +} + + + +/* Protect the key encoded in canonical format in PLAINKEY. We assume + a valid S-Exp here. */ +int +agent_protect (const unsigned char *plainkey, const char *passphrase, + unsigned char **result, size_t *resultlen) +{ + int rc; + const unsigned char *s; + const unsigned char *hash_begin, *hash_end; + const unsigned char *prot_begin, *prot_end, *real_end; + size_t n; + int c, infidx, i; + unsigned char hashvalue[20]; + char timestamp_exp[35]; + unsigned char *protected; + size_t protectedlen; + int depth = 0; + unsigned char *p; + gcry_md_hd_t md; + + /* Create an S-expression with the procted-at timestamp. */ + memcpy (timestamp_exp, "(12:protected-at15:", 19); + gnupg_get_isotime (timestamp_exp+19); + timestamp_exp[19+15] = ')'; + + /* Parse original key. */ + s = plainkey; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "private-key")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + depth++; + hash_begin = s; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + for (infidx=0; protect_info[infidx].algo + && !smatch (&s, n, protect_info[infidx].algo); infidx++) + ; + if (!protect_info[infidx].algo) + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + prot_begin = prot_end = NULL; + for (i=0; (c=protect_info[infidx].parmlist[i]); i++) + { + if (i == protect_info[infidx].prot_from) + prot_begin = s; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (n != 1 || c != *s) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s +=n; /* skip value */ + if (*s != ')') + return gpg_error (GPG_ERR_INV_SEXP); + depth--; + if (i == protect_info[infidx].prot_to) + prot_end = s; + s++; + } + if (*s != ')' || !prot_begin || !prot_end ) + return gpg_error (GPG_ERR_INV_SEXP); + depth--; + hash_end = s; + s++; + /* skip to the end of the S-exp */ + assert (depth == 1); + rc = sskip (&s, &depth); + if (rc) + return rc; + assert (!depth); + real_end = s-1; + + + /* Hash the stuff. Because the timestamp_exp won't get protected, + we can't simply hash a continuous buffer but need to use several + md_writes. */ + rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 ); + if (rc) + return rc; + gcry_md_write (md, hash_begin, hash_end - hash_begin); + gcry_md_write (md, timestamp_exp, 35); + gcry_md_write (md, ")", 1); + memcpy (hashvalue, gcry_md_read (md, GCRY_MD_SHA1), 20); + gcry_md_close (md); + + rc = do_encryption (prot_begin, prot_end - prot_begin + 1, + passphrase, hashvalue, + &protected, &protectedlen); + if (rc) + return rc; + + /* Now create the protected version of the key. Note that the 10 + extra bytes are for for the inserted "protected-" string (the + beginning of the plaintext reads: "((11:private-key(" ). The 35 + term is the space for (12:protected-at15:). */ + *resultlen = (10 + + (prot_begin-plainkey) + + protectedlen + + 35 + + (real_end-prot_end)); + *result = p = xtrymalloc (*resultlen); + if (!p) + { + gpg_error_t tmperr = out_of_core (); + xfree (protected); + return tmperr; + } + memcpy (p, "(21:protected-", 14); + p += 14; + memcpy (p, plainkey+4, prot_begin - plainkey - 4); + p += prot_begin - plainkey - 4; + memcpy (p, protected, protectedlen); + p += protectedlen; + + memcpy (p, timestamp_exp, 35); + p += 35; + + memcpy (p, prot_end+1, real_end - prot_end); + p += real_end - prot_end; + assert ( p - *result == *resultlen); + xfree (protected); + + return 0; +} + + +/* Do the actual decryption and check the return list for consistency. */ +static int +do_decryption (const unsigned char *protected, size_t protectedlen, + const char *passphrase, + const unsigned char *s2ksalt, unsigned long s2kcount, + const unsigned char *iv, size_t ivlen, + unsigned char **result) +{ + int rc = 0; + int blklen; + gcry_cipher_hd_t hd; + unsigned char *outbuf; + size_t reallen; + + blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER); + if (protectedlen < 4 || (protectedlen%blklen)) + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + + rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC, + GCRY_CIPHER_SECURE); + if (rc) + return rc; + + outbuf = gcry_malloc_secure (protectedlen); + if (!outbuf) + rc = out_of_core (); + if (!rc) + rc = gcry_cipher_setiv (hd, iv, ivlen); + if (!rc) + { + unsigned char *key; + size_t keylen = PROT_CIPHER_KEYLEN; + + key = gcry_malloc_secure (keylen); + if (!key) + rc = out_of_core (); + else + { + rc = hash_passphrase (passphrase, GCRY_MD_SHA1, + 3, s2ksalt, s2kcount, key, keylen); + if (!rc) + rc = gcry_cipher_setkey (hd, key, keylen); + xfree (key); + } + } + if (!rc) + rc = gcry_cipher_decrypt (hd, outbuf, protectedlen, + protected, protectedlen); + gcry_cipher_close (hd); + if (rc) + { + xfree (outbuf); + return rc; + } + /* Do a quick check first. */ + if (*outbuf != '(' && outbuf[1] != '(') + { + xfree (outbuf); + return gpg_error (GPG_ERR_BAD_PASSPHRASE); + } + /* Check that we have a consistent S-Exp. */ + reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL); + if (!reallen || (reallen + blklen < protectedlen) ) + { + xfree (outbuf); + return gpg_error (GPG_ERR_BAD_PASSPHRASE); + } + *result = outbuf; + return 0; +} + + +/* Merge the parameter list contained in CLEARTEXT with the original + protect lists PROTECTEDKEY by replacing the list at REPLACEPOS. + Return the new list in RESULT and the MIC value in the 20 byte + buffer SHA1HASH. CUTOFF and CUTLEN will receive the offset and the + length of the resulting list which should go into the MIC + calculation but then be removed. */ +static int +merge_lists (const unsigned char *protectedkey, + size_t replacepos, + const unsigned char *cleartext, + unsigned char *sha1hash, + unsigned char **result, size_t *resultlen, + size_t *cutoff, size_t *cutlen) +{ + size_t n, newlistlen; + unsigned char *newlist, *p; + const unsigned char *s; + const unsigned char *startpos, *endpos; + int i, rc; + + *result = NULL; + *resultlen = 0; + *cutoff = 0; + *cutlen = 0; + + if (replacepos < 26) + return gpg_error (GPG_ERR_BUG); + + /* Estimate the required size of the resulting list. We have a large + safety margin of >20 bytes (MIC hash from CLEARTEXT and the + removed "protected-" */ + newlistlen = gcry_sexp_canon_len (protectedkey, 0, NULL, NULL); + if (!newlistlen) + return gpg_error (GPG_ERR_BUG); + n = gcry_sexp_canon_len (cleartext, 0, NULL, NULL); + if (!n) + return gpg_error (GPG_ERR_BUG); + newlistlen += n; + newlist = gcry_malloc_secure (newlistlen); + if (!newlist) + return out_of_core (); + + /* Copy the initial segment */ + strcpy ((char*)newlist, "(11:private-key"); + p = newlist + 15; + memcpy (p, protectedkey+15+10, replacepos-15-10); + p += replacepos-15-10; + + /* copy the cleartext */ + s = cleartext; + if (*s != '(' && s[1] != '(') + return gpg_error (GPG_ERR_BUG); /*we already checked this */ + s += 2; + startpos = s; + while ( *s == '(' ) + { + s++; + n = snext (&s); + if (!n) + goto invalid_sexp; + s += n; + n = snext (&s); + if (!n) + goto invalid_sexp; + s += n; + if ( *s != ')' ) + goto invalid_sexp; + s++; + } + if ( *s != ')' ) + goto invalid_sexp; + endpos = s; + s++; + /* Intermezzo: Get the MIC */ + if (*s != '(') + goto invalid_sexp; + s++; + n = snext (&s); + if (!smatch (&s, n, "hash")) + goto invalid_sexp; + n = snext (&s); + if (!smatch (&s, n, "sha1")) + goto invalid_sexp; + n = snext (&s); + if (n != 20) + goto invalid_sexp; + memcpy (sha1hash, s, 20); + s += n; + if (*s != ')') + goto invalid_sexp; + /* End intermezzo */ + + /* append the parameter list */ + memcpy (p, startpos, endpos - startpos); + p += endpos - startpos; + + /* Skip over the protected list element in the original list. */ + s = protectedkey + replacepos; + assert (*s == '('); + s++; + i = 1; + rc = sskip (&s, &i); + if (rc) + goto failure; + /* Record the position of the optional protected-at expression. */ + if (*s == '(') + { + const unsigned char *save_s = s; + s++; + n = snext (&s); + if (smatch (&s, n, "protected-at")) + { + i = 1; + rc = sskip (&s, &i); + if (rc) + goto failure; + *cutlen = s - save_s; + } + s = save_s; + } + startpos = s; + i = 2; /* we are inside this level */ + rc = sskip (&s, &i); + if (rc) + goto failure; + assert (s[-1] == ')'); + endpos = s; /* one behind the end of the list */ + + /* Append the rest. */ + if (*cutlen) + *cutoff = p - newlist; + memcpy (p, startpos, endpos - startpos); + p += endpos - startpos; + + + /* ready */ + *result = newlist; + *resultlen = newlistlen; + return 0; + + failure: + wipememory (newlist, newlistlen); + xfree (newlist); + return rc; + + invalid_sexp: + wipememory (newlist, newlistlen); + xfree (newlist); + return gpg_error (GPG_ERR_INV_SEXP); +} + + + +/* Unprotect the key encoded in canonical format. We assume a valid + S-Exp here. If a protected-at item is available, its value will + be stored at protocted_at unless this is NULL. */ +int +agent_unprotect (const unsigned char *protectedkey, const char *passphrase, + gnupg_isotime_t protected_at, + unsigned char **result, size_t *resultlen) +{ + int rc; + const unsigned char *s; + const unsigned char *protect_list; + size_t n; + int infidx, i; + unsigned char sha1hash[20], sha1hash2[20]; + const unsigned char *s2ksalt; + unsigned long s2kcount; + const unsigned char *iv; + const unsigned char *prot_begin; + unsigned char *cleartext = NULL; /* Just to avoid gcc warning. */ + unsigned char *final; + size_t finallen; + size_t cutoff, cutlen; + + if (protected_at) + *protected_at = 0; + + s = protectedkey; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "protected-private-key")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + for (infidx=0; protect_info[infidx].algo + && !smatch (&s, n, protect_info[infidx].algo); infidx++) + ; + if (!protect_info[infidx].algo) + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + + /* See wether we have a protected-at timestamp. */ + protect_list = s; /* Save for later. */ + if (protected_at) + { + while (*s == '(') + { + prot_begin = s; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "protected-at")) + { + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (n != 15) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + memcpy (protected_at, s, 15); + protected_at[15] = 0; + break; + } + s += n; + i = 1; + rc = sskip (&s, &i); + if (rc) + return rc; + } + } + + /* Now find the list with the protected information. Here is an + example for such a list: + (protected openpgp-s2k3-sha1-aes-cbc + ((sha1 ) ) + ) + */ + s = protect_list; + for (;;) + { + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + prot_begin = s; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "protected")) + break; + s += n; + i = 1; + rc = sskip (&s, &i); + if (rc) + return rc; + } + /* found */ + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc")) + return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION); + if (*s != '(' || s[1] != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s += 2; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "sha1")) + return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION); + n = snext (&s); + if (n != 8) + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + s2ksalt = s; + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + /* We expect a list close as next, so we can simply use strtoul() + here. We might want to check that we only have digits - but this + is nothing we should worry about */ + if (s[n] != ')' ) + return gpg_error (GPG_ERR_INV_SEXP); + + /* Old versions of gpg-agent used the funny floating point number in + a byte encoding as specified by OpenPGP. However this is not + needed and thus we now store it as a plain unsigned integer. We + can easily distinguish the old format by looking at its value: + Less than 256 is an old-style encoded number; other values are + plain integers. In any case we check that they are at least + 65536 because we never used a lower value in the past and we + should have a lower limit. */ + s2kcount = strtoul ((const char*)s, NULL, 10); + if (!s2kcount) + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + if (s2kcount < 256) + s2kcount = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6); + if (s2kcount < 65536) + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + + s += n; + s++; /* skip list end */ + + n = snext (&s); + if (n != 16) /* Wrong blocksize for IV (we support only aes-128). */ + return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + iv = s; + s += n; + if (*s != ')' ) + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + rc = do_decryption (s, n, + passphrase, s2ksalt, s2kcount, + iv, 16, + &cleartext); + if (rc) + return rc; + + rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext, + sha1hash, &final, &finallen, &cutoff, &cutlen); + /* Albeit cleartext has been allocated in secure memory and thus + xfree will wipe it out, we do an extra wipe just in case + somethings goes badly wrong. */ + wipememory (cleartext, n); + xfree (cleartext); + if (rc) + return rc; + + rc = calculate_mic (final, sha1hash2); + if (!rc && memcmp (sha1hash, sha1hash2, 20)) + rc = gpg_error (GPG_ERR_CORRUPTED_PROTECTION); + if (rc) + { + wipememory (final, finallen); + xfree (final); + return rc; + } + /* Now remove tha part which is included in the MIC but should not + go into the final thing. */ + if (cutlen) + { + memmove (final+cutoff, final+cutoff+cutlen, finallen-cutoff-cutlen); + finallen -= cutlen; + } + + *result = final; + *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL); + return 0; +} + +/* Check the type of the private key, this is one of the constants: + PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the + value 0), PRIVATE_KEY_CLEAR for an unprotected private key. + PRIVATE_KEY_PROTECTED for an protected private key or + PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored + elsewhere. */ +int +agent_private_key_type (const unsigned char *privatekey) +{ + const unsigned char *s; + size_t n; + + s = privatekey; + if (*s != '(') + return PRIVATE_KEY_UNKNOWN; + s++; + n = snext (&s); + if (!n) + return PRIVATE_KEY_UNKNOWN; + if (smatch (&s, n, "protected-private-key")) + return PRIVATE_KEY_PROTECTED; + if (smatch (&s, n, "shadowed-private-key")) + return PRIVATE_KEY_SHADOWED; + if (smatch (&s, n, "private-key")) + return PRIVATE_KEY_CLEAR; + return PRIVATE_KEY_UNKNOWN; +} + + + +/* Transform a passphrase into a suitable key of length KEYLEN and + store this key in the caller provided buffer KEY. The caller must + provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on + that mode an S2KSALT of 8 random bytes and an S2KCOUNT. + + Returns an error code on failure. */ +static int +hash_passphrase (const char *passphrase, int hashalgo, + int s2kmode, + const unsigned char *s2ksalt, + unsigned long s2kcount, + unsigned char *key, size_t keylen) +{ + int rc; + gcry_md_hd_t md; + int pass, i; + int used = 0; + int pwlen = strlen (passphrase); + + if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3) + || !hashalgo || !keylen || !key || !passphrase) + return gpg_error (GPG_ERR_INV_VALUE); + if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt) + return gpg_error (GPG_ERR_INV_VALUE); + + rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE); + if (rc) + return rc; + + for (pass=0; used < keylen; pass++) + { + if (pass) + { + gcry_md_reset (md); + for (i=0; i < pass; i++) /* preset the hash context */ + gcry_md_putc (md, 0); + } + + if (s2kmode == 1 || s2kmode == 3) + { + int len2 = pwlen + 8; + unsigned long count = len2; + + if (s2kmode == 3) + { + count = s2kcount; + if (count < len2) + count = len2; + } + + while (count > len2) + { + gcry_md_write (md, s2ksalt, 8); + gcry_md_write (md, passphrase, pwlen); + count -= len2; + } + if (count < 8) + gcry_md_write (md, s2ksalt, count); + else + { + gcry_md_write (md, s2ksalt, 8); + count -= 8; + gcry_md_write (md, passphrase, count); + } + } + else + gcry_md_write (md, passphrase, pwlen); + + gcry_md_final (md); + i = gcry_md_get_algo_dlen (hashalgo); + if (i > keylen - used) + i = keylen - used; + memcpy (key+used, gcry_md_read (md, hashalgo), i); + used += i; + } + gcry_md_close(md); + return 0; +} + + + + +/* Create an canonical encoded S-expression with the shadow info from + a card's SERIALNO and the IDSTRING. */ +unsigned char * +make_shadow_info (const char *serialno, const char *idstring) +{ + const char *s; + char *info, *p; + char numbuf[20]; + size_t n; + + for (s=serialno, n=0; *s && s[1]; s += 2) + n++; + + info = p = xtrymalloc (1 + sizeof numbuf + n + + sizeof numbuf + strlen (idstring) + 1 + 1); + if (!info) + return NULL; + *p++ = '('; + p = stpcpy (p, smklen (numbuf, sizeof numbuf, n, NULL)); + for (s=serialno; *s && s[1]; s += 2) + *(unsigned char *)p++ = xtoi_2 (s); + p = stpcpy (p, smklen (numbuf, sizeof numbuf, strlen (idstring), NULL)); + p = stpcpy (p, idstring); + *p++ = ')'; + *p = 0; + return (unsigned char *)info; +} + + + +/* Create a shadow key from a public key. We use the shadow protocol + "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting + S-expression is returned in an allocated buffer RESULT will point + to. The input parameters are expected to be valid canonicalized + S-expressions */ +int +agent_shadow_key (const unsigned char *pubkey, + const unsigned char *shadow_info, + unsigned char **result) +{ + const unsigned char *s; + const unsigned char *point; + size_t n; + int depth = 0; + char *p; + size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL); + size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL); + + if (!pubkey_len || !shadow_info_len) + return gpg_error (GPG_ERR_INV_VALUE); + s = pubkey; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "public-key")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; /* skip over the algorithm name */ + + while (*s != ')') + { + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s +=n; /* skip value */ + if (*s != ')') + return gpg_error (GPG_ERR_INV_SEXP); + depth--; + s++; + } + point = s; /* insert right before the point */ + depth--; + s++; + assert (depth == 1); + + /* Calculate required length by taking in account: the "shadowed-" + prefix, the "shadowed", "t1-v1" as well as some parenthesis */ + n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; + *result = xtrymalloc (n); + p = (char*)*result; + if (!p) + return out_of_core (); + p = stpcpy (p, "(20:shadowed-private-key"); + /* (10:public-key ...)*/ + memcpy (p, pubkey+14, point - (pubkey+14)); + p += point - (pubkey+14); + p = stpcpy (p, "(8:shadowed5:t1-v1"); + memcpy (p, shadow_info, shadow_info_len); + p += shadow_info_len; + *p++ = ')'; + memcpy (p, point, pubkey_len - (point - pubkey)); + p += pubkey_len - (point - pubkey); + + return 0; +} + +/* Parse a canonical encoded shadowed key and return a pointer to the + inner list with the shadow_info */ +int +agent_get_shadow_info (const unsigned char *shadowkey, + unsigned char const **shadow_info) +{ + const unsigned char *s; + size_t n; + int depth = 0; + + s = shadowkey; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (!smatch (&s, n, "shadowed-private-key")) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s += n; /* skip over the algorithm name */ + + for (;;) + { + if (*s == ')') + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + depth++; + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "shadowed")) + break; + s += n; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + s +=n; /* skip value */ + if (*s != ')') + return gpg_error (GPG_ERR_INV_SEXP); + depth--; + s++; + } + /* Found the shadowed list, S points to the protocol */ + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + if (smatch (&s, n, "t1-v1")) + { + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + *shadow_info = s; + } + else + return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL); + return 0; +} + + +/* Parse the canonical encoded SHADOW_INFO S-expression. On success + the hex encoded serial number is returned as a malloced strings at + R_HEXSN and the Id string as a malloced string at R_IDSTR. On + error an error code is returned and NULL is stored at the result + parameters addresses. If the serial number or the ID string is not + required, NULL may be passed for them. */ +gpg_error_t +parse_shadow_info (const unsigned char *shadow_info, + char **r_hexsn, char **r_idstr) +{ + const unsigned char *s; + size_t n; + + if (r_hexsn) + *r_hexsn = NULL; + if (r_idstr) + *r_idstr = NULL; + + s = shadow_info; + if (*s != '(') + return gpg_error (GPG_ERR_INV_SEXP); + s++; + n = snext (&s); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); + + if (r_hexsn) + { + *r_hexsn = bin2hex (s, n, NULL); + if (!*r_hexsn) + return gpg_error_from_syserror (); + } + s += n; + + n = snext (&s); + if (!n) + { + if (r_hexsn) + { + xfree (*r_hexsn); + *r_hexsn = NULL; + } + return gpg_error (GPG_ERR_INV_SEXP); + } + + if (r_idstr) + { + *r_idstr = xtrymalloc (n+1); + if (!*r_idstr) + { + if (r_hexsn) + { + xfree (*r_hexsn); + *r_hexsn = NULL; + } + return gpg_error_from_syserror (); + } + memcpy (*r_idstr, s, n); + (*r_idstr)[n] = 0; + } + + return 0; +} + diff --git a/agent/t-protect.c b/agent/t-protect.c new file mode 100644 index 0000000..0e29caf --- /dev/null +++ b/agent/t-protect.c @@ -0,0 +1,310 @@ +/* t-protect.c - Module tests for protect.c + * Copyright (C) 2005 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "agent.h" + + +#define pass() do { ; } while(0) +#define fail() do { fprintf (stderr, "%s:%d: test failed\n",\ + __FILE__,__LINE__); \ + exit (1); \ + } while(0) + + +static void +test_agent_protect (void) +{ + /* Protect the key encoded in canonical format in PLAINKEY. We assume + a valid S-Exp here. */ + + unsigned int i; + int ret; + struct key_spec + { + const char *string; + }; + /* Valid RSA key. */ + struct key_spec key_rsa_valid = + { + "\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73" + "\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xB6\xB5\x09\x59\x6A\x9E\xCA\xBC\x93\x92" + "\x12\xF8\x91\xE6\x56\xA6\x26\xBA\x07\xDA\x85\x21\xA9\xCA\xD4\xC0\x8E\x64\x0C\x04" + "\x05\x2F\xBB\x87\xF4\x24\xEF\x1A\x02\x75\xA4\x8A\x92\x99\xAC\x9D\xB6\x9A\xBE\x3D" + "\x01\x24\xE6\xC7\x56\xB1\xF7\xDF\xB9\xB8\x42\xD6\x25\x1A\xEA\x6E\xE8\x53\x90\x49" + "\x5C\xAD\xA7\x3D\x67\x15\x37\xFC\xE5\x85\x0A\x93\x2F\x32\xBA\xB6\x0A\xB1\xAC\x1F" + "\x85\x2C\x1F\x83\xC6\x25\xE7\xA7\xD7\x0C\xDA\x9E\xF1\x6D\x5C\x8E\x47\x73\x9D\x77" + "\xDF\x59\x26\x1A\xBE\x84\x54\x80\x7F\xF4\x41\xE1\x43\xFB\xD3\x7F\x85\x45\x29\x28" + "\x31\x3A\x65\x33\x3A\x01\x00\x01\x29\x28\x31\x3A\x64\x31\x32\x38\x3A\x07\x7A\xD3" + "\xDE\x28\x42\x45\xF4\x80\x6A\x1B\x82\xB7\x9E\x61\x6F\xBD\xE8\x21\xC8\x2D\x69\x1A" + "\x65\x66\x5E\x57\xB5\xFA\xD3\xF3\x4E\x67\xF4\x01\xE7\xBD\x2E\x28\x69\x9E\x89\xD9" + "\xC4\x96\xCF\x82\x19\x45\xAE\x83\xAC\x7A\x12\x31\x17\x6A\x19\x6B\xA6\x02\x7E\x77" + "\xD8\x57\x89\x05\x5D\x50\x40\x4A\x7A\x2A\x95\xB1\x51\x2F\x91\xF1\x90\xBB\xAE\xF7" + "\x30\xED\x55\x0D\x22\x7D\x51\x2F\x89\xC0\xCD\xB3\x1A\xC0\x6F\xA9\xA1\x95\x03\xDD" + "\xF6\xB6\x6D\x0B\x42\xB9\x69\x1B\xFD\x61\x40\xEC\x17\x20\xFF\xC4\x8A\xE0\x0C\x34" + "\x79\x6D\xC8\x99\xE5\x29\x28\x31\x3A\x70\x36\x35\x3A\x00\xD5\x86\xC7\x8E\x5F\x1B" + "\x4B\xF2\xE7\xCD\x7A\x04\xCA\x09\x19\x11\x70\x6F\x19\x78\x8B\x93\xE4\x4E\xE2\x0A" + "\xAF\x46\x2E\x83\x63\xE9\x8A\x72\x25\x3E\xD8\x45\xCC\xBF\x24\x81\xBB\x35\x1E\x85" + "\x57\xC8\x5B\xCF\xFF\x0D\xAB\xDB\xFF\x8E\x26\xA7\x9A\x09\x38\x09\x6F\x27\x29\x28" + "\x31\x3A\x71\x36\x35\x3A\x00\xDB\x0C\xDF\x60\xF2\x6F\x2A\x29\x6C\x88\xD6\xBF\x9F" + "\x8E\x5B\xE4\x5C\x0D\xDD\x71\x3C\x96\xCC\x73\xEB\xCB\x48\xB0\x61\x74\x09\x43\xF2" + "\x1D\x2A\x93\xD6\xE4\x2A\x72\x11\xE7\xF0\x2A\x95\xDC\xED\x6C\x39\x0A\x67\xAD\x21" + "\xEC\xF7\x39\xAE\x8A\x0C\xA4\x6F\xF2\xEB\xB3\x29\x28\x31\x3A\x75\x36\x34\x3A\x33" + "\x14\x91\x95\xF1\x69\x12\xDB\x20\xA4\x8D\x02\x0D\xBC\x3B\x9E\x38\x81\xB3\x9D\x72" + "\x2B\xF7\x93\x78\xF6\x34\x0F\x43\x14\x8A\x6E\x9F\xC5\xF5\x3E\x28\x53\xB7\x38\x7B" + "\xA4\x44\x3B\xA5\x3A\x52\xFC\xA8\x17\x3D\xE6\xE8\x5B\x42\xF9\x78\x3D\x4A\x78\x17" + "\xD0\x68\x0B\x29\x29\x29\x00" + }; + /* This RSA key is missing the last closing brace. */ + struct key_spec key_rsa_bogus_0 = + { + "\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73" + "\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xB6\xB5\x09\x59\x6A\x9E\xCA\xBC\x93\x92" + "\x12\xF8\x91\xE6\x56\xA6\x26\xBA\x07\xDA\x85\x21\xA9\xCA\xD4\xC0\x8E\x64\x0C\x04" + "\x05\x2F\xBB\x87\xF4\x24\xEF\x1A\x02\x75\xA4\x8A\x92\x99\xAC\x9D\xB6\x9A\xBE\x3D" + "\x01\x24\xE6\xC7\x56\xB1\xF7\xDF\xB9\xB8\x42\xD6\x25\x1A\xEA\x6E\xE8\x53\x90\x49" + "\x5C\xAD\xA7\x3D\x67\x15\x37\xFC\xE5\x85\x0A\x93\x2F\x32\xBA\xB6\x0A\xB1\xAC\x1F" + "\x85\x2C\x1F\x83\xC6\x25\xE7\xA7\xD7\x0C\xDA\x9E\xF1\x6D\x5C\x8E\x47\x73\x9D\x77" + "\xDF\x59\x26\x1A\xBE\x84\x54\x80\x7F\xF4\x41\xE1\x43\xFB\xD3\x7F\x85\x45\x29\x28" + "\x31\x3A\x65\x33\x3A\x01\x00\x01\x29\x28\x31\x3A\x64\x31\x32\x38\x3A\x07\x7A\xD3" + "\xDE\x28\x42\x45\xF4\x80\x6A\x1B\x82\xB7\x9E\x61\x6F\xBD\xE8\x21\xC8\x2D\x69\x1A" + "\x65\x66\x5E\x57\xB5\xFA\xD3\xF3\x4E\x67\xF4\x01\xE7\xBD\x2E\x28\x69\x9E\x89\xD9" + "\xC4\x96\xCF\x82\x19\x45\xAE\x83\xAC\x7A\x12\x31\x17\x6A\x19\x6B\xA6\x02\x7E\x77" + "\xD8\x57\x89\x05\x5D\x50\x40\x4A\x7A\x2A\x95\xB1\x51\x2F\x91\xF1\x90\xBB\xAE\xF7" + "\x30\xED\x55\x0D\x22\x7D\x51\x2F\x89\xC0\xCD\xB3\x1A\xC0\x6F\xA9\xA1\x95\x03\xDD" + "\xF6\xB6\x6D\x0B\x42\xB9\x69\x1B\xFD\x61\x40\xEC\x17\x20\xFF\xC4\x8A\xE0\x0C\x34" + "\x79\x6D\xC8\x99\xE5\x29\x28\x31\x3A\x70\x36\x35\x3A\x00\xD5\x86\xC7\x8E\x5F\x1B" + "\x4B\xF2\xE7\xCD\x7A\x04\xCA\x09\x19\x11\x70\x6F\x19\x78\x8B\x93\xE4\x4E\xE2\x0A" + "\xAF\x46\x2E\x83\x63\xE9\x8A\x72\x25\x3E\xD8\x45\xCC\xBF\x24\x81\xBB\x35\x1E\x85" + "\x57\xC8\x5B\xCF\xFF\x0D\xAB\xDB\xFF\x8E\x26\xA7\x9A\x09\x38\x09\x6F\x27\x29\x28" + "\x31\x3A\x71\x36\x35\x3A\x00\xDB\x0C\xDF\x60\xF2\x6F\x2A\x29\x6C\x88\xD6\xBF\x9F" + "\x8E\x5B\xE4\x5C\x0D\xDD\x71\x3C\x96\xCC\x73\xEB\xCB\x48\xB0\x61\x74\x09\x43\xF2" + "\x1D\x2A\x93\xD6\xE4\x2A\x72\x11\xE7\xF0\x2A\x95\xDC\xED\x6C\x39\x0A\x67\xAD\x21" + "\xEC\xF7\x39\xAE\x8A\x0C\xA4\x6F\xF2\xEB\xB3\x29\x28\x31\x3A\x75\x36\x34\x3A\x33" + "\x14\x91\x95\xF1\x69\x12\xDB\x20\xA4\x8D\x02\x0D\xBC\x3B\x9E\x38\x81\xB3\x9D\x72" + "\x2B\xF7\x93\x78\xF6\x34\x0F\x43\x14\x8A\x6E\x9F\xC5\xF5\x3E\x28\x53\xB7\x38\x7B" + "\xA4\x44\x3B\xA5\x3A\x52\xFC\xA8\x17\x3D\xE6\xE8\x5B\x42\xF9\x78\x3D\x4A\x78\x17" + "\xD0\x68\x0B\x29\x29\x00" + }; + /* This RSA key is the `e' value. */ + struct key_spec key_rsa_bogus_1 = + { + "\x28\x31\x31\x3A\x70\x72\x69\x76\x61\x74\x65\x2D\x6B\x65\x79\x28\x33\x3A\x72\x73" + "\x61\x28\x31\x3A\x6E\x31\x32\x39\x3A\x00\xA8\x80\xB6\x71\xF4\x95\x9F\x49\x84\xED" + "\xC1\x1D\x5F\xFF\xED\x14\x7B\x9C\x6A\x62\x0B\x7B\xE2\x3E\x41\x48\x49\x85\xF5\x64" + "\x50\x04\x9D\x30\xFC\x84\x1F\x01\xC3\xC3\x15\x03\x48\x6D\xFE\x59\x0B\xB0\xD0\x3E" + "\x68\x8A\x05\x7A\x62\xB0\xB9\x6E\xC5\xD2\xA8\xEE\x0C\x6B\xDE\x5E\x3D\x8E\xE8\x8F" + "\xB3\xAE\x86\x99\x7E\xDE\x2B\xC2\x4D\x60\x51\xDB\xB1\x2C\xD0\x38\xEC\x88\x62\x3E" + "\xA9\xDD\x11\x53\x04\x17\xE4\xF2\x07\x50\xDC\x44\xED\x14\xF5\x0B\xAB\x9C\xBC\x24" + "\xC6\xCB\xAD\x0F\x05\x25\x94\xE2\x73\xEB\x14\xD5\xEE\x5E\x18\xF0\x40\x31\x29\x28" + "\x31\x3A\x64\x31\x32\x38\x3A\x40\xD0\x55\x9D\x2A\xA7\xBC\xBF\xE2\x3E\x33\x98\x71" + "\x7B\x37\x3D\xB8\x38\x57\xA1\x43\xEA\x90\x81\x42\xCA\x23\xE1\xBF\x9C\xA8\xBC\xC5" + "\x9B\xF8\x9D\x77\x71\xCD\xD3\x85\x8B\x20\x3A\x92\xE9\xBC\x79\xF3\xF7\xF5\x6D\x15" + "\xA3\x58\x3F\xC2\xEB\xED\x72\xD4\xE0\xCF\xEC\xB3\xEC\xEB\x09\xEA\x1E\x72\x6A\xBA" + "\x95\x82\x2C\x7E\x30\x95\x66\x3F\xA8\x2D\x40\x0F\x7A\x12\x4E\xF0\x71\x0F\x97\xDB" + "\x81\xE4\x39\x6D\x24\x58\xFA\xAB\x3A\x36\x73\x63\x01\x77\x42\xC7\x9A\xEA\x87\xDA" + "\x93\x8F\x6C\x64\xAD\x9E\xF0\xCA\xA2\x89\xA4\x0E\xB3\x25\x73\x29\x28\x31\x3A\x70" + "\x36\x35\x3A\x00\xC3\xF7\x37\x3F\x9D\x93\xEC\xC7\x5E\x4C\xB5\x73\x29\x62\x35\x80" + "\xC6\x7C\x1B\x1E\x68\x5F\x92\x56\x77\x0A\xE2\x8E\x95\x74\x87\xA5\x2F\x83\x2D\xF7" + "\xA1\xC2\x78\x54\x18\x6E\xDE\x35\xF0\x9F\x7A\xCA\x80\x5C\x83\x5C\x44\xAD\x8B\xE7" + "\x5B\xE2\x63\x7D\x6A\xC7\x98\x97\x29\x28\x31\x3A\x71\x36\x35\x3A\x00\xDC\x1F\xB1" + "\xB3\xD8\x13\xE0\x09\x19\xFD\x1C\x58\xA1\x2B\x02\xB4\xC8\xF2\x1C\xE7\xF9\xC6\x3B" + "\x68\xB9\x72\x43\x86\xEF\xA9\x94\x68\x02\xEF\x7D\x77\xE0\x0A\xD1\xD7\x48\xFD\xCD" + "\x98\xDA\x13\x8A\x76\x48\xD4\x0F\x63\x28\xFA\x01\x1B\xF3\xC7\x15\xB8\x53\x22\x7E" + "\x77\x29\x28\x31\x3A\x75\x36\x35\x3A\x00\xB3\xBB\x4D\xEE\x5A\xAF\xD0\xF2\x56\x8A" + "\x10\x2D\x6F\x4B\x2D\x76\x49\x9B\xE9\xA8\x60\x5D\x9E\x7E\x50\x86\xF1\xA1\x0F\x28" + "\x9B\x7B\xE8\xDD\x1F\x87\x4E\x79\x7B\x50\x12\xA7\xB4\x8B\x52\x38\xEC\x7C\xBB\xB9" + "\x55\x87\x11\x1C\x74\xE7\x7F\xA0\xBA\xE3\x34\x5D\x61\xBF\x29\x29\x29\x00" + }; + + struct + { + const char *key; + const char *passphrase; + int no_result_expected; + int compare_results; + unsigned char *result_expected; + size_t resultlen_expected; + int ret_expected; + unsigned char *result; + size_t resultlen; + } specs[] = + { + /* Invalid S-Expressions */ + /* - non-NULL */ + { "", + "passphrase", 1, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 }, + /* - NULL; disabled, this segfaults */ + //{ NULL, + // "passphrase", 1, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 }, + + /* Valid and invalid keys. */ + { key_rsa_valid.string, + "passphrase", 0, 0, NULL, 0, 0, NULL, 0 }, + { key_rsa_bogus_0.string, + "passphrase", 0, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 }, + { key_rsa_bogus_1.string, + "passphrase", 0, 0, NULL, 0, GPG_ERR_INV_SEXP, NULL, 0 }, + + /* FIXME: add more test data. */ + }; + + for (i = 0; i < DIM (specs); i++) + { + ret = agent_protect ((const unsigned char*)specs[i].key, + specs[i].passphrase, + &specs[i].result, &specs[i].resultlen); + if (gpg_err_code (ret) != specs[i].ret_expected) + { + printf ("agent_protect() returned `%i/%s'; expected `%i/%s'\n", + ret, gpg_strerror (ret), + specs[i].ret_expected, gpg_strerror (specs[i].ret_expected)); + abort (); + } + + if (specs[i].no_result_expected) + { + assert (! specs[i].result); + assert (! specs[i].resultlen); + } + else + { + if (specs[i].compare_results) + { + assert (specs[i].resultlen == specs[i].resultlen_expected); + if (specs[i].result_expected) + assert (! memcmp (specs[i].result, specs[i].result_expected, + specs[i].resultlen)); + else + assert (! specs[i].result); + } + xfree (specs[i].result); + } + } +} + + +static void +test_agent_unprotect (void) +{ + /* Unprotect the key encoded in canonical format. We assume a valid + S-Exp here. */ +/* int */ +/* agent_unprotect (const unsigned char *protectedkey, const char *passphrase, */ +/* unsigned char **result, size_t *resultlen) */ +} + + +static void +test_agent_private_key_type (void) +{ +/* Check the type of the private key, this is one of the constants: + PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the + value 0), PRIVATE_KEY_CLEAR for an unprotected private key. + PRIVATE_KEY_PROTECTED for an protected private key or + PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored + elsewhere. */ +/* int */ +/* agent_private_key_type (const unsigned char *privatekey) */ +} + + +static void +test_make_shadow_info (void) +{ +#if 0 + static struct + { + const char *snstr; + const char *idstr; + const char *expected; + } data[] = { + { "", "", NULL }, + + }; + int i; + unsigned char *result; + + for (i=0; i < DIM(data); i++) + { + result = make_shadow_info (data[i].snstr, data[i].idstr); + if (!result && !data[i].expected) + pass (); + else if (!result && data[i].expected) + fail (); + else if (!data[i].expected) + fail (); + /* fixme: Need to compare the result but also need to check + proper S-expression syntax. */ + } +#endif +} + + + +static void +test_agent_shadow_key (void) +{ +/* Create a shadow key from a public key. We use the shadow protocol + "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting + S-expression is returned in an allocated buffer RESULT will point + to. The input parameters are expected to be valid canonicalized + S-expressions */ +/* int */ +/* agent_shadow_key (const unsigned char *pubkey, */ +/* const unsigned char *shadow_info, */ +/* unsigned char **result) */ +} + + +static void +test_agent_get_shadow_info (void) +{ +/* Parse a canonical encoded shadowed key and return a pointer to the + inner list with the shadow_info */ +/* int */ +/* agent_get_shadow_info (const unsigned char *shadowkey, */ +/* unsigned char const **shadow_info) */ +} + + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + gcry_control (GCRYCTL_DISABLE_SECMEM); + + test_agent_protect (); + test_agent_unprotect (); + test_agent_private_key_type (); + test_make_shadow_info (); + test_agent_shadow_key (); + test_agent_get_shadow_info (); + + return 0; +} diff --git a/agent/trans.c b/agent/trans.c new file mode 100644 index 0000000..9e48889 --- /dev/null +++ b/agent/trans.c @@ -0,0 +1,41 @@ +/* trans.c - translatable strings + * 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 3 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, see . + */ + +/* To avoid any problems with the gettext implementation (there used + to be some vulnerabilities in the last years and the use of + external files is a minor security problem in itself), we use our + own simple translation stuff */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" + +const char * +trans (const char *text) +{ + return text; +} diff --git a/agent/trustlist.c b/agent/trustlist.c new file mode 100644 index 0000000..be5406b --- /dev/null +++ b/agent/trustlist.c @@ -0,0 +1,763 @@ +/* trustlist.c - Maintain the list of trusted keys + * Copyright (C) 2002, 2004, 2006, 2007, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "agent.h" +#include /* fixme: need a way to avoid assuan calls here */ +#include "i18n.h" +#include "estream.h" + + +/* A structure to store the information from the trust file. */ +struct trustitem_s +{ + struct + { + int disabled:1; /* This entry is disabled. */ + int for_pgp:1; /* Set by '*' or 'P' as first flag. */ + int for_smime:1; /* Set by '*' or 'S' as first flag. */ + int relax:1; /* Relax checking of root certificate + constraints. */ + int cm:1; /* Use chain model for validation. */ + } flags; + unsigned char fpr[20]; /* The binary fingerprint. */ +}; +typedef struct trustitem_s trustitem_t; + +/* Malloced table and its allocated size with all trust items. */ +static trustitem_t *trusttable; +static size_t trusttablesize; +/* A mutex used to protect the table. */ +static pth_mutex_t trusttable_lock; + + + +static const char headerblurb[] = +"# This is the list of trusted keys. Comment lines, like this one, as\n" +"# well as empty lines are ignored. Lines have a length limit but this\n" +"# is not a serious limitation as the format of the entries is fixed and\n" +"# checked by gpg-agent. A non-comment line starts with optional white\n" +"# space, followed by the SHA-1 fingerpint in hex, followed by a flag\n" +"# which may be one of 'P', 'S' or '*' and optionally followed by a list of\n" +"# other flags. The fingerprint may be prefixed with a '!' to mark the\n" +"# key as not trusted. You should give the gpg-agent a HUP or run the\n" +"# command \"gpgconf --reload gpg-agent\" after changing this file.\n" +"\n\n" +"# Include the default trust list\n" +"include-default\n" +"\n"; + + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_trustlist (void) +{ + static int initialized; + + if (!initialized) + { + if (!pth_mutex_init (&trusttable_lock)) + log_fatal ("error initializing mutex: %s\n", strerror (errno)); + initialized = 1; + } +} + + + + +static void +lock_trusttable (void) +{ + if (!pth_mutex_acquire (&trusttable_lock, 0, NULL)) + log_fatal ("failed to acquire mutex in %s\n", __FILE__); +} + +static void +unlock_trusttable (void) +{ + if (!pth_mutex_release (&trusttable_lock)) + log_fatal ("failed to release mutex in %s\n", __FILE__); +} + + + +static gpg_error_t +read_one_trustfile (const char *fname, int allow_include, + trustitem_t **addr_of_table, + size_t *addr_of_tablesize, + int *addr_of_tableidx) +{ + gpg_error_t err = 0; + FILE *fp; + int n, c; + char *p, line[256]; + trustitem_t *table, *ti; + int tableidx; + size_t tablesize; + int lnr = 0; + + table = *addr_of_table; + tablesize = *addr_of_tablesize; + tableidx = *addr_of_tableidx; + + fp = fopen (fname, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err)); + goto leave; + } + + while (fgets (line, DIM(line)-1, fp)) + { + lnr++; + + if (!*line || line[strlen(line)-1] != '\n') + { + /* Eat until end of line. */ + while ( (c=getc (fp)) != EOF && c != '\n') + ; + err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG + : GPG_ERR_INCOMPLETE_LINE); + log_error (_("file `%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + continue; + } + line[strlen(line)-1] = 0; /* Chop the LF. */ + + /* Allow for empty lines and spaces */ + for (p=line; spacep (p); p++) + ; + if (!*p || *p == '#') + continue; + + if (!strncmp (p, "include-default", 15) + && (!p[15] || spacep (p+15))) + { + char *etcname; + gpg_error_t err2; + + if (!allow_include) + { + log_error (_("statement \"%s\" ignored in `%s', line %d\n"), + "include-default", fname, lnr); + continue; + } + /* fixme: Should check for trailing garbage. */ + + etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); + if ( !strcmp (etcname, fname) ) /* Same file. */ + log_info (_("statement \"%s\" ignored in `%s', line %d\n"), + "include-default", fname, lnr); + else if ( access (etcname, F_OK) && errno == ENOENT ) + { + /* A non existent system trustlist is not an error. + Just print a note. */ + log_info (_("system trustlist `%s' not available\n"), etcname); + } + else + { + err2 = read_one_trustfile (etcname, 0, + &table, &tablesize, &tableidx); + if (err2) + err = err2; + } + xfree (etcname); + + continue; + } + + if (tableidx == tablesize) /* Need more space. */ + { + trustitem_t *tmp; + size_t tmplen; + + tmplen = tablesize + 20; + tmp = xtryrealloc (table, tmplen * sizeof *table); + if (!tmp) + { + err = gpg_error_from_syserror (); + goto leave; + } + table = tmp; + tablesize = tmplen; + } + + ti = table + tableidx; + + memset (&ti->flags, 0, sizeof ti->flags); + if (*p == '!') + { + ti->flags.disabled = 1; + p++; + while (spacep (p)) + p++; + } + + n = hexcolon2bin (p, ti->fpr, 20); + if (n < 0) + { + log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr); + err = gpg_error (GPG_ERR_BAD_DATA); + continue; + } + p += n; + for (; spacep (p); p++) + ; + + /* Process the first flag which needs to be the first for + backward compatibility. */ + if (!*p || *p == '*' ) + { + ti->flags.for_smime = 1; + ti->flags.for_pgp = 1; + } + else if ( *p == 'P' || *p == 'p') + { + ti->flags.for_pgp = 1; + } + else if ( *p == 'S' || *p == 's') + { + ti->flags.for_smime = 1; + } + else + { + log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr); + err = gpg_error (GPG_ERR_BAD_DATA); + continue; + } + p++; + if ( *p && !spacep (p) ) + { + log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr); + err = gpg_error (GPG_ERR_BAD_DATA); + continue; + } + + /* Now check for more key-value pairs of the form NAME[=VALUE]. */ + while (*p) + { + for (; spacep (p); p++) + ; + if (!*p) + break; + n = strcspn (p, "= \t"); + if (p[n] == '=') + { + log_error ("assigning a value to a flag is not yet supported; " + "in `%s', line %d\n", fname, lnr); + err = gpg_error (GPG_ERR_BAD_DATA); + p++; + } + else if (n == 5 && !memcmp (p, "relax", 5)) + ti->flags.relax = 1; + else if (n == 2 && !memcmp (p, "cm", 2)) + ti->flags.cm = 1; + else + log_error ("flag `%.*s' in `%s', line %d ignored\n", + n, p, fname, lnr); + p += n; + } + tableidx++; + } + if ( !err && !feof (fp) ) + { + err = gpg_error_from_syserror (); + log_error (_("error reading `%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + } + + leave: + if (fp) + fclose (fp); + *addr_of_table = table; + *addr_of_tablesize = tablesize; + *addr_of_tableidx = tableidx; + return err; +} + + +/* Read the trust files and update the global table on success. */ +static gpg_error_t +read_trustfiles (void) +{ + gpg_error_t err; + trustitem_t *table, *ti; + int tableidx; + size_t tablesize; + char *fname; + int allow_include = 1; + + tablesize = 20; + table = xtrycalloc (tablesize, sizeof *table); + if (!table) + return gpg_error_from_syserror (); + tableidx = 0; + + fname = make_filename (opt.homedir, "trustlist.txt", NULL); + if ( access (fname, F_OK) ) + { + if ( errno == ENOENT ) + ; /* Silently ignore a non-existing trustfile. */ + else + { + err = gpg_error_from_syserror (); + log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err)); + } + xfree (fname); + fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); + allow_include = 0; + } + err = read_one_trustfile (fname, allow_include, + &table, &tablesize, &tableidx); + xfree (fname); + + if (err) + { + xfree (table); + if (gpg_err_code (err) == GPG_ERR_ENOENT) + { + /* Take a missing trustlist as an empty one. */ + lock_trusttable (); + xfree (trusttable); + trusttable = NULL; + trusttablesize = 0; + unlock_trusttable (); + err = 0; + } + return err; + } + + /* Fixme: we should drop duplicates and sort the table. */ + ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table); + if (!ti) + { + err = gpg_error_from_syserror (); + xfree (table); + return err; + } + + lock_trusttable (); + xfree (trusttable); + trusttable = ti; + trusttablesize = tableidx; + unlock_trusttable (); + return 0; +} + + + +/* Check whether the given fpr is in our trustdb. We expect FPR to be + an all uppercase hexstring of 40 characters. */ +gpg_error_t +agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled) +{ + gpg_error_t err; + trustitem_t *ti; + size_t len; + unsigned char fprbin[20]; + + if (r_disabled) + *r_disabled = 0; + + if ( hexcolon2bin (fpr, fprbin, 20) < 0 ) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!trusttable) + { + err = read_trustfiles (); + if (err) + { + log_error (_("error reading list of trusted root certificates\n")); + return err; + } + } + + if (trusttable) + { + for (ti=trusttable, len = trusttablesize; len; ti++, len--) + if (!memcmp (ti->fpr, fprbin, 20)) + { + if (ti->flags.disabled && r_disabled) + *r_disabled = 1; + + if (ti->flags.relax) + { + err = agent_write_status (ctrl, + "TRUSTLISTFLAG", "relax", + NULL); + if (err) + return err; + } + else if (ti->flags.cm) + { + err = agent_write_status (ctrl, + "TRUSTLISTFLAG", "cm", + NULL); + if (err) + return err; + } + return ti->flags.disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0; + } + } + return gpg_error (GPG_ERR_NOT_TRUSTED); +} + + +/* Write all trust entries to FP. */ +gpg_error_t +agent_listtrusted (void *assuan_context) +{ + trustitem_t *ti; + char key[51]; + gpg_error_t err; + size_t len; + + if (!trusttable) + { + err = read_trustfiles (); + if (err) + { + log_error (_("error reading list of trusted root certificates\n")); + return err; + } + } + + if (trusttable) + { + /* We need to lock the table because the scheduler may interrupt + assuan_send_data and an other thread may then re-read the table. */ + lock_trusttable (); + for (ti=trusttable, len = trusttablesize; len; ti++, len--) + { + if (ti->flags.disabled) + continue; + bin2hex (ti->fpr, 20, key); + key[40] = ' '; + key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*' + : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' '); + key[42] = '\n'; + assuan_send_data (assuan_context, key, 43); + assuan_send_data (assuan_context, NULL, 0); /* flush */ + } + unlock_trusttable (); + } + + return 0; +} + + +/* Create a copy of string with colons inserted after each two bytes. + Caller needs to release the string. In case of a memory failure, + NULL is returned. */ +static char * +insert_colons (const char *string) +{ + char *buffer, *p; + size_t n = strlen (string); + size_t nnew = n + (n+1)/2; + + p = buffer = xtrymalloc ( nnew + 1 ); + if (!buffer) + return NULL; + while (*string) + { + *p++ = *string++; + if (*string) + { + *p++ = *string++; + if (*string) + *p++ = ':'; + } + } + *p = 0; + assert (strlen (buffer) <= nnew); + + return buffer; +} + + +/* To pretty print DNs in the Pinentry, we replace slashes by + REPLSTRING. The caller needs to free the returned string. NULL is + returned on error with ERRNO set. */ +static char * +reformat_name (const char *name, const char *replstring) +{ + const char *s; + char *newname; + char *d; + size_t count; + size_t replstringlen = strlen (replstring); + + /* If the name does not start with a slash it is not a preformatted + DN and thus we don't bother to reformat it. */ + if (*name != '/') + return xtrystrdup (name); + + /* Count the names. Note that a slash contained in a DN part is + expected to be C style escaped and thus the slashes we see here + are the actual part delimiters. */ + for (s=name+1, count=0; *s; s++) + if (*s == '/') + count++; + newname = xtrymalloc (strlen (name) + count*replstringlen + 1); + if (!newname) + return NULL; + for (s=name+1, d=newname; *s; s++) + if (*s == '/') + d = stpcpy (d, replstring); + else + *d++ = *s; + *d = 0; + return newname; +} + + +/* Insert the given fpr into our trustdb. We expect FPR to be an all + uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'. + This function does first check whether that key has already been put + into the trustdb and returns success in this case. Before a FPR + actually gets inserted, the user is asked by means of the Pinentry + whether this is actual want he wants to do. */ +gpg_error_t +agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) +{ + gpg_error_t err = 0; + char *desc; + char *fname; + estream_t fp; + char *fprformatted; + char *nameformatted; + int is_disabled; + int yes_i_trust; + + /* Check whether we are at all allowed to modify the trustlist. + This is useful so that the trustlist may be a symlink to a global + trustlist with only admin priviliges to modify it. Of course + this is not a secure way of denying access, but it avoids the + usual clicking on an Okay button most users are used to. */ + fname = make_filename (opt.homedir, "trustlist.txt", NULL); + if ( access (fname, W_OK) && errno != ENOENT) + { + xfree (fname); + return gpg_error (GPG_ERR_EPERM); + } + xfree (fname); + + if (!agent_istrusted (ctrl, fpr, &is_disabled)) + { + return 0; /* We already got this fingerprint. Silently return + success. */ + } + + /* This feature must explicitly been enabled. */ + if (!opt.allow_mark_trusted) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + if (is_disabled) + { + /* There is an disabled entry in the trustlist. Return an error + so that the user won't be asked again for that one. Changing + this flag with the integrated marktrusted feature is and will + not be made possible. */ + return gpg_error (GPG_ERR_NOT_TRUSTED); + } + + + /* Insert a new one. */ + nameformatted = reformat_name (name, "%0A "); + if (!nameformatted) + return gpg_error_from_syserror (); + + /* First a general question whether this is trusted. */ + desc = xtryasprintf ( + /* TRANSLATORS: This prompt is shown by the Pinentry + and has one special property: A "%%0A" is used by + Pinentry to insert a line break. The double + percent sign is actually needed because it is also + a printf format string. If you need to insert a + plain % sign, you need to encode it as "%%25". The + "%s" gets replaced by the name as stored in the + certificate. */ + _("Do you ultimately trust%%0A" + " \"%s\"%%0A" + "to correctly certify user certificates?"), + nameformatted); + if (!desc) + { + xfree (nameformatted); + return out_of_core (); + } + err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"), 1); + xfree (desc); + if (!err) + yes_i_trust = 1; + else if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED) + yes_i_trust = 0; + else + { + xfree (nameformatted); + return err; + } + + + fprformatted = insert_colons (fpr); + if (!fprformatted) + { + xfree (nameformatted); + return out_of_core (); + } + + /* If the user trusts this certificate he has to verify the + fingerprint of course. */ + if (yes_i_trust) + { + desc = xtryasprintf + ( + /* TRANSLATORS: This prompt is shown by the Pinentry and has + one special property: A "%%0A" is used by Pinentry to + insert a line break. The double percent sign is actually + needed because it is also a printf format string. If you + need to insert a plain % sign, you need to encode it as + "%%25". The second "%s" gets replaced by a hexdecimal + fingerprint string whereas the first one receives the name + as stored in the certificate. */ + _("Please verify that the certificate identified as:%%0A" + " \"%s\"%%0A" + "has the fingerprint:%%0A" + " %s"), nameformatted, fprformatted); + if (!desc) + { + xfree (fprformatted); + xfree (nameformatted); + return out_of_core (); + } + + /* TRANSLATORS: "Correct" is the label of a button and intended + to be hit if the fingerprint matches the one of the CA. The + other button is "the default "Cancel" of the Pinentry. */ + err = agent_get_confirmation (ctrl, desc, _("Correct"), _("Wrong"), 1); + xfree (desc); + if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED) + yes_i_trust = 0; + else if (err) + { + xfree (fprformatted); + xfree (nameformatted); + return err; + } + } + + + /* Now check again to avoid duplicates. We take the lock to make + sure that nobody else plays with our file and force a reread. */ + lock_trusttable (); + agent_reload_trustlist (); + if (!agent_istrusted (ctrl, fpr, &is_disabled) || is_disabled) + { + unlock_trusttable (); + xfree (fprformatted); + xfree (nameformatted); + return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0; + } + + fname = make_filename (opt.homedir, "trustlist.txt", NULL); + if ( access (fname, F_OK) && errno == ENOENT) + { + fp = es_fopen (fname, "wx"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't create `%s': %s\n", fname, gpg_strerror (err)); + xfree (fname); + unlock_trusttable (); + xfree (fprformatted); + xfree (nameformatted); + return err; + } + es_fputs (headerblurb, fp); + es_fclose (fp); + } + fp = es_fopen (fname, "a+"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open `%s': %s\n", fname, gpg_strerror (err)); + xfree (fname); + unlock_trusttable (); + xfree (fprformatted); + xfree (nameformatted); + return err; + } + + /* Append the key. */ + es_fputs ("\n# ", fp); + xfree (nameformatted); + nameformatted = reformat_name (name, "\n# "); + if (!nameformatted || strchr (name, '\n')) + { + /* Note that there should never be a LF in NAME but we better + play safe and print a sanitized version in this case. */ + es_write_sanitized (fp, name, strlen (name), NULL, NULL); + } + else + es_fputs (nameformatted, fp); + es_fprintf (fp, "\n%s%s %c\n", yes_i_trust?"":"!", fprformatted, flag); + if (es_ferror (fp)) + err = gpg_error_from_syserror (); + + if (es_fclose (fp)) + err = gpg_error_from_syserror (); + + agent_reload_trustlist (); + xfree (fname); + unlock_trusttable (); + xfree (fprformatted); + xfree (nameformatted); + return err; +} + + +/* This function may be called to force reloading of the + trustlist. */ +void +agent_reload_trustlist (void) +{ + /* All we need to do is to delete the trusttable. At the next + access it will get re-read. */ + lock_trusttable (); + xfree (trusttable); + trusttable = NULL; + trusttablesize = 0; + unlock_trusttable (); + bump_key_eventcounter (); +} diff --git a/am/cmacros.am b/am/cmacros.am new file mode 100644 index 0000000..be34ca3 --- /dev/null +++ b/am/cmacros.am @@ -0,0 +1,55 @@ +# 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 3 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, see . + +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@\"" \ + -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" +endif + + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. +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 + + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..289c21e --- /dev/null +++ b/autogen.sh @@ -0,0 +1,243 @@ +#! /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 +FORCE= +if test x"$1" = x"--force"; then + FORCE=" --force" + shift +fi + +# ***** W32 build script ******* +# Used to cross-compile for Windows. +if test "$1" = "--build-w32"; then + tmp=`dirname $0` + tsdir=`cd "$tmp"; pwd` + shift + if [ ! -f $tsdir/scripts/config.guess ]; then + echo "$tsdir/scripts/config.guess not found" >&2 + exit 1 + fi + build=`$tsdir/scripts/config.guess` + + [ -z "$w32root" ] && w32root="$HOME/w32root" + echo "Using $w32root as standard install directory" >&2 + + # Locate the cross compiler + crossbindir= + for host in i586-mingw32msvc i386-mingw32msvc mingw32; do + if ${host}-gcc --version >/dev/null 2>&1 ; then + crossbindir=/usr/${host}/bin + conf_CC="CC=${host}-gcc" + break; + fi + done + if [ -z "$crossbindir" ]; then + echo "Cross compiler kit not installed" >&2 + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + echo "Stop." >&2 + exit 1 + fi + + if [ -f "$tsdir/config.log" ]; then + if ! head $tsdir/config.log | grep "$host" >/dev/null; then + echo "Please run a 'make distclean' first" >&2 + exit 1 + fi + fi + + ./configure --enable-maintainer-mode --prefix=${w32root} \ + --host=${host} --build=${build} \ + --enable-gpgtar \ + --with-gpg-error-prefix=${w32root} \ + --with-ksba-prefix=${w32root} \ + --with-libgcrypt-prefix=${w32root} \ + --with-libassuan-prefix=${w32root} \ + --with-zlib=${w32root} \ + --with-regex=${w32root} \ + --with-pth-prefix=${w32root} \ + --with-adns=${w32root} "$@" + rc=$? + exit $rc +fi +# ***** end W32 build script ******* + +# ***** AMD64 cross build script ******* +# Used to cross-compile for AMD64 (for testing) +if test "$1" = "--build-amd64"; then + tmp=`dirname $0` + tsdir=`cd "$tmp"; pwd` + shift + if [ ! -f $tsdir/scripts/config.guess ]; then + echo "$tsdir/scripts/config.guess not found" >&2 + exit 1 + fi + build=`$tsdir/scripts/config.guess` + + [ -z "$amd64root" ] && amd64root="$HOME/amd64root" + echo "Using $amd64root as standard install directory" >&2 + + # Locate the cross compiler + crossbindir= + for host in x86_64-linux-gnu amd64-linux-gnu; do + if ${host}-gcc --version >/dev/null 2>&1 ; then + crossbindir=/usr/${host}/bin + conf_CC="CC=${host}-gcc" + break; + fi + done + if [ -z "$crossbindir" ]; then + echo "Cross compiler kit not installed" >&2 + echo "Stop." >&2 + exit 1 + fi + + if [ -f "$tsdir/config.log" ]; then + if ! head $tsdir/config.log | grep "$host" >/dev/null; then + echo "Please run a 'make distclean' first" >&2 + exit 1 + fi + fi + + $tsdir/configure --enable-maintainer-mode --prefix=${amd64root} \ + --host=${host} --build=${build} \ + --with-gpg-error-prefix=${amd64root} \ + --with-ksba-prefix=${amd64root} \ + --with-libgcrypt-prefix=${amd64root} \ + --with-libassuan-prefix=${amd64root} \ + --with-zlib=/usr/x86_64-linux-gnu/usr \ + --with-pth-prefix=/usr/x86_64-linux-gnu/usr + rc=$? + exit $rc +fi +# ***** end AMD64 cross build script ******* + + +# 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 <&2 +*** Activating trailing whitespace git pre-commit hook. *** + For more information see this thread: + http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084html + To deactivate this pre-commit hook again move .git/hooks/pre-commit + and .git/hooks/pre-commit.sample out of the way. +EOF + cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit + chmod -c +x .git/hooks/pre-commit + fi + tmp=$(git config --get filter.cleanpo.clean) + if [ "$tmp" != "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ] + then + echo "*** Adding GIT filter.cleanpo.clean configuration." >&2 + git config --add filter.cleanpo.clean \ + "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" + fi + if [ -f scripts/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then + cat <&2 +*** Activating commit log message check hook. *** +EOF + cp -av scripts/git-hooks/commit-msg .git/hooks/commit-msg + chmod -c +x .git/hooks/commit-msg + fi +fi + + +echo "Running aclocal -I m4 -I gl/m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..." +$ACLOCAL -I m4 -I gl/m4 $ACLOCAL_FLAGS +echo "Running autoheader..." +$AUTOHEADER +echo "Running automake --gnu ..." +$AUTOMAKE --gnu; +echo "Running autoconf${FORCE} ..." +$AUTOCONF${FORCE} + +echo "You may now run: + ./configure --sysconfdir=/etc --enable-maintainer-mode --enable-symcryptrun --enable-mailto --enable-gpgtar && make +" diff --git a/common/ChangeLog-2011 b/common/ChangeLog-2011 new file mode 100644 index 0000000..0d0d1cc --- /dev/null +++ b/common/ChangeLog-2011 @@ -0,0 +1,1638 @@ +2011-12-02 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2011-08-04 Werner Koch + + * ssh-utils.c, ssh-utils.h: New. + * t-ssh-utils.c: New. + * Makefile.am (t_ssh_utils_LDADD): New. + (module_tests): Add t-ssh-utils.c + +2011-08-04 Werner Koch + + * pka.c (get_pka_info): Remove set but unused variables ARCOUNT + and NSCOUNT. + * estream.c (es_fwrite, es_fread): Remove set but unused variable + ERR. + +2011-04-29 Werner Koch + + * estream.c (es_pth_kill): New. + (estream_pth_killed): New. + (ESTREAM_MUTEX_LOCK, ESTREAM_MUTEX_UNLOCK) + (ESTREAM_MUTEX_TRYLOCK, ESTREAM_MUTEX_INITIALIZE): Take care of + the killed status. + (ESTREAM_SYS_YIELD): Ditto. + (es_pth_read, es_pth_write): Ditto. + (es_init_do): Ditto. + +2011-01-20 Werner Koch + + * estream.c (es_func_mem_write): Fix computation of NEWSIZE. + +2011-01-11 Werner Koch + + Estream changes as used by gnupg master from 2010-07-19. + + * estream.c (es_fname_get, es_fname_set): New. + (fname_set_internal): New. + (struct estream_internal): Add fields printable_fname and + printable_fname_inuse. + (_es_get_std_stream): Set stream name. + (es_fopen, es_freopen, es_deinitialize): Set fname. + +2011-01-10 Thomas Mraz (wk) + + * pka.c (get_pka_info) [!USE_ADNS]: Turn ANSWER into a union to + avoid aliasing problems with modern compilers. See bug#1307. + Reported by Steve Grubb. + +2011-01-10 Werner Koch + + * session-env.c (update_var): Fix same value test. Fixes + bug#1311. + +2010-09-16 Werner Koch + + * util.h: Add GPG_ERR_MISSING_ISSUER_CERT. + * status.c (get_inv_recpsgnr_code): Ditto. + +2010-05-03 Werner Koch + + * asshelp.c (lock_agent_spawning, unlock_agent_spawning): New. + (start_new_gpg_agent): Test for configured standard socket and + try to fire up the agent in this case. + + * exechelp.c (gnupg_spawn_process_detached): Do not reuse PID for + the second fork. + (gnupg_wait_process): Do not log a message if EXITCODE is given. + +2010-03-17 Werner Koch + + * asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to + avoid starting two agents. + +2010-03-12 Werner Koch + + * status.h (STATUS_ENTER): New. + +2010-02-11 Marcus Brinkmann + + From trunk 2009-10-16, 2009-11-02, 2009-11-05: + + * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead + of LIBASSUAN_PTH_CFLAGS. + * get-passphrase.c (default_inq_cb, membuf_data_cb): Change return + type to gpg_error_t. + * asshelp.c (start_new_gpg_agent): Update use of + assuan_socket_connect and assuan_pipe_connect. Convert posix FD + to assuan FD. + [HAVE_W32_SYSTEM]: Add missing argument in assuan_socket_connect + invocation. + * iobuf.c (iobuf_open_fd_or_name): Fix type of FD in function + declaration. + +2009-10-13 Werner Koch + + From trunk 2009-09-23: + + * asshelp.c (start_new_gpg_agent): Allocate assuan context before + starting server. + +2009-12-21 Marcus Brinkmann (wk) + + * Makefile.am (audit-events.h, status.h) [!MAINTAINER_MODE]: No + longer include these rules if not in maintainer mode. + +2009-12-08 Werner Koch + + * dns-cert.c: Add support for ADNS. + +2009-12-07 Werner Koch + + * pka.c (get_pka_info): Add support for ADNS. + * src.v (getsrv): Add support for ADNS. + + * srv.c (getsrv): s/xrealloc/xtryrealloc/. + +2009-12-04 Werner Koch + + * Makefile.am (audit-events.h, status-codes.h): Create files in + the source dir. Fixes bug#1164. + +2009-12-03 Werner Koch + + From trunk: + * audit.c (proc_type_decrypt, proc_type_sign): Implemented. + (proc_type_verify): Print hash algo infos. + * audit.h (AUDIT_DATA_CIPHER_ALGO, AUDIT_BAD_DATA_CIPHER_ALSO) + (AUDIT_NEW_RECP, AUDIT_DECRYPTION_RESULT, AUDIT_RECP_RESULT) + (AUDIT_ATTR_HASH_ALGO, AUDIT_SIGNED_BY, AUDIT_SIGNING_DONE): + +2009-09-03 Werner Koch + + Update from libestream: + * estream-printf.c: Include stdint.h only if HAVE_STDINT_H is + defined. + * estream-printf.c: Remove all test code. Use macro DEBUG instead + of TEST for debugging. + * estream-printf.c (pr_float): Make buffer larger for silly high + numbers. + +2009-08-11 David Shaw + + * ttyio.h, ttyio.c (tty_enable_completion): Some ifdefs around + HAVE_LIBREADLINE to allow building when readline isn't available. + +2009-08-06 Werner Koch + + * status.h (STATUS_INV_SGNR, STATUS_NO_SGNR): New. + * status.c (get_inv_recpsgnr_code): New. + +2009-07-23 David Shaw + + * srv.c (getsrv): Fix type-punning warning. + +2009-07-23 Werner Koch + + * util.h (GPG_ERR_NOT_ENABLED): New. + * audit.h (enum): Add AUDIT_CRL_CHECK. + * audit.c (proc_type_verify): Show CRL check result. + +2009-07-06 Werner Koch + + * get-passphrase.c (struct agentargs): Add SESSION_ENV and remove + obsolete args. + (gnupg_prepare_get_passphrase): Ditto. + + * session-env.c, session-env.h: New. + * t-session-env.c: New. + * Makefile.am (common_sources, module_tests): Add them. + * asshelp.h: Include "session-env.h" + * asshelp.c (send_one_option): Add arg PUTENV. + (send_pinentry_environment): Replace most args by SESSION_ENV and + rewrite fucntion. + (start_new_gpg_agent): Likewise. + + * t-exechelp.c (test_close_all_fds): Remove debug code. + +2009-07-01 Werner Koch + + * sexputil.c (get_pk_algo_from_canon_sexp): New. + +2009-06-29 Werner Koch + + * estream.c (BUFFER_ROUND_TO_BLOCK): Remove unused macro. + (es_func_mem_write): Rewrite reallocation part. + + * estream.c (es_write_sanitized_utf8_buffer): Typo typo fix. + +2009-06-25 Werner Koch + + * estream.c (es_write_sanitized_utf8_buffer): Typo fix. + +2009-06-24 Werner Koch + + * estream.c (es_read_line): In the malloc error case, set + MAX_LENGTH to 0 only if requested. + * xreadline.c (read_line): Ditto. + * estream.c (es_write_sanitized_utf8_buffer): Pass on error from + es_fputs. + * sexputil.c (get_rsa_pk_from_canon_sexp): Check for error after + the loop. Reported by Fabian Keil. + +2009-06-22 Werner Koch + + * estream.c (es_pth_read, es_pth_write) [W32]: New. + (ESTREAM_SYS_READ, ESTREAM_SYS_WRITE) [HAVE_PTH]: Use them. + +2009-06-03 Werner Koch + + * estream.c (es_convert_mode): Rewrite and support the "x" flag. + +2009-05-28 David Shaw + + From 1.4: + + * http.h, http.c (send_request) Pass in a STRLIST for additional + headers. Change all callers. + +2009-05-27 David Shaw + + From 1.4: + + * http.h, http.c (send_request): Pass in srvtag and make its + presence sufficient to turn the feature on. + (http_open): From here. + (http_document): And here. + + * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ + is too small these days. + +2009-05-22 Werner Koch + + * ttyio.c (tty_cleanup_after_signal): New. + +2009-05-19 Werner Koch + + * simple-pwquery.c (agent_open): Use SUN_LEN + (JNLIB_NEED_AFLOCAL): Define and include mischelp.h. + +2009-05-07 Werner Koch + + * sexputil.c (get_rsa_pk_from_canon_sexp): New. + * t-sexputil.c (test_make_canon_sexp_from_rsa_pk): Extend the test. + +2009-04-28 Werner Koch + + * sexputil.c (make_canon_sexp_from_rsa_pk): New. + * t-sexputil.c (test_make_canon_sexp_from_rsa_pk): New. + +2009-04-01 Werner Koch + + * iobuf.c: Port David's changes from 1.4: + (fd_cache_invalidate): Pass return code from close back. + (direct_open, iobuf_ioctl): Check that eturn value. + (fd_cache_synchronize): New. + (iobuf_ioctl): Add new sub command 4 (fsync). + + * iobuf.c (fd_cache_strcmp): New. Taken from 1.4. + (fd_cache_invalidate, fd_cache_close, fd_cache_open): Use it. + + * exechelp.c (gnupg_spawn_process): Implement new flag bit 6. + * sysutils.c (gnupg_allow_set_foregound_window): Allow the use of + ASFW_ANY. + + * membuf.c (put_membuf, get_membuf): Wipe memory on out of core. + +2009-03-31 Werner Koch + + * percent.c (percent_unescape, percent_plus_unescape): New. + (percent_plus_unescape_inplace, percent_unescape_inplace): New. + (do_plus_or_plain_unescape, count_unescape, do_unescape): New. + (do_unescape_inplace): New. + * t-percent.c (test_percent_plus_escape): Test percent_plus_unescape. + + * get-passphrase.c, get-passphrase.h: New. + * Makefile.am (without_pth_sources): New. + +2009-03-18 Werner Koch + + * exechelp.c: Include sys/resource.h and sys/stat.h. + (get_max_open_fds): New. + (do_exec): Use it. + (get_all_open_fds): New. + (close_all_fds): New. + (do_exec): Use close_all_fds. + * t-exechelp.c: New. + +2009-03-13 David Shaw + + * http.c (do_parse_uri): Properly handle IPv6 literal addresses as + per RFC-2732. Adapted from patch by Phil Pennock. + +2009-03-12 Werner Koch + + * gettime.c: Include i18n.h. + (dump_isotime): New. + +2009-03-06 Werner Koch + + * sexputil.c (make_canon_sexp): New. + +2009-03-03 Werner Koch + + * exechelp.c (do_exec): Make sure that /dev/null connected FDs are + not closed. + +2009-01-19 Werner Koch + + * audit.c (writeout_li): Translate a few more result strings. + Fixes bug#970. + + * convert.c (hex2str): Fix optimization to append a nul character. + +2008-12-05 Werner Koch + + * percent.c, t-percent.c: New. + + * exechelp.c (gnupg_spawn_process, gnupg_spawn_process_fd) + (gnupg_spawn_process_detached) [W32]: Remove debug output. + +2008-11-20 Werner Koch + + * audit.c (writeout_li): Translate OKTEXT. + +2008-11-04 Werner Koch + + * i18n.c (i18n_init) [USE_SIMPLE_GETTEXT]: Adjust for changed + w32-gettext.c. + * homedir.c (gnupg_localedir): New. + +2008-10-20 Werner Koch + + * http.c (http_register_tls_callback) [!HTTP_USE_GNUTLS]: Mark + unused arg. + * localename.c (do_nl_locale_name): Ditto. + * audit.c (event2str): Silent gcc warning. + * sysutils.c (translate_sys2libc_fd): Mark unused arg. + (translate_sys2libc_fd_int): Ditto. + * iobuf.c (translate_file_handle): Ditto. + * asshelp.c (send_one_option): Ditto. + * exechelp.c (gnupg_spawn_process): Ditto. + * signal.c (got_usr_signal): Ditto + * estream.c (es_func_fd_create) [!W32]: Ditto. + (es_func_fp_create) [!W32]: Ditto. + (es_write_hexstring): Ditto. + (dummy_mutex_call_void, dummy_mutex_call_int) [HAVE_PTH]: New. + (ESTREAM_MUTEX_LOCK, ESTREAM_MUTEX_UNLOCK, ESTREAM_MUTEX_TRYLOCK) + (ESTREAM_MUTEX_INITIALIZE) [HAVE_PTH]: Use dummy calls so to mark + unused arg. + +2008-10-19 Werner Koch + + * estream-printf.c (estream_vsnprintf): Fix return value. + (check_snprintf): Add a new test. + (one_test) [W32]: Disable test. + +2008-10-17 Werner Koch + + * util.h (snprintf) [W32]: Redefine to estream_snprintf. + +2008-09-03 Werner Koch + + * convert.c (hex2str): New. + (hex2str_alloc): New. + * t-convert.c (test_hex2str): New. + +2008-08-19 Werner Koch + + * iobuf.c: Avoid passing a NULL (iobuf_t)->desc to the log + function. Should in general never be NULL, but well. Reported by + M. Heneka. + +2008-06-26 Werner Koch + + * estream.c (es_write_sanitized): Loose check for control + characters to better cope with utf-8. The range 0x80..0x9f is + nowadays not anymore accidently used for control charaters. + +2008-06-25 Marcus Brinkmann + + Revert last three changes related to handle translation. + * sysutils.c: + (FD_TRANSLATE_MAX, fd_translate, fd_translate_len) + (translate_table_init, translate_table_lookup): Removed. + * iobuf.c (check_special_filename): Do not use + translate_table_lookup. + * sysutils.h (translate_table_init, translate_table_lookup): + Remove prototypes. + +2008-06-19 Werner Koch + + * sysutils.c: Remove . + (fd_translate_max): Use macro for the size. + (translate_table_init): Protect read against EINTR and replace + isspace by spacep. + +2008-06-18 Marcus Brinkmann + + * sysutils.c (TRANS_MAX): Bump up to 350 to be on the safe side. + + * sysutils.h (translate_table_init, translate_table_lookup): New + prototypes. + * sysutils.c: Include . + (FD_TRANSLATE_MAX): New macro. + (fd_translate, fd_translate_len): New static variables. + (translate_table_init, translate_table_lookup): New functions. + (translate_sys2libc_fd_int): Translate file descriptor. + * iobuf.c (check_special_filename): Translate handle values from + special filenames. + +2008-06-16 Werner Koch + + * homedir.c (w32_commondir): New. + (gnupg_sysconfdir): Use it. + +2008-06-09 Werner Koch + + * b64dec.c: New. + +2008-06-05 Werner Koch + + * util.h (gnupg_copy_time): Replace strcpy by memcpy. + +2008-05-26 Werner Koch + + * asshelp.c (send_one_option, send_pinentry_environment): use + xfree and xtrystrdup. + + * i18n.c (i18n_switchto_utf8) [USE_SIMPLE_GETTEXT]: Return NULL. + + * homedir.c (gnupg_module_name): Add + GNUPG_MODULE_NAME_CONNECT_AGENT and GNUPG_MODULE_NAME_GPGCONF. + +2008-04-21 Werner Koch + + * http.c (http_wait_response) [W32]: Use DuplicateHandle because + it is a socket. + (cookie_read) [W32]: Use recv in place of read. + +2008-04-08 Werner Koch + + * i18n.c (i18n_switchto_utf8, i18n_switchback) + [USE_SIMPLE_GETTEXT]: Implement. + +2008-04-07 Werner Koch + + * b64enc.c (b64enc_start): Detect PGP mode. + (b64enc_finish): Write PGP CRC. + * util.h (struct b64state): Add field CRC. + * t-b64.c: New. + + * pka.c (get_pka_info): Use xtrymalloc and check result. + +2008-03-25 Werner Koch + + * localename.c: Strip all W32 code. Include w32help.h. + (gnupg_messages_locale_name) [W32]: Use the gettext_localename. + +2008-03-17 Werner Koch + + * iobuf.c (IOBUF_BUFFER_SIZE): Actually use this macro. + + * simple-pwquery.c (agent_send_all_options): Fix last change. + +2008-03-06 Werner Koch + + * simple-pwquery.c (agent_send_all_options): Add support for + XAUTHORITY and PINENTRY_USER_DATA. + +2008-02-15 Marcus Brinkmann + + * exechelp.c (gnupg_spawn_process_fd): Add flag DETACHED_PROCESS + unconditionally (required for all callers at the moment). + +2008-02-14 Werner Koch + + * sysutils.c (gnupg_allow_set_foregound_window): New. + (WINVER) [W32]: Define. + +2008-01-31 Werner Koch + + * audit.c (audit_print_result): Make sure that the output is + always UTF8. + +2008-01-27 Werner Koch + + * exechelp.c (gnupg_spawn_process): Add arg FLAGS and changed all + callers to pass 0 for it. + +2007-12-13 Werner Koch + + * sexputil.c (hash_algo_from_sigval): New. + * t-sexputil.c: New. + * Makefile.am (module_tests): Add it. + +2007-12-11 Werner Koch + + * asshelp.c (send_pinentry_environment): Allow using of old + gpg-agents not capabale of the xauthority and pinentry_user_data + options. + +2007-12-04 Werner Koch + + * Makefile.am (t_helpfile_LDADD, module_maint_tests): New. + * t-helpfile.c: New. + * helpfile.c: New. + * membuf.h (is_membuf_ready, MEMBUF_ZERO): New. + * localename.c: New. Taken from gettext with modifications as done + for GpgOL. Export one new function. + * util.h (gnupg_messages_locale_name, gnupg_get_help_string): Added. + + * sysutils.c (gnupg_reopen_std): New. Taken from ../g10/gpg.c. + +2007-11-27 Werner Koch + + * Makefile.am (CLEANFILES): New. + + * homedir.c (dirmngr_socket_name): Use CSIDL_WINDOWS. + +2007-11-15 Werner Koch + + * asshelp.c (send_pinentry_environment): Add args XAUTHORITY and + PINENTRY_USER_DATA. + (start_new_gpg_agent): Ditto. + +2007-11-07 Werner Koch + + * status.h: New. + * errors.h: Remove. + +2007-11-05 Werner Koch + + * audit.c, audit.h: New. + * Makefile.am: Add rules to build audit-events.h. + * exaudit.awk: New. + * mkstrtable.awk: New. Taken from libgpg-error. + +2007-10-19 Werner Koch + + * i18n.c (i18n_switchto_utf8, i18n_switchback): New. + +2007-10-01 Werner Koch + + * sysutils.h (FD2INT, INT2FD): New. + +2007-09-21 Werner Koch + + * homedir.c (default_homedir): Make registry work. Reported by + Marc Mutz. + +2007-08-29 Werner Koch + + * exechelp.c (gnupg_wait_process): Add arg EXITCODE. Changed all + callers. + (gnupg_create_inbound_pipe): New. + * util.h (GNUPG_MODULE_NAME_GPGSM, GNUPG_MODULE_NAME_GPG): New. + * homedir.c (gnupg_module_name): Add them + +2007-08-28 Werner Koch + + * gettime.c (check_isotime, add_isotime): New. Originally written + for DirMngr by me. + (add_days_to_isotime): New. + (date2jd, jd2date, days_per_month, days_per_year): New. Taken from + my ancient (1988) code used in Wedit (time2.c). + +2007-08-27 Werner Koch + + * util.h (GNUPG_MODULE_NAME_CHECK_PATTERN): New. + * homedir.c (gnupg_module_name): Add it. + * exechelp.c (w32_fd_or_null) [W32]: New. + (gnupg_spawn_process_fd): New. + (gnupg_wait_process) [W32]: Close the handle after if the process has + returned. + +2007-08-22 Werner Koch + + Updated estream from libestream. + + * estream.c (mem_malloc, mem_realloc, mem_free): New. Use them + instead of the ES_MEM_foo. + * estream.c (estream_cookie_mem): Remove members DONT_FREE, + APPEND_ZERO, PTR and SIZE. Add MEMORY_LIMIT. Put GROW into a new + FLAGS struct. + (es_func_mem_create): Remove APPEND_ZERO, DONT_FREE, PTR and + SIZE. Add MEMORY_LIMIT. + (es_func_mem_write, es_func_mem_seek, es_func_mem_destroy): Revamp. + (es_open_memstream): Change API to just take a memory limit and a + mode argument. Rename to .. + (es_fopenmem): .. this. + (HAVE_W32_SYSTEM) [_WIN32]: Define if not defined. + (tmpfd) [W32]: Implement directly using the W32 API. + (es_fgets): Rewrite without using doreadline. + +2007-08-21 Werner Koch + + * sysutils.c (gnupg_tmpfile): New. + * t-sysutils.c: New. + * Makefile.am (module_tests): Add t-sysutils. + +2007-08-20 Werner Koch + + * exechelp.c [W32]: Redefine X_OK to F_OK. + +2007-08-16 Werner Koch + + * Makefile.am (t_convert_DEPENDENCIES): Remove + ($(PROGRAMS)): Remove. + (t_common_ldadd): Use libcommon.a and not the macro. + +2007-08-14 Werner Koch + + * homedir.c (dirmngr_socket_name): New. + +2007-08-07 Werner Koch + + * tlv.c, tlv.h: Move from ../scd/. + * tlv.c (parse_sexp, parse_ber_header): Add ERRSOURCE arg and prefix + name with a _. + * tlv.h: Use macro to convey ERRSOURCE. + +2007-08-02 Werner Koch + + * gc-opt-flags.h: New. + +2007-08-01 Werner Koch + + * estream-printf.c (read_dummy_value): Removed as it is useless now. + (read_values): Remove check on !vaargs which is not anymore needed + and anyway not portable. Reported by Peter O'Gorman. + +2007-07-16 Werner Koch + + * estream.c (es_func_file_create): Clear NO_CLOSE flag. + +2007-07-12 Werner Koch + + * sysutils.h (gnupg_fd_t): New. + * sysutils.c (translate_sys2libc_fd): Use that type instead of int. + (translate_sys2libc_fd_int): New. + +2007-07-09 Werner Koch + + * t-gettime.c (test_isotime2epoch): Use time_t and not u32. + +2007-07-05 Werner Koch + + * t-gettime.c: New. + * gettime.c (isotime2epoch, epoch2isotime): New. + +2007-07-04 Werner Koch + + * estream.c (es_init_do): Do not throw an error if pth has already + been initialized. + +2007-06-26 Werner Koch + + * Makefile.am ($(PROGRAMS)): New. + + * util.h (init_common_subsystems): Moved to .. + * init.h: .. New. + * util.h: Include init.h. + + * homedir.c (standard_homedir): New. + (default_homedir) [W32]: Reimplemented in terms of + standard_homedir. Fixed memory leak. + +2007-06-25 Werner Koch + + * iobuf.c: Add more documentation and slighly restructured macro + defintion for better readability. + (FILEP_OR_FD): Rename to fp_or_fd_t. + (CLOSE_CACHE): Rename to close_cache_t. + + * sysutils.c (translate_sys2libc_fd): New using the code from iobuf.c. + * iobuf.c: Include sysutils.h. + (iobuf_translate_file_handle): Remove. + (translate_file_handle): Use new function. + + * estream-printf.c [TEST]: Header including fixes. + (do_format): Do not append a trailing Nul. This avoids spurious + Nuls in the es_printf output. + (estream_vsnprintf, estream_vasprintf): Take this in account. + + * estream.h (struct es__stream): Change FLAGS to a bit structure. + (ES__FLAG_WRITING): Replace by a bit from FLAGS. * estream.c + (struct estream_internal): Rename FLAGS to MODEFLAGS so that they + are not confused with the estream flags. + (es_initialize, es_create): Add arg MODEFLAGS so that we can setup + the intial writemode. Changed all callers to pass them. + (es_convert_mode): Set O_BINARY. + (es_func_fd_create, es_func_fp_create, es_func_file_create) [W32]: + Call setmode if requested. + +2007-06-24 Werner Koch + + * estream.c (do_fpopen, es_fpopen, es_fpopen_nc): New. + (es_func_fp_create, es_func_fp_read, es_func_fp_write) + (es_func_fp_seek, es_func_fp_destroy): New. + +2007-06-22 Werner Koch + + * estream.c (es_fdopen): Factored code out to.. + (do_fdopen): .. new. + (es_fdopen_nc): New. + (estream_cookie_fd): Add field NO_CLOSE. + (es_func_fd_create): Add arg NO_CLOSE and changed all callers. + (es_func_fd_destroy): Handle the new flag. + + * homedir.c (gnupg_libexecdir) [W32]: Factor code out to .. + (w32_rootdir): .. new. + (gnupg_sysconfdir, gnupg_libdir, gnupg_datadir) [W32]: Return + name based on w32_rootdir(). + +2007-06-21 Werner Koch + + * membuf.h (get_membuf_len): New. + + * membuf.c (init_membuf_secure): Really allocate in secure memory. + (put_membuf_str): New. + + * ttyio.c (tty_getf): New. + + * util.h (ctrl_t): Declare it here. + + * asshelp.c (start_new_gpg_agent): New. Based on code from + ../sm/call-agent.c + +2007-06-20 Werner Koch + + * sysutils.c (gnupg_sleep): New. + * sysutils.h [W32]: Remove _sleep wrapper. Changed all callers to + use gnupg_sleep. + + * exechelp.c (build_w32_commandline_copy): New. + (build_w32_commandline): Factored some code out to new function + and correctly process a PGMNAME with spaces. + (gnupg_spawn_process_detached) [W32]: Implement. + +2007-06-14 Werner Koch + + * simple-pwquery.h (MAP_SPWQ_ERROR_IMPL): New. + (SPWQ_NO_PIN_ENTRY): New. + * simple-pwquery.c (simple_pw_set_socket): New. + (agent_open): Use it if GPG_AGENT_INFO is not set. + (simple_pwquery): Extended to allow returning of otehyr error codes. + + * util.h (GNUPG_MODULE_NAME_AGENT, GNUPG_MODULE_NAME_PINENTRY) + (GNUPG_MODULE_NAME_SCDAEMON, GNUPG_MODULE_NAME_DIRMNGR) + (GNUPG_MODULE_NAME_PROTECT_TOOL): New. + * homedir.c (gnupg_module_name): New. + (gnupg_bindir): New. + +2007-06-12 Werner Koch + + * homedir.c (gnupg_sysconfdir): New. + (gnupg_libexecdir): New. Taken from g10/misc.c:get_libexecdir. + (gnupg_datadir): New. + (gnupg_libdir): New. + + * http.c (connect_server) [W32]: Do not call init_sockets if + HTTP_NO_WSASTARTUP is defined. + + * init.c: New. + + * estream.c (es_init_do): Init stream lock here because we can't + use a static initialization with W32pth. + +2007-06-11 Werner Koch + + * Makefile.am (t_common_ldadd): Use libcommonstd macro. + +2007-06-06 Werner Koch + + * Makefile.am: Include am/cmacros.am. + + * sysutils.h [W32]: Remove prototypes for the registry access. + * w32reg.c: Move to ../jnlib/w32-reg.c. + + * i18n.c (i18n_init): New. + + * simple-gettext.c: Remove. + + * iobuf.c (iobuf_get_filelength): Rename SIZE to EXSIZE to silent + shadowing warning. + +2007-06-04 Werner Koch + + * http.c [W32]: Include unistd.h also in this case. + (write_server) [W32]: Fixed error code. + (init_sockets): Fixed syntax error. + (cookie_close): Replace close by sock_close macro. + + * estream.c [w32]: Do not init Mutex. + + * Makefile.am (common_sources) [USE_SNS_SRV]: Build srv.c only + when needed. + + * ttyio.c (init_ttyfp) [W32]: Do not use TTYFP. + + * util.h: Include ../jnlib/dynload.h. + + * dynload.h: Move to ../jnlib. + +2007-05-30 Werner Koch + + * estream.c (MEM_FREE, MEM_ALLOC, MEM_REALLOC): Prefix with ES_ as + windows.h also has such definitions, + +2007-05-15 Werner Koch + + * util.h: Do not include gnulib's vasprintf. Redefine asprintf + and vasprintf. + + * xasprintf.c (xasprintf, xtryasprintf): Use estream_vasprintf. + + * estream-printf.h, estream-printf.c: New. Taken from current + libestream SVN. + * Makefile.am (common_sources): Add them. + +2007-05-14 Werner Koch + + * sexp-parse.h (smklen): New. + * sexputil.c: Include sexp-parse.h. + (make_simple_sexp_from_hexstr): Replace sprintf by smklen. + +2007-05-07 Werner Koch + + * signal.c (got_fatal_signal): Protect SIG from being clobbered by + a faulty signal implementaion. Suggested by James Juran. + +2007-04-25 Werner Koch + + * i18n.h (ngettext): New. + * simple-gettext.c (ngettext): New. + +2007-04-20 Werner Koch + + * miscellaneous.c (my_gcry_logger, my_gcry_outofcore_handler): + Moved from gpg-agent to here. + (my_gcry_fatalerror_handler): new. + (setup_libgcrypt_logging): New. + +2007-03-19 Werner Koch + + * miscellaneous.c (print_hexstring): New. + * estream.c (es_fprintf_unlocked): New. + (es_write_sanitized): New. + (es_write_hexstring): New. + (es_write_sanitized_utf8_buffer) [GNUPG_MAJOR_VERSION]: New. + +2007-03-09 David Shaw + + From STABLE-BRANCH-1-4 + + * http.c (do_parse_uri): Remove the hkp port 11371 detection. We + implement hkp in the keyserver handler, and the support here makes + it appear like a bad hkp request actually succeeded. + +2007-01-31 Werner Koch + + * Makefile.am (t_common_ldadd): Add LIBINCONV and LIBINTL. + +2007-01-25 Werner Koch + + * simple-pwquery.c (simple_pwquery): New arg OPT_CHECK. + +2006-12-13 David Shaw + + * Makefile.am (AM_CPPFLAGS): Include intl/ so we can reference the + built-in headers. + +2006-11-23 Werner Koch + + * http.c: Include i18n.h + +2006-11-21 Werner Koch + + * estream.c: Remove explicit Pth soft mapping diabling becuase it + is now done in config.h. + +2006-11-15 Werner Koch + + * estream.c: Disabled Pth soft mapping. + (my_funopen_hook_ret_t): New. + (print_fun_writer): Use it here. + + * iobuf.c (fd_cache_close): Use %d instead of %p for debug output. + +2006-11-03 Werner Koch + + * Makefile.am (t_convert_DEPENDENCIES): Add libcommon. From + Gentoo. + +2006-10-24 Marcus Brinkmann + + * Makefile.am (libcommon_a_CFLAGS): Add $(LIBASSUAN_CFLAGS). + (libsimple_pwquery_a_CFLAGS): New variable. + +2006-10-20 Werner Koch + + * convert.c (hex2bin): New. + +2006-10-17 Werner Koch + + * estream.c (struct estream_internal, es_initialize) + (es_deinitialize, print_fun_writer, es_print): New and modified + functions to avoid tempfiles for printf style printing. + + * Makefile.am (libcommonpth_a_SOURCES): New. We now build a secon + version of the library with explicit Pth support. + * exechelp.c, estream.c: Make use of WITHOUT_GNU_PTH. + +2006-10-08 Werner Koch + + * gpgrlhelp.c: Trun all functions into dummies if readline is not + available. + +2006-10-06 Werner Koch + + * Makefile.am (AM_CFLAGS): Use PTH version of libassuan. + + * util.h (GNUPG_GCC_A_SENTINEL): Defined for gcc >= 4. + +2006-10-04 David Shaw + + * gpgrlhelp.c: readline requires stdio.h. + +2006-10-04 Werner Koch + + * membuf.c (init_membuf_secure): New. + (put_membuf): Make sure that ERRNO is set even if the underlying + malloc code does not work properly. + (get_membuf): Set ERRNO on error. + (get_membuf): Allow to pass LEN as NULL. + +2006-10-02 Werner Koch + + * iobuf.c (iobuf_unread): Removed. This code is not required. + Also removed the entire unget buffer stuff. + +2006-09-27 Werner Koch + + * util.h: Do not include strsep.h and strpbrk.h. + (isascii): Removed as it is now in jnlib. + + * iobuf.c (pop_filter, underflow, iobuf_close): Free the unget + buffer. + +2006-09-27 Florian Weimer (wk) + + * iobuf.c (iobuf_unread): New. + +2006-09-22 Werner Koch + + * i18n.h: Changed license to an all permissive one. + + * ttyio.c (tty_get): We need to use readline too. Added two more + hooks. + +2006-09-21 Werner Koch + + * ttyio.c (tty_private_set_rl_hooks): New. + (tty_enable_completion, tty_disable_completion): Use a hook to + enable readline support. Now always available. + (tty_cleanup_rl_after_signal): New. + + * ttyio.h: Removed readline specific stuff. Included util.h. + * common-defs.h: New. + +2006-09-15 Werner Koch + + * convert.c: New. + (hexcolon2bin): New. + (bin2hex, bin2hexcolon, do_binhex): New. + * t-convert.c: New + +2006-09-14 Werner Koch + + * util.h (out_of_core): Use new gpg_error_from_syserror function. + + * http.c (init_sockets): Changed it to require 2.2 unless it is + build within gnupg 1 where we require 1.1 (and not anymore allow + for 1.0). + +2006-09-07 Werner Koch + + * exechelp.c (gnupg_spawn_process): Factor out post fork code to .. + (do_exec): .. new function. Allow passing of -1 for the fds. + (gnupg_spawn_process): Terminate gcrypt's secure memory in the child. + (gnupg_spawn_process_detached): New. + +2006-09-06 Werner Koch + + * maperror.c: Removed. + + * util.h (out_of_core): New. + +2006-09-04 Werner Koch + + * http.c (http_get_header): New. + (capitalize_header_name, store_header): New. + (parse_response): Store headers away. + (send_request): Return GPG_ERR_NOT_FOUND if connect_server failed. + * http.h: New flag HTTP_FLAG_NEED_HEADER. + +2006-08-21 Werner Koch + + * Makefile.am (libcommon_a_SOURCES): Added keyserver.h + + * openpgpdefs.h: New. Stripped from ..g10/packet.h. + +2006-08-16 Werner Koch + + * keyserver.h: Moved from ../include to here. + + * http.c: Include srv.h. + + * srv.c, srv.h: New. Taken from GnuPG 1.4 + +2006-08-14 Werner Koch + + * http.h (struct http_context_s): Moved to implementation. + * http.c (http_open): Changed call to return a context. + (http_open_document): Ditto. + (http_get_read_ptr, http_get_read_ptr, http_get_status_code): New. + (do_parse_uri): Replaced strlwr by straight code to ease + standalone use of this file. + (http_wait_response): Removed arg STATUS_CODE as it is available + through an accessor function. Adjusted caller. + (http_escape_string): New. + + * estream.c (es_read_line): Renamed to .. + (doreadline): .. this. Changed all callers. + (es_read_line): New. This is theusual limited getline variabnt as + used at several places. Here taken and adjusted from xreadline.c + (es_free): New. + +2006-08-11 Werner Koch + + * http.c: Major internal changes to optionallly support GNUTLS and + ESTREAM. + (http_open): Move initialization of the stream ... + (send_request): .. here. + (http_register_tls_callback): New. + + * estream.c (es_writen): Try to seek only is a seek function has + been registered. + +2006-08-09 Werner Koch + + * http.c, http.h: New. Taken from gnupg 1.4.5, merged with + changes done for the Dirmngr project (by g10 Code) and cleaned up + some stuff. + (make_header_line): New. Change all caller to make user of the new + * Makefile.am (libcommon_a_SOURCES): Added http.c and http.h. + +2006-05-23 Werner Koch + + * gettime.c (isotimestamp): New. + + * ttyio.c (tty_get_ttyname): Posixly correct usage of ctermid. + + * dns-cert.c: New. Taken from 1.4.3's util/cert.c. + * dns-cert.h: New. + +2006-05-22 Werner Koch + + * pka.c: New. Taked from 1.4.3. + * pka.h: New. + * Makefile.am: Added pka. + +2006-05-19 Werner Koch + + * yesno.c (answer_is_yes_no_default, answer_is_yes_no_quit): + Updated from 1.4.3. + (answer_is_okay_cancel): new. From 1.4.3. + + * miscellaneous.c (match_multistr): New. Taken from 1.4.3. + + * ttyio.c (tty_enable_completion, tty_disable_completion): New + dummy functions. + * ttyio.h: Add prototypes and stubs. + +2006-04-19 Werner Koch + + * iobuf.c (iobuf_get_fd): New. Taken from 1.4.3. + (iobuf_is_pipe_filename): New. + (pop_filter): Made static. + (iobuf_skip_rest): New. Orginal patch by Florian + Weimer. Added new argument PARTIAL. + (block_filter): Remove the old gpg indeterminate length mode. + (block_filter): Properly handle a partial body stream + that ends with a 5-byte length that happens to be zero. + (iobuf_set_block_mode, iobuf_in_block_mode): Removed as + superfluous. + (iobuf_get_filelength): New arg OVERFLOW. + (iobuf_get_filelength) [W32]: Use GetFileSizeEx if available + * miscellaneous.c (is_file_compressed): Take care of OVERFLOW. + +2006-04-18 Werner Koch + + * homedir.c (w32_shgetfolderpath): New. Taken from gpg 1.4.3. + (default_homedir): Use it. + +2005-10-08 Marcus Brinkmann + + * signal.c (get_signal_name): Check value of HAVE_DECL_SYS_SIGLIST + instead of just if it is defined. + +2005-09-28 Marcus Brinkmann + + * Makefile.am (AM_CFLAGS): Add $(LIBASSUAN_CFLAGS). + +2005-07-04 Marcus Brinkmann + + * simple-pwquery.h (simple_pwclear): New prototype. + * simple-pwquery.c (simple_pwclear): New function. + +2005-06-15 Werner Koch + + * miscellaneous.c (make_printable_string): Made P a void*. + + * sexputil.c (keygrip_from_canon_sexp, cmp_simple_canon_sexp): + Fixed signed/unsigned pointer mismatch. + (make_simple_sexp_from_hexstr): Ditto. This is all too ugly; I + wonder why gcc-4's default is to warn about them and forcing us to + use cast the warning away. + * iobuf.c (block_filter): Ditto. + (iobuf_flush): Ditto. + (iobuf_read_line): Ditto. + (iobuf_read): Make BUFFER a void *. + (iobuf_write): Make BUFFER a const void *. + * ttyio.c (tty_print_utf8_string2): Ditto. + * estream.c (estream_cookie_mem): Make MEMORY unsigned char*. + (es_write): Make BUFFER a void *. + (es_writen): Ditto. + (es_func_fd_read, es_func_fd_write, es_func_mem_read) + (es_func_mem_write): Ditto. + (es_read, es_readn): Ditto. + (es_func_mem_write): Made MEMORY_NEW an unsigned char *. + * estream.h (es_cookie_read_function_t) + (es_cookie_write_function_t): Changed buffer arg to void*. + +2005-06-03 Werner Koch + + * estream.c: Use HAVE_CONFIG_H and not USE_CONFIG_H! + (es_func_fd_read, es_func_fd_write): Protect against EINTR. + +2005-06-01 Werner Koch + + * Makefile.am (AM_CPPFLAGS): Added. + + * util.h: Add some includes for gnulib. + (ttyname, isascii): Define them inline. + * fseeko.c, ftello.c: Removed. + * strsep.c, mkdtemp.c: Removed. + * ttyname.c, isascii.c: Removed. + +2005-05-31 Werner Koch + + * dynload.h: s/__inline__/inline/. + +2005-05-13 Werner Koch + + * signal.c (got_fatal_signal): Print the signal number if we can't + get a name for it. + (get_signal_name): Return NULL if no name is available. Fixed + conditional for sys_siglist to the correct one. + +2005-04-17 Werner Koch + + * sexputil.c (cmp_simple_canon_sexp): New. + (make_simple_sexp_from_hexstr): New. + +2005-04-07 Werner Koch + + * sexputil.c: New. + +2005-04-11 Marcus Brinkmann + + * simple-pwquery.c (simple_pwquery): Use spwq_secure_free. + +2005-03-03 Werner Koch + + * Makefile.am (AM_CFLAGS): Added PTH_CFLAGS. Noted by Kazu Yamamoto. + +2005-02-25 Werner Koch + + * xasprintf.c (xtryasprintf): New. + +2005-01-26 Moritz Schulte + + * Makefile.am (libcommon_a_SOURCES): New source files: estream.c, + estream.h. + * estream.c, estream.h: New files. + +2005-01-03 Werner Koch + + * asshelp.c (send_pinentry_environment): Fixed changed from + 2004-12-18; cut+paste error for lc-messages. + +2004-12-21 Werner Koch + + * simple-pwquery.c (agent_open) [W32]: Implement for W32. + (readline) [W32]: Use recv instead of read. + (writen) [W32]: Use send instead of write. + (my_stpcpy): Define a stpcpy replacement so that this file + continues to be self-contained. + (agent_send_all_options) [W32]: Don't call ttyname. + +2004-12-21 Marcus Brinkmann + + * simple-pwquery.h (simple_query): Add prototype. + * simple-pwquery.c (simple_query): New function. + +2004-12-21 Werner Koch + + * signal.c (got_fatal_signal, got_usr_signal) + (got_fatal_signal) [DOSISH]: Don't build. + * simple-gettext.c: Include sysutils.h + + * homedir.c: New. Use CSIDL_APPDATA for W32 as the default home + directory. + * Makefile.am (libcommon_a_SOURCES): Add it. + (EXTRA_DIST): Removed mkerror and mkerrtok. + +2004-12-20 Werner Koch + + * sysutils.h [W32]: Define sleep. + * util.h: Add prototype for mkdtemp. + + * membuf.c (put_membuf): Wipe out buffer after a failed realloc. + +2004-12-19 Werner Koch + + * maperror.c (map_assuan_err_with_source): Oops, args were swapped. + +2004-12-18 Werner Koch + + * maperror.c (map_assuan_err): Renamed to .. + (map_assuan_err_with_source): .. this and add arg SOURCE.c + * asshelp.c (send_pinentry_environment, send_one_option): Add arg + ERRSOURCE. + +2004-12-15 Werner Koch + + * sysutils.h [W32]: Prototypes for registry functions. + * w32reg.c: Include sysutils.h + + * simple-pwquery.c [W32]: Dummy code to allow a build. + + * exechelp.c [W32]: Implemented for W32 . + + * ttyname.c: New. + + * asshelp.c (send_one_option): New. + (send_pinentry_environment): Cleaned up and made sure that empty + values are not send. + +2004-12-07 Werner Koch + + * asshelp.c (send_pinentry_environment) [W32]: Do not use ttyname. + +2004-12-06 Werner Koch + + * exechelp.h, exechelp.c: New. Based on code from ../sm/import.c. + +2004-12-03 Werner Koch + + * strsep.c: Fixed copyright comments. + +2004-11-26 Werner Koch + + * simple-gettext.c: New taken from gnupg 1.3.x + + * simple-pwquery.c [_WIN32]: Include winsock2.h. + (agent_open): Disable it until we have our AF_UNIX implementation + ready. + * fseeko.c, ftello.c: Include sys/types for the sake of W32. + +2004-11-23 Werner Koch + + * b64enc.c: Include stdio.h and string.h + +2004-08-18 Werner Koch + + * simple-pwquery.c (simple_pwquery): Handle gpg-error style return + code for canceled. + +2004-07-20 Werner Koch + + * maperror.c: Removed header ksba.h. Not required anymore. + +2004-06-14 Werner Koch + + * 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, 2003, 2004, 2005, 2006, 2007, + 2008, 2009 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 new file mode 100644 index 0000000..75b4623 --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,142 @@ +# Makefile for common gnupg modules +# Copyright (C) 2001, 2003, 2007 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 3 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, see . + +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk \ + audit-events.h status-codes.h ChangeLog-2011 + +noinst_LIBRARIES = libcommon.a libcommonpth.a libsimple-pwquery.a libgpgrl.a +noinst_PROGRAMS = $(module_tests) $(module_maint_tests) +TESTS = $(module_tests) + +BUILT_SOURCES = audit-events.h status-codes.h + +CLEANFILES = audit-events.h status-codes.h + +AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl + +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) + +include $(top_srcdir)/am/cmacros.am + +common_sources = \ + common-defs.h \ + util.h i18n.c i18n.h \ + status.c status.h\ + openpgpdefs.h \ + gc-opt-flags.h \ + keyserver.h \ + sexp-parse.h \ + tlv.c tlv.h \ + init.c init.h \ + sexputil.c \ + sysutils.c sysutils.h \ + homedir.c \ + gettime.c \ + yesno.c \ + b64enc.c b64dec.c \ + convert.c \ + percent.c \ + miscellaneous.c \ + xasprintf.c \ + xreadline.c \ + membuf.c membuf.h \ + iobuf.c iobuf.h \ + ttyio.c ttyio.h \ + asshelp.c asshelp.h \ + exechelp.c exechelp.h \ + signal.c \ + estream.c estream.h estream-printf.c estream-printf.h \ + audit.c audit.h \ + srv.h \ + dns-cert.c dns-cert.h \ + pka.c pka.h \ + http.c http.h \ + localename.c \ + session-env.c session-env.h \ + ssh-utils.c ssh-utils.h \ + helpfile.c + +# Sources only useful without PTH. +without_pth_sources = \ + get-passphrase.c get-passphrase.h + + +libcommon_a_SOURCES = $(common_sources) $(without_pth_sources) +if USE_DNS_SRV +libcommon_a_SOURCES += srv.c +endif +libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_GNU_PTH=1 + +libcommonpth_a_SOURCES = $(common_sources) +if USE_DNS_SRV +libcommonpth_a_SOURCES += srv.c +endif +libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) + +libsimple_pwquery_a_SOURCES = \ + simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h +libsimple_pwquery_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) + +libgpgrl_a_SOURCES = \ + gpgrlhelp.c + +if MAINTAINER_MODE +# Note: Due to the dependency on Makefile, the file will always be +# rebuilt, so we allow this only in maintainer mode. + +# Create the audit-events.h include file from audit.h +# Note: We create the target file in the source directory because it +# is a distributed built source. If we would not do that we may end +# up with two files and then it is not clear which version of the +# files will be picked up. +audit-events.h: Makefile mkstrtable.awk exaudit.awk audit.h + $(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \ + | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ + -v namespace=eventstr_ > $(srcdir)/audit-events.h + +# Create the status-codes.h include file from status.h +status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h + $(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \ + | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ + -v namespace=statusstr_ > $(srcdir)/status-codes.h + +endif + + +# +# Module tests +# +module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil t-exechelp \ + t-session-env t-ssh-utils +module_maint_tests = t-helpfile t-b64 + +t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +t_convert_LDADD = $(t_common_ldadd) +t_percent_LDADD = $(t_common_ldadd) +t_gettime_LDADD = $(t_common_ldadd) +t_sysutils_LDADD = $(t_common_ldadd) +t_helpfile_LDADD = $(t_common_ldadd) +t_sexputil_LDADD = $(t_common_ldadd) +t_b64_LDADD = $(t_common_ldadd) +t_exechelp_LDADD = $(t_common_ldadd) +t_session_env_LDADD = $(t_common_ldadd) +t_ssh_utils_LDADD = $(t_common_ldadd) diff --git a/common/Makefile.in b/common/Makefile.in new file mode 100644 index 0000000..04c00b1 --- /dev/null +++ b/common/Makefile.in @@ -0,0 +1,2035 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# 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. + +@SET_MAKE@ + +# Makefile for common gnupg modules +# Copyright (C) 2001, 2003, 2007 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 3 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, see . + +# 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 3 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, see . + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +TESTS = $(am__EXEEXT_1) +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/am/cmacros.am +@HAVE_DOSISH_SYSTEM_FALSE@am__append_1 = -DGNUPG_BINDIR="\"$(bindir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" + + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. +@GNUPG_AGENT_PGM_TRUE@am__append_2 = -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" +@GNUPG_PINENTRY_PGM_TRUE@am__append_3 = -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" +@GNUPG_SCDAEMON_PGM_TRUE@am__append_4 = -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" +@GNUPG_DIRMNGR_PGM_TRUE@am__append_5 = -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" +@GNUPG_PROTECT_TOOL_PGM_TRUE@am__append_6 = -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" +@USE_DNS_SRV_TRUE@am__append_7 = srv.c +@USE_DNS_SRV_TRUE@am__append_8 = srv.c +subdir = common +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/gl/m4/absolute-header.m4 \ + $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/allocsa.m4 \ + $(top_srcdir)/gl/m4/eealloc.m4 \ + $(top_srcdir)/gl/m4/gnulib-comp.m4 \ + $(top_srcdir)/gl/m4/gnulib-tool.m4 \ + $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/setenv.m4 \ + $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/strpbrk.m4 \ + $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/estream.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gnupg-pth.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/size_max.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libcommon_a_AR = $(AR) $(ARFLAGS) +libcommon_a_LIBADD = +am__libcommon_a_SOURCES_DIST = common-defs.h util.h i18n.c i18n.h \ + status.c status.h openpgpdefs.h gc-opt-flags.h keyserver.h \ + sexp-parse.h tlv.c tlv.h init.c init.h sexputil.c sysutils.c \ + sysutils.h homedir.c gettime.c yesno.c b64enc.c b64dec.c \ + convert.c percent.c miscellaneous.c xasprintf.c xreadline.c \ + membuf.c membuf.h iobuf.c iobuf.h ttyio.c ttyio.h asshelp.c \ + asshelp.h exechelp.c exechelp.h signal.c estream.c estream.h \ + estream-printf.c estream-printf.h audit.c audit.h srv.h \ + dns-cert.c dns-cert.h pka.c pka.h http.c http.h localename.c \ + session-env.c session-env.h ssh-utils.c ssh-utils.h helpfile.c \ + get-passphrase.c get-passphrase.h srv.c +am__objects_1 = libcommon_a-i18n.$(OBJEXT) \ + libcommon_a-status.$(OBJEXT) libcommon_a-tlv.$(OBJEXT) \ + libcommon_a-init.$(OBJEXT) libcommon_a-sexputil.$(OBJEXT) \ + libcommon_a-sysutils.$(OBJEXT) libcommon_a-homedir.$(OBJEXT) \ + libcommon_a-gettime.$(OBJEXT) libcommon_a-yesno.$(OBJEXT) \ + libcommon_a-b64enc.$(OBJEXT) libcommon_a-b64dec.$(OBJEXT) \ + libcommon_a-convert.$(OBJEXT) libcommon_a-percent.$(OBJEXT) \ + libcommon_a-miscellaneous.$(OBJEXT) \ + libcommon_a-xasprintf.$(OBJEXT) \ + libcommon_a-xreadline.$(OBJEXT) libcommon_a-membuf.$(OBJEXT) \ + libcommon_a-iobuf.$(OBJEXT) libcommon_a-ttyio.$(OBJEXT) \ + libcommon_a-asshelp.$(OBJEXT) libcommon_a-exechelp.$(OBJEXT) \ + libcommon_a-signal.$(OBJEXT) libcommon_a-estream.$(OBJEXT) \ + libcommon_a-estream-printf.$(OBJEXT) \ + libcommon_a-audit.$(OBJEXT) libcommon_a-dns-cert.$(OBJEXT) \ + libcommon_a-pka.$(OBJEXT) libcommon_a-http.$(OBJEXT) \ + libcommon_a-localename.$(OBJEXT) \ + libcommon_a-session-env.$(OBJEXT) \ + libcommon_a-ssh-utils.$(OBJEXT) libcommon_a-helpfile.$(OBJEXT) +am__objects_2 = libcommon_a-get-passphrase.$(OBJEXT) +@USE_DNS_SRV_TRUE@am__objects_3 = libcommon_a-srv.$(OBJEXT) +am_libcommon_a_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) +libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS) +libcommonpth_a_AR = $(AR) $(ARFLAGS) +libcommonpth_a_LIBADD = +am__libcommonpth_a_SOURCES_DIST = common-defs.h util.h i18n.c i18n.h \ + status.c status.h openpgpdefs.h gc-opt-flags.h keyserver.h \ + sexp-parse.h tlv.c tlv.h init.c init.h sexputil.c sysutils.c \ + sysutils.h homedir.c gettime.c yesno.c b64enc.c b64dec.c \ + convert.c percent.c miscellaneous.c xasprintf.c xreadline.c \ + membuf.c membuf.h iobuf.c iobuf.h ttyio.c ttyio.h asshelp.c \ + asshelp.h exechelp.c exechelp.h signal.c estream.c estream.h \ + estream-printf.c estream-printf.h audit.c audit.h srv.h \ + dns-cert.c dns-cert.h pka.c pka.h http.c http.h localename.c \ + session-env.c session-env.h ssh-utils.c ssh-utils.h helpfile.c \ + srv.c +am__objects_4 = libcommonpth_a-i18n.$(OBJEXT) \ + libcommonpth_a-status.$(OBJEXT) libcommonpth_a-tlv.$(OBJEXT) \ + libcommonpth_a-init.$(OBJEXT) \ + libcommonpth_a-sexputil.$(OBJEXT) \ + libcommonpth_a-sysutils.$(OBJEXT) \ + libcommonpth_a-homedir.$(OBJEXT) \ + libcommonpth_a-gettime.$(OBJEXT) \ + libcommonpth_a-yesno.$(OBJEXT) libcommonpth_a-b64enc.$(OBJEXT) \ + libcommonpth_a-b64dec.$(OBJEXT) \ + libcommonpth_a-convert.$(OBJEXT) \ + libcommonpth_a-percent.$(OBJEXT) \ + libcommonpth_a-miscellaneous.$(OBJEXT) \ + libcommonpth_a-xasprintf.$(OBJEXT) \ + libcommonpth_a-xreadline.$(OBJEXT) \ + libcommonpth_a-membuf.$(OBJEXT) libcommonpth_a-iobuf.$(OBJEXT) \ + libcommonpth_a-ttyio.$(OBJEXT) \ + libcommonpth_a-asshelp.$(OBJEXT) \ + libcommonpth_a-exechelp.$(OBJEXT) \ + libcommonpth_a-signal.$(OBJEXT) \ + libcommonpth_a-estream.$(OBJEXT) \ + libcommonpth_a-estream-printf.$(OBJEXT) \ + libcommonpth_a-audit.$(OBJEXT) \ + libcommonpth_a-dns-cert.$(OBJEXT) libcommonpth_a-pka.$(OBJEXT) \ + libcommonpth_a-http.$(OBJEXT) \ + libcommonpth_a-localename.$(OBJEXT) \ + libcommonpth_a-session-env.$(OBJEXT) \ + libcommonpth_a-ssh-utils.$(OBJEXT) \ + libcommonpth_a-helpfile.$(OBJEXT) +@USE_DNS_SRV_TRUE@am__objects_5 = libcommonpth_a-srv.$(OBJEXT) +am_libcommonpth_a_OBJECTS = $(am__objects_4) $(am__objects_5) +libcommonpth_a_OBJECTS = $(am_libcommonpth_a_OBJECTS) +libgpgrl_a_AR = $(AR) $(ARFLAGS) +libgpgrl_a_LIBADD = +am_libgpgrl_a_OBJECTS = gpgrlhelp.$(OBJEXT) +libgpgrl_a_OBJECTS = $(am_libgpgrl_a_OBJECTS) +libsimple_pwquery_a_AR = $(AR) $(ARFLAGS) +libsimple_pwquery_a_LIBADD = +am_libsimple_pwquery_a_OBJECTS = \ + libsimple_pwquery_a-simple-pwquery.$(OBJEXT) \ + libsimple_pwquery_a-asshelp.$(OBJEXT) +libsimple_pwquery_a_OBJECTS = $(am_libsimple_pwquery_a_OBJECTS) +am__EXEEXT_1 = t-convert$(EXEEXT) t-percent$(EXEEXT) \ + t-gettime$(EXEEXT) t-sysutils$(EXEEXT) t-sexputil$(EXEEXT) \ + t-exechelp$(EXEEXT) t-session-env$(EXEEXT) \ + t-ssh-utils$(EXEEXT) +am__EXEEXT_2 = t-helpfile$(EXEEXT) t-b64$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +t_b64_SOURCES = t-b64.c +t_b64_OBJECTS = t-b64.$(OBJEXT) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +t_b64_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_convert_SOURCES = t-convert.c +t_convert_OBJECTS = t-convert.$(OBJEXT) +t_convert_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_exechelp_SOURCES = t-exechelp.c +t_exechelp_OBJECTS = t-exechelp.$(OBJEXT) +t_exechelp_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_gettime_SOURCES = t-gettime.c +t_gettime_OBJECTS = t-gettime.$(OBJEXT) +t_gettime_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_helpfile_SOURCES = t-helpfile.c +t_helpfile_OBJECTS = t-helpfile.$(OBJEXT) +t_helpfile_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_percent_SOURCES = t-percent.c +t_percent_OBJECTS = t-percent.$(OBJEXT) +t_percent_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_session_env_SOURCES = t-session-env.c +t_session_env_OBJECTS = t-session-env.$(OBJEXT) +t_session_env_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_sexputil_SOURCES = t-sexputil.c +t_sexputil_OBJECTS = t-sexputil.$(OBJEXT) +t_sexputil_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_ssh_utils_SOURCES = t-ssh-utils.c +t_ssh_utils_OBJECTS = t-ssh-utils.$(OBJEXT) +t_ssh_utils_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_sysutils_SOURCES = t-sysutils.c +t_sysutils_OBJECTS = t-sysutils.$(OBJEXT) +t_sysutils_DEPENDENCIES = $(am__DEPENDENCIES_2) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libcommon_a_SOURCES) $(libcommonpth_a_SOURCES) \ + $(libgpgrl_a_SOURCES) $(libsimple_pwquery_a_SOURCES) t-b64.c \ + t-convert.c t-exechelp.c t-gettime.c t-helpfile.c t-percent.c \ + t-session-env.c t-sexputil.c t-ssh-utils.c t-sysutils.c +DIST_SOURCES = $(am__libcommon_a_SOURCES_DIST) \ + $(am__libcommonpth_a_SOURCES_DIST) $(libgpgrl_a_SOURCES) \ + $(libsimple_pwquery_a_SOURCES) t-b64.c t-convert.c \ + t-exechelp.c t-gettime.c t-helpfile.c t-percent.c \ + t-session-env.c t-sexputil.c t-ssh-utils.c t-sysutils.c +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@ +ACLOCAL = @ACLOCAL@ +ADNSLIBS = @ADNSLIBS@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAQPROG = @FAQPROG@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_CURL = @GPGKEYS_CURL@ +GPGKEYS_FINGER = @GPGKEYS_FINGER@ +GPGKEYS_HKP = @GPGKEYS_HKP@ +GPGKEYS_KDNS = @GPGKEYS_KDNS@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGKEYS_MAILTO = @GPGKEYS_MAILTO@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GREP = @GREP@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +PTH_CFLAGS = @PTH_CFLAGS@ +PTH_CONFIG = @PTH_CONFIG@ +PTH_LIBS = @PTH_LIBS@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +UNISTD_H = @UNISTD_H@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDRES = @WINDRES@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIBS = @ZLIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk \ + audit-events.h status-codes.h ChangeLog-2011 + +noinst_LIBRARIES = libcommon.a libcommonpth.a libsimple-pwquery.a libgpgrl.a +BUILT_SOURCES = audit-events.h status-codes.h +CLEANFILES = audit-events.h status-codes.h +AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl \ + -DLOCALEDIR=\"$(localedir)\" $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a +common_sources = \ + common-defs.h \ + util.h i18n.c i18n.h \ + status.c status.h\ + openpgpdefs.h \ + gc-opt-flags.h \ + keyserver.h \ + sexp-parse.h \ + tlv.c tlv.h \ + init.c init.h \ + sexputil.c \ + sysutils.c sysutils.h \ + homedir.c \ + gettime.c \ + yesno.c \ + b64enc.c b64dec.c \ + convert.c \ + percent.c \ + miscellaneous.c \ + xasprintf.c \ + xreadline.c \ + membuf.c membuf.h \ + iobuf.c iobuf.h \ + ttyio.c ttyio.h \ + asshelp.c asshelp.h \ + exechelp.c exechelp.h \ + signal.c \ + estream.c estream.h estream-printf.c estream-printf.h \ + audit.c audit.h \ + srv.h \ + dns-cert.c dns-cert.h \ + pka.c pka.h \ + http.c http.h \ + localename.c \ + session-env.c session-env.h \ + ssh-utils.c ssh-utils.h \ + helpfile.c + + +# Sources only useful without PTH. +without_pth_sources = \ + get-passphrase.c get-passphrase.h + +libcommon_a_SOURCES = $(common_sources) $(without_pth_sources) \ + $(am__append_7) +libcommon_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) -DWITHOUT_GNU_PTH=1 +libcommonpth_a_SOURCES = $(common_sources) $(am__append_8) +libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +libsimple_pwquery_a_SOURCES = \ + simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h + +libsimple_pwquery_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) +libgpgrl_a_SOURCES = \ + gpgrlhelp.c + + +# +# Module tests +# +module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil t-exechelp \ + t-session-env t-ssh-utils + +module_maint_tests = t-helpfile t-b64 +t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +t_convert_LDADD = $(t_common_ldadd) +t_percent_LDADD = $(t_common_ldadd) +t_gettime_LDADD = $(t_common_ldadd) +t_sysutils_LDADD = $(t_common_ldadd) +t_helpfile_LDADD = $(t_common_ldadd) +t_sexputil_LDADD = $(t_common_ldadd) +t_b64_LDADD = $(t_common_ldadd) +t_exechelp_LDADD = $(t_common_ldadd) +t_session_env_LDADD = $(t_common_ldadd) +t_ssh_utils_LDADD = $(t_common_ldadd) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/am/cmacros.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu common/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu common/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES) + -rm -f libcommon.a + $(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD) + $(RANLIB) libcommon.a +libcommonpth.a: $(libcommonpth_a_OBJECTS) $(libcommonpth_a_DEPENDENCIES) + -rm -f libcommonpth.a + $(libcommonpth_a_AR) libcommonpth.a $(libcommonpth_a_OBJECTS) $(libcommonpth_a_LIBADD) + $(RANLIB) libcommonpth.a +libgpgrl.a: $(libgpgrl_a_OBJECTS) $(libgpgrl_a_DEPENDENCIES) + -rm -f libgpgrl.a + $(libgpgrl_a_AR) libgpgrl.a $(libgpgrl_a_OBJECTS) $(libgpgrl_a_LIBADD) + $(RANLIB) libgpgrl.a +libsimple-pwquery.a: $(libsimple_pwquery_a_OBJECTS) $(libsimple_pwquery_a_DEPENDENCIES) + -rm -f libsimple-pwquery.a + $(libsimple_pwquery_a_AR) libsimple-pwquery.a $(libsimple_pwquery_a_OBJECTS) $(libsimple_pwquery_a_LIBADD) + $(RANLIB) libsimple-pwquery.a + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +t-b64$(EXEEXT): $(t_b64_OBJECTS) $(t_b64_DEPENDENCIES) + @rm -f t-b64$(EXEEXT) + $(LINK) $(t_b64_OBJECTS) $(t_b64_LDADD) $(LIBS) +t-convert$(EXEEXT): $(t_convert_OBJECTS) $(t_convert_DEPENDENCIES) + @rm -f t-convert$(EXEEXT) + $(LINK) $(t_convert_OBJECTS) $(t_convert_LDADD) $(LIBS) +t-exechelp$(EXEEXT): $(t_exechelp_OBJECTS) $(t_exechelp_DEPENDENCIES) + @rm -f t-exechelp$(EXEEXT) + $(LINK) $(t_exechelp_OBJECTS) $(t_exechelp_LDADD) $(LIBS) +t-gettime$(EXEEXT): $(t_gettime_OBJECTS) $(t_gettime_DEPENDENCIES) + @rm -f t-gettime$(EXEEXT) + $(LINK) $(t_gettime_OBJECTS) $(t_gettime_LDADD) $(LIBS) +t-helpfile$(EXEEXT): $(t_helpfile_OBJECTS) $(t_helpfile_DEPENDENCIES) + @rm -f t-helpfile$(EXEEXT) + $(LINK) $(t_helpfile_OBJECTS) $(t_helpfile_LDADD) $(LIBS) +t-percent$(EXEEXT): $(t_percent_OBJECTS) $(t_percent_DEPENDENCIES) + @rm -f t-percent$(EXEEXT) + $(LINK) $(t_percent_OBJECTS) $(t_percent_LDADD) $(LIBS) +t-session-env$(EXEEXT): $(t_session_env_OBJECTS) $(t_session_env_DEPENDENCIES) + @rm -f t-session-env$(EXEEXT) + $(LINK) $(t_session_env_OBJECTS) $(t_session_env_LDADD) $(LIBS) +t-sexputil$(EXEEXT): $(t_sexputil_OBJECTS) $(t_sexputil_DEPENDENCIES) + @rm -f t-sexputil$(EXEEXT) + $(LINK) $(t_sexputil_OBJECTS) $(t_sexputil_LDADD) $(LIBS) +t-ssh-utils$(EXEEXT): $(t_ssh_utils_OBJECTS) $(t_ssh_utils_DEPENDENCIES) + @rm -f t-ssh-utils$(EXEEXT) + $(LINK) $(t_ssh_utils_OBJECTS) $(t_ssh_utils_LDADD) $(LIBS) +t-sysutils$(EXEEXT): $(t_sysutils_OBJECTS) $(t_sysutils_DEPENDENCIES) + @rm -f t-sysutils$(EXEEXT) + $(LINK) $(t_sysutils_OBJECTS) $(t_sysutils_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgrlhelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-asshelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-audit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-b64dec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-b64enc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-convert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-dns-cert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-estream-printf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-estream.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-exechelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-get-passphrase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-gettime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-helpfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-homedir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-i18n.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-iobuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-localename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-membuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-miscellaneous.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-percent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-pka.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-session-env.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-sexputil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-signal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-srv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-ssh-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-sysutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-tlv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-ttyio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-xasprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-xreadline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_a-yesno.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-asshelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-audit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-b64dec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-b64enc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-convert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-dns-cert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-estream-printf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-estream.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-exechelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-gettime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-helpfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-homedir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-i18n.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-iobuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-localename.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-membuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-miscellaneous.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-percent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-pka.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-session-env.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-sexputil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-signal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-srv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-ssh-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-sysutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-tlv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-ttyio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-xasprintf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-xreadline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommonpth_a-yesno.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsimple_pwquery_a-asshelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-b64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-convert.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-exechelp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-gettime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-helpfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-percent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-session-env.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sexputil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ssh-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-sysutils.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +libcommon_a-i18n.o: i18n.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-i18n.o -MD -MP -MF $(DEPDIR)/libcommon_a-i18n.Tpo -c -o libcommon_a-i18n.o `test -f 'i18n.c' || echo '$(srcdir)/'`i18n.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-i18n.Tpo $(DEPDIR)/libcommon_a-i18n.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i18n.c' object='libcommon_a-i18n.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-i18n.o `test -f 'i18n.c' || echo '$(srcdir)/'`i18n.c + +libcommon_a-i18n.obj: i18n.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-i18n.obj -MD -MP -MF $(DEPDIR)/libcommon_a-i18n.Tpo -c -o libcommon_a-i18n.obj `if test -f 'i18n.c'; then $(CYGPATH_W) 'i18n.c'; else $(CYGPATH_W) '$(srcdir)/i18n.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-i18n.Tpo $(DEPDIR)/libcommon_a-i18n.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i18n.c' object='libcommon_a-i18n.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-i18n.obj `if test -f 'i18n.c'; then $(CYGPATH_W) 'i18n.c'; else $(CYGPATH_W) '$(srcdir)/i18n.c'; fi` + +libcommon_a-status.o: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-status.o -MD -MP -MF $(DEPDIR)/libcommon_a-status.Tpo -c -o libcommon_a-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-status.Tpo $(DEPDIR)/libcommon_a-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='libcommon_a-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c + +libcommon_a-status.obj: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-status.obj -MD -MP -MF $(DEPDIR)/libcommon_a-status.Tpo -c -o libcommon_a-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-status.Tpo $(DEPDIR)/libcommon_a-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='libcommon_a-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` + +libcommon_a-tlv.o: tlv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-tlv.o -MD -MP -MF $(DEPDIR)/libcommon_a-tlv.Tpo -c -o libcommon_a-tlv.o `test -f 'tlv.c' || echo '$(srcdir)/'`tlv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-tlv.Tpo $(DEPDIR)/libcommon_a-tlv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlv.c' object='libcommon_a-tlv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-tlv.o `test -f 'tlv.c' || echo '$(srcdir)/'`tlv.c + +libcommon_a-tlv.obj: tlv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-tlv.obj -MD -MP -MF $(DEPDIR)/libcommon_a-tlv.Tpo -c -o libcommon_a-tlv.obj `if test -f 'tlv.c'; then $(CYGPATH_W) 'tlv.c'; else $(CYGPATH_W) '$(srcdir)/tlv.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-tlv.Tpo $(DEPDIR)/libcommon_a-tlv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlv.c' object='libcommon_a-tlv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-tlv.obj `if test -f 'tlv.c'; then $(CYGPATH_W) 'tlv.c'; else $(CYGPATH_W) '$(srcdir)/tlv.c'; fi` + +libcommon_a-init.o: init.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-init.o -MD -MP -MF $(DEPDIR)/libcommon_a-init.Tpo -c -o libcommon_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-init.Tpo $(DEPDIR)/libcommon_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='init.c' object='libcommon_a-init.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c + +libcommon_a-init.obj: init.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-init.obj -MD -MP -MF $(DEPDIR)/libcommon_a-init.Tpo -c -o libcommon_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-init.Tpo $(DEPDIR)/libcommon_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='init.c' object='libcommon_a-init.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` + +libcommon_a-sexputil.o: sexputil.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-sexputil.o -MD -MP -MF $(DEPDIR)/libcommon_a-sexputil.Tpo -c -o libcommon_a-sexputil.o `test -f 'sexputil.c' || echo '$(srcdir)/'`sexputil.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-sexputil.Tpo $(DEPDIR)/libcommon_a-sexputil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sexputil.c' object='libcommon_a-sexputil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-sexputil.o `test -f 'sexputil.c' || echo '$(srcdir)/'`sexputil.c + +libcommon_a-sexputil.obj: sexputil.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-sexputil.obj -MD -MP -MF $(DEPDIR)/libcommon_a-sexputil.Tpo -c -o libcommon_a-sexputil.obj `if test -f 'sexputil.c'; then $(CYGPATH_W) 'sexputil.c'; else $(CYGPATH_W) '$(srcdir)/sexputil.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-sexputil.Tpo $(DEPDIR)/libcommon_a-sexputil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sexputil.c' object='libcommon_a-sexputil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-sexputil.obj `if test -f 'sexputil.c'; then $(CYGPATH_W) 'sexputil.c'; else $(CYGPATH_W) '$(srcdir)/sexputil.c'; fi` + +libcommon_a-sysutils.o: sysutils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-sysutils.o -MD -MP -MF $(DEPDIR)/libcommon_a-sysutils.Tpo -c -o libcommon_a-sysutils.o `test -f 'sysutils.c' || echo '$(srcdir)/'`sysutils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-sysutils.Tpo $(DEPDIR)/libcommon_a-sysutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sysutils.c' object='libcommon_a-sysutils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-sysutils.o `test -f 'sysutils.c' || echo '$(srcdir)/'`sysutils.c + +libcommon_a-sysutils.obj: sysutils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-sysutils.obj -MD -MP -MF $(DEPDIR)/libcommon_a-sysutils.Tpo -c -o libcommon_a-sysutils.obj `if test -f 'sysutils.c'; then $(CYGPATH_W) 'sysutils.c'; else $(CYGPATH_W) '$(srcdir)/sysutils.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-sysutils.Tpo $(DEPDIR)/libcommon_a-sysutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sysutils.c' object='libcommon_a-sysutils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-sysutils.obj `if test -f 'sysutils.c'; then $(CYGPATH_W) 'sysutils.c'; else $(CYGPATH_W) '$(srcdir)/sysutils.c'; fi` + +libcommon_a-homedir.o: homedir.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-homedir.o -MD -MP -MF $(DEPDIR)/libcommon_a-homedir.Tpo -c -o libcommon_a-homedir.o `test -f 'homedir.c' || echo '$(srcdir)/'`homedir.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-homedir.Tpo $(DEPDIR)/libcommon_a-homedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='homedir.c' object='libcommon_a-homedir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-homedir.o `test -f 'homedir.c' || echo '$(srcdir)/'`homedir.c + +libcommon_a-homedir.obj: homedir.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-homedir.obj -MD -MP -MF $(DEPDIR)/libcommon_a-homedir.Tpo -c -o libcommon_a-homedir.obj `if test -f 'homedir.c'; then $(CYGPATH_W) 'homedir.c'; else $(CYGPATH_W) '$(srcdir)/homedir.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-homedir.Tpo $(DEPDIR)/libcommon_a-homedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='homedir.c' object='libcommon_a-homedir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-homedir.obj `if test -f 'homedir.c'; then $(CYGPATH_W) 'homedir.c'; else $(CYGPATH_W) '$(srcdir)/homedir.c'; fi` + +libcommon_a-gettime.o: gettime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-gettime.o -MD -MP -MF $(DEPDIR)/libcommon_a-gettime.Tpo -c -o libcommon_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-gettime.Tpo $(DEPDIR)/libcommon_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gettime.c' object='libcommon_a-gettime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c + +libcommon_a-gettime.obj: gettime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-gettime.obj -MD -MP -MF $(DEPDIR)/libcommon_a-gettime.Tpo -c -o libcommon_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-gettime.Tpo $(DEPDIR)/libcommon_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gettime.c' object='libcommon_a-gettime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` + +libcommon_a-yesno.o: yesno.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-yesno.o -MD -MP -MF $(DEPDIR)/libcommon_a-yesno.Tpo -c -o libcommon_a-yesno.o `test -f 'yesno.c' || echo '$(srcdir)/'`yesno.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-yesno.Tpo $(DEPDIR)/libcommon_a-yesno.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='yesno.c' object='libcommon_a-yesno.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-yesno.o `test -f 'yesno.c' || echo '$(srcdir)/'`yesno.c + +libcommon_a-yesno.obj: yesno.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-yesno.obj -MD -MP -MF $(DEPDIR)/libcommon_a-yesno.Tpo -c -o libcommon_a-yesno.obj `if test -f 'yesno.c'; then $(CYGPATH_W) 'yesno.c'; else $(CYGPATH_W) '$(srcdir)/yesno.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-yesno.Tpo $(DEPDIR)/libcommon_a-yesno.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='yesno.c' object='libcommon_a-yesno.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-yesno.obj `if test -f 'yesno.c'; then $(CYGPATH_W) 'yesno.c'; else $(CYGPATH_W) '$(srcdir)/yesno.c'; fi` + +libcommon_a-b64enc.o: b64enc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-b64enc.o -MD -MP -MF $(DEPDIR)/libcommon_a-b64enc.Tpo -c -o libcommon_a-b64enc.o `test -f 'b64enc.c' || echo '$(srcdir)/'`b64enc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-b64enc.Tpo $(DEPDIR)/libcommon_a-b64enc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64enc.c' object='libcommon_a-b64enc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-b64enc.o `test -f 'b64enc.c' || echo '$(srcdir)/'`b64enc.c + +libcommon_a-b64enc.obj: b64enc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-b64enc.obj -MD -MP -MF $(DEPDIR)/libcommon_a-b64enc.Tpo -c -o libcommon_a-b64enc.obj `if test -f 'b64enc.c'; then $(CYGPATH_W) 'b64enc.c'; else $(CYGPATH_W) '$(srcdir)/b64enc.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-b64enc.Tpo $(DEPDIR)/libcommon_a-b64enc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64enc.c' object='libcommon_a-b64enc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-b64enc.obj `if test -f 'b64enc.c'; then $(CYGPATH_W) 'b64enc.c'; else $(CYGPATH_W) '$(srcdir)/b64enc.c'; fi` + +libcommon_a-b64dec.o: b64dec.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-b64dec.o -MD -MP -MF $(DEPDIR)/libcommon_a-b64dec.Tpo -c -o libcommon_a-b64dec.o `test -f 'b64dec.c' || echo '$(srcdir)/'`b64dec.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-b64dec.Tpo $(DEPDIR)/libcommon_a-b64dec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64dec.c' object='libcommon_a-b64dec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-b64dec.o `test -f 'b64dec.c' || echo '$(srcdir)/'`b64dec.c + +libcommon_a-b64dec.obj: b64dec.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-b64dec.obj -MD -MP -MF $(DEPDIR)/libcommon_a-b64dec.Tpo -c -o libcommon_a-b64dec.obj `if test -f 'b64dec.c'; then $(CYGPATH_W) 'b64dec.c'; else $(CYGPATH_W) '$(srcdir)/b64dec.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-b64dec.Tpo $(DEPDIR)/libcommon_a-b64dec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64dec.c' object='libcommon_a-b64dec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-b64dec.obj `if test -f 'b64dec.c'; then $(CYGPATH_W) 'b64dec.c'; else $(CYGPATH_W) '$(srcdir)/b64dec.c'; fi` + +libcommon_a-convert.o: convert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-convert.o -MD -MP -MF $(DEPDIR)/libcommon_a-convert.Tpo -c -o libcommon_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-convert.Tpo $(DEPDIR)/libcommon_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='convert.c' object='libcommon_a-convert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c + +libcommon_a-convert.obj: convert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-convert.obj -MD -MP -MF $(DEPDIR)/libcommon_a-convert.Tpo -c -o libcommon_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-convert.Tpo $(DEPDIR)/libcommon_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='convert.c' object='libcommon_a-convert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` + +libcommon_a-percent.o: percent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-percent.o -MD -MP -MF $(DEPDIR)/libcommon_a-percent.Tpo -c -o libcommon_a-percent.o `test -f 'percent.c' || echo '$(srcdir)/'`percent.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-percent.Tpo $(DEPDIR)/libcommon_a-percent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='percent.c' object='libcommon_a-percent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-percent.o `test -f 'percent.c' || echo '$(srcdir)/'`percent.c + +libcommon_a-percent.obj: percent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-percent.obj -MD -MP -MF $(DEPDIR)/libcommon_a-percent.Tpo -c -o libcommon_a-percent.obj `if test -f 'percent.c'; then $(CYGPATH_W) 'percent.c'; else $(CYGPATH_W) '$(srcdir)/percent.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-percent.Tpo $(DEPDIR)/libcommon_a-percent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='percent.c' object='libcommon_a-percent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-percent.obj `if test -f 'percent.c'; then $(CYGPATH_W) 'percent.c'; else $(CYGPATH_W) '$(srcdir)/percent.c'; fi` + +libcommon_a-miscellaneous.o: miscellaneous.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-miscellaneous.o -MD -MP -MF $(DEPDIR)/libcommon_a-miscellaneous.Tpo -c -o libcommon_a-miscellaneous.o `test -f 'miscellaneous.c' || echo '$(srcdir)/'`miscellaneous.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-miscellaneous.Tpo $(DEPDIR)/libcommon_a-miscellaneous.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='miscellaneous.c' object='libcommon_a-miscellaneous.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-miscellaneous.o `test -f 'miscellaneous.c' || echo '$(srcdir)/'`miscellaneous.c + +libcommon_a-miscellaneous.obj: miscellaneous.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-miscellaneous.obj -MD -MP -MF $(DEPDIR)/libcommon_a-miscellaneous.Tpo -c -o libcommon_a-miscellaneous.obj `if test -f 'miscellaneous.c'; then $(CYGPATH_W) 'miscellaneous.c'; else $(CYGPATH_W) '$(srcdir)/miscellaneous.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-miscellaneous.Tpo $(DEPDIR)/libcommon_a-miscellaneous.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='miscellaneous.c' object='libcommon_a-miscellaneous.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-miscellaneous.obj `if test -f 'miscellaneous.c'; then $(CYGPATH_W) 'miscellaneous.c'; else $(CYGPATH_W) '$(srcdir)/miscellaneous.c'; fi` + +libcommon_a-xasprintf.o: xasprintf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-xasprintf.o -MD -MP -MF $(DEPDIR)/libcommon_a-xasprintf.Tpo -c -o libcommon_a-xasprintf.o `test -f 'xasprintf.c' || echo '$(srcdir)/'`xasprintf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-xasprintf.Tpo $(DEPDIR)/libcommon_a-xasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xasprintf.c' object='libcommon_a-xasprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-xasprintf.o `test -f 'xasprintf.c' || echo '$(srcdir)/'`xasprintf.c + +libcommon_a-xasprintf.obj: xasprintf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-xasprintf.obj -MD -MP -MF $(DEPDIR)/libcommon_a-xasprintf.Tpo -c -o libcommon_a-xasprintf.obj `if test -f 'xasprintf.c'; then $(CYGPATH_W) 'xasprintf.c'; else $(CYGPATH_W) '$(srcdir)/xasprintf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-xasprintf.Tpo $(DEPDIR)/libcommon_a-xasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xasprintf.c' object='libcommon_a-xasprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-xasprintf.obj `if test -f 'xasprintf.c'; then $(CYGPATH_W) 'xasprintf.c'; else $(CYGPATH_W) '$(srcdir)/xasprintf.c'; fi` + +libcommon_a-xreadline.o: xreadline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-xreadline.o -MD -MP -MF $(DEPDIR)/libcommon_a-xreadline.Tpo -c -o libcommon_a-xreadline.o `test -f 'xreadline.c' || echo '$(srcdir)/'`xreadline.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-xreadline.Tpo $(DEPDIR)/libcommon_a-xreadline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xreadline.c' object='libcommon_a-xreadline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-xreadline.o `test -f 'xreadline.c' || echo '$(srcdir)/'`xreadline.c + +libcommon_a-xreadline.obj: xreadline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-xreadline.obj -MD -MP -MF $(DEPDIR)/libcommon_a-xreadline.Tpo -c -o libcommon_a-xreadline.obj `if test -f 'xreadline.c'; then $(CYGPATH_W) 'xreadline.c'; else $(CYGPATH_W) '$(srcdir)/xreadline.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-xreadline.Tpo $(DEPDIR)/libcommon_a-xreadline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xreadline.c' object='libcommon_a-xreadline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-xreadline.obj `if test -f 'xreadline.c'; then $(CYGPATH_W) 'xreadline.c'; else $(CYGPATH_W) '$(srcdir)/xreadline.c'; fi` + +libcommon_a-membuf.o: membuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-membuf.o -MD -MP -MF $(DEPDIR)/libcommon_a-membuf.Tpo -c -o libcommon_a-membuf.o `test -f 'membuf.c' || echo '$(srcdir)/'`membuf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-membuf.Tpo $(DEPDIR)/libcommon_a-membuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='membuf.c' object='libcommon_a-membuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-membuf.o `test -f 'membuf.c' || echo '$(srcdir)/'`membuf.c + +libcommon_a-membuf.obj: membuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-membuf.obj -MD -MP -MF $(DEPDIR)/libcommon_a-membuf.Tpo -c -o libcommon_a-membuf.obj `if test -f 'membuf.c'; then $(CYGPATH_W) 'membuf.c'; else $(CYGPATH_W) '$(srcdir)/membuf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-membuf.Tpo $(DEPDIR)/libcommon_a-membuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='membuf.c' object='libcommon_a-membuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-membuf.obj `if test -f 'membuf.c'; then $(CYGPATH_W) 'membuf.c'; else $(CYGPATH_W) '$(srcdir)/membuf.c'; fi` + +libcommon_a-iobuf.o: iobuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-iobuf.o -MD -MP -MF $(DEPDIR)/libcommon_a-iobuf.Tpo -c -o libcommon_a-iobuf.o `test -f 'iobuf.c' || echo '$(srcdir)/'`iobuf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-iobuf.Tpo $(DEPDIR)/libcommon_a-iobuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iobuf.c' object='libcommon_a-iobuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-iobuf.o `test -f 'iobuf.c' || echo '$(srcdir)/'`iobuf.c + +libcommon_a-iobuf.obj: iobuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-iobuf.obj -MD -MP -MF $(DEPDIR)/libcommon_a-iobuf.Tpo -c -o libcommon_a-iobuf.obj `if test -f 'iobuf.c'; then $(CYGPATH_W) 'iobuf.c'; else $(CYGPATH_W) '$(srcdir)/iobuf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-iobuf.Tpo $(DEPDIR)/libcommon_a-iobuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iobuf.c' object='libcommon_a-iobuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-iobuf.obj `if test -f 'iobuf.c'; then $(CYGPATH_W) 'iobuf.c'; else $(CYGPATH_W) '$(srcdir)/iobuf.c'; fi` + +libcommon_a-ttyio.o: ttyio.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-ttyio.o -MD -MP -MF $(DEPDIR)/libcommon_a-ttyio.Tpo -c -o libcommon_a-ttyio.o `test -f 'ttyio.c' || echo '$(srcdir)/'`ttyio.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-ttyio.Tpo $(DEPDIR)/libcommon_a-ttyio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ttyio.c' object='libcommon_a-ttyio.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-ttyio.o `test -f 'ttyio.c' || echo '$(srcdir)/'`ttyio.c + +libcommon_a-ttyio.obj: ttyio.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-ttyio.obj -MD -MP -MF $(DEPDIR)/libcommon_a-ttyio.Tpo -c -o libcommon_a-ttyio.obj `if test -f 'ttyio.c'; then $(CYGPATH_W) 'ttyio.c'; else $(CYGPATH_W) '$(srcdir)/ttyio.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-ttyio.Tpo $(DEPDIR)/libcommon_a-ttyio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ttyio.c' object='libcommon_a-ttyio.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-ttyio.obj `if test -f 'ttyio.c'; then $(CYGPATH_W) 'ttyio.c'; else $(CYGPATH_W) '$(srcdir)/ttyio.c'; fi` + +libcommon_a-asshelp.o: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-asshelp.o -MD -MP -MF $(DEPDIR)/libcommon_a-asshelp.Tpo -c -o libcommon_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-asshelp.Tpo $(DEPDIR)/libcommon_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libcommon_a-asshelp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c + +libcommon_a-asshelp.obj: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-asshelp.obj -MD -MP -MF $(DEPDIR)/libcommon_a-asshelp.Tpo -c -o libcommon_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-asshelp.Tpo $(DEPDIR)/libcommon_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libcommon_a-asshelp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` + +libcommon_a-exechelp.o: exechelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-exechelp.o -MD -MP -MF $(DEPDIR)/libcommon_a-exechelp.Tpo -c -o libcommon_a-exechelp.o `test -f 'exechelp.c' || echo '$(srcdir)/'`exechelp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-exechelp.Tpo $(DEPDIR)/libcommon_a-exechelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='exechelp.c' object='libcommon_a-exechelp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-exechelp.o `test -f 'exechelp.c' || echo '$(srcdir)/'`exechelp.c + +libcommon_a-exechelp.obj: exechelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-exechelp.obj -MD -MP -MF $(DEPDIR)/libcommon_a-exechelp.Tpo -c -o libcommon_a-exechelp.obj `if test -f 'exechelp.c'; then $(CYGPATH_W) 'exechelp.c'; else $(CYGPATH_W) '$(srcdir)/exechelp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-exechelp.Tpo $(DEPDIR)/libcommon_a-exechelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='exechelp.c' object='libcommon_a-exechelp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-exechelp.obj `if test -f 'exechelp.c'; then $(CYGPATH_W) 'exechelp.c'; else $(CYGPATH_W) '$(srcdir)/exechelp.c'; fi` + +libcommon_a-signal.o: signal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-signal.o -MD -MP -MF $(DEPDIR)/libcommon_a-signal.Tpo -c -o libcommon_a-signal.o `test -f 'signal.c' || echo '$(srcdir)/'`signal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-signal.Tpo $(DEPDIR)/libcommon_a-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signal.c' object='libcommon_a-signal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-signal.o `test -f 'signal.c' || echo '$(srcdir)/'`signal.c + +libcommon_a-signal.obj: signal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-signal.obj -MD -MP -MF $(DEPDIR)/libcommon_a-signal.Tpo -c -o libcommon_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-signal.Tpo $(DEPDIR)/libcommon_a-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signal.c' object='libcommon_a-signal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` + +libcommon_a-estream.o: estream.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-estream.o -MD -MP -MF $(DEPDIR)/libcommon_a-estream.Tpo -c -o libcommon_a-estream.o `test -f 'estream.c' || echo '$(srcdir)/'`estream.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-estream.Tpo $(DEPDIR)/libcommon_a-estream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream.c' object='libcommon_a-estream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-estream.o `test -f 'estream.c' || echo '$(srcdir)/'`estream.c + +libcommon_a-estream.obj: estream.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-estream.obj -MD -MP -MF $(DEPDIR)/libcommon_a-estream.Tpo -c -o libcommon_a-estream.obj `if test -f 'estream.c'; then $(CYGPATH_W) 'estream.c'; else $(CYGPATH_W) '$(srcdir)/estream.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-estream.Tpo $(DEPDIR)/libcommon_a-estream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream.c' object='libcommon_a-estream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-estream.obj `if test -f 'estream.c'; then $(CYGPATH_W) 'estream.c'; else $(CYGPATH_W) '$(srcdir)/estream.c'; fi` + +libcommon_a-estream-printf.o: estream-printf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-estream-printf.o -MD -MP -MF $(DEPDIR)/libcommon_a-estream-printf.Tpo -c -o libcommon_a-estream-printf.o `test -f 'estream-printf.c' || echo '$(srcdir)/'`estream-printf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-estream-printf.Tpo $(DEPDIR)/libcommon_a-estream-printf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream-printf.c' object='libcommon_a-estream-printf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-estream-printf.o `test -f 'estream-printf.c' || echo '$(srcdir)/'`estream-printf.c + +libcommon_a-estream-printf.obj: estream-printf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-estream-printf.obj -MD -MP -MF $(DEPDIR)/libcommon_a-estream-printf.Tpo -c -o libcommon_a-estream-printf.obj `if test -f 'estream-printf.c'; then $(CYGPATH_W) 'estream-printf.c'; else $(CYGPATH_W) '$(srcdir)/estream-printf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-estream-printf.Tpo $(DEPDIR)/libcommon_a-estream-printf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream-printf.c' object='libcommon_a-estream-printf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-estream-printf.obj `if test -f 'estream-printf.c'; then $(CYGPATH_W) 'estream-printf.c'; else $(CYGPATH_W) '$(srcdir)/estream-printf.c'; fi` + +libcommon_a-audit.o: audit.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-audit.o -MD -MP -MF $(DEPDIR)/libcommon_a-audit.Tpo -c -o libcommon_a-audit.o `test -f 'audit.c' || echo '$(srcdir)/'`audit.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-audit.Tpo $(DEPDIR)/libcommon_a-audit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='audit.c' object='libcommon_a-audit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-audit.o `test -f 'audit.c' || echo '$(srcdir)/'`audit.c + +libcommon_a-audit.obj: audit.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-audit.obj -MD -MP -MF $(DEPDIR)/libcommon_a-audit.Tpo -c -o libcommon_a-audit.obj `if test -f 'audit.c'; then $(CYGPATH_W) 'audit.c'; else $(CYGPATH_W) '$(srcdir)/audit.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-audit.Tpo $(DEPDIR)/libcommon_a-audit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='audit.c' object='libcommon_a-audit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-audit.obj `if test -f 'audit.c'; then $(CYGPATH_W) 'audit.c'; else $(CYGPATH_W) '$(srcdir)/audit.c'; fi` + +libcommon_a-dns-cert.o: dns-cert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-dns-cert.o -MD -MP -MF $(DEPDIR)/libcommon_a-dns-cert.Tpo -c -o libcommon_a-dns-cert.o `test -f 'dns-cert.c' || echo '$(srcdir)/'`dns-cert.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-dns-cert.Tpo $(DEPDIR)/libcommon_a-dns-cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns-cert.c' object='libcommon_a-dns-cert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-dns-cert.o `test -f 'dns-cert.c' || echo '$(srcdir)/'`dns-cert.c + +libcommon_a-dns-cert.obj: dns-cert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-dns-cert.obj -MD -MP -MF $(DEPDIR)/libcommon_a-dns-cert.Tpo -c -o libcommon_a-dns-cert.obj `if test -f 'dns-cert.c'; then $(CYGPATH_W) 'dns-cert.c'; else $(CYGPATH_W) '$(srcdir)/dns-cert.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-dns-cert.Tpo $(DEPDIR)/libcommon_a-dns-cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns-cert.c' object='libcommon_a-dns-cert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-dns-cert.obj `if test -f 'dns-cert.c'; then $(CYGPATH_W) 'dns-cert.c'; else $(CYGPATH_W) '$(srcdir)/dns-cert.c'; fi` + +libcommon_a-pka.o: pka.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-pka.o -MD -MP -MF $(DEPDIR)/libcommon_a-pka.Tpo -c -o libcommon_a-pka.o `test -f 'pka.c' || echo '$(srcdir)/'`pka.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-pka.Tpo $(DEPDIR)/libcommon_a-pka.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pka.c' object='libcommon_a-pka.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-pka.o `test -f 'pka.c' || echo '$(srcdir)/'`pka.c + +libcommon_a-pka.obj: pka.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-pka.obj -MD -MP -MF $(DEPDIR)/libcommon_a-pka.Tpo -c -o libcommon_a-pka.obj `if test -f 'pka.c'; then $(CYGPATH_W) 'pka.c'; else $(CYGPATH_W) '$(srcdir)/pka.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-pka.Tpo $(DEPDIR)/libcommon_a-pka.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pka.c' object='libcommon_a-pka.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-pka.obj `if test -f 'pka.c'; then $(CYGPATH_W) 'pka.c'; else $(CYGPATH_W) '$(srcdir)/pka.c'; fi` + +libcommon_a-http.o: http.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-http.o -MD -MP -MF $(DEPDIR)/libcommon_a-http.Tpo -c -o libcommon_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-http.Tpo $(DEPDIR)/libcommon_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http.c' object='libcommon_a-http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c + +libcommon_a-http.obj: http.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-http.obj -MD -MP -MF $(DEPDIR)/libcommon_a-http.Tpo -c -o libcommon_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-http.Tpo $(DEPDIR)/libcommon_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http.c' object='libcommon_a-http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` + +libcommon_a-localename.o: localename.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-localename.o -MD -MP -MF $(DEPDIR)/libcommon_a-localename.Tpo -c -o libcommon_a-localename.o `test -f 'localename.c' || echo '$(srcdir)/'`localename.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-localename.Tpo $(DEPDIR)/libcommon_a-localename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='localename.c' object='libcommon_a-localename.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-localename.o `test -f 'localename.c' || echo '$(srcdir)/'`localename.c + +libcommon_a-localename.obj: localename.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-localename.obj -MD -MP -MF $(DEPDIR)/libcommon_a-localename.Tpo -c -o libcommon_a-localename.obj `if test -f 'localename.c'; then $(CYGPATH_W) 'localename.c'; else $(CYGPATH_W) '$(srcdir)/localename.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-localename.Tpo $(DEPDIR)/libcommon_a-localename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='localename.c' object='libcommon_a-localename.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-localename.obj `if test -f 'localename.c'; then $(CYGPATH_W) 'localename.c'; else $(CYGPATH_W) '$(srcdir)/localename.c'; fi` + +libcommon_a-session-env.o: session-env.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-session-env.o -MD -MP -MF $(DEPDIR)/libcommon_a-session-env.Tpo -c -o libcommon_a-session-env.o `test -f 'session-env.c' || echo '$(srcdir)/'`session-env.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-session-env.Tpo $(DEPDIR)/libcommon_a-session-env.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='session-env.c' object='libcommon_a-session-env.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-session-env.o `test -f 'session-env.c' || echo '$(srcdir)/'`session-env.c + +libcommon_a-session-env.obj: session-env.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-session-env.obj -MD -MP -MF $(DEPDIR)/libcommon_a-session-env.Tpo -c -o libcommon_a-session-env.obj `if test -f 'session-env.c'; then $(CYGPATH_W) 'session-env.c'; else $(CYGPATH_W) '$(srcdir)/session-env.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-session-env.Tpo $(DEPDIR)/libcommon_a-session-env.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='session-env.c' object='libcommon_a-session-env.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-session-env.obj `if test -f 'session-env.c'; then $(CYGPATH_W) 'session-env.c'; else $(CYGPATH_W) '$(srcdir)/session-env.c'; fi` + +libcommon_a-ssh-utils.o: ssh-utils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-ssh-utils.o -MD -MP -MF $(DEPDIR)/libcommon_a-ssh-utils.Tpo -c -o libcommon_a-ssh-utils.o `test -f 'ssh-utils.c' || echo '$(srcdir)/'`ssh-utils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-ssh-utils.Tpo $(DEPDIR)/libcommon_a-ssh-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssh-utils.c' object='libcommon_a-ssh-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-ssh-utils.o `test -f 'ssh-utils.c' || echo '$(srcdir)/'`ssh-utils.c + +libcommon_a-ssh-utils.obj: ssh-utils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-ssh-utils.obj -MD -MP -MF $(DEPDIR)/libcommon_a-ssh-utils.Tpo -c -o libcommon_a-ssh-utils.obj `if test -f 'ssh-utils.c'; then $(CYGPATH_W) 'ssh-utils.c'; else $(CYGPATH_W) '$(srcdir)/ssh-utils.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-ssh-utils.Tpo $(DEPDIR)/libcommon_a-ssh-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssh-utils.c' object='libcommon_a-ssh-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-ssh-utils.obj `if test -f 'ssh-utils.c'; then $(CYGPATH_W) 'ssh-utils.c'; else $(CYGPATH_W) '$(srcdir)/ssh-utils.c'; fi` + +libcommon_a-helpfile.o: helpfile.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-helpfile.o -MD -MP -MF $(DEPDIR)/libcommon_a-helpfile.Tpo -c -o libcommon_a-helpfile.o `test -f 'helpfile.c' || echo '$(srcdir)/'`helpfile.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-helpfile.Tpo $(DEPDIR)/libcommon_a-helpfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpfile.c' object='libcommon_a-helpfile.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-helpfile.o `test -f 'helpfile.c' || echo '$(srcdir)/'`helpfile.c + +libcommon_a-helpfile.obj: helpfile.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-helpfile.obj -MD -MP -MF $(DEPDIR)/libcommon_a-helpfile.Tpo -c -o libcommon_a-helpfile.obj `if test -f 'helpfile.c'; then $(CYGPATH_W) 'helpfile.c'; else $(CYGPATH_W) '$(srcdir)/helpfile.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-helpfile.Tpo $(DEPDIR)/libcommon_a-helpfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpfile.c' object='libcommon_a-helpfile.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-helpfile.obj `if test -f 'helpfile.c'; then $(CYGPATH_W) 'helpfile.c'; else $(CYGPATH_W) '$(srcdir)/helpfile.c'; fi` + +libcommon_a-get-passphrase.o: get-passphrase.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-get-passphrase.o -MD -MP -MF $(DEPDIR)/libcommon_a-get-passphrase.Tpo -c -o libcommon_a-get-passphrase.o `test -f 'get-passphrase.c' || echo '$(srcdir)/'`get-passphrase.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-get-passphrase.Tpo $(DEPDIR)/libcommon_a-get-passphrase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='get-passphrase.c' object='libcommon_a-get-passphrase.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-get-passphrase.o `test -f 'get-passphrase.c' || echo '$(srcdir)/'`get-passphrase.c + +libcommon_a-get-passphrase.obj: get-passphrase.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-get-passphrase.obj -MD -MP -MF $(DEPDIR)/libcommon_a-get-passphrase.Tpo -c -o libcommon_a-get-passphrase.obj `if test -f 'get-passphrase.c'; then $(CYGPATH_W) 'get-passphrase.c'; else $(CYGPATH_W) '$(srcdir)/get-passphrase.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-get-passphrase.Tpo $(DEPDIR)/libcommon_a-get-passphrase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='get-passphrase.c' object='libcommon_a-get-passphrase.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-get-passphrase.obj `if test -f 'get-passphrase.c'; then $(CYGPATH_W) 'get-passphrase.c'; else $(CYGPATH_W) '$(srcdir)/get-passphrase.c'; fi` + +libcommon_a-srv.o: srv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-srv.o -MD -MP -MF $(DEPDIR)/libcommon_a-srv.Tpo -c -o libcommon_a-srv.o `test -f 'srv.c' || echo '$(srcdir)/'`srv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-srv.Tpo $(DEPDIR)/libcommon_a-srv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv.c' object='libcommon_a-srv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-srv.o `test -f 'srv.c' || echo '$(srcdir)/'`srv.c + +libcommon_a-srv.obj: srv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -MT libcommon_a-srv.obj -MD -MP -MF $(DEPDIR)/libcommon_a-srv.Tpo -c -o libcommon_a-srv.obj `if test -f 'srv.c'; then $(CYGPATH_W) 'srv.c'; else $(CYGPATH_W) '$(srcdir)/srv.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_a-srv.Tpo $(DEPDIR)/libcommon_a-srv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv.c' object='libcommon_a-srv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommon_a_CFLAGS) $(CFLAGS) -c -o libcommon_a-srv.obj `if test -f 'srv.c'; then $(CYGPATH_W) 'srv.c'; else $(CYGPATH_W) '$(srcdir)/srv.c'; fi` + +libcommonpth_a-i18n.o: i18n.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-i18n.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-i18n.Tpo -c -o libcommonpth_a-i18n.o `test -f 'i18n.c' || echo '$(srcdir)/'`i18n.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-i18n.Tpo $(DEPDIR)/libcommonpth_a-i18n.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i18n.c' object='libcommonpth_a-i18n.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-i18n.o `test -f 'i18n.c' || echo '$(srcdir)/'`i18n.c + +libcommonpth_a-i18n.obj: i18n.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-i18n.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-i18n.Tpo -c -o libcommonpth_a-i18n.obj `if test -f 'i18n.c'; then $(CYGPATH_W) 'i18n.c'; else $(CYGPATH_W) '$(srcdir)/i18n.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-i18n.Tpo $(DEPDIR)/libcommonpth_a-i18n.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i18n.c' object='libcommonpth_a-i18n.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-i18n.obj `if test -f 'i18n.c'; then $(CYGPATH_W) 'i18n.c'; else $(CYGPATH_W) '$(srcdir)/i18n.c'; fi` + +libcommonpth_a-status.o: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-status.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-status.Tpo -c -o libcommonpth_a-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-status.Tpo $(DEPDIR)/libcommonpth_a-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='libcommonpth_a-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c + +libcommonpth_a-status.obj: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-status.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-status.Tpo -c -o libcommonpth_a-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-status.Tpo $(DEPDIR)/libcommonpth_a-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='libcommonpth_a-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` + +libcommonpth_a-tlv.o: tlv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-tlv.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-tlv.Tpo -c -o libcommonpth_a-tlv.o `test -f 'tlv.c' || echo '$(srcdir)/'`tlv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-tlv.Tpo $(DEPDIR)/libcommonpth_a-tlv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlv.c' object='libcommonpth_a-tlv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-tlv.o `test -f 'tlv.c' || echo '$(srcdir)/'`tlv.c + +libcommonpth_a-tlv.obj: tlv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-tlv.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-tlv.Tpo -c -o libcommonpth_a-tlv.obj `if test -f 'tlv.c'; then $(CYGPATH_W) 'tlv.c'; else $(CYGPATH_W) '$(srcdir)/tlv.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-tlv.Tpo $(DEPDIR)/libcommonpth_a-tlv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlv.c' object='libcommonpth_a-tlv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-tlv.obj `if test -f 'tlv.c'; then $(CYGPATH_W) 'tlv.c'; else $(CYGPATH_W) '$(srcdir)/tlv.c'; fi` + +libcommonpth_a-init.o: init.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-init.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-init.Tpo -c -o libcommonpth_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-init.Tpo $(DEPDIR)/libcommonpth_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='init.c' object='libcommonpth_a-init.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-init.o `test -f 'init.c' || echo '$(srcdir)/'`init.c + +libcommonpth_a-init.obj: init.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-init.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-init.Tpo -c -o libcommonpth_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-init.Tpo $(DEPDIR)/libcommonpth_a-init.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='init.c' object='libcommonpth_a-init.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-init.obj `if test -f 'init.c'; then $(CYGPATH_W) 'init.c'; else $(CYGPATH_W) '$(srcdir)/init.c'; fi` + +libcommonpth_a-sexputil.o: sexputil.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-sexputil.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-sexputil.Tpo -c -o libcommonpth_a-sexputil.o `test -f 'sexputil.c' || echo '$(srcdir)/'`sexputil.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-sexputil.Tpo $(DEPDIR)/libcommonpth_a-sexputil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sexputil.c' object='libcommonpth_a-sexputil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-sexputil.o `test -f 'sexputil.c' || echo '$(srcdir)/'`sexputil.c + +libcommonpth_a-sexputil.obj: sexputil.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-sexputil.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-sexputil.Tpo -c -o libcommonpth_a-sexputil.obj `if test -f 'sexputil.c'; then $(CYGPATH_W) 'sexputil.c'; else $(CYGPATH_W) '$(srcdir)/sexputil.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-sexputil.Tpo $(DEPDIR)/libcommonpth_a-sexputil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sexputil.c' object='libcommonpth_a-sexputil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-sexputil.obj `if test -f 'sexputil.c'; then $(CYGPATH_W) 'sexputil.c'; else $(CYGPATH_W) '$(srcdir)/sexputil.c'; fi` + +libcommonpth_a-sysutils.o: sysutils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-sysutils.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-sysutils.Tpo -c -o libcommonpth_a-sysutils.o `test -f 'sysutils.c' || echo '$(srcdir)/'`sysutils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-sysutils.Tpo $(DEPDIR)/libcommonpth_a-sysutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sysutils.c' object='libcommonpth_a-sysutils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-sysutils.o `test -f 'sysutils.c' || echo '$(srcdir)/'`sysutils.c + +libcommonpth_a-sysutils.obj: sysutils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-sysutils.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-sysutils.Tpo -c -o libcommonpth_a-sysutils.obj `if test -f 'sysutils.c'; then $(CYGPATH_W) 'sysutils.c'; else $(CYGPATH_W) '$(srcdir)/sysutils.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-sysutils.Tpo $(DEPDIR)/libcommonpth_a-sysutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sysutils.c' object='libcommonpth_a-sysutils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-sysutils.obj `if test -f 'sysutils.c'; then $(CYGPATH_W) 'sysutils.c'; else $(CYGPATH_W) '$(srcdir)/sysutils.c'; fi` + +libcommonpth_a-homedir.o: homedir.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-homedir.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-homedir.Tpo -c -o libcommonpth_a-homedir.o `test -f 'homedir.c' || echo '$(srcdir)/'`homedir.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-homedir.Tpo $(DEPDIR)/libcommonpth_a-homedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='homedir.c' object='libcommonpth_a-homedir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-homedir.o `test -f 'homedir.c' || echo '$(srcdir)/'`homedir.c + +libcommonpth_a-homedir.obj: homedir.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-homedir.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-homedir.Tpo -c -o libcommonpth_a-homedir.obj `if test -f 'homedir.c'; then $(CYGPATH_W) 'homedir.c'; else $(CYGPATH_W) '$(srcdir)/homedir.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-homedir.Tpo $(DEPDIR)/libcommonpth_a-homedir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='homedir.c' object='libcommonpth_a-homedir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-homedir.obj `if test -f 'homedir.c'; then $(CYGPATH_W) 'homedir.c'; else $(CYGPATH_W) '$(srcdir)/homedir.c'; fi` + +libcommonpth_a-gettime.o: gettime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-gettime.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-gettime.Tpo -c -o libcommonpth_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-gettime.Tpo $(DEPDIR)/libcommonpth_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gettime.c' object='libcommonpth_a-gettime.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-gettime.o `test -f 'gettime.c' || echo '$(srcdir)/'`gettime.c + +libcommonpth_a-gettime.obj: gettime.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-gettime.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-gettime.Tpo -c -o libcommonpth_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-gettime.Tpo $(DEPDIR)/libcommonpth_a-gettime.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gettime.c' object='libcommonpth_a-gettime.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-gettime.obj `if test -f 'gettime.c'; then $(CYGPATH_W) 'gettime.c'; else $(CYGPATH_W) '$(srcdir)/gettime.c'; fi` + +libcommonpth_a-yesno.o: yesno.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-yesno.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-yesno.Tpo -c -o libcommonpth_a-yesno.o `test -f 'yesno.c' || echo '$(srcdir)/'`yesno.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-yesno.Tpo $(DEPDIR)/libcommonpth_a-yesno.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='yesno.c' object='libcommonpth_a-yesno.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-yesno.o `test -f 'yesno.c' || echo '$(srcdir)/'`yesno.c + +libcommonpth_a-yesno.obj: yesno.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-yesno.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-yesno.Tpo -c -o libcommonpth_a-yesno.obj `if test -f 'yesno.c'; then $(CYGPATH_W) 'yesno.c'; else $(CYGPATH_W) '$(srcdir)/yesno.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-yesno.Tpo $(DEPDIR)/libcommonpth_a-yesno.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='yesno.c' object='libcommonpth_a-yesno.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-yesno.obj `if test -f 'yesno.c'; then $(CYGPATH_W) 'yesno.c'; else $(CYGPATH_W) '$(srcdir)/yesno.c'; fi` + +libcommonpth_a-b64enc.o: b64enc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-b64enc.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-b64enc.Tpo -c -o libcommonpth_a-b64enc.o `test -f 'b64enc.c' || echo '$(srcdir)/'`b64enc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-b64enc.Tpo $(DEPDIR)/libcommonpth_a-b64enc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64enc.c' object='libcommonpth_a-b64enc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-b64enc.o `test -f 'b64enc.c' || echo '$(srcdir)/'`b64enc.c + +libcommonpth_a-b64enc.obj: b64enc.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-b64enc.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-b64enc.Tpo -c -o libcommonpth_a-b64enc.obj `if test -f 'b64enc.c'; then $(CYGPATH_W) 'b64enc.c'; else $(CYGPATH_W) '$(srcdir)/b64enc.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-b64enc.Tpo $(DEPDIR)/libcommonpth_a-b64enc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64enc.c' object='libcommonpth_a-b64enc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-b64enc.obj `if test -f 'b64enc.c'; then $(CYGPATH_W) 'b64enc.c'; else $(CYGPATH_W) '$(srcdir)/b64enc.c'; fi` + +libcommonpth_a-b64dec.o: b64dec.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-b64dec.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-b64dec.Tpo -c -o libcommonpth_a-b64dec.o `test -f 'b64dec.c' || echo '$(srcdir)/'`b64dec.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-b64dec.Tpo $(DEPDIR)/libcommonpth_a-b64dec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64dec.c' object='libcommonpth_a-b64dec.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-b64dec.o `test -f 'b64dec.c' || echo '$(srcdir)/'`b64dec.c + +libcommonpth_a-b64dec.obj: b64dec.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-b64dec.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-b64dec.Tpo -c -o libcommonpth_a-b64dec.obj `if test -f 'b64dec.c'; then $(CYGPATH_W) 'b64dec.c'; else $(CYGPATH_W) '$(srcdir)/b64dec.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-b64dec.Tpo $(DEPDIR)/libcommonpth_a-b64dec.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='b64dec.c' object='libcommonpth_a-b64dec.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-b64dec.obj `if test -f 'b64dec.c'; then $(CYGPATH_W) 'b64dec.c'; else $(CYGPATH_W) '$(srcdir)/b64dec.c'; fi` + +libcommonpth_a-convert.o: convert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-convert.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-convert.Tpo -c -o libcommonpth_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-convert.Tpo $(DEPDIR)/libcommonpth_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='convert.c' object='libcommonpth_a-convert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-convert.o `test -f 'convert.c' || echo '$(srcdir)/'`convert.c + +libcommonpth_a-convert.obj: convert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-convert.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-convert.Tpo -c -o libcommonpth_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-convert.Tpo $(DEPDIR)/libcommonpth_a-convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='convert.c' object='libcommonpth_a-convert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-convert.obj `if test -f 'convert.c'; then $(CYGPATH_W) 'convert.c'; else $(CYGPATH_W) '$(srcdir)/convert.c'; fi` + +libcommonpth_a-percent.o: percent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-percent.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-percent.Tpo -c -o libcommonpth_a-percent.o `test -f 'percent.c' || echo '$(srcdir)/'`percent.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-percent.Tpo $(DEPDIR)/libcommonpth_a-percent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='percent.c' object='libcommonpth_a-percent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-percent.o `test -f 'percent.c' || echo '$(srcdir)/'`percent.c + +libcommonpth_a-percent.obj: percent.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-percent.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-percent.Tpo -c -o libcommonpth_a-percent.obj `if test -f 'percent.c'; then $(CYGPATH_W) 'percent.c'; else $(CYGPATH_W) '$(srcdir)/percent.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-percent.Tpo $(DEPDIR)/libcommonpth_a-percent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='percent.c' object='libcommonpth_a-percent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-percent.obj `if test -f 'percent.c'; then $(CYGPATH_W) 'percent.c'; else $(CYGPATH_W) '$(srcdir)/percent.c'; fi` + +libcommonpth_a-miscellaneous.o: miscellaneous.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-miscellaneous.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-miscellaneous.Tpo -c -o libcommonpth_a-miscellaneous.o `test -f 'miscellaneous.c' || echo '$(srcdir)/'`miscellaneous.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-miscellaneous.Tpo $(DEPDIR)/libcommonpth_a-miscellaneous.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='miscellaneous.c' object='libcommonpth_a-miscellaneous.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-miscellaneous.o `test -f 'miscellaneous.c' || echo '$(srcdir)/'`miscellaneous.c + +libcommonpth_a-miscellaneous.obj: miscellaneous.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-miscellaneous.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-miscellaneous.Tpo -c -o libcommonpth_a-miscellaneous.obj `if test -f 'miscellaneous.c'; then $(CYGPATH_W) 'miscellaneous.c'; else $(CYGPATH_W) '$(srcdir)/miscellaneous.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-miscellaneous.Tpo $(DEPDIR)/libcommonpth_a-miscellaneous.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='miscellaneous.c' object='libcommonpth_a-miscellaneous.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-miscellaneous.obj `if test -f 'miscellaneous.c'; then $(CYGPATH_W) 'miscellaneous.c'; else $(CYGPATH_W) '$(srcdir)/miscellaneous.c'; fi` + +libcommonpth_a-xasprintf.o: xasprintf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-xasprintf.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-xasprintf.Tpo -c -o libcommonpth_a-xasprintf.o `test -f 'xasprintf.c' || echo '$(srcdir)/'`xasprintf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-xasprintf.Tpo $(DEPDIR)/libcommonpth_a-xasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xasprintf.c' object='libcommonpth_a-xasprintf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-xasprintf.o `test -f 'xasprintf.c' || echo '$(srcdir)/'`xasprintf.c + +libcommonpth_a-xasprintf.obj: xasprintf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-xasprintf.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-xasprintf.Tpo -c -o libcommonpth_a-xasprintf.obj `if test -f 'xasprintf.c'; then $(CYGPATH_W) 'xasprintf.c'; else $(CYGPATH_W) '$(srcdir)/xasprintf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-xasprintf.Tpo $(DEPDIR)/libcommonpth_a-xasprintf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xasprintf.c' object='libcommonpth_a-xasprintf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-xasprintf.obj `if test -f 'xasprintf.c'; then $(CYGPATH_W) 'xasprintf.c'; else $(CYGPATH_W) '$(srcdir)/xasprintf.c'; fi` + +libcommonpth_a-xreadline.o: xreadline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-xreadline.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-xreadline.Tpo -c -o libcommonpth_a-xreadline.o `test -f 'xreadline.c' || echo '$(srcdir)/'`xreadline.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-xreadline.Tpo $(DEPDIR)/libcommonpth_a-xreadline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xreadline.c' object='libcommonpth_a-xreadline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-xreadline.o `test -f 'xreadline.c' || echo '$(srcdir)/'`xreadline.c + +libcommonpth_a-xreadline.obj: xreadline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-xreadline.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-xreadline.Tpo -c -o libcommonpth_a-xreadline.obj `if test -f 'xreadline.c'; then $(CYGPATH_W) 'xreadline.c'; else $(CYGPATH_W) '$(srcdir)/xreadline.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-xreadline.Tpo $(DEPDIR)/libcommonpth_a-xreadline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xreadline.c' object='libcommonpth_a-xreadline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-xreadline.obj `if test -f 'xreadline.c'; then $(CYGPATH_W) 'xreadline.c'; else $(CYGPATH_W) '$(srcdir)/xreadline.c'; fi` + +libcommonpth_a-membuf.o: membuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-membuf.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-membuf.Tpo -c -o libcommonpth_a-membuf.o `test -f 'membuf.c' || echo '$(srcdir)/'`membuf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-membuf.Tpo $(DEPDIR)/libcommonpth_a-membuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='membuf.c' object='libcommonpth_a-membuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-membuf.o `test -f 'membuf.c' || echo '$(srcdir)/'`membuf.c + +libcommonpth_a-membuf.obj: membuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-membuf.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-membuf.Tpo -c -o libcommonpth_a-membuf.obj `if test -f 'membuf.c'; then $(CYGPATH_W) 'membuf.c'; else $(CYGPATH_W) '$(srcdir)/membuf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-membuf.Tpo $(DEPDIR)/libcommonpth_a-membuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='membuf.c' object='libcommonpth_a-membuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-membuf.obj `if test -f 'membuf.c'; then $(CYGPATH_W) 'membuf.c'; else $(CYGPATH_W) '$(srcdir)/membuf.c'; fi` + +libcommonpth_a-iobuf.o: iobuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-iobuf.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-iobuf.Tpo -c -o libcommonpth_a-iobuf.o `test -f 'iobuf.c' || echo '$(srcdir)/'`iobuf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-iobuf.Tpo $(DEPDIR)/libcommonpth_a-iobuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iobuf.c' object='libcommonpth_a-iobuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-iobuf.o `test -f 'iobuf.c' || echo '$(srcdir)/'`iobuf.c + +libcommonpth_a-iobuf.obj: iobuf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-iobuf.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-iobuf.Tpo -c -o libcommonpth_a-iobuf.obj `if test -f 'iobuf.c'; then $(CYGPATH_W) 'iobuf.c'; else $(CYGPATH_W) '$(srcdir)/iobuf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-iobuf.Tpo $(DEPDIR)/libcommonpth_a-iobuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iobuf.c' object='libcommonpth_a-iobuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-iobuf.obj `if test -f 'iobuf.c'; then $(CYGPATH_W) 'iobuf.c'; else $(CYGPATH_W) '$(srcdir)/iobuf.c'; fi` + +libcommonpth_a-ttyio.o: ttyio.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-ttyio.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-ttyio.Tpo -c -o libcommonpth_a-ttyio.o `test -f 'ttyio.c' || echo '$(srcdir)/'`ttyio.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-ttyio.Tpo $(DEPDIR)/libcommonpth_a-ttyio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ttyio.c' object='libcommonpth_a-ttyio.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-ttyio.o `test -f 'ttyio.c' || echo '$(srcdir)/'`ttyio.c + +libcommonpth_a-ttyio.obj: ttyio.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-ttyio.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-ttyio.Tpo -c -o libcommonpth_a-ttyio.obj `if test -f 'ttyio.c'; then $(CYGPATH_W) 'ttyio.c'; else $(CYGPATH_W) '$(srcdir)/ttyio.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-ttyio.Tpo $(DEPDIR)/libcommonpth_a-ttyio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ttyio.c' object='libcommonpth_a-ttyio.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-ttyio.obj `if test -f 'ttyio.c'; then $(CYGPATH_W) 'ttyio.c'; else $(CYGPATH_W) '$(srcdir)/ttyio.c'; fi` + +libcommonpth_a-asshelp.o: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-asshelp.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-asshelp.Tpo -c -o libcommonpth_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-asshelp.Tpo $(DEPDIR)/libcommonpth_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libcommonpth_a-asshelp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c + +libcommonpth_a-asshelp.obj: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-asshelp.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-asshelp.Tpo -c -o libcommonpth_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-asshelp.Tpo $(DEPDIR)/libcommonpth_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libcommonpth_a-asshelp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` + +libcommonpth_a-exechelp.o: exechelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-exechelp.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-exechelp.Tpo -c -o libcommonpth_a-exechelp.o `test -f 'exechelp.c' || echo '$(srcdir)/'`exechelp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-exechelp.Tpo $(DEPDIR)/libcommonpth_a-exechelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='exechelp.c' object='libcommonpth_a-exechelp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-exechelp.o `test -f 'exechelp.c' || echo '$(srcdir)/'`exechelp.c + +libcommonpth_a-exechelp.obj: exechelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-exechelp.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-exechelp.Tpo -c -o libcommonpth_a-exechelp.obj `if test -f 'exechelp.c'; then $(CYGPATH_W) 'exechelp.c'; else $(CYGPATH_W) '$(srcdir)/exechelp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-exechelp.Tpo $(DEPDIR)/libcommonpth_a-exechelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='exechelp.c' object='libcommonpth_a-exechelp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-exechelp.obj `if test -f 'exechelp.c'; then $(CYGPATH_W) 'exechelp.c'; else $(CYGPATH_W) '$(srcdir)/exechelp.c'; fi` + +libcommonpth_a-signal.o: signal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-signal.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-signal.Tpo -c -o libcommonpth_a-signal.o `test -f 'signal.c' || echo '$(srcdir)/'`signal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-signal.Tpo $(DEPDIR)/libcommonpth_a-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signal.c' object='libcommonpth_a-signal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-signal.o `test -f 'signal.c' || echo '$(srcdir)/'`signal.c + +libcommonpth_a-signal.obj: signal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-signal.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-signal.Tpo -c -o libcommonpth_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-signal.Tpo $(DEPDIR)/libcommonpth_a-signal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='signal.c' object='libcommonpth_a-signal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` + +libcommonpth_a-estream.o: estream.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-estream.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-estream.Tpo -c -o libcommonpth_a-estream.o `test -f 'estream.c' || echo '$(srcdir)/'`estream.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-estream.Tpo $(DEPDIR)/libcommonpth_a-estream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream.c' object='libcommonpth_a-estream.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-estream.o `test -f 'estream.c' || echo '$(srcdir)/'`estream.c + +libcommonpth_a-estream.obj: estream.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-estream.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-estream.Tpo -c -o libcommonpth_a-estream.obj `if test -f 'estream.c'; then $(CYGPATH_W) 'estream.c'; else $(CYGPATH_W) '$(srcdir)/estream.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-estream.Tpo $(DEPDIR)/libcommonpth_a-estream.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream.c' object='libcommonpth_a-estream.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-estream.obj `if test -f 'estream.c'; then $(CYGPATH_W) 'estream.c'; else $(CYGPATH_W) '$(srcdir)/estream.c'; fi` + +libcommonpth_a-estream-printf.o: estream-printf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-estream-printf.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-estream-printf.Tpo -c -o libcommonpth_a-estream-printf.o `test -f 'estream-printf.c' || echo '$(srcdir)/'`estream-printf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-estream-printf.Tpo $(DEPDIR)/libcommonpth_a-estream-printf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream-printf.c' object='libcommonpth_a-estream-printf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-estream-printf.o `test -f 'estream-printf.c' || echo '$(srcdir)/'`estream-printf.c + +libcommonpth_a-estream-printf.obj: estream-printf.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-estream-printf.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-estream-printf.Tpo -c -o libcommonpth_a-estream-printf.obj `if test -f 'estream-printf.c'; then $(CYGPATH_W) 'estream-printf.c'; else $(CYGPATH_W) '$(srcdir)/estream-printf.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-estream-printf.Tpo $(DEPDIR)/libcommonpth_a-estream-printf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='estream-printf.c' object='libcommonpth_a-estream-printf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-estream-printf.obj `if test -f 'estream-printf.c'; then $(CYGPATH_W) 'estream-printf.c'; else $(CYGPATH_W) '$(srcdir)/estream-printf.c'; fi` + +libcommonpth_a-audit.o: audit.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-audit.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-audit.Tpo -c -o libcommonpth_a-audit.o `test -f 'audit.c' || echo '$(srcdir)/'`audit.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-audit.Tpo $(DEPDIR)/libcommonpth_a-audit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='audit.c' object='libcommonpth_a-audit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-audit.o `test -f 'audit.c' || echo '$(srcdir)/'`audit.c + +libcommonpth_a-audit.obj: audit.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-audit.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-audit.Tpo -c -o libcommonpth_a-audit.obj `if test -f 'audit.c'; then $(CYGPATH_W) 'audit.c'; else $(CYGPATH_W) '$(srcdir)/audit.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-audit.Tpo $(DEPDIR)/libcommonpth_a-audit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='audit.c' object='libcommonpth_a-audit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-audit.obj `if test -f 'audit.c'; then $(CYGPATH_W) 'audit.c'; else $(CYGPATH_W) '$(srcdir)/audit.c'; fi` + +libcommonpth_a-dns-cert.o: dns-cert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-dns-cert.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-dns-cert.Tpo -c -o libcommonpth_a-dns-cert.o `test -f 'dns-cert.c' || echo '$(srcdir)/'`dns-cert.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-dns-cert.Tpo $(DEPDIR)/libcommonpth_a-dns-cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns-cert.c' object='libcommonpth_a-dns-cert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-dns-cert.o `test -f 'dns-cert.c' || echo '$(srcdir)/'`dns-cert.c + +libcommonpth_a-dns-cert.obj: dns-cert.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-dns-cert.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-dns-cert.Tpo -c -o libcommonpth_a-dns-cert.obj `if test -f 'dns-cert.c'; then $(CYGPATH_W) 'dns-cert.c'; else $(CYGPATH_W) '$(srcdir)/dns-cert.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-dns-cert.Tpo $(DEPDIR)/libcommonpth_a-dns-cert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns-cert.c' object='libcommonpth_a-dns-cert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-dns-cert.obj `if test -f 'dns-cert.c'; then $(CYGPATH_W) 'dns-cert.c'; else $(CYGPATH_W) '$(srcdir)/dns-cert.c'; fi` + +libcommonpth_a-pka.o: pka.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-pka.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-pka.Tpo -c -o libcommonpth_a-pka.o `test -f 'pka.c' || echo '$(srcdir)/'`pka.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-pka.Tpo $(DEPDIR)/libcommonpth_a-pka.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pka.c' object='libcommonpth_a-pka.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-pka.o `test -f 'pka.c' || echo '$(srcdir)/'`pka.c + +libcommonpth_a-pka.obj: pka.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-pka.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-pka.Tpo -c -o libcommonpth_a-pka.obj `if test -f 'pka.c'; then $(CYGPATH_W) 'pka.c'; else $(CYGPATH_W) '$(srcdir)/pka.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-pka.Tpo $(DEPDIR)/libcommonpth_a-pka.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pka.c' object='libcommonpth_a-pka.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-pka.obj `if test -f 'pka.c'; then $(CYGPATH_W) 'pka.c'; else $(CYGPATH_W) '$(srcdir)/pka.c'; fi` + +libcommonpth_a-http.o: http.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-http.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-http.Tpo -c -o libcommonpth_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-http.Tpo $(DEPDIR)/libcommonpth_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http.c' object='libcommonpth_a-http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c + +libcommonpth_a-http.obj: http.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-http.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-http.Tpo -c -o libcommonpth_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-http.Tpo $(DEPDIR)/libcommonpth_a-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http.c' object='libcommonpth_a-http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` + +libcommonpth_a-localename.o: localename.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-localename.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-localename.Tpo -c -o libcommonpth_a-localename.o `test -f 'localename.c' || echo '$(srcdir)/'`localename.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-localename.Tpo $(DEPDIR)/libcommonpth_a-localename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='localename.c' object='libcommonpth_a-localename.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-localename.o `test -f 'localename.c' || echo '$(srcdir)/'`localename.c + +libcommonpth_a-localename.obj: localename.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-localename.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-localename.Tpo -c -o libcommonpth_a-localename.obj `if test -f 'localename.c'; then $(CYGPATH_W) 'localename.c'; else $(CYGPATH_W) '$(srcdir)/localename.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-localename.Tpo $(DEPDIR)/libcommonpth_a-localename.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='localename.c' object='libcommonpth_a-localename.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-localename.obj `if test -f 'localename.c'; then $(CYGPATH_W) 'localename.c'; else $(CYGPATH_W) '$(srcdir)/localename.c'; fi` + +libcommonpth_a-session-env.o: session-env.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-session-env.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-session-env.Tpo -c -o libcommonpth_a-session-env.o `test -f 'session-env.c' || echo '$(srcdir)/'`session-env.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-session-env.Tpo $(DEPDIR)/libcommonpth_a-session-env.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='session-env.c' object='libcommonpth_a-session-env.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-session-env.o `test -f 'session-env.c' || echo '$(srcdir)/'`session-env.c + +libcommonpth_a-session-env.obj: session-env.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-session-env.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-session-env.Tpo -c -o libcommonpth_a-session-env.obj `if test -f 'session-env.c'; then $(CYGPATH_W) 'session-env.c'; else $(CYGPATH_W) '$(srcdir)/session-env.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-session-env.Tpo $(DEPDIR)/libcommonpth_a-session-env.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='session-env.c' object='libcommonpth_a-session-env.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-session-env.obj `if test -f 'session-env.c'; then $(CYGPATH_W) 'session-env.c'; else $(CYGPATH_W) '$(srcdir)/session-env.c'; fi` + +libcommonpth_a-ssh-utils.o: ssh-utils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-ssh-utils.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-ssh-utils.Tpo -c -o libcommonpth_a-ssh-utils.o `test -f 'ssh-utils.c' || echo '$(srcdir)/'`ssh-utils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-ssh-utils.Tpo $(DEPDIR)/libcommonpth_a-ssh-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssh-utils.c' object='libcommonpth_a-ssh-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-ssh-utils.o `test -f 'ssh-utils.c' || echo '$(srcdir)/'`ssh-utils.c + +libcommonpth_a-ssh-utils.obj: ssh-utils.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-ssh-utils.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-ssh-utils.Tpo -c -o libcommonpth_a-ssh-utils.obj `if test -f 'ssh-utils.c'; then $(CYGPATH_W) 'ssh-utils.c'; else $(CYGPATH_W) '$(srcdir)/ssh-utils.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-ssh-utils.Tpo $(DEPDIR)/libcommonpth_a-ssh-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssh-utils.c' object='libcommonpth_a-ssh-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-ssh-utils.obj `if test -f 'ssh-utils.c'; then $(CYGPATH_W) 'ssh-utils.c'; else $(CYGPATH_W) '$(srcdir)/ssh-utils.c'; fi` + +libcommonpth_a-helpfile.o: helpfile.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-helpfile.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-helpfile.Tpo -c -o libcommonpth_a-helpfile.o `test -f 'helpfile.c' || echo '$(srcdir)/'`helpfile.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-helpfile.Tpo $(DEPDIR)/libcommonpth_a-helpfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpfile.c' object='libcommonpth_a-helpfile.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-helpfile.o `test -f 'helpfile.c' || echo '$(srcdir)/'`helpfile.c + +libcommonpth_a-helpfile.obj: helpfile.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-helpfile.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-helpfile.Tpo -c -o libcommonpth_a-helpfile.obj `if test -f 'helpfile.c'; then $(CYGPATH_W) 'helpfile.c'; else $(CYGPATH_W) '$(srcdir)/helpfile.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-helpfile.Tpo $(DEPDIR)/libcommonpth_a-helpfile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpfile.c' object='libcommonpth_a-helpfile.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-helpfile.obj `if test -f 'helpfile.c'; then $(CYGPATH_W) 'helpfile.c'; else $(CYGPATH_W) '$(srcdir)/helpfile.c'; fi` + +libcommonpth_a-srv.o: srv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-srv.o -MD -MP -MF $(DEPDIR)/libcommonpth_a-srv.Tpo -c -o libcommonpth_a-srv.o `test -f 'srv.c' || echo '$(srcdir)/'`srv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-srv.Tpo $(DEPDIR)/libcommonpth_a-srv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv.c' object='libcommonpth_a-srv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-srv.o `test -f 'srv.c' || echo '$(srcdir)/'`srv.c + +libcommonpth_a-srv.obj: srv.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -MT libcommonpth_a-srv.obj -MD -MP -MF $(DEPDIR)/libcommonpth_a-srv.Tpo -c -o libcommonpth_a-srv.obj `if test -f 'srv.c'; then $(CYGPATH_W) 'srv.c'; else $(CYGPATH_W) '$(srcdir)/srv.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommonpth_a-srv.Tpo $(DEPDIR)/libcommonpth_a-srv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='srv.c' object='libcommonpth_a-srv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcommonpth_a_CFLAGS) $(CFLAGS) -c -o libcommonpth_a-srv.obj `if test -f 'srv.c'; then $(CYGPATH_W) 'srv.c'; else $(CYGPATH_W) '$(srcdir)/srv.c'; fi` + +libsimple_pwquery_a-simple-pwquery.o: simple-pwquery.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -MT libsimple_pwquery_a-simple-pwquery.o -MD -MP -MF $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Tpo -c -o libsimple_pwquery_a-simple-pwquery.o `test -f 'simple-pwquery.c' || echo '$(srcdir)/'`simple-pwquery.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Tpo $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simple-pwquery.c' object='libsimple_pwquery_a-simple-pwquery.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -c -o libsimple_pwquery_a-simple-pwquery.o `test -f 'simple-pwquery.c' || echo '$(srcdir)/'`simple-pwquery.c + +libsimple_pwquery_a-simple-pwquery.obj: simple-pwquery.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -MT libsimple_pwquery_a-simple-pwquery.obj -MD -MP -MF $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Tpo -c -o libsimple_pwquery_a-simple-pwquery.obj `if test -f 'simple-pwquery.c'; then $(CYGPATH_W) 'simple-pwquery.c'; else $(CYGPATH_W) '$(srcdir)/simple-pwquery.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Tpo $(DEPDIR)/libsimple_pwquery_a-simple-pwquery.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simple-pwquery.c' object='libsimple_pwquery_a-simple-pwquery.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -c -o libsimple_pwquery_a-simple-pwquery.obj `if test -f 'simple-pwquery.c'; then $(CYGPATH_W) 'simple-pwquery.c'; else $(CYGPATH_W) '$(srcdir)/simple-pwquery.c'; fi` + +libsimple_pwquery_a-asshelp.o: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -MT libsimple_pwquery_a-asshelp.o -MD -MP -MF $(DEPDIR)/libsimple_pwquery_a-asshelp.Tpo -c -o libsimple_pwquery_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsimple_pwquery_a-asshelp.Tpo $(DEPDIR)/libsimple_pwquery_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libsimple_pwquery_a-asshelp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -c -o libsimple_pwquery_a-asshelp.o `test -f 'asshelp.c' || echo '$(srcdir)/'`asshelp.c + +libsimple_pwquery_a-asshelp.obj: asshelp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -MT libsimple_pwquery_a-asshelp.obj -MD -MP -MF $(DEPDIR)/libsimple_pwquery_a-asshelp.Tpo -c -o libsimple_pwquery_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsimple_pwquery_a-asshelp.Tpo $(DEPDIR)/libsimple_pwquery_a-asshelp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asshelp.c' object='libsimple_pwquery_a-asshelp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsimple_pwquery_a_CFLAGS) $(CFLAGS) -c -o libsimple_pwquery_a-asshelp.obj `if test -f 'asshelp.c'; then $(CYGPATH_W) 'asshelp.c'; else $(CYGPATH_W) '$(srcdir)/asshelp.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +# Note: Due to the dependency on Makefile, the file will always be +# rebuilt, so we allow this only in maintainer mode. + +# Create the audit-events.h include file from audit.h +# Note: We create the target file in the source directory because it +# is a distributed built source. If we would not do that we may end +# up with two files and then it is not clear which version of the +# files will be picked up. +@MAINTAINER_MODE_TRUE@audit-events.h: Makefile mkstrtable.awk exaudit.awk audit.h +@MAINTAINER_MODE_TRUE@ $(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \ +@MAINTAINER_MODE_TRUE@ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ +@MAINTAINER_MODE_TRUE@ -v namespace=eventstr_ > $(srcdir)/audit-events.h + +# Create the status-codes.h include file from status.h +@MAINTAINER_MODE_TRUE@status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h +@MAINTAINER_MODE_TRUE@ $(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \ +@MAINTAINER_MODE_TRUE@ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ +@MAINTAINER_MODE_TRUE@ -v namespace=statusstr_ > $(srcdir)/status-codes.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/common/README b/common/README new file mode 100644 index 0000000..a90224b --- /dev/null +++ b/common/README @@ -0,0 +1,11 @@ +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 new file mode 100644 index 0000000..3dc4b22 --- /dev/null +++ b/common/asshelp.c @@ -0,0 +1,457 @@ +/* asshelp.c - Helper functions for Assuan + * Copyright (C) 2002, 2004, 2007, 2009, 2010 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif + +#define JNLIB_NEED_LOG_LOGV +#include "i18n.h" +#include "util.h" +#include "exechelp.h" +#include "sysutils.h" +#include "status.h" +#include "asshelp.h" + +/* The type we use for lock_agent_spawning. */ +#ifdef HAVE_W32_SYSTEM +# define lock_agent_t HANDLE +#else +# define lock_agent_t DOTLOCK +#endif + + +static gpg_error_t +send_one_option (assuan_context_t ctx, gpg_err_source_t errsource, + const char *name, const char *value, int use_putenv) +{ + gpg_error_t err; + char *optstr; + + (void)errsource; + + if (!value || !*value) + err = 0; /* Avoid sending empty strings. */ + else if (asprintf (&optstr, "OPTION %s%s=%s", + use_putenv? "putenv=":"", name, value) < 0) + err = gpg_error_from_syserror (); + else + { + err = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + xfree (optstr); + } + + return err; +} + + +/* Send the assuan commands pertaining to the pinentry environment. The + OPT_* arguments are optional and may be used to override the + defaults taken from the current locale. */ +gpg_error_t +send_pinentry_environment (assuan_context_t ctx, + gpg_err_source_t errsource, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env) + +{ + gpg_error_t err = 0; +#if defined(HAVE_SETLOCALE) + char *old_lc = NULL; +#endif + char *dft_lc = NULL; + const char *dft_ttyname; + int iterator; + const char *name, *assname, *value; + int is_default; + + iterator = 0; + while ((name = session_env_list_stdenvnames (&iterator, &assname))) + { + value = session_env_getenv_or_default (session_env, name, NULL); + if (!value) + continue; + + if (assname) + err = send_one_option (ctx, errsource, assname, value, 0); + else + { + err = send_one_option (ctx, errsource, name, value, 1); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* Server too old; can't pass the new envvars. */ + } + if (err) + return err; + } + + + dft_ttyname = session_env_getenv_or_default (session_env, "GPG_TTY", + &is_default); + if (dft_ttyname && !is_default) + dft_ttyname = NULL; /* We need the default value. */ + + /* Send the value for LC_CTYPE. */ +#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) + old_lc = setlocale (LC_CTYPE, NULL); + if (old_lc) + { + old_lc = xtrystrdup (old_lc); + if (!old_lc) + return gpg_error_from_syserror (); + } + dft_lc = setlocale (LC_CTYPE, ""); +#endif + if (opt_lc_ctype || (dft_ttyname && dft_lc)) + { + err = send_one_option (ctx, errsource, "lc-ctype", + opt_lc_ctype ? opt_lc_ctype : dft_lc, 0); + } +#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) + if (old_lc) + { + setlocale (LC_CTYPE, old_lc); + xfree (old_lc); + } +#endif + if (err) + return err; + + /* Send the value for LC_MESSAGES. */ +#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) + old_lc = setlocale (LC_MESSAGES, NULL); + if (old_lc) + { + old_lc = xtrystrdup (old_lc); + if (!old_lc) + return gpg_error_from_syserror (); + } + dft_lc = setlocale (LC_MESSAGES, ""); +#endif + if (opt_lc_messages || (dft_ttyname && dft_lc)) + { + err = send_one_option (ctx, errsource, "lc-messages", + opt_lc_messages ? opt_lc_messages : dft_lc, 0); + } +#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) + if (old_lc) + { + setlocale (LC_MESSAGES, old_lc); + xfree (old_lc); + } +#endif + if (err) + return err; + + return 0; +} + + +/* Lock the agent spawning process. The caller needs to provide the + address of a variable to store the lock information. */ +static gpg_error_t +lock_agent_spawning (lock_agent_t *lock, const char *homedir) +{ +#ifdef HAVE_W32_SYSTEM + int waitrc; + + (void)homedir; /* Not required. */ + + *lock = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel"); + if (!*lock) + { + log_error ("failed to create the spawn_agent mutex: %s\n", + w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); + } + + waitrc = WaitForSingleObject (*lock, 5000); + if (waitrc == WAIT_OBJECT_0) + return 0; + + if (waitrc == WAIT_TIMEOUT) + log_info ("error waiting for the spawn_agent mutex: timeout\n"); + else + log_info ("error waiting for the spawn_agent mutex: " + "(code=%d) %s\n", waitrc, w32_strerror (-1)); + return gpg_error (GPG_ERR_GENERAL); +#else /*!HAVE_W32_SYSTEM*/ + char *fname; + + *lock = NULL; + + fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL); + if (!fname) + return gpg_error_from_syserror (); + + *lock = create_dotlock (fname); + xfree (fname); + if (!*lock) + return gpg_error_from_syserror (); + + /* FIXME: We should use a timeout of 5000 here - however + make_dotlock does not yet support values other than -1 and 0. */ + if (make_dotlock (*lock, -1)) + return gpg_error_from_syserror (); + + return 0; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Unlock the spawning process. */ +static void +unlock_agent_spawning (lock_agent_t *lock) +{ + if (*lock) + { +#ifdef HAVE_W32_SYSTEM + if (!ReleaseMutex (*lock)) + log_error ("failed to release the spawn_agent mutex: %s\n", + w32_strerror (-1)); + CloseHandle (*lock); +#else /*!HAVE_W32_SYSTEM*/ + destroy_dotlock (*lock); +#endif /*!HAVE_W32_SYSTEM*/ + *lock = NULL; + } +} + + +/* Try to connect to the agent via socket or fork it off and work by + pipes. Handle the server's initial greeting. Returns a new assuan + context at R_CTX or an error code. */ +gpg_error_t +start_new_gpg_agent (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *agent_program, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg) +{ + /* If we ever failed to connect via a socket we will force the use + of the pipe based server for the lifetime of the process. */ + static int force_pipe_server = 0; + + gpg_error_t err = 0; + char *infostr, *p; + assuan_context_t ctx; + + *r_ctx = NULL; + + err = assuan_new (&ctx); + if (err) + { + log_error ("error allocating assuan context: %s\n", gpg_strerror (err)); + return err; + } + + restart: + infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); + if (!infostr || !*infostr) + { + char *sockname; + const char *argv[3]; + pid_t pid; + int excode; + + /* First check whether we can connect at the standard + socket. */ + sockname = make_filename (homedir, "S.gpg-agent", NULL); + err = assuan_socket_connect (ctx, sockname, 0, 0); + + if (err) + { + /* With no success start a new server. */ + if (verbose) + log_info (_("no running gpg-agent - starting one\n")); + + if (status_cb) + status_cb (status_cb_arg, STATUS_PROGRESS, + "starting_agent ? 0 0", NULL); + + 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)); + xfree (sockname); + assuan_release (ctx); + return tmperr; + } + + if (!agent_program || !*agent_program) + agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); + + argv[0] = "--use-standard-socket-p"; + argv[1] = NULL; + err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid); + if (err) + log_debug ("starting `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + else if ((err = gnupg_wait_process (agent_program, pid, &excode))) + { + if (excode == -1) + log_debug ("running `%s' for testing failed: %s\n", + agent_program, gpg_strerror (err)); + } + + if (!err && !excode) + { + /* If the agent has been configured for use with a + standard socket, an environment variable is not + required and thus we we can savely start the agent + here. */ + lock_agent_t lock; + + argv[0] = "--daemon"; + argv[1] = "--use-standard-socket"; + argv[2] = NULL; + + if (!(err = lock_agent_spawning (&lock, homedir)) + && assuan_socket_connect (ctx, sockname, 0, 0)) + { + err = gnupg_spawn_process_detached (agent_program, argv,NULL); + if (err) + log_error ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (err)); + else + { + int i; + + if (verbose) + log_info (_("waiting %d seconds for the agent " + "to come up\n"), 5); + for (i=0; i < 5; i++) + { + gnupg_sleep (1); + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (!err) + break; + } + } + } + + unlock_agent_spawning (&lock); + } + else + { + /* If using the standard socket is not the default we + start the agent as a pipe server which gives us most + of the required features except for passphrase + caching etc. */ + const char *pgmname; + int no_close_list[3]; + int i; + + if ( !(pgmname = strrchr (agent_program, '/'))) + pgmname = agent_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + err = assuan_pipe_connect (ctx, agent_program, argv, + no_close_list, NULL, NULL, 0); + } + } + xfree (sockname); + } + else + { + int prot; + int pid; + + infostr = xstrdup (infostr); + if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) + { + log_error (_("malformed GPG_AGENT_INFO environment variable\n")); + xfree (infostr); + force_pipe_server = 1; + goto restart; + } + *p++ = 0; + pid = atoi (p); + while (*p && *p != PATHSEP_C) + 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; + goto restart; + } + + err = assuan_socket_connect (ctx, infostr, pid, 0); + xfree (infostr); + if (gpg_err_code (err) == GPG_ERR_ASS_CONNECT_FAILED) + { + log_info (_("can't connect to the agent - trying fall back\n")); + force_pipe_server = 1; + goto restart; + } + } + + if (err) + { + log_error ("can't connect to the agent: %s\n", gpg_strerror (err)); + assuan_release (ctx); + return gpg_error (GPG_ERR_NO_AGENT); + } + + if (debug) + log_debug ("connection to agent established\n"); + + err = assuan_transact (ctx, "RESET", + NULL, NULL, NULL, NULL, NULL, NULL); + if (!err) + err = send_pinentry_environment (ctx, errsource, + opt_lc_ctype, opt_lc_messages, + session_env); + if (err) + { + assuan_release (ctx); + return err; + } + + *r_ctx = ctx; + return 0; +} + diff --git a/common/asshelp.h b/common/asshelp.h new file mode 100644 index 0000000..f7bc88b --- /dev/null +++ b/common/asshelp.h @@ -0,0 +1,50 @@ +/* asshelp.h - Helper functions for Assuan + * Copyright (C) 2004, 2007 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_ASSHELP_H +#define GNUPG_COMMON_ASSHELP_H + +#include +#include + +#include "session-env.h" + +gpg_error_t +send_pinentry_environment (assuan_context_t ctx, + gpg_err_source_t errsource, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env); + +/* This fucntion is used by the call-agent.c modules to fire up a new + agent. */ +gpg_error_t +start_new_gpg_agent (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *agent_program, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg); + + +#endif /*GNUPG_COMMON_ASSHELP_H*/ diff --git a/common/audit-events.h b/common/audit-events.h new file mode 100644 index 0000000..74484ea --- /dev/null +++ b/common/audit-events.h @@ -0,0 +1,114 @@ +/* Output of mkstrtable.awk. DO NOT EDIT. */ + +/* audit.h - Definitions for the audit subsystem + * Copyright (C) 2007 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 3 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, see . + */ + +/* The purpose of this complex string table is to produce + optimal code with a minimum of relocations. */ + +static const char eventstr_msgstr[] = + "null event" "\0" + "setup ready" "\0" + "agent ready" "\0" + "dirmngr ready" "\0" + "gpg ready" "\0" + "gpgsm ready" "\0" + "got data" "\0" + "detached signature" "\0" + "cert only sig" "\0" + "data hash algo" "\0" + "attr hash algo" "\0" + "data cipher algo" "\0" + "bad data hash algo" "\0" + "bad data cipher algo" "\0" + "data hashing" "\0" + "read error" "\0" + "write error" "\0" + "usage error" "\0" + "save cert" "\0" + "new sig" "\0" + "sig name" "\0" + "sig status" "\0" + "new recp" "\0" + "recp name" "\0" + "recp result" "\0" + "decryption result" "\0" + "validate chain" "\0" + "chain begin" "\0" + "chain cert" "\0" + "chain rootcert" "\0" + "chain end" "\0" + "chain status" "\0" + "root trusted" "\0" + "crl check" "\0" + "got recipients" "\0" + "session key" "\0" + "encrypted to" "\0" + "encryption done" "\0" + "signed by" "\0" + "signing done"; + +static const int eventstr_msgidx[] = + { + 0, + 11, + 23, + 35, + 49, + 59, + 71, + 80, + 99, + 113, + 128, + 143, + 160, + 179, + 200, + 213, + 224, + 236, + 248, + 258, + 266, + 275, + 286, + 295, + 305, + 317, + 335, + 350, + 362, + 373, + 388, + 398, + 411, + 424, + 434, + 449, + 461, + 474, + 490, + 500, + + }; + +#define eventstr_msgidxof(code) (0 ? -1 \ + : ((code >= 0) && (code <= 39)) ? (code - 0) \ + : -1) diff --git a/common/audit.c b/common/audit.c new file mode 100644 index 0000000..02a0a2b --- /dev/null +++ b/common/audit.c @@ -0,0 +1,1324 @@ +/* audit.c - GnuPG's audit subsystem + * Copyright (C) 2007, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "i18n.h" +#include "audit.h" +#include "audit-events.h" + +/* A list to maintain a list of helptags. */ +struct helptag_s +{ + struct helptag_s *next; + const char *name; +}; +typedef struct helptag_s *helptag_t; + + +/* One log entry. */ +struct log_item_s +{ + audit_event_t event; /* The event. */ + gpg_error_t err; /* The logged error code. */ + int intvalue; /* A logged integer value. */ + char *string; /* A malloced string or NULL. */ + ksba_cert_t cert; /* A certifciate or NULL. */ + int have_err:1; + int have_intvalue:1; +}; +typedef struct log_item_s *log_item_t; + + + +/* The main audit object. */ +struct audit_ctx_s +{ + const char *failure; /* If set a description of the internal failure. */ + audit_type_t type; + + log_item_t log; /* The table with the log entries. */ + size_t logsize; /* The allocated size for LOG. */ + size_t logused; /* The used size of LOG. */ + + estream_t outstream; /* The current output stream. */ + int use_html; /* The output shall be HTML formatted. */ + int indentlevel; /* Current level of indentation. */ + helptag_t helptags; /* List of help keys. */ +}; + + + + +static void writeout_para (audit_ctx_t ctx, + const char *format, ...) JNLIB_GCC_A_PRINTF(2,3); +static void writeout_li (audit_ctx_t ctx, const char *oktext, + const char *format, ...) JNLIB_GCC_A_PRINTF(3,4); +static void writeout_rem (audit_ctx_t ctx, + const char *format, ...) JNLIB_GCC_A_PRINTF(2,3); + + +/* Add NAME to the list of help tags. NAME needs to be a const string + an this function merly stores this pointer. */ +static void +add_helptag (audit_ctx_t ctx, const char *name) +{ + helptag_t item; + + for (item=ctx->helptags; item; item = item->next) + if (!strcmp (item->name, name)) + return; /* Already in the list. */ + item = xtrycalloc (1, sizeof *item); + if (!item) + return; /* Don't care about memory problems. */ + item->name = name; + item->next = ctx->helptags; + ctx->helptags = item; +} + + +/* Remove all help tags from the context. */ +static void +clear_helptags (audit_ctx_t ctx) +{ + while (ctx->helptags) + { + helptag_t tmp = ctx->helptags->next; + xfree (ctx->helptags); + ctx->helptags = tmp; + } +} + + + +static const char * +event2str (audit_event_t event) +{ + /* We need the cast so that compiler does not complain about an + always true comparison (>= 0) for an unsigned value. */ + int idx = eventstr_msgidxof ((int)event); + if (idx == -1) + return "Unknown event"; + else + return eventstr_msgstr + eventstr_msgidx[idx]; +} + + + +/* Create a new audit context. In case of an error NULL is returned + and errno set appropriately. */ +audit_ctx_t +audit_new (void) +{ + audit_ctx_t ctx; + + ctx = xtrycalloc (1, sizeof *ctx); + + return ctx; +} + + +/* Release an audit context. Passing NULL for CTX is allowed and does + nothing. */ +void +audit_release (audit_ctx_t ctx) +{ + int idx; + if (!ctx) + return; + if (ctx->log) + { + for (idx=0; idx < ctx->logused; idx++) + { + if (ctx->log[idx].string) + xfree (ctx->log[idx].string); + if (ctx->log[idx].cert) + ksba_cert_release (ctx->log[idx].cert); + } + xfree (ctx->log); + } + clear_helptags (ctx); + xfree (ctx); +} + + +/* Set the type for the audit operation. If CTX is NULL, this is a + dummy fucntion. */ +void +audit_set_type (audit_ctx_t ctx, audit_type_t type) +{ + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + + if (ctx->type && ctx->type != type) + { + ctx->failure = "conflict in type initialization"; + return; + } + ctx->type = type; +} + + +/* Create a new log item and put it into the table. Return that log + item on success; return NULL on memory failure and mark that in + CTX. */ +static log_item_t +create_log_item (audit_ctx_t ctx) +{ + log_item_t item, table; + size_t size; + + if (!ctx->log) + { + size = 10; + table = xtrymalloc (size * sizeof *table); + if (!table) + { + ctx->failure = "Out of memory in create_log_item"; + return NULL; + } + ctx->log = table; + ctx->logsize = size; + item = ctx->log + 0; + ctx->logused = 1; + } + else if (ctx->logused >= ctx->logsize) + { + size = ctx->logsize + 10; + table = xtryrealloc (ctx->log, size * sizeof *table); + if (!table) + { + ctx->failure = "Out of memory while reallocating in create_log_item"; + return NULL; + } + ctx->log = table; + ctx->logsize = size; + item = ctx->log + ctx->logused++; + } + else + item = ctx->log + ctx->logused++; + + item->event = AUDIT_NULL_EVENT; + item->err = 0; + item->have_err = 0; + item->intvalue = 0; + item->have_intvalue = 0; + item->string = NULL; + item->cert = NULL; + + return item; + +} + +/* Add a new event to the audit log. If CTX is NULL, this function + does nothing. */ +void +audit_log (audit_ctx_t ctx, audit_event_t event) +{ + log_item_t item; + + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + if (!event) + { + ctx->failure = "Invalid event passed to audit_log"; + return; + } + if (!(item = create_log_item (ctx))) + return; + item->event = event; +} + +/* Add a new event to the audit log. If CTX is NULL, this function + does nothing. This version also adds the result of the operation + to the log. */ +void +audit_log_ok (audit_ctx_t ctx, audit_event_t event, gpg_error_t err) +{ + log_item_t item; + + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + if (!event) + { + ctx->failure = "Invalid event passed to audit_log_ok"; + return; + } + if (!(item = create_log_item (ctx))) + return; + item->event = event; + item->err = err; + item->have_err = 1; +} + + +/* Add a new event to the audit log. If CTX is NULL, this function + does nothing. This version also add the integer VALUE to the log. */ +void +audit_log_i (audit_ctx_t ctx, audit_event_t event, int value) +{ + log_item_t item; + + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + if (!event) + { + ctx->failure = "Invalid event passed to audit_log_i"; + return; + } + if (!(item = create_log_item (ctx))) + return; + item->event = event; + item->intvalue = value; + item->have_intvalue = 1; +} + + +/* Add a new event to the audit log. If CTX is NULL, this function + does nothing. This version also add the integer VALUE to the log. */ +void +audit_log_s (audit_ctx_t ctx, audit_event_t event, const char *value) +{ + log_item_t item; + char *tmp; + + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + if (!event) + { + ctx->failure = "Invalid event passed to audit_log_s"; + return; + } + tmp = xtrystrdup (value? value : ""); + if (!tmp) + { + ctx->failure = "Out of memory in audit_event"; + return; + } + if (!(item = create_log_item (ctx))) + { + xfree (tmp); + return; + } + item->event = event; + item->string = tmp; +} + +/* Add a new event to the audit log. If CTX is NULL, this function + does nothing. This version also adds the certificate CERT and the + result of an operation to the log. */ +void +audit_log_cert (audit_ctx_t ctx, audit_event_t event, + ksba_cert_t cert, gpg_error_t err) +{ + log_item_t item; + + if (!ctx || ctx->failure) + return; /* Audit not enabled or an internal error has occurred. */ + if (!event) + { + ctx->failure = "Invalid event passed to audit_log_cert"; + return; + } + if (!(item = create_log_item (ctx))) + return; + item->event = event; + item->err = err; + item->have_err = 1; + if (cert) + { + ksba_cert_ref (cert); + item->cert = cert; + } +} + + +/* Write TEXT to the outstream. */ +static void +writeout (audit_ctx_t ctx, const char *text) +{ + if (ctx->use_html) + { + for (; *text; text++) + { + if (*text == '<') + es_fputs ("<", ctx->outstream); + else if (*text == '&') + es_fputs ("&", ctx->outstream); + else + es_putc (*text, ctx->outstream); + } + } + else + es_fputs (text, ctx->outstream); +} + + +/* Write TEXT to the outstream using a variable argument list. */ +static void +writeout_v (audit_ctx_t ctx, const char *format, va_list arg_ptr) +{ + char *buf; + + estream_vasprintf (&buf, format, arg_ptr); + if (buf) + { + writeout (ctx, buf); + xfree (buf); + } + else + writeout (ctx, "[!!Out of core!!]"); +} + + +/* Write TEXT as a paragraph. */ +static void +writeout_para (audit_ctx_t ctx, const char *format, ...) +{ + va_list arg_ptr; + + if (ctx->use_html) + es_fputs ("

", ctx->outstream); + va_start (arg_ptr, format) ; + writeout_v (ctx, format, arg_ptr); + va_end (arg_ptr); + if (ctx->use_html) + es_fputs ("

\n", ctx->outstream); + else + es_fputc ('\n', ctx->outstream); +} + + +static void +enter_li (audit_ctx_t ctx) +{ + if (ctx->use_html) + { + if (!ctx->indentlevel) + { + es_fputs ("\n" + " \n" + " \n" + " \n" + " \n", + ctx->outstream); + } + } + ctx->indentlevel++; +} + + +static void +leave_li (audit_ctx_t ctx) +{ + ctx->indentlevel--; + if (ctx->use_html) + { + if (!ctx->indentlevel) + es_fputs ("
\n", ctx->outstream); + } +} + + +/* Write TEXT as a list element. If OKTEXT is not NULL, append it to + the last line. */ +static void +writeout_li (audit_ctx_t ctx, const char *oktext, const char *format, ...) +{ + va_list arg_ptr; + const char *color = NULL; + + if (ctx->use_html && format && oktext) + { + if (!strcmp (oktext, "Yes") + || !strcmp (oktext, "good") ) + color = "green"; + else if (!strcmp (oktext, "No") + || !strcmp (oktext, "bad") ) + color = "red"; + } + + if (format && oktext) + { + const char *s = NULL; + + if (!strcmp (oktext, "Yes")) + oktext = _("Yes"); + else if (!strcmp (oktext, "No")) + oktext = _("No"); + else if (!strcmp (oktext, "good")) + { + /* TRANSLATORS: Copy the prefix between the vertical bars + verbatim. It will not be printed. */ + oktext = _("|audit-log-result|Good"); + } + else if (!strcmp (oktext, "bad")) + oktext = _("|audit-log-result|Bad"); + else if (!strcmp (oktext, "unsupported")) + oktext = _("|audit-log-result|Not supported"); + else if (!strcmp (oktext, "no-cert")) + oktext = _("|audit-log-result|No certificate"); + else if (!strcmp (oktext, "disabled")) + oktext = _("|audit-log-result|Not enabled"); + else if (!strcmp (oktext, "error")) + oktext = _("|audit-log-result|Error"); + else if (!strcmp (oktext, "not-used")) + oktext = _("|audit-log-result|Not used"); + else if (!strcmp (oktext, "okay")) + oktext = _("|audit-log-result|Okay"); + else if (!strcmp (oktext, "skipped")) + oktext = _("|audit-log-result|Skipped"); + else if (!strcmp (oktext, "some")) + oktext = _("|audit-log-result|Some"); + else + s = ""; + + /* If we have set a prefix, skip it. */ + if (!s && *oktext == '|' && (s=strchr (oktext+1,'|'))) + oktext = s+1; + } + + if (ctx->use_html) + { + int i; + + es_fputs ("
", ctx->outstream); + if (color) + es_fprintf (ctx->outstream, "*", color); + else + es_fputs ("*", ctx->outstream); + for (i=1; i < ctx->indentlevel; i++) + es_fputs ("  ", ctx->outstream); + es_fputs ("", ctx->outstream); + } + else + es_fprintf (ctx->outstream, "* %*s", (ctx->indentlevel-1)*2, ""); + if (format) + { + va_start (arg_ptr, format) ; + writeout_v (ctx, format, arg_ptr); + va_end (arg_ptr); + } + if (ctx->use_html) + es_fputs ("
", ctx->outstream); + if (format && oktext) + { + if (ctx->use_html) + { + es_fputs ("", ctx->outstream); + if (color) + es_fprintf (ctx->outstream, "", color); + } + else + writeout (ctx, ": "); + writeout (ctx, oktext); + if (color) + es_fputs ("", ctx->outstream); + } + + if (ctx->use_html) + es_fputs ("\n", ctx->outstream); + else + es_fputc ('\n', ctx->outstream); +} + + +/* Write a remark line. */ +static void +writeout_rem (audit_ctx_t ctx, const char *format, ...) +{ + va_list arg_ptr; + + if (ctx->use_html) + { + int i; + + es_fputs ("
*", ctx->outstream); + for (i=1; i < ctx->indentlevel; i++) + es_fputs ("  ", ctx->outstream); + es_fputs ("    (", ctx->outstream); + + } + else + es_fprintf (ctx->outstream, "* %*s (", (ctx->indentlevel-1)*2, ""); + if (format) + { + va_start (arg_ptr, format) ; + writeout_v (ctx, format, arg_ptr); + va_end (arg_ptr); + } + if (ctx->use_html) + es_fputs (")
\n", ctx->outstream); + else + es_fputs (")\n", ctx->outstream); +} + + +/* Return the first log item for EVENT. If STOPEVENT is not 0 never + look behind that event in the log. If STARTITEM is not NULL start + search _after_that item. */ +static log_item_t +find_next_log_item (audit_ctx_t ctx, log_item_t startitem, + audit_event_t event, audit_event_t stopevent) +{ + int idx; + + for (idx=0; idx < ctx->logused; idx++) + { + if (startitem) + { + if (ctx->log + idx == startitem) + startitem = NULL; + } + else if (stopevent && ctx->log[idx].event == stopevent) + break; + else if (ctx->log[idx].event == event) + return ctx->log + idx; + } + return NULL; +} + + +static log_item_t +find_log_item (audit_ctx_t ctx, audit_event_t event, audit_event_t stopevent) +{ + return find_next_log_item (ctx, NULL, event, stopevent); +} + + +/* Helper to a format a serial number. */ +static char * +format_serial (ksba_const_sexp_t sn) +{ + const char *p = (const char *)sn; + unsigned long n; + char *endp; + + if (!p) + return NULL; + if (*p != '(') + BUG (); /* Not a valid S-expression. */ + n = strtoul (p+1, &endp, 10); + p = endp; + if (*p != ':') + BUG (); /* Not a valid S-expression. */ + return bin2hex (p+1, n, NULL); +} + + +/* Return a malloced string with the serial number and the issuer DN + of the certificate. */ +static char * +get_cert_name (ksba_cert_t cert) +{ + char *result; + ksba_sexp_t sn; + char *issuer, *p; + + if (!cert) + return xtrystrdup ("[no certificate]"); + + issuer = ksba_cert_get_issuer (cert, 0); + sn = ksba_cert_get_serial (cert); + if (issuer && sn) + { + p = format_serial (sn); + if (!p) + result = xtrystrdup ("[invalid S/N]"); + else + { + result = xtrymalloc (strlen (p) + strlen (issuer) + 2 + 1); + if (result) + { + *result = '#'; + strcpy (stpcpy (stpcpy (result+1, p),"/"), issuer); + } + xfree (p); + } + } + else + result = xtrystrdup ("[missing S/N or issuer]"); + ksba_free (sn); + xfree (issuer); + return result; +} + +/* Return a malloced string with the serial number and the issuer DN + of the certificate. */ +static char * +get_cert_subject (ksba_cert_t cert, int idx) +{ + char *result; + char *subject; + + if (!cert) + return xtrystrdup ("[no certificate]"); + + subject = ksba_cert_get_subject (cert, idx); + if (subject) + { + result = xtrymalloc (strlen (subject) + 1 + 1); + if (result) + { + *result = '/'; + strcpy (result+1, subject); + } + } + else + result = NULL; + xfree (subject); + return result; +} + + +/* List the given certificiate. If CERT is NULL, this is a NOP. */ +static void +list_cert (audit_ctx_t ctx, ksba_cert_t cert, int with_subj) +{ + char *name; + int idx; + + name = get_cert_name (cert); + writeout_rem (ctx, "%s", name); + xfree (name); + if (with_subj) + { + enter_li (ctx); + for (idx=0; (name = get_cert_subject (cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } +} + + +/* List the chain of certificates from STARTITEM up to STOPEVENT. The + certifcates are written out as comments. */ +static void +list_certchain (audit_ctx_t ctx, log_item_t startitem, audit_event_t stopevent) +{ + log_item_t item; + + startitem = find_next_log_item (ctx, startitem, AUDIT_CHAIN_BEGIN,stopevent); + writeout_li (ctx, startitem? "Yes":"No", _("Certificate chain available")); + if (!startitem) + return; + + item = find_next_log_item (ctx, startitem, + AUDIT_CHAIN_ROOTCERT, AUDIT_CHAIN_END); + if (!item) + writeout_rem (ctx, "%s", _("root certificate missing")); + else + { + list_cert (ctx, item->cert, 0); + } + item = startitem; + while ( ((item = find_next_log_item (ctx, item, + AUDIT_CHAIN_CERT, AUDIT_CHAIN_END)))) + { + list_cert (ctx, item->cert, 1); + } +} + + + +/* Process an encrypt operation's log. */ +static void +proc_type_encrypt (audit_ctx_t ctx) +{ + log_item_t loopitem, item; + int recp_no, idx; + char numbuf[35]; + int algo; + char *name; + + item = find_log_item (ctx, AUDIT_ENCRYPTION_DONE, 0); + writeout_li (ctx, item?"Yes":"No", "%s", _("Data encryption succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + + item = find_log_item (ctx, AUDIT_SESSION_KEY, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Session key created")); + if (item) + { + algo = gcry_cipher_map_name (item->string); + if (algo) + writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo)); + else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2")) + writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2"); + else if (item->string) + writeout_rem (ctx, _("unsupported algorithm: %s"), item->string); + else + writeout_rem (ctx, _("seems to be not encrypted")); + } + + item = find_log_item (ctx, AUDIT_GOT_RECIPIENTS, 0); + snprintf (numbuf, sizeof numbuf, "%d", + item && item->have_intvalue? item->intvalue : 0); + writeout_li (ctx, numbuf, "%s", _("Number of recipients")); + + /* Loop over all recipients. */ + loopitem = NULL; + recp_no = 0; + while ((loopitem=find_next_log_item (ctx, loopitem, AUDIT_ENCRYPTED_TO, 0))) + { + recp_no++; + writeout_li (ctx, NULL, _("Recipient %d"), recp_no); + if (loopitem->cert) + { + name = get_cert_name (loopitem->cert); + writeout_rem (ctx, "%s", name); + xfree (name); + enter_li (ctx); + for (idx=0; (name = get_cert_subject (loopitem->cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } + } + + leave_li (ctx); +} + + + +/* Process a sign operation's log. */ +static void +proc_type_sign (audit_ctx_t ctx) +{ + log_item_t item, loopitem; + int signer, idx; + const char *result; + ksba_cert_t cert; + char *name; + int lastalgo; + + item = find_log_item (ctx, AUDIT_SIGNING_DONE, 0); + writeout_li (ctx, item?"Yes":"No", "%s", _("Data signing succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + /* Write remarks with the data hash algorithms. We use a very + simple scheme to avoid some duplicates. */ + loopitem = NULL; + lastalgo = 0; + while ((loopitem = find_next_log_item + (ctx, loopitem, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG))) + { + if (loopitem->intvalue && loopitem->intvalue != lastalgo) + writeout_rem (ctx, _("data hash algorithm: %s"), + gcry_md_algo_name (loopitem->intvalue)); + lastalgo = loopitem->intvalue; + } + + /* Loop over all signer. */ + loopitem = NULL; + signer = 0; + while ((loopitem=find_next_log_item (ctx, loopitem, AUDIT_NEW_SIG, 0))) + { + signer++; + + item = find_next_log_item (ctx, loopitem, AUDIT_SIGNED_BY, AUDIT_NEW_SIG); + if (!item) + result = "error"; + else if (!item->err) + result = "okay"; + else if (gpg_err_code (item->err) == GPG_ERR_CANCELED) + result = "skipped"; + else + result = gpg_strerror (item->err); + cert = item? item->cert : NULL; + + writeout_li (ctx, result, _("Signer %d"), signer); + item = find_next_log_item (ctx, loopitem, + AUDIT_ATTR_HASH_ALGO, AUDIT_NEW_SIG); + if (item) + writeout_rem (ctx, _("attr hash algorithm: %s"), + gcry_md_algo_name (item->intvalue)); + + if (cert) + { + name = get_cert_name (cert); + writeout_rem (ctx, "%s", name); + xfree (name); + enter_li (ctx); + for (idx=0; (name = get_cert_subject (cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } + } + + leave_li (ctx); +} + + + +/* Process a decrypt operation's log. */ +static void +proc_type_decrypt (audit_ctx_t ctx) +{ + log_item_t loopitem, item; + int algo, recpno; + char *name; + char numbuf[35]; + int idx; + + item = find_log_item (ctx, AUDIT_DECRYPTION_RESULT, 0); + writeout_li (ctx, item && !item->err?"Yes":"No", + "%s", _("Data decryption succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + + item = find_log_item (ctx, AUDIT_DATA_CIPHER_ALGO, 0); + algo = item? item->intvalue : 0; + writeout_li (ctx, algo?"Yes":"No", "%s", _("Encryption algorithm supported")); + if (algo) + writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo)); + + item = find_log_item (ctx, AUDIT_BAD_DATA_CIPHER_ALGO, 0); + if (item && item->string) + { + algo = gcry_cipher_map_name (item->string); + if (algo) + writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo)); + else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2")) + writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2"); + else if (item->string) + writeout_rem (ctx, _("unsupported algorithm: %s"), item->string); + else + writeout_rem (ctx, _("seems to be not encrypted")); + } + + + for (recpno = 0, item = NULL; + (item = find_next_log_item (ctx, item, AUDIT_NEW_RECP, 0)); recpno++) + ; + snprintf (numbuf, sizeof numbuf, "%d", recpno); + writeout_li (ctx, numbuf, "%s", _("Number of recipients")); + + /* Loop over all recipients. */ + loopitem = NULL; + while ((loopitem = find_next_log_item (ctx, loopitem, AUDIT_NEW_RECP, 0))) + { + const char *result; + + recpno = loopitem->have_intvalue? loopitem->intvalue : -1; + + item = find_next_log_item (ctx, loopitem, + AUDIT_RECP_RESULT, AUDIT_NEW_RECP); + if (!item) + result = "not-used"; + else if (!item->err) + result = "okay"; + else if (gpg_err_code (item->err) == GPG_ERR_CANCELED) + result = "skipped"; + else + result = gpg_strerror (item->err); + + item = find_next_log_item (ctx, loopitem, + AUDIT_RECP_NAME, AUDIT_NEW_RECP); + writeout_li (ctx, result, _("Recipient %d"), recpno); + if (item && item->string) + writeout_rem (ctx, "%s", item->string); + + /* If we have a certificate write out more infos. */ + item = find_next_log_item (ctx, loopitem, + AUDIT_SAVE_CERT, AUDIT_NEW_RECP); + if (item && item->cert) + { + enter_li (ctx); + for (idx=0; (name = get_cert_subject (item->cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } + } + + leave_li (ctx); +} + + + +/* Process a verification operation's log. */ +static void +proc_type_verify (audit_ctx_t ctx) +{ + log_item_t loopitem, item; + int signo, count, idx, n_good, n_bad; + char numbuf[35]; + const char *result; + + /* If there is at least one signature status we claim that the + verification succeeded. This does not mean that the data has + verified okay. */ + item = find_log_item (ctx, AUDIT_SIG_STATUS, 0); + writeout_li (ctx, item?"Yes":"No", "%s", _("Data verification succeeded")); + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, AUDIT_NEW_SIG); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + if (!item) + goto leave; + + item = find_log_item (ctx, AUDIT_NEW_SIG, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Signature available")); + if (!item) + goto leave; + + /* Print info about the used data hashing algorithms. */ + for (idx=0, n_good=n_bad=0; idx < ctx->logused; idx++) + { + item = ctx->log + idx; + if (item->event == AUDIT_NEW_SIG) + break; + else if (item->event == AUDIT_DATA_HASH_ALGO) + n_good++; + else if (item->event == AUDIT_BAD_DATA_HASH_ALGO) + n_bad++; + } + item = find_log_item (ctx, AUDIT_DATA_HASHING, AUDIT_NEW_SIG); + if (!item || item->err || !n_good) + result = "No"; + else if (n_good && !n_bad) + result = "Yes"; + else + result = "Some"; + writeout_li (ctx, result, "%s", _("Parsing data succeeded")); + if (n_good || n_bad) + { + for (idx=0; idx < ctx->logused; idx++) + { + item = ctx->log + idx; + if (item->event == AUDIT_NEW_SIG) + break; + else if (item->event == AUDIT_DATA_HASH_ALGO) + writeout_rem (ctx, _("data hash algorithm: %s"), + gcry_md_algo_name (item->intvalue)); + else if (item->event == AUDIT_BAD_DATA_HASH_ALGO) + writeout_rem (ctx, _("bad data hash algorithm: %s"), + item->string? item->string:"?"); + } + } + + + /* Loop over all signatures. */ + loopitem = find_log_item (ctx, AUDIT_NEW_SIG, 0); + assert (loopitem); + do + { + signo = loopitem->have_intvalue? loopitem->intvalue : -1; + + item = find_next_log_item (ctx, loopitem, + AUDIT_SIG_STATUS, AUDIT_NEW_SIG); + writeout_li (ctx, item? item->string:"?", _("Signature %d"), signo); + item = find_next_log_item (ctx, loopitem, + AUDIT_SIG_NAME, AUDIT_NEW_SIG); + if (item) + writeout_rem (ctx, "%s", item->string); + + item = find_next_log_item (ctx, loopitem, + AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG); + if (item) + writeout_rem (ctx, _("data hash algorithm: %s"), + gcry_md_algo_name (item->intvalue)); + item = find_next_log_item (ctx, loopitem, + AUDIT_ATTR_HASH_ALGO, AUDIT_NEW_SIG); + if (item) + writeout_rem (ctx, _("attr hash algorithm: %s"), + gcry_md_algo_name (item->intvalue)); + + enter_li (ctx); + + /* List the certificate chain. */ + list_certchain (ctx, loopitem, AUDIT_NEW_SIG); + + /* Show the result of the chain validation. */ + item = find_next_log_item (ctx, loopitem, + AUDIT_CHAIN_STATUS, AUDIT_NEW_SIG); + if (item && item->have_err) + { + writeout_li (ctx, item->err? "No":"Yes", + _("Certificate chain valid")); + if (item->err) + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + } + + /* Show whether the root certificate is fine. */ + item = find_next_log_item (ctx, loopitem, + AUDIT_ROOT_TRUSTED, AUDIT_CHAIN_STATUS); + if (item) + { + writeout_li (ctx, item->err?"No":"Yes", "%s", + _("Root certificate trustworthy")); + if (item->err) + { + add_helptag (ctx, "gpgsm.root-cert-not-trusted"); + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + list_cert (ctx, item->cert, 0); + } + } + + /* Show result of the CRL/OCSP check. */ + item = find_next_log_item (ctx, loopitem, + AUDIT_CRL_CHECK, AUDIT_NEW_SIG); + if (item) + { + const char *ok; + switch (gpg_err_code (item->err)) + { + case 0: ok = "good"; break; + case GPG_ERR_CERT_REVOKED: ok = "bad"; break; + case GPG_ERR_NOT_ENABLED: ok = "disabled"; break; + case GPG_ERR_NO_CRL_KNOWN: + ok = _("no CRL found for certificate"); + break; + case GPG_ERR_CRL_TOO_OLD: + ok = _("the available CRL is too old"); + break; + default: ok = gpg_strerror (item->err); break; + } + + writeout_li (ctx, ok, "%s", _("CRL/OCSP check of certificates")); + if (item->err + && gpg_err_code (item->err) != GPG_ERR_CERT_REVOKED + && gpg_err_code (item->err) != GPG_ERR_NOT_ENABLED) + add_helptag (ctx, "gpgsm.crl-problem"); + } + + leave_li (ctx); + } + while ((loopitem = find_next_log_item (ctx, loopitem, AUDIT_NEW_SIG, 0))); + + + leave: + /* Always list the certificates stored in the signature. */ + item = NULL; + count = 0; + while ( ((item = find_next_log_item (ctx, item, + AUDIT_SAVE_CERT, AUDIT_NEW_SIG)))) + count++; + snprintf (numbuf, sizeof numbuf, "%d", count); + writeout_li (ctx, numbuf, _("Included certificates")); + item = NULL; + while ( ((item = find_next_log_item (ctx, item, + AUDIT_SAVE_CERT, AUDIT_NEW_SIG)))) + { + char *name = get_cert_name (item->cert); + writeout_rem (ctx, "%s", name); + xfree (name); + enter_li (ctx); + for (idx=0; (name = get_cert_subject (item->cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } + leave_li (ctx); +} + + + + +/* Print the formatted audit result. THIS IS WORK IN PROGRESS. */ +void +audit_print_result (audit_ctx_t ctx, estream_t out, int use_html) +{ + int idx; + size_t n; + log_item_t item; + helptag_t helptag; + const char *s; + int show_raw = 0; + char *orig_codeset; + + if (!ctx) + return; + + orig_codeset = i18n_switchto_utf8 (); + + /* We use an environment variable to include some debug info in the + log. */ + if ((s = getenv ("gnupg_debug_audit"))) + show_raw = 1; + + assert (!ctx->outstream); + ctx->outstream = out; + ctx->use_html = use_html; + ctx->indentlevel = 0; + clear_helptags (ctx); + + if (use_html) + es_fputs ("
\n", ctx->outstream); + + if (!ctx->log || !ctx->logused) + { + writeout_para (ctx, _("No audit log entries.")); + goto leave; + } + + if (show_raw) + { + int maxlen; + + for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++) + { + n = strlen (eventstr_msgstr + eventstr_msgidx[idx]); + if (n > maxlen) + maxlen = n; + } + + if (use_html) + es_fputs ("
\n", out);
+      for (idx=0; idx < ctx->logused; idx++)
+        {
+          es_fprintf (out, "log: %-*s", 
+                      maxlen, event2str (ctx->log[idx].event));
+          if (ctx->log[idx].have_intvalue)
+            es_fprintf (out, " i=%d", ctx->log[idx].intvalue); 
+          if (ctx->log[idx].string)
+            {
+              es_fputs (" s=`", out); 
+              writeout (ctx, ctx->log[idx].string); 
+              es_fputs ("'", out); 
+            }
+          if (ctx->log[idx].cert)
+            es_fprintf (out, " has_cert"); 
+          if (ctx->log[idx].have_err)
+            {
+              es_fputs (" err=`", out);
+              writeout (ctx, gpg_strerror (ctx->log[idx].err)); 
+              es_fputs ("'", out);
+            }
+          es_fputs ("\n", out);
+        }
+      if (use_html)
+        es_fputs ("
\n", out); + else + es_fputs ("\n", out); + } + + enter_li (ctx); + switch (ctx->type) + { + case AUDIT_TYPE_NONE: + writeout_li (ctx, NULL, _("Unknown operation")); + break; + case AUDIT_TYPE_ENCRYPT: + proc_type_encrypt (ctx); + break; + case AUDIT_TYPE_SIGN: + proc_type_sign (ctx); + break; + case AUDIT_TYPE_DECRYPT: + proc_type_decrypt (ctx); + break; + case AUDIT_TYPE_VERIFY: + proc_type_verify (ctx); + break; + } + item = find_log_item (ctx, AUDIT_AGENT_READY, 0); + if (item && item->have_err) + { + writeout_li (ctx, item->err? "No":"Yes", "%s", _("Gpg-Agent usable")); + if (item->err) + { + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + add_helptag (ctx, "gnupg.agent-problem"); + } + } + item = find_log_item (ctx, AUDIT_DIRMNGR_READY, 0); + if (item && item->have_err) + { + writeout_li (ctx, item->err? "No":"Yes", "%s", _("Dirmngr usable")); + if (item->err) + { + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + add_helptag (ctx, "gnupg.dirmngr-problem"); + } + } + leave_li (ctx); + + + /* Show the help from the collected help tags. */ + if (ctx->helptags) + { + if (use_html) + { + es_fputs ("
\n", ctx->outstream); + if (ctx->helptags->next) + es_fputs ("
    \n", ctx->outstream); + } + else + es_fputs ("\n\n", ctx->outstream); + } + for (helptag = ctx->helptags; helptag; helptag = helptag->next) + { + char *text; + + if (use_html && ctx->helptags->next) + es_fputs ("
  • \n", ctx->outstream); + + text = gnupg_get_help_string (helptag->name, 0); + if (text) + { + writeout_para (ctx, "%s", text); + xfree (text); + } + else + writeout_para (ctx, _("No help available for `%s'."), helptag->name); + if (use_html && ctx->helptags->next) + es_fputs ("
  • \n", ctx->outstream); + if (helptag->next) + es_fputs ("\n", ctx->outstream); + } + if (use_html && ctx->helptags && ctx->helptags->next) + es_fputs ("
\n", ctx->outstream); + + leave: + if (use_html) + es_fputs ("
\n", ctx->outstream); + ctx->outstream = NULL; + ctx->use_html = 0; + clear_helptags (ctx); + i18n_switchback (orig_codeset); +} + diff --git a/common/audit.h b/common/audit.h new file mode 100644 index 0000000..bc67a2e --- /dev/null +++ b/common/audit.h @@ -0,0 +1,224 @@ +/* audit.h - Definitions for the audit subsystem + * Copyright (C) 2007 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_AUDIT_H +#define GNUPG_COMMON_AUDIT_H + +#include + +#include "estream.h" + +struct audit_ctx_s; +typedef struct audit_ctx_s *audit_ctx_t; + +/* Constants for the audit type. */ +typedef enum + { + AUDIT_TYPE_NONE = 0, /* No type set. */ + AUDIT_TYPE_ENCRYPT, /* Data encryption. */ + AUDIT_TYPE_SIGN, /* Signature creation. */ + AUDIT_TYPE_DECRYPT, /* Data decryption. */ + AUDIT_TYPE_VERIFY /* Signature verification. */ + } +audit_type_t; + +/* The events we support. */ +typedef enum + { + AUDIT_NULL_EVENT = 0, + /* No such event. Its value shall be 0 and no other values shall + be assigned to the other enum symbols. This is required so + that the exaudit.awk script comes up with correct values + without running cc. */ + + AUDIT_SETUP_READY, + /* All preparations done so that the actual processing can start + now. This indicates that all parameters are okay and we can + start to process the actual data. */ + + AUDIT_AGENT_READY, /* err */ + /* Indicates whether the gpg-agent is available. For some + operations the agent is not required and thus no such event + will be logged. */ + + AUDIT_DIRMNGR_READY, /* err */ + /* Indicates whether the Dirmngr is available. For some + operations the Dirmngr is not required and thus no such event + will be logged. */ + + AUDIT_GPG_READY, /* err */ + /* Indicates whether the Gpg engine is available. */ + + AUDIT_GPGSM_READY, /* err */ + /* Indicates whether the Gpgsm engine is available. */ + + AUDIT_GOT_DATA, + /* Data to be processed has been seen. */ + + AUDIT_DETACHED_SIGNATURE, + /* The signature is a detached one. */ + + AUDIT_CERT_ONLY_SIG, + /* A certifciate only signature has been detected. */ + + AUDIT_DATA_HASH_ALGO, /* int */ + /* The hash algo given as argument is used for the data. This + event will be repeated for all hash algorithms used with the + data. */ + + AUDIT_ATTR_HASH_ALGO, /* int */ + /* The hash algo given as argument is used to hash the message + digest and other signed attributes of this signature. */ + + AUDIT_DATA_CIPHER_ALGO, /* int */ + /* The cipher algo given as argument is used for this data. */ + + AUDIT_BAD_DATA_HASH_ALGO, /* string */ + /* The hash algo as specified by the signature can't be used. + STRING is the description of this algorithm which usually is an + OID string. STRING may be NULL. */ + + AUDIT_BAD_DATA_CIPHER_ALGO, /* string */ + /* The symmetric cipher algorithm is not supported. STRING is the + description of this algorithm which usually is an OID string. + STRING may be NULL. */ + + AUDIT_DATA_HASHING, /* ok_err */ + /* Logs the result of the data hashing. */ + + AUDIT_READ_ERROR, /* ok_err */ + /* A generic read error occurred. */ + + AUDIT_WRITE_ERROR, /* ok_err */ + /* A generic write error occurred. */ + + AUDIT_USAGE_ERROR, + /* The program was used in an inappropriate way; For example by + passing a data object while the signature does not expect one + or vice versa. */ + + AUDIT_SAVE_CERT, /* cert, ok_err */ + /* Save the certificate received in a message. */ + + AUDIT_NEW_SIG, /* int */ + /* Start the verification of a new signature for the last data + object. The argument is the signature number as used + internally by the program. */ + + AUDIT_SIG_NAME, /* string */ + /* The name of a signer. This is the name or other identification + data as known from the signature and not the name from the + certificate used for verification. An example for STRING when + using CMS is: "#1234/CN=Prostetnic Vogon Jeltz". */ + + AUDIT_SIG_STATUS, /* string */ + /* The signature status of the current signer. This is the last + audit information for one signature. STRING gives the status: + + "error" - there was a problem checking this or any signature. + "unsupported" - the signature type is not supported. + "no-cert" - The certificate of the signer was not found (the + S/N+issuer of the signer is already in the log). + "bad" - bad signature + "good" - good signature + */ + + AUDIT_NEW_RECP, /* int */ + /* A new recipient has been seen during decryption. The argument + is the recipient number as used internally by the program. */ + + AUDIT_RECP_NAME, /* string */ + /* The name of a recipient. This is the name or other identification + data as known from the decryption and not the name from the + certificate used for decryption. An example for STRING when + using CMS is: "#1234/CN=Prostetnic Vogon Jeltz". */ + + AUDIT_RECP_RESULT, /* ok_err */ + /* The status of the session key decryption. This is only written + for recipients tried. */ + + AUDIT_DECRYPTION_RESULT, /* ok_err */ + /* The status of the entire decryption. The decryption was + successful if the error code is 0. */ + + AUDIT_VALIDATE_CHAIN, + /* Start the validation of a certificate chain. */ + + AUDIT_CHAIN_BEGIN, + AUDIT_CHAIN_CERT, /* cert */ + AUDIT_CHAIN_ROOTCERT,/* cert */ + AUDIT_CHAIN_END, + /* These 4 events are used to log the certificates making up a + certificate chain. ROOTCERT is used for the trustanchor and + CERT for all other certificates. */ + + AUDIT_CHAIN_STATUS, /* err */ + /* Tells the final status of the chain validation. */ + + AUDIT_ROOT_TRUSTED, /* cert, err */ + /* Tells whether the root certificate is trusted. This event is + emmited durcing chain validation. */ + + AUDIT_CRL_CHECK, /* err */ + /* Tells the status of a CRL or OCSP check. */ + + AUDIT_GOT_RECIPIENTS, /* int */ + /* Records the number of recipients to be used for encryption. + This includes the recipients set by --encrypt-to but records 0 + if no real recipient has been given. */ + + AUDIT_SESSION_KEY, /* string */ + /* Mark the creation or availibility of the session key. The + parameter is the algorithm ID. */ + + AUDIT_ENCRYPTED_TO, /* cert, err */ + /* Records the certificate used for encryption and whether the + session key could be encrypted to it (err==0). */ + + AUDIT_ENCRYPTION_DONE, + /* Encryption succeeded. */ + + AUDIT_SIGNED_BY, /* cert, err */ + /* Records the certificate used for signed and whether the signure + could be created (if err==0). */ + + AUDIT_SIGNING_DONE, + /* Signing succeeded. */ + + + AUDIT_LAST_EVENT /* Marker for parsing this list. */ + } +audit_event_t; + + +audit_ctx_t audit_new (void); +void audit_release (audit_ctx_t ctx); +void audit_set_type (audit_ctx_t ctx, audit_type_t type); +void audit_log (audit_ctx_t ctx, audit_event_t event); +void audit_log_ok (audit_ctx_t ctx, audit_event_t event, gpg_error_t err); +void audit_log_i (audit_ctx_t ctx, audit_event_t event, int value); +void audit_log_s (audit_ctx_t ctx, audit_event_t event, const char *value); +void audit_log_cert (audit_ctx_t ctx, audit_event_t event, + ksba_cert_t cert, gpg_error_t err); + +void audit_print_result (audit_ctx_t ctx, estream_t stream, int use_html); + + + +#endif /*GNUPG_COMMON_AUDIT_H*/ diff --git a/common/b64dec.c b/common/b64dec.c new file mode 100644 index 0000000..af223ae --- /dev/null +++ b/common/b64dec.c @@ -0,0 +1,217 @@ +/* b64dec.c - Simple Base64 decoder. + * Copyright (C) 2008 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "util.h" + + +/* The reverse base-64 list used for base-64 decoding. */ +static unsigned char const asctobin[128] = + { + 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 + }; + +enum decoder_states + { + s_init, s_idle, s_lfseen, s_begin, + s_b64_0, s_b64_1, s_b64_2, s_b64_3, + s_waitendtitle, s_waitend + }; + + + +/* Initialize the context for the base64 decoder. If TITLE is NULL a + plain base64 decoding is done. If it is the empty string the + decoder will skip everything until a "-----BEGIN " line has been + seen, decoding ends at a "----END " line. + + Not yet implemented: If TITLE is either "PGP" or begins with "PGP " + the PGP armor lines are skipped as well. */ +gpg_error_t +b64dec_start (struct b64state *state, const char *title) +{ + memset (state, 0, sizeof *state); + if (title) + { + if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' ')) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + state->title = xtrystrdup (title); + if (!state->title) + return gpg_error_from_syserror (); + state->idx = s_init; + } + else + state->idx = s_b64_0; + return 0; +} + + +/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the + new length of the buffer at R_NBYTES. */ +gpg_error_t +b64dec_proc (struct b64state *state, void *buffer, size_t length, + size_t *r_nbytes) +{ + enum decoder_states ds = state->idx; + unsigned char val = state->radbuf[0]; + int pos = state->quad_count; + char *d, *s; + + if (state->stop_seen) + { + *r_nbytes = 0; + return gpg_error (GPG_ERR_EOF); + } + + for (s=d=buffer; length && !state->stop_seen; length--, s++) + { + switch (ds) + { + case s_idle: + if (*s == '\n') + { + ds = s_lfseen; + pos = 0; + } + break; + case s_init: + ds = s_lfseen; + case s_lfseen: + if (*s != "-----BEGIN "[pos]) + ds = s_idle; + else if (pos == 10) + ds = s_begin; + else + pos++; + break; + case s_begin: + if (*s == '\n') + ds = s_b64_0; + break; + case s_b64_0: + case s_b64_1: + case s_b64_2: + case s_b64_3: + { + int c; + + if (*s == '-' && state->title) + { + /* Not a valid Base64 character: assume end + header. */ + ds = s_waitend; + } + else if (*s == '=') + { + /* Pad character: stop */ + if (ds == s_b64_1) + *d++ = val; + ds = state->title? s_waitendtitle : s_waitend; + } + else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t') + ; /* Skip white spaces. */ + else if ( (*s & 0x80) + || (c = asctobin[*(unsigned char *)s]) == 255) + { + /* Skip invalid encodings. */ + state->invalid_encoding = 1; + } + else if (ds == s_b64_0) + { + val = c << 2; + ds = s_b64_1; + } + else if (ds == s_b64_1) + { + val |= (c>>4)&3; + *d++ = val; + val = (c<<4)&0xf0; + ds = s_b64_2; + } + else if (ds == s_b64_2) + { + val |= (c>>2)&15; + *d++ = val; + val = (c<<6)&0xc0; + ds = s_b64_3; + } + else + { + val |= c&0x3f; + *d++ = val; + ds = s_b64_0; + } + } + break; + case s_waitendtitle: + if (*s == '-') + ds = s_waitend; + break; + case s_waitend: + if ( *s == '\n') + state->stop_seen = 1; + break; + default: + BUG(); + } + } + + + state->idx = ds; + state->radbuf[0] = val; + state->quad_count = pos; + *r_nbytes = (d -(char*) buffer); + return 0; +} + + +/* This function needs to be called before releasing the decoder + state. It may return an error code in case an encoding error has + been found during decoding. */ +gpg_error_t +b64dec_finish (struct b64state *state) +{ + xfree (state->title); + state->title = NULL; + return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; +} + diff --git a/common/b64enc.c b/common/b64enc.c new file mode 100644 index 0000000..4722bd1 --- /dev/null +++ b/common/b64enc.c @@ -0,0 +1,351 @@ +/* b64enc.c - Simple Base64 encoder. + * Copyright (C) 2001, 2003, 2004, 2008 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 3 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, see . + */ + +#include +#include +#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 +#define B64ENC_USE_PGPCRC 32 + +/* The base-64 character list */ +static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +/* Stuff required to create the OpenPGP CRC. This crc_table has been + created using this code: + + #include + #include + + #define CRCPOLY 0x864CFB + + int + main (void) + { + int i, j; + uint32_t t; + uint32_t crc_table[256]; + + 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; + } + } + + puts ("static const u32 crc_table[256] = {"); + for (i=j=0; i < 256; i++) + { + printf ("%s 0x%08lx", j? "":" ", (unsigned long)crc_table[i]); + if (i != 255) + { + putchar (','); + if ( ++j > 5) + { + j = 0; + putchar ('\n'); + } + } + } + puts ("\n};"); + return 0; + } +*/ +#define CRCINIT 0xB704CE +static const u32 crc_table[256] = { + 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, + 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf, + 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, + 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, + 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa, + 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, + 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, + 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, + 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, + 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, + 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, + 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, + 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, + 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, 0x30563856, 0x30d074ad, + 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, + 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, + 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821, + 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, + 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, + 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5, + 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, + 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, + 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66, + 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, + 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, + 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2, + 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, + 0x62b54340, 0x62330fbb, 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, + 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e, + 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, + 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, + 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea, + 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, + 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, + 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604, + 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, + 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, + 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69, + 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, + 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, + 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c, + 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, + 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538 +}; + + +/* 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. + If TITLE starts with "PGP " the OpenPGP CRC checksum will be + written as well. 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) + { + if (!strncmp (title, "PGP ", 4)) + { + state->flags |= B64ENC_USE_PGPCRC; + state->crc = CRCINIT; + } + state->title = xtrystrdup (title); + if (!state->title) + return gpg_error_from_syserror (); + } + 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; + if ( (state->flags & B64ENC_USE_PGPCRC) + && 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); + + if ( (state->flags & B64ENC_USE_PGPCRC) ) + { + size_t n; + u32 crc = state->crc; + + for (p=buffer, n=nbytes; n; p++, n-- ) + crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p]; + state->crc = (crc & 0x00ffffff); + } + + 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_syserror (); +} + +gpg_error_t +b64enc_finish (struct b64state *state) +{ + gpg_error_t err = 0; + unsigned char radbuf[4]; + int idx, quad_count; + FILE *fp; + char tmp[4]; + + 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) + { + 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->flags & B64ENC_USE_PGPCRC) ) + { + /* Write the CRC. */ + putc ('=', fp); + radbuf[0] = state->crc >>16; + radbuf[1] = state->crc >> 8; + radbuf[2] = state->crc; + 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); + if (ferror (fp)) + goto write_error; + if (!(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_syserror (); + + cleanup: + if (state->title) + { + xfree (state->title); + state->title = NULL; + } + state->fp = NULL; + return err; +} + diff --git a/common/common-defs.h b/common/common-defs.h new file mode 100644 index 0000000..4a550c3 --- /dev/null +++ b/common/common-defs.h @@ -0,0 +1,33 @@ +/* common-defs.h - Private declarations for common/ + * Copyright (C) 2006 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_COMMON_DEFS_H +#define GNUPG_COMMON_COMMON_DEFS_H + +/*-- ttyio.c --*/ +void tty_private_set_rl_hooks (void (*init_stream) (FILE *), + void (*set_completer) (rl_completion_func_t*), + void (*inhibit_completion) (int), + void (*cleanup_after_signal) (void), + char *(*readline_fun) (const char*), + void (*add_history_fun) (const char*)); + + + +#endif /*GNUPG_COMMON_COMMON_DEFS_H*/ diff --git a/common/convert.c b/common/convert.c new file mode 100644 index 0000000..d3e8b64 --- /dev/null +++ b/common/convert.c @@ -0,0 +1,249 @@ +/* convert.c - Hex conversion functions. + * Copyright (C) 2006, 2008 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 3 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, see . + */ + +#include +#include +#include +#include + +#include "util.h" + + +#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) + + +/* Convert STRING consisting of hex characters into its binary + representation and store that at BUFFER. BUFFER needs to be of + LENGTH bytes. The function checks that the STRING will convert + exactly to LENGTH bytes. The string is delimited by either end of + string or a white space character. The function returns -1 on + error or the length of the parsed string. */ +int +hex2bin (const char *string, void *buffer, size_t length) +{ + int i; + const char *s = string; + + for (i=0; i < length; ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return -1; /* Invalid hex digits. */ + ((unsigned char*)buffer)[i++] = xtoi_2 (s); + s += 2; + } + if (*s && (!isascii (*s) || !isspace (*s)) ) + return -1; /* Not followed by Nul or white space. */ + if (i != length) + return -1; /* Not of expected length. */ + if (*s) + s++; /* Skip the delimiter. */ + return s - string; +} + + +/* Convert STRING consisting of hex characters into its binary representation + and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The + function check that the STRING will convert exactly to LENGTH + bytes. Colons inbetween the hex digits are allowed, if one colon + has been given a colon is expected very 2 characters. The string + is delimited by either end of string or a white space character. + The function returns -1 on error or the length of the parsed + string. */ +int +hexcolon2bin (const char *string, void *buffer, size_t length) +{ + int i; + const char *s = string; + int need_colon = 0; + + for (i=0; i < length; ) + { + if (i==1 && *s == ':') /* Skip colons between hex digits. */ + { + need_colon = 1; + s++; + } + else if (need_colon && *s == ':') + s++; + else if (need_colon) + return -1; /* Colon expected. */ + if (!hexdigitp (s) || !hexdigitp (s+1)) + return -1; /* Invalid hex digits. */ + ((unsigned char*)buffer)[i++] = xtoi_2 (s); + s += 2; + } + if (*s == ':') + return -1; /* Trailing colons are not allowed. */ + if (*s && (!isascii (*s) || !isspace (*s)) ) + return -1; /* Not followed by Nul or white space. */ + if (i != length) + return -1; /* Not of expected length. */ + if (*s) + s++; /* Skip the delimiter. */ + return s - string; +} + + + +static char * +do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon) +{ + const unsigned char *s; + char *p; + + if (!stringbuf) + { + /* Not really correct for with_colon but we don't care about the + one wasted byte. */ + size_t n = with_colon? 3:2; + size_t nbytes = n * length + 1; + if (length && (nbytes-1) / n != length) + { + errno = ENOMEM; + return NULL; + } + stringbuf = xtrymalloc (nbytes); + if (!stringbuf) + return NULL; + } + + for (s = buffer, p = stringbuf; length; length--, s++) + { + if (with_colon && s != buffer) + *p++ = ':'; + *p++ = tohex ((*s>>4)&15); + *p++ = tohex (*s&15); + } + *p = 0; + + return stringbuf; +} + + +/* Convert LENGTH bytes of data in BUFFER into hex encoding and store + that at the provided STRINGBUF. STRINGBUF must be allocated of at + least (2*LENGTH+1) bytes or be NULL so that the function mallocs an + appropriate buffer. Returns STRINGBUF or NULL on error (which may + only occur if STRINGBUF has been NULL and the internal malloc + failed). */ +char * +bin2hex (const void *buffer, size_t length, char *stringbuf) +{ + return do_bin2hex (buffer, length, stringbuf, 0); +} + +/* Convert LENGTH bytes of data in BUFFER into hex encoding and store + that at the provided STRINGBUF. STRINGBUF must be allocated of at + least (3*LENGTH+1) bytes or be NULL so that the function mallocs an + appropriate buffer. Returns STRINGBUF or NULL on error (which may + only occur if STRINGBUF has been NULL and the internal malloc + failed). */ +char * +bin2hexcolon (const void *buffer, size_t length, char *stringbuf) +{ + return do_bin2hex (buffer, length, stringbuf, 1); +} + + + +/* Convert HEXSTRING consisting of hex characters into string and + store that at BUFFER. HEXSTRING is either delimited by end of + string or a white space character. The function makes sure that + the resulting string in BUFFER is terminated by a Nul character. + BUFSIZE is the availabe length of BUFFER; if the converted result + plus a possible required Nul character does not fit into this + buffer, the function returns NULL and won't change the existing + conent of buffer. In-place conversion is possible as long as + BUFFER points to HEXSTRING. + + If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but + does not store anything. This may be used to find the end of + hexstring. + + On sucess the function returns a pointer to the next character + after HEXSTRING (which is either end-of-string or a the next white + space). If BUFLEN is not NULL the strlen of buffer is stored + there; this will even be done if BUFFER has been passed as NULL. */ +const char * +hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen) +{ + const char *s = hexstring; + int idx, count; + int need_nul = 0; + + if (buflen) + *buflen = 0; + + for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++) + ; + if (*s && (!isascii (*s) || !isspace (*s)) ) + return NULL; /* Not followed by Nul or white space. */ + /* We need to append a nul character. However we don't want that if + the hexstring already ends with "00". */ + need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0')); + if (need_nul) + count++; + + if (buffer) + { + if (count > bufsize) + return NULL; /* Too long. */ + + for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2) + ((unsigned char*)buffer)[idx++] = xtoi_2 (s); + if (need_nul) + buffer[idx] = 0; + } + + if (buflen) + *buflen = count - 1; + return s; +} + + +/* Same as hex2str but this function allocated a new string. Returns + NULL on error. If R_COUNT is not NULL, the number of scanned bytes + will be stored there. ERRNO is set on error. */ +char * +hex2str_alloc (const char *hexstring, size_t *r_count) +{ + const char *tail; + size_t nbytes; + char *result; + + tail = hex2str (hexstring, NULL, 0, &nbytes); + if (!tail) + { + if (r_count) + *r_count = 0; + errno = EINVAL; + return NULL; + } + if (r_count) + *r_count = tail - hexstring; + result = xtrymalloc (nbytes+1); + if (!result) + return NULL; + if (!hex2str (hexstring, result, nbytes+1, NULL)) + BUG (); + return result; +} + + + diff --git a/common/dns-cert.c b/common/dns-cert.c new file mode 100644 index 0000000..efdefaf --- /dev/null +++ b/common/dns-cert.c @@ -0,0 +1,342 @@ +/* dns-cert.c - DNS CERT code + * Copyright (C) 2005, 2006, 2009 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 3 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, see . + */ + +#include +#include +#ifdef USE_DNS_CERT +# ifdef HAVE_W32_SYSTEM +# include +# else +# include +# include +# include +# endif +# include +#endif +#ifdef USE_ADNS +# include +# ifndef HAVE_ADNS_FREE +# define adns_free free +# endif +#endif + +#include "util.h" +#include "iobuf.h" +#include "dns-cert.h" + +/* Not every installation has gotten around to supporting CERTs + yet... */ +#ifndef T_CERT +#define T_CERT 37 +#endif + +/* ADNS has no support for CERT yes. */ +#define my_adns_r_cert 37 + + + +/* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for + IPGP provided. Note that this fucntion retruns the first CERT + found with a supported type; it is expected that only one CERT + record is used. */ +int +get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, + unsigned char **fpr, size_t *fpr_len, char **url) +{ +#ifdef USE_DNS_CERT +#ifdef USE_ADNS + adns_state state; + adns_answer *answer = NULL; + int rc; + unsigned int ctype; + int count; + + rc = adns_init (&state, adns_if_noerrprint, NULL); + if (rc) + { + log_error ("error initializing adns: %s\n", strerror (errno)); + return -1; + } + + rc = adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert), + adns_qf_quoteok_query, &answer); + if (rc) + { + /* log_error ("DNS query failed: %s\n", strerror (errno)); */ + adns_finish (state); + return -1; + } + if (answer->status != adns_s_ok) + { + /* log_error ("DNS query returned an error: %s (%s)\n", */ + /* adns_strerror (answer->status), */ + /* adns_errabbrev (answer->status)); */ + adns_free (answer); + adns_finish (state); + return 0; + } + + for (rc = 0, count=0; !rc && count < answer->nrrs; count++) + { + int datalen = answer->rrs.byteblock[count].len; + const unsigned char *data = answer->rrs.byteblock[count].data; + + if (datalen < 5) + continue; /* Truncated CERT record - skip. */ + + ctype = ((data[0]<<8)|data[1]); + /* (key tag and algorithm fields are not required.) */ + data += 5; + datalen -= 5; + + if (ctype == 3 && datalen >= 11) + { + /* CERT type is PGP. Gpg checks for a minimum length of 11, + thus we do the same. */ + *iobuf = iobuf_temp_with_content ((char*)data, datalen); + rc = 1; + } + else if (ctype == 6 && datalen && datalen < 1023 + && datalen >= data[0]+1 && fpr && fpr_len && url) + { + /* CERT type is IPGP. We made sure tha the data is + plausible and that the caller requested the + information. */ + *fpr_len = data[0]; + if (*fpr_len) + { + *fpr = xmalloc (*fpr_len); + memcpy (*fpr, data+1, *fpr_len); + } + else + *fpr = NULL; + + if (datalen > *fpr_len + 1) + { + *url = xmalloc (datalen - (*fpr_len+1) + 1); + memcpy (*url, data + (*fpr_len+1), datalen - (*fpr_len+1)); + (*url)[datalen - (*fpr_len+1)] = '\0'; + } + else + *url = NULL; + + rc = 2; + } + } + + adns_free (answer); + adns_finish (state); + return rc; + +#else /*!USE_ADNS*/ + + unsigned char *answer; + int r,ret=-1; + u16 count; + + if(fpr) + *fpr=NULL; + + if(url) + *url=NULL; + + answer=xmalloc(max_size); + + r=res_query(name,C_IN,T_CERT,answer,max_size); + /* Not too big, not too small, no errors and at least 1 answer. */ + if(r>=sizeof(HEADER) && r<=max_size + && (((HEADER *)answer)->rcode)==NOERROR + && (count=ntohs(((HEADER *)answer)->ancount))) + { + int rc; + unsigned char *pt,*emsg; + + emsg=&answer[r]; + + pt=&answer[sizeof(HEADER)]; + + /* Skip over the query */ + + rc=dn_skipname(pt,emsg); + if(rc==-1) + goto fail; + + pt+=rc+QFIXEDSZ; + + /* There are several possible response types for a CERT request. + We're interested in the PGP (a key) and IPGP (a URI) types. + Skip all others. TODO: A key is better than a URI since + we've gone through all this bother to fetch it, so favor that + if we have both PGP and IPGP? */ + + while(count-->0 && pt=pt[0]+1 + && fpr && fpr_len && url) + { + /* IPGP type */ + *fpr_len=pt[0]; + + if(*fpr_len) + { + *fpr=xmalloc(*fpr_len); + memcpy(*fpr,&pt[1],*fpr_len); + } + else + *fpr=NULL; + + if(dlen>*fpr_len+1) + { + *url=xmalloc(dlen-(*fpr_len+1)+1); + memcpy(*url,&pt[*fpr_len+1],dlen-(*fpr_len+1)); + (*url)[dlen-(*fpr_len+1)]='\0'; + } + else + *url=NULL; + + ret=2; + break; + } + + /* Neither type matches, so go around to the next answer. */ + pt+=dlen; + } + } + + fail: + xfree(answer); + return ret; +#endif /*!USE_ADNS*/ +#else /* !USE_DNS_CERT */ + return -1; +#endif +} + + + +/* Test with simon.josefsson.org */ + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + unsigned char *fpr; + size_t fpr_len; + char *url; + int rc; + IOBUF iobuf; + + if(argc!=2) + { + printf("cert-test [name]\n"); + return 1; + } + + printf("CERT lookup on %s\n",argv[1]); + + rc=get_dns_cert (argv[1],16384,&iobuf,&fpr,&fpr_len,&url); + if(rc==-1) + printf("error\n"); + else if(rc==0) + printf("no answer\n"); + else if(rc==1) + { + printf("key found: %d bytes\n",(int)iobuf_get_temp_length(iobuf)); + iobuf_close(iobuf); + } + else if(rc==2) + { + if(fpr) + { + size_t i; + printf("Fingerprint found (%d bytes): ",(int)fpr_len); + for(i=0;i. + */ +#ifndef GNUPG_COMMON_DNS_CERT_H +#define GNUPG_COMMON_DNS_CERT_H + +int get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, + unsigned char **fpr, size_t *fpr_len, char **url); + + +#endif /*GNUPG_COMMON_DNS_CERT_H*/ diff --git a/common/estream-printf.c b/common/estream-printf.c new file mode 100644 index 0000000..a5f3a69 --- /dev/null +++ b/common/estream-printf.c @@ -0,0 +1,1788 @@ +/* estream-printf.c - Versatile C-99 compliant printf formatting + * Copyright (C) 2007, 2008, 2009 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream 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. + * + * Libestream is distributed in the hope that 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 Libestream; if not, see . + */ + +/* Required autoconf tests: + + AC_TYPE_LONG_LONG_INT defines HAVE_LONG_LONG_INT + AC_TYPE_LONG_DOUBLE defines HAVE_LONG_DOUBLE + AC_TYPE_INTMAX_T defines HAVE_INTMAX_T + AC_TYPE_UINTMAX_T defines HAVE_UINTMAX_T + AC_CHECK_TYPES([ptrdiff_t]) defines HAVE_PTRDIFF_T + AC_CHECK_SIZEOF([unsigned long]) defines SIZEOF_UNSIGNED_LONG + AC_CHECK_SIZEOF([void *]) defines SIZEOF_VOID_P + HAVE_LANGINFO_THOUSANDS_SEP + + Note that the file estream.m4 provides the autoconf macro + ESTREAM_PRINTF_INIT which runs all required checks. + See estream-printf.h for ways to tune this code. + + Missing stuff: wchar and wint_t + thousands_sep in pr_float. + +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(HAVE_INTMAX_T) || defined(HAVE_UINTMAX_T) +# ifdef HAVE_STDINT_H +# include +# endif +#endif +#ifdef HAVE_LANGINFO_THOUSANDS_SEP +#include +#endif +#ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE +# include _ESTREAM_PRINTF_EXTRA_INCLUDE +#endif +#include "estream-printf.h" + +/* #define DEBUG 1 */ + + +/* Allow redefinition of asprintf used malloc functions. */ +#if defined(_ESTREAM_PRINTF_MALLOC) +#define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a)) +#else +#define my_printf_malloc(a) malloc((a)) +#endif +#if defined(_ESTREAM_PRINTF_FREE) +#define my_printf_free(a) _ESTREAM_PRINTF_FREE((a)) +#else +#define my_printf_free(a) free((a)) +#endif + + +/* Calculate array dimension. */ +#ifndef DIM +#define DIM(array) (sizeof (array) / sizeof (*array)) +#endif + + +/* We allow for that many args without requiring malloced memory. */ +#define DEFAULT_MAX_ARGSPECS 5 + +/* We allow for that many values without requiring malloced memory. */ +#define DEFAULT_MAX_VALUES 8 + +/* We allocate this many new array argspec elements each time. */ +#define ARGSPECS_BUMP_VALUE 10 + +/* Special values for the field width and the precision. */ +#define NO_FIELD_VALUE (-1) +#define STAR_FIELD_VALUE (-2) + +/* Bit valuues used for the conversion flags. */ +#define FLAG_GROUPING 1 +#define FLAG_LEFT_JUST 2 +#define FLAG_PLUS_SIGN 4 +#define FLAG_SPACE_PLUS 8 +#define FLAG_ALT_CONV 16 +#define FLAG_ZERO_PAD 32 + +/* Constants used the length modifiers. */ +typedef enum + { + LENMOD_NONE = 0, + LENMOD_CHAR, /* "hh" */ + LENMOD_SHORT, /* "h" */ + LENMOD_LONG, /* "l" */ + LENMOD_LONGLONG, /* "ll" */ + LENMOD_INTMAX, /* "j" */ + LENMOD_SIZET, /* "z" */ + LENMOD_PTRDIFF, /* "t" */ + LENMOD_LONGDBL /* "L" */ + } lenmod_t; + +/* All the conversion specifiers. */ +typedef enum + { + CONSPEC_UNKNOWN = 0, + CONSPEC_DECIMAL, + CONSPEC_OCTAL, + CONSPEC_UNSIGNED, + CONSPEC_HEX, + CONSPEC_HEX_UP, + CONSPEC_FLOAT, + CONSPEC_FLOAT_UP, + CONSPEC_EXP, + CONSPEC_EXP_UP, + CONSPEC_F_OR_G, + CONSPEC_F_OR_G_UP, + CONSPEC_HEX_EXP, + CONSPEC_HEX_EXP_UP, + CONSPEC_CHAR, + CONSPEC_STRING, + CONSPEC_POINTER, + CONSPEC_STRERROR, + CONSPEC_BYTES_SO_FAR + } conspec_t; + + +/* Constants describing all the suppoorted types. Note that we list + all the types we know about even if certain types are not available + on this system. */ +typedef enum + { + VALTYPE_UNSUPPORTED = 0, /* Artificial type for error detection. */ + VALTYPE_CHAR, + VALTYPE_SCHAR, + VALTYPE_UCHAR, + VALTYPE_SHORT, + VALTYPE_USHORT, + VALTYPE_INT, + VALTYPE_UINT, + VALTYPE_LONG, + VALTYPE_ULONG, + VALTYPE_LONGLONG, + VALTYPE_ULONGLONG, + VALTYPE_DOUBLE, + VALTYPE_LONGDOUBLE, + VALTYPE_STRING, + VALTYPE_INTMAX, + VALTYPE_UINTMAX, + VALTYPE_SIZE, + VALTYPE_PTRDIFF, + VALTYPE_POINTER, + VALTYPE_CHAR_PTR, + VALTYPE_SCHAR_PTR, + VALTYPE_SHORT_PTR, + VALTYPE_INT_PTR, + VALTYPE_LONG_PTR, + VALTYPE_LONGLONG_PTR, + VALTYPE_INTMAX_PTR, + VALTYPE_SIZE_PTR, + VALTYPE_PTRDIFF_PTR + } valtype_t; + + +/* A union used to store the actual values. */ +typedef union +{ + char a_char; + signed char a_schar; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long int a_long; + unsigned long int a_ulong; +#ifdef HAVE_LONG_LONG_INT + long long int a_longlong; + unsigned long long int a_ulonglong; +#endif + double a_double; +#ifdef HAVE_LONG_DOUBLE + long double a_longdouble; +#endif + const char *a_string; +#ifdef HAVE_INTMAX_T + intmax_t a_intmax; +#endif +#ifdef HAVE_UINTMAX_T + intmax_t a_uintmax; +#endif + size_t a_size; +#ifdef HAVE_PTRDIFF_T + ptrdiff_t a_ptrdiff; +#endif + void *a_void_ptr; + char *a_char_ptr; + signed char *a_schar_ptr; + short *a_short_ptr; + int *a_int_ptr; + long *a_long_ptr; +#ifdef HAVE_LONG_LONG_INT + long long int *a_longlong_ptr; +#endif +#ifdef HAVE_INTMAX_T + intmax_t *a_intmax_ptr; +#endif + size_t *a_size_ptr; +#ifdef HAVE_PTRDIFF_T + ptrdiff_t *a_ptrdiff_ptr; +#endif +} value_t; + +/* An object used to keep track of a format option and arguments. */ +struct argspec_s +{ + size_t length; /* The length of these args including the percent. */ + unsigned int flags; /* The conversion flags (bits defined by FLAG_foo). */ + int width; /* The field width. */ + int precision; /* The precision. */ + lenmod_t lenmod; /* The length modifier. */ + conspec_t conspec; /* The conversion specifier. */ + int arg_pos; /* The position of the argument. This one may + be -1 to indicate that no value is expected + (e.g. for "%m"). */ + int width_pos; /* The position of the argument for a field + width star's value. 0 for not used. */ + int precision_pos; /* The position of the argument for the a + precision star's value. 0 for not used. */ + valtype_t vt; /* The type of the corresponding argument. */ +}; +typedef struct argspec_s *argspec_t; + +/* An object to build up a table of values and their types. */ +struct valueitem_s +{ + valtype_t vt; /* The type of the value. */ + value_t value; /* The value. */ +}; +typedef struct valueitem_s *valueitem_t; + + +#ifdef DEBUG +static void +dump_argspecs (argspec_t arg, size_t argcount) +{ + int idx; + + for (idx=0; argcount; argcount--, arg++, idx++) + fprintf (stderr, + "%2d: len=%u flags=%u width=%d prec=%d mod=%d " + "con=%d vt=%d pos=%d-%d-%d\n", + idx, + (unsigned int)arg->length, + arg->flags, + arg->width, + arg->precision, + arg->lenmod, + arg->conspec, + arg->vt, + arg->arg_pos, + arg->width_pos, + arg->precision_pos); +} +#endif /*DEBUG*/ + + +/* Set the vt field for ARG. */ +static void +compute_type (argspec_t arg) +{ + switch (arg->conspec) + { + case CONSPEC_UNKNOWN: + arg->vt = VALTYPE_UNSUPPORTED; + break; + + case CONSPEC_DECIMAL: + switch (arg->lenmod) + { + case LENMOD_CHAR: arg->vt = VALTYPE_SCHAR; break; + case LENMOD_SHORT: arg->vt = VALTYPE_SHORT; break; + case LENMOD_LONG: arg->vt = VALTYPE_LONG; break; + case LENMOD_LONGLONG: arg->vt = VALTYPE_LONGLONG; break; + case LENMOD_INTMAX: arg->vt = VALTYPE_INTMAX; break; + case LENMOD_SIZET: arg->vt = VALTYPE_SIZE; break; + case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF; break; + default: arg->vt = VALTYPE_INT; break; + } + break; + + case CONSPEC_OCTAL: + case CONSPEC_UNSIGNED: + case CONSPEC_HEX: + case CONSPEC_HEX_UP: + switch (arg->lenmod) + { + case LENMOD_CHAR: arg->vt = VALTYPE_UCHAR; break; + case LENMOD_SHORT: arg->vt = VALTYPE_USHORT; break; + case LENMOD_LONG: arg->vt = VALTYPE_ULONG; break; + case LENMOD_LONGLONG: arg->vt = VALTYPE_ULONGLONG; break; + case LENMOD_INTMAX: arg->vt = VALTYPE_UINTMAX; break; + case LENMOD_SIZET: arg->vt = VALTYPE_SIZE; break; + case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF; break; + default: arg->vt = VALTYPE_UINT; break; + } + break; + + case CONSPEC_FLOAT: + case CONSPEC_FLOAT_UP: + case CONSPEC_EXP: + case CONSPEC_EXP_UP: + case CONSPEC_F_OR_G: + case CONSPEC_F_OR_G_UP: + case CONSPEC_HEX_EXP: + case CONSPEC_HEX_EXP_UP: + switch (arg->lenmod) + { + case LENMOD_LONGDBL: arg->vt = VALTYPE_LONGDOUBLE; break; + case LENMOD_LONG: arg->vt = VALTYPE_DOUBLE; break; + default: arg->vt = VALTYPE_DOUBLE; break; + } + break; + + case CONSPEC_CHAR: + arg->vt = VALTYPE_INT; + break; + + case CONSPEC_STRING: + arg->vt = VALTYPE_STRING; + break; + + case CONSPEC_POINTER: + arg->vt = VALTYPE_POINTER; + break; + + case CONSPEC_STRERROR: + arg->vt = VALTYPE_STRING; + break; + + case CONSPEC_BYTES_SO_FAR: + switch (arg->lenmod) + { + case LENMOD_CHAR: arg->vt = VALTYPE_SCHAR_PTR; break; + case LENMOD_SHORT: arg->vt = VALTYPE_SHORT_PTR; break; + case LENMOD_LONG: arg->vt = VALTYPE_LONG_PTR; break; + case LENMOD_LONGLONG: arg->vt = VALTYPE_LONGLONG_PTR; break; + case LENMOD_INTMAX: arg->vt = VALTYPE_INTMAX_PTR; break; + case LENMOD_SIZET: arg->vt = VALTYPE_SIZE_PTR; break; + case LENMOD_PTRDIFF: arg->vt = VALTYPE_PTRDIFF_PTR; break; + default: arg->vt = VALTYPE_INT_PTR; break; + } + break; + + } +} + + + +/* Parse the FORMAT string and populate the specification array stored + at the address ARGSPECS_ADDR. The caller has provided enough space + to store up to MAX_ARGSPECS in that buffer. The function may + however ignore the provided buffer and malloc a larger one. On + success the addrrss of that larger buffer will be stored at + ARGSPECS_ADDR. The actual number of specifications will be + returned at R_ARGSPECS_COUNT. */ +static int +parse_format (const char *format, + argspec_t *argspecs_addr, size_t max_argspecs, + size_t *r_argspecs_count) +{ + const char *s; + argspec_t argspecs = *argspecs_addr; + argspec_t arg; + size_t argcount = 0; + + if (!format) + goto leave_einval; + + for (; *format; format++) + { + unsigned int flags; + int width, precision; + lenmod_t lenmod; + conspec_t conspec; + int arg_pos, width_pos, precision_pos; + + if (*format != '%') + continue; + s = ++format; + if (!*s) + goto leave_einval; + if (*s == '%') + continue; /* Just a quoted percent. */ + + /* First check whether there is a positional argument. */ + arg_pos = 0; /* No positional argument given. */ + if (*s >= '1' && *s <= '9') + { + const char *save_s = s; + + arg_pos = (*s++ - '0'); + for (; *s >= '0' && *s <= '9'; s++) + arg_pos = 10*arg_pos + (*s - '0'); + if (arg_pos < 0) + goto leave_einval; /* Overflow during conversion. */ + if (*s == '$') + s++; + else + { + arg_pos = 0; + s = save_s; + } + } + + /* Parse the flags. */ + flags = 0; + for ( ; *s; s++) + { + switch (*s) + { + case '\'': flags |= FLAG_GROUPING; break; + case '-': flags |= FLAG_LEFT_JUST; break; + case '+': flags |= FLAG_PLUS_SIGN; break; + case ' ': flags |= FLAG_SPACE_PLUS; break; + case '#': flags |= FLAG_ALT_CONV; break; + case '0': flags |= FLAG_ZERO_PAD; break; + default: + goto flags_parsed; + } + } + flags_parsed: + + /* Parse the field width. */ + width_pos = 0; + if (*s == '*') + { + width = STAR_FIELD_VALUE; + s++; + /* If we have a positional argument, another one might also + be used to give the position of the star's value. */ + if (arg_pos && *s >= '1' && *s <= '9') + { + width_pos = (*s++ - '0'); + for (; *s >= '0' && *s <= '9'; s++) + width_pos = 10*width_pos + (*s - '0'); + if (width_pos < 1) + goto leave_einval; /* Overflow during conversion. */ + if (*s != '$') + goto leave_einval; /* Not followed by $. */ + s++; + } + } + else if ( *s >= '0' && *s <= '9') + { + width = (*s++ - '0'); + for (; *s >= '0' && *s <= '9'; s++) + { + if (!width && *s == '0') + goto leave_einval; /* Leading zeroes are not allowed. + Fixme: check what other + implementations do. */ + width = 10*width + (*s - '0'); + } + if (width < 0) + goto leave_einval; /* Overflow during conversion. */ + } + else + width = NO_FIELD_VALUE; + + /* Parse the precision. */ + precision_pos = 0; + precision = NO_FIELD_VALUE; + if (*s == '.') + { + int ignore_value = (s[1] == '-'); + + s++; + if (*s == '*') + { + precision = STAR_FIELD_VALUE; + s++; + /* If we have a positional argument, another one might also + be used to give the position of the star's value. */ + if (arg_pos && *s >= '1' && *s <= '9') + { + precision_pos = (*s++ - '0'); + for (; *s >= '0' && *s <= '9'; s++) + precision_pos = 10*precision_pos + (*s - '0'); + if (precision_pos < 1) + goto leave_einval; /* Overflow during conversion. */ + if (*s != '$') + goto leave_einval; /* Not followed by $. */ + s++; + } + } + else if ( *s >= '0' && *s <= '9') + { + precision = (*s++ - '0'); + for (; *s >= '0' && *s <= '9'; s++) + { + if (!precision && *s == '0') + goto leave_einval; /* Leading zeroes are not allowed. + Fixme: check what other + implementations do. */ + precision = 10*precision + (*s - '0'); + } + if (precision < 0) + goto leave_einval; /* Overflow during conversion. */ + } + else + precision = 0; + if (ignore_value) + precision = NO_FIELD_VALUE; + } + + /* Parse the length modifiers. */ + switch (*s) + { + case 'h': + if (s[1] == 'h') + { + lenmod = LENMOD_CHAR; + s++; + } + else + lenmod = LENMOD_SHORT; + s++; + break; + case 'l': + if (s[1] == 'l') + { + lenmod = LENMOD_LONGLONG; + s++; + } + else + lenmod = LENMOD_LONG; + s++; + break; + case 'j': lenmod = LENMOD_INTMAX; s++; break; + case 'z': lenmod = LENMOD_SIZET; s++; break; + case 't': lenmod = LENMOD_PTRDIFF; s++; break; + case 'L': lenmod = LENMOD_LONGDBL; s++; break; + default: lenmod = LENMOD_NONE; break; + } + + /* Parse the conversion specifier. */ + switch (*s) + { + case 'd': + case 'i': conspec = CONSPEC_DECIMAL; break; + case 'o': conspec = CONSPEC_OCTAL; break; + case 'u': conspec = CONSPEC_UNSIGNED; break; + case 'x': conspec = CONSPEC_HEX; break; + case 'X': conspec = CONSPEC_HEX_UP; break; + case 'f': conspec = CONSPEC_FLOAT; break; + case 'F': conspec = CONSPEC_FLOAT_UP; break; + case 'e': conspec = CONSPEC_EXP; break; + case 'E': conspec = CONSPEC_EXP_UP; break; + case 'g': conspec = CONSPEC_F_OR_G; break; + case 'G': conspec = CONSPEC_F_OR_G_UP; break; + case 'a': conspec = CONSPEC_HEX_EXP; break; + case 'A': conspec = CONSPEC_HEX_EXP_UP; break; + case 'c': conspec = CONSPEC_CHAR; break; + case 's': conspec = CONSPEC_STRING; break; + case 'p': conspec = CONSPEC_POINTER; break; + case 'n': conspec = CONSPEC_BYTES_SO_FAR; break; + case 'C': conspec = CONSPEC_CHAR; lenmod = LENMOD_LONG; break; + case 'S': conspec = CONSPEC_STRING; lenmod = LENMOD_LONG; break; + case 'm': conspec = CONSPEC_STRERROR; arg_pos = -1; break; + default: conspec = CONSPEC_UNKNOWN; + } + + /* Save the args. */ + if (argcount >= max_argspecs) + { + /* We either need to allocate a new array instead of the + caller provided one or realloc the array. Instead of + using realloc we allocate a new one and release the + original one then. */ + size_t n, newmax; + argspec_t newarg; + + newmax = max_argspecs + ARGSPECS_BUMP_VALUE; + if (newmax <= max_argspecs) + goto leave_einval; /* Too many arguments. */ + newarg = calloc (newmax, sizeof *newarg); + if (!newarg) + goto leave; + for (n=0; n < argcount; n++) + newarg[n] = argspecs[n]; + if (argspecs != *argspecs_addr) + free (argspecs); + argspecs = newarg; + max_argspecs = newmax; + } + + arg = argspecs + argcount; + arg->length = s - format + 2; + arg->flags = flags; + arg->width = width; + arg->precision = precision; + arg->lenmod = lenmod; + arg->conspec = conspec; + arg->arg_pos = arg_pos; + arg->width_pos = width_pos; + arg->precision_pos = precision_pos; + compute_type (arg); + argcount++; + format = s; + } + + *argspecs_addr = argspecs; + *r_argspecs_count = argcount; + return 0; /* Success. */ + + leave_einval: + errno = EINVAL; + leave: + if (argspecs != *argspecs_addr) + free (argspecs); + *argspecs_addr = NULL; + return -1; +} + + +/* This function reads all the values as specified by VALUETABLE into + VALUETABLE. The values are expected in VAARGS. The function + returns -1 if a specified type is not supported. */ +static int +read_values (valueitem_t valuetable, size_t valuetable_len, va_list vaargs) +{ + int validx; + + for (validx=0; validx < valuetable_len; validx++) + { + value_t *value = &valuetable[validx].value; + valtype_t vt = valuetable[validx].vt; + + switch (vt) + { + case VALTYPE_CHAR: value->a_char = va_arg (vaargs, int); break; + case VALTYPE_CHAR_PTR: + value->a_char_ptr = va_arg (vaargs, char *); + break; + case VALTYPE_SCHAR: value->a_schar = va_arg (vaargs, int); break; + case VALTYPE_SCHAR_PTR: + value->a_schar_ptr = va_arg (vaargs, signed char *); + break; + case VALTYPE_UCHAR: value->a_uchar = va_arg (vaargs, int); break; + case VALTYPE_SHORT: value->a_short = va_arg (vaargs, int); break; + case VALTYPE_USHORT: value->a_ushort = va_arg (vaargs, int); break; + case VALTYPE_SHORT_PTR: + value->a_short_ptr = va_arg (vaargs, short *); + break; + case VALTYPE_INT: + value->a_int = va_arg (vaargs, int); + break; + case VALTYPE_INT_PTR: + value->a_int_ptr = va_arg (vaargs, int *); + break; + case VALTYPE_UINT: + value->a_uint = va_arg (vaargs, unsigned int); + break; + case VALTYPE_LONG: + value->a_long = va_arg (vaargs, long); + break; + case VALTYPE_ULONG: + value->a_ulong = va_arg (vaargs, unsigned long); + break; + case VALTYPE_LONG_PTR: + value->a_long_ptr = va_arg (vaargs, long *); + break; +#ifdef HAVE_LONG_LONG_INT + case VALTYPE_LONGLONG: + value->a_longlong = va_arg (vaargs, long long int); + break; + case VALTYPE_ULONGLONG: + value->a_ulonglong = va_arg (vaargs, unsigned long long int); + break; + case VALTYPE_LONGLONG_PTR: + value->a_longlong_ptr = va_arg (vaargs, long long *); + break; +#endif + case VALTYPE_DOUBLE: + value->a_double = va_arg (vaargs, double); + break; +#ifdef HAVE_LONG_DOUBLE + case VALTYPE_LONGDOUBLE: + value->a_longdouble = va_arg (vaargs, long double); + break; +#endif + case VALTYPE_STRING: + value->a_string = va_arg (vaargs, const char *); + break; + case VALTYPE_POINTER: + value->a_void_ptr = va_arg (vaargs, void *); + break; +#ifdef HAVE_INTMAX_T + case VALTYPE_INTMAX: + value->a_intmax = va_arg (vaargs, intmax_t); + break; + case VALTYPE_INTMAX_PTR: + value->a_intmax_ptr = va_arg (vaargs, intmax_t *); + break; +#endif +#ifdef HAVE_UINTMAX_T + case VALTYPE_UINTMAX: + value->a_uintmax = va_arg (vaargs, uintmax_t); + break; +#endif + case VALTYPE_SIZE: + value->a_size = va_arg (vaargs, size_t); + break; + case VALTYPE_SIZE_PTR: + value->a_size_ptr = va_arg (vaargs, size_t *); + break; +#ifdef HAVE_PTRDIFF_T + case VALTYPE_PTRDIFF: + value->a_ptrdiff = va_arg (vaargs, ptrdiff_t); + break; + case VALTYPE_PTRDIFF_PTR: + value->a_ptrdiff_ptr = va_arg (vaargs, ptrdiff_t *); + break; +#endif + default: /* Unsupported type. */ + return -1; + } + } + return 0; +} + + + +/* Output COUNT padding characters PADCHAR and update NBYTES by the + number of bytes actually written. */ +static int +pad_out (estream_printf_out_t outfnc, void *outfncarg, + int padchar, int count, size_t *nbytes) +{ + char buf[32]; + size_t n; + int rc; + + while (count > 0) + { + n = (count <= sizeof buf)? count : sizeof buf; + memset (buf, padchar, n); + rc = outfnc (outfncarg, buf, n); + if (rc) + return rc; + *nbytes += n; + count -= n; + } + + return 0; +} + + +/* "d,i,o,u,x,X" formatting. OUTFNC and OUTFNCARG describes the + output routine, ARG gives the argument description and VALUE the + actual value (its type is available through arg->vt). */ +static int +pr_integer (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + int rc; +#ifdef HAVE_LONG_LONG_INT + unsigned long long aulong; +#else + unsigned long aulong; +#endif + char numbuf[100]; + char *p, *pend; + size_t n; + char signchar = 0; + int n_prec; /* Number of extra precision digits required. */ + int n_extra; /* Extra number of prefix or sign characters. */ + + if (arg->conspec == CONSPEC_DECIMAL) + { +#ifdef HAVE_LONG_LONG_INT + long long along; +#else + long along; +#endif + + switch (arg->vt) + { + case VALTYPE_SHORT: along = value.a_short; break; + case VALTYPE_INT: along = value.a_int; break; + case VALTYPE_LONG: along = value.a_long; break; +#ifdef HAVE_LONG_LONG_INT + case VALTYPE_LONGLONG: along = value.a_longlong; break; + case VALTYPE_SIZE: along = value.a_size; break; +# ifdef HAVE_INTMAX_T + case VALTYPE_INTMAX: along = value.a_intmax; break; +# endif +# ifdef HAVE_PTRDIFF_T + case VALTYPE_PTRDIFF: along = value.a_ptrdiff; break; +# endif +#endif /*HAVE_LONG_LONG_INT*/ + default: + return -1; + } + if (along < 0) + { + aulong = -along; + signchar = '-'; + } + else + aulong = along; + } + else + { + switch (arg->vt) + { + case VALTYPE_USHORT: aulong = value.a_ushort; break; + case VALTYPE_UINT: aulong = value.a_uint; break; + case VALTYPE_ULONG: aulong = value.a_ulong; break; +#ifdef HAVE_LONG_LONG_INT + case VALTYPE_ULONGLONG: aulong = value.a_ulonglong; break; + case VALTYPE_SIZE: aulong = value.a_size; break; +# ifdef HAVE_UINTMAX_T + case VALTYPE_UINTMAX: aulong = value.a_uintmax; break; +# endif +# ifdef HAVE_PTRDIFF_T + case VALTYPE_PTRDIFF: aulong = value.a_ptrdiff; break; +# endif +#endif /*HAVE_LONG_LONG_INT*/ + default: + return -1; + } + } + + if (signchar == '-') + ; + else if ((arg->flags & FLAG_PLUS_SIGN)) + signchar = '+'; + else if ((arg->flags & FLAG_SPACE_PLUS)) + signchar = ' '; + + n_extra = !!signchar; + + /* We build the string up backwards. */ + p = pend = numbuf + DIM(numbuf); + if ((!aulong && !arg->precision)) + ; + else if (arg->conspec == CONSPEC_DECIMAL + || arg->conspec == CONSPEC_UNSIGNED) + { + int grouping = -1; + const char * grouping_string = +#ifdef HAVE_LANGINFO_THOUSANDS_SEP + nl_langinfo(THOUSANDS_SEP); +#else + "'"; +#endif + + do + { + if ((arg->flags & FLAG_GROUPING) + && (++grouping == 3) && *grouping_string) + { + *--p = *grouping_string; + grouping = 0; + } + *--p = '0' + (aulong % 10); + aulong /= 10; + } + while (aulong); + } + else if (arg->conspec == CONSPEC_OCTAL) + { + do + { + *--p = '0' + (aulong % 8); + aulong /= 8; + } + while (aulong); + if ((arg->flags & FLAG_ALT_CONV) && *p != '0') + *--p = '0'; + } + else /* HEX or HEXUP */ + { + const char *digits = ((arg->conspec == CONSPEC_HEX) + ? "0123456789abcdef" : "0123456789ABCDEF"); + do + { + *--p = digits[(aulong % 16)]; + aulong /= 16; + } + while (aulong); + if ((arg->flags & FLAG_ALT_CONV)) + n_extra += 2; + } + + n = pend - p; + + if ((arg->flags & FLAG_ZERO_PAD) + && arg->precision == NO_FIELD_VALUE && !(arg->flags & FLAG_LEFT_JUST) + && n && arg->width - n_extra > n ) + n_prec = arg->width - n_extra - n; + else if (arg->precision > 0 && arg->precision > n) + n_prec = arg->precision - n; + else + n_prec = 0; + + if (!(arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width - n_extra > n + && arg->width - n_extra - n >= n_prec ) + { + rc = pad_out (outfnc, outfncarg, ' ', + arg->width - n_extra - n - n_prec, nbytes); + if (rc) + return rc; + } + + if (signchar) + { + rc = outfnc (outfncarg, &signchar, 1); + if (rc) + return rc; + *nbytes += 1; + } + + if ((arg->flags & FLAG_ALT_CONV) + && (arg->conspec == CONSPEC_HEX || arg->conspec == CONSPEC_HEX_UP)) + { + rc = outfnc (outfncarg, arg->conspec == CONSPEC_HEX? "0x": "0X", 2); + if (rc) + return rc; + *nbytes += 2; + } + + if (n_prec) + { + rc = pad_out (outfnc, outfncarg, '0', n_prec, nbytes); + if (rc) + return rc; + } + + rc = outfnc (outfncarg, p, pend - p); + if (rc) + return rc; + *nbytes += pend - p; + + if ((arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width - n_extra - n_prec > n) + { + rc = pad_out (outfnc, outfncarg, ' ', + arg->width - n_extra - n_prec - n, nbytes); + if (rc) + return rc; + } + + return 0; +} + + +/* "e,E,f,F,g,G,a,A" formatting. OUTFNC and OUTFNCARG describes the + output routine, ARG gives the argument description and VALUE the + actual value (its type is available through arg->vt). For + portability reasons sprintf is used for the actual formatting. + This is useful because sprint is the only standard function to + convert a floating number into its ascii representation. To avoid + using malloc we just pass the precision to sprintf and do the final + formatting with our own code. */ +static int +pr_float (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + int rc; +#ifdef HAVE_LONG_DOUBLE + long double adblfloat = 0; /* Just to please gcc. */ + int use_dbl = 0; +#endif + double afloat; + char numbuf[350]; + char formatstr[20]; + char *p, *pend; + size_t n; + char signchar = 0; + int n_extra; /* Extra number of prefix or sign characters. */ + + switch (arg->vt) + { + case VALTYPE_DOUBLE: afloat = value.a_double; break; +#ifdef HAVE_LONG_DOUBLE + case VALTYPE_LONGDOUBLE: + afloat = 0; /* Just to please gcc. */ + adblfloat = value.a_longdouble; + use_dbl=1; break; +#endif + default: + return -1; + } + + /* We build the string using sprint. */ + p = formatstr + sizeof formatstr; + *--p = 0; + switch (arg->conspec) + { + case CONSPEC_FLOAT: *--p = 'f'; break; + case CONSPEC_FLOAT_UP: *--p = 'F'; break; + case CONSPEC_EXP: *--p = 'e'; break; + case CONSPEC_EXP_UP: *--p = 'E'; break; + case CONSPEC_F_OR_G: *--p = 'g'; break; + case CONSPEC_F_OR_G_UP: *--p = 'G'; break; + case CONSPEC_HEX_EXP: *--p = 'a'; break; + case CONSPEC_HEX_EXP_UP: *--p = 'A'; break; + default: + return -1; /* Actually a bug. */ + } +#ifdef HAVE_LONG_DOUBLE + if (use_dbl) + *--p = 'L'; +#endif + if (arg->precision != NO_FIELD_VALUE) + { + /* Limit it to a meaningful value so that even a stupid sprintf + won't overflow our buffer. */ + n = arg->precision <= 100? arg->precision : 100; + do + { + *--p = '0' + (n % 10); + n /= 10; + } + while (n); + *--p = '.'; + } + if ((arg->flags & FLAG_ALT_CONV)) + *--p = '#'; + *--p = '%'; +#ifdef HAVE_LONG_DOUBLE + if (use_dbl) + sprintf (numbuf, p, adblfloat); + else +#endif /*HAVE_LONG_DOUBLE*/ + sprintf (numbuf, p, afloat); + p = numbuf; + n = strlen (numbuf); + pend = p + n; + + if (*p =='-') + { + signchar = '-'; + p++; + n--; + } + else if ((arg->flags & FLAG_PLUS_SIGN)) + signchar = '+'; + else if ((arg->flags & FLAG_SPACE_PLUS)) + signchar = ' '; + + n_extra = !!signchar; + + if (!(arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width - n_extra > n) + { + rc = pad_out (outfnc, outfncarg, ' ', arg->width - n_extra - n, nbytes); + if (rc) + return rc; + } + + if (signchar) + { + rc = outfnc (outfncarg, &signchar, 1); + if (rc) + return rc; + *nbytes += 1; + } + + rc = outfnc (outfncarg, p, pend - p); + if (rc) + return rc; + *nbytes += pend - p; + + if ((arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width - n_extra > n) + { + rc = pad_out (outfnc, outfncarg, ' ', arg->width - n_extra - n, nbytes); + if (rc) + return rc; + } + + return 0; +} + + +/* "c" formatting. */ +static int +pr_char (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + int rc; + char buf[1]; + + if (arg->vt != VALTYPE_INT) + return -1; + buf[0] = (unsigned int)value.a_int; + rc = outfnc (outfncarg, buf, 1); + if(rc) + return rc; + *nbytes += 1; + + return 0; +} + + +/* "s" formatting. */ +static int +pr_string (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + int rc; + size_t n; + const char *string, *s; + + if (arg->vt != VALTYPE_STRING) + return -1; + string = value.a_string; + if (!string) + string = "(null)"; + if (arg->precision >= 0) + { + for (n=0,s=string; *s && n < arg->precision; s++) + n++; + } + else + n = strlen (string); + + if (!(arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width > n ) + { + rc = pad_out (outfnc, outfncarg, ' ', arg->width - n, nbytes); + if (rc) + return rc; + } + + rc = outfnc (outfncarg, string, n); + if (rc) + return rc; + *nbytes += n; + + if ((arg->flags & FLAG_LEFT_JUST) + && arg->width >= 0 && arg->width > n) + { + rc = pad_out (outfnc, outfncarg, ' ', arg->width - n, nbytes); + if (rc) + return rc; + } + + return 0; +} + + +/* "p" formatting. */ +static int +pr_pointer (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + int rc; +#if defined(HAVE_LONG_LONG_INT) && (SIZEOF_UNSIGNED_LONG < SIZEOF_VOID_P) + unsigned long long aulong; +#else + unsigned long aulong; +#endif + char numbuf[100]; + char *p, *pend; + + if (arg->vt != VALTYPE_POINTER) + return -1; + /* We assume that a pointer can be converted to an unsigned long. + That is not correct for a 64 bit Windows, but then we assume that + long long is supported and usable for storing a pointer. */ +#if defined(HAVE_LONG_LONG_INT) && (SIZEOF_UNSIGNED_LONG < SIZEOF_VOID_P) + aulong = (unsigned long long)value.a_void_ptr; +#else + aulong = (unsigned long)value.a_void_ptr; +#endif + + p = pend = numbuf + DIM(numbuf); + do + { + *--p = "0123456789abcdefx"[(aulong % 16)]; + aulong /= 16; + } + while (aulong); + while ((pend-p) < 2*sizeof (aulong)) + *--p = '0'; + *--p = 'x'; + *--p = '0'; + + rc = outfnc (outfncarg, p, pend - p); + if (rc) + return rc; + *nbytes += pend - p; + + return 0; +} + +/* "n" pesudo format operation. */ +static int +pr_bytes_so_far (estream_printf_out_t outfnc, void *outfncarg, + argspec_t arg, value_t value, size_t *nbytes) +{ + (void)outfnc; + (void)outfncarg; + + switch (arg->vt) + { + case VALTYPE_SCHAR_PTR: + *value.a_schar_ptr = (signed char)(unsigned int)(*nbytes); + break; + case VALTYPE_SHORT_PTR: + *value.a_short_ptr = (short)(unsigned int)(*nbytes); + break; + case VALTYPE_LONG_PTR: + *value.a_long_ptr = (long)(*nbytes); + break; +#ifdef HAVE_LONG_LONG_INT + case VALTYPE_LONGLONG_PTR: + *value.a_longlong_ptr = (long long)(*nbytes); + break; +#endif +#ifdef HAVE_INTMAX_T + case VALTYPE_INTMAX_PTR: + *value.a_intmax_ptr = (intmax_t)(*nbytes); + break; +#endif + case VALTYPE_SIZE_PTR: + *value.a_size_ptr = (*nbytes); + break; +#ifdef HAVE_PTRDIFF_T + case VALTYPE_PTRDIFF_PTR: + *value.a_ptrdiff_ptr = (ptrdiff_t)(*nbytes); + break; +#endif + case VALTYPE_INT_PTR: + *value.a_int_ptr = (int)(*nbytes); + break; + default: + return -1; /* An unsupported type has been used. */ + } + + return 0; +} + + + +/* Run the actual formatting. OUTFNC and OUTFNCARG are the output + functions. FORMAT is format string ARGSPECS is the parsed format + string, ARGSPECS_LEN the number of items in ARGSPECS. VALUETABLE + holds the values and may be directly addressed using the position + arguments given by ARGSPECS. MYERRNO is used for the "%m" + conversion. NBYTES well be updated to reflect the number of bytes + send to the output function. */ +static int +do_format (estream_printf_out_t outfnc, void *outfncarg, + const char *format, argspec_t argspecs, size_t argspecs_len, + valueitem_t valuetable, int myerrno, size_t *nbytes) +{ + int rc = 0; + const char *s; + argspec_t arg = argspecs; + int argidx = 0; /* Only used for assertion. */ + size_t n; + value_t value; + + s = format; + while ( *s ) + { + if (*s != '%') + { + s++; + continue; + } + if (s != format) + { + rc = outfnc (outfncarg, format, (n=s-format)); + if (rc) + return rc; + *nbytes += n; + } + if (s[1] == '%') + { + /* Note that this code ignores one trailing percent escape - + this is however okay as the args parser must have + detected this already. */ + rc = outfnc (outfncarg, s, 1); + if (rc) + return rc; + *nbytes += 1; + s += 2; + format = s; + continue; + } + + /* Save the next start. */ + s += arg->length; + format = s; + + assert (argidx < argspecs_len); + argidx++; + + /* Apply indirect field width and precision values. */ + if (arg->width == STAR_FIELD_VALUE) + { + assert (valuetable[arg->width_pos-1].vt == VALTYPE_INT); + arg->width = valuetable[arg->width_pos-1].value.a_int; + if (arg->width < 0) + { + arg->width = -arg->width; + arg->flags |= FLAG_LEFT_JUST; + } + } + if (arg->precision == STAR_FIELD_VALUE) + { + assert (valuetable[arg->precision_pos-1].vt == VALTYPE_INT); + arg->precision = valuetable[arg->precision_pos-1].value.a_int; + if (arg->precision < 0) + arg->precision = NO_FIELD_VALUE; + } + + if (arg->arg_pos == -1 && arg->conspec == CONSPEC_STRERROR) + value.a_string = strerror (myerrno); + else + { + assert (arg->vt == valuetable[arg->arg_pos-1].vt); + value = valuetable[arg->arg_pos-1].value; + } + + switch (arg->conspec) + { + case CONSPEC_UNKNOWN: assert (!"bug"); break; + + case CONSPEC_DECIMAL: + case CONSPEC_UNSIGNED: + case CONSPEC_OCTAL: + case CONSPEC_HEX: + case CONSPEC_HEX_UP: + rc = pr_integer (outfnc, outfncarg, arg, value, nbytes); + break; + case CONSPEC_FLOAT: + case CONSPEC_FLOAT_UP: + case CONSPEC_EXP: + case CONSPEC_EXP_UP: + case CONSPEC_F_OR_G: + case CONSPEC_F_OR_G_UP: + case CONSPEC_HEX_EXP: + case CONSPEC_HEX_EXP_UP: + rc = pr_float (outfnc, outfncarg, arg, value, nbytes); + break; + case CONSPEC_CHAR: + rc = pr_char (outfnc, outfncarg, arg, value, nbytes); + break; + case CONSPEC_STRING: + case CONSPEC_STRERROR: + rc = pr_string (outfnc, outfncarg, arg, value, nbytes); + break; + case CONSPEC_POINTER: + rc = pr_pointer (outfnc, outfncarg, arg, value, nbytes); + break; + case CONSPEC_BYTES_SO_FAR: + rc = pr_bytes_so_far (outfnc, outfncarg, arg, value, nbytes); + break; + } + if (rc) + return rc; + arg++; + } + + /* Print out any trailing stuff. */ + n = s - format; + rc = n? outfnc (outfncarg, format, n) : 0; + if (!rc) + *nbytes += n; + + return rc; +} + + + + +/* The versatile printf formatting routine. It expects a callback + function OUTFNC and an opaque argument OUTFNCARG used for actual + output of the formatted stuff. FORMAT is the format specification + and VAARGS a variable argumemt list matching the arguments of + FORMAT. */ +int +estream_format (estream_printf_out_t outfnc, + void *outfncarg, + const char *format, va_list vaargs) +{ + /* Buffer to hold the argspecs and a pointer to it.*/ + struct argspec_s argspecs_buffer[DEFAULT_MAX_ARGSPECS]; + argspec_t argspecs = argspecs_buffer; + size_t argspecs_len; /* Number of specifications in ARGSPECS. */ + + /* Buffer to hold the description for the values. */ + struct valueitem_s valuetable_buffer[DEFAULT_MAX_VALUES]; + valueitem_t valuetable = valuetable_buffer; + + int rc; /* Return code. */ + size_t argidx; /* Used to index the argspecs array. */ + size_t validx; /* Used to index the valuetable. */ + int max_pos;/* Highest argument position. */ + + size_t nbytes = 0; /* Keep track of the number of bytes passed to + the output function. */ + + int myerrno = errno; /* Save the errno for use with "%m". */ + + + /* Parse the arguments to come up with descriptive list. We can't + do this on the fly because we need to support positional + arguments. */ + rc = parse_format (format, &argspecs, DIM(argspecs_buffer), &argspecs_len); + if (rc) + goto leave; + + /* Check that all ARG_POS fields are set. */ + for (argidx=0,max_pos=0; argidx < argspecs_len; argidx++) + { + if (argspecs[argidx].arg_pos != -1 + && argspecs[argidx].arg_pos > max_pos) + max_pos = argspecs[argidx].arg_pos; + if (argspecs[argidx].width_pos > max_pos) + max_pos = argspecs[argidx].width_pos; + if (argspecs[argidx].precision_pos > max_pos) + max_pos = argspecs[argidx].precision_pos; + } + if (!max_pos) + { + /* Fill in all the positions. */ + for (argidx=0; argidx < argspecs_len; argidx++) + { + if (argspecs[argidx].width == STAR_FIELD_VALUE) + argspecs[argidx].width_pos = ++max_pos; + if (argspecs[argidx].precision == STAR_FIELD_VALUE) + argspecs[argidx].precision_pos = ++max_pos; + if (argspecs[argidx].arg_pos != -1 ) + argspecs[argidx].arg_pos = ++max_pos; + } + } + else + { + /* Check that they are all filled. More test are done later. */ + for (argidx=0; argidx < argspecs_len; argidx++) + { + if (!argspecs[argidx].arg_pos + || (argspecs[argidx].width == STAR_FIELD_VALUE + && !argspecs[argidx].width_pos) + || (argspecs[argidx].precision == STAR_FIELD_VALUE + && !argspecs[argidx].precision_pos)) + goto leave_einval; + } + } + /* Check that there is no overflow in max_pos and that it has a + reasonable length. There may never be more elements than the + number of characters in FORMAT. */ + if (max_pos < 0 || max_pos >= strlen (format)) + goto leave_einval; + +#ifdef DEBUG + dump_argspecs (argspecs, argspecs_len); +#endif + + /* Allocate a table to hold the values. If it is small enough we + use a stack allocated buffer. */ + if (max_pos > DIM(valuetable_buffer)) + { + valuetable = calloc (max_pos, sizeof *valuetable); + if (!valuetable) + goto leave_error; + } + else + { + for (validx=0; validx < DIM(valuetable_buffer); validx++) + valuetable[validx].vt = VALTYPE_UNSUPPORTED; + } + for (argidx=0; argidx < argspecs_len; argidx++) + { + if (argspecs[argidx].arg_pos != - 1) + { + validx = argspecs[argidx].arg_pos - 1; + if (valuetable[validx].vt) + goto leave_einval; /* Already defined. */ + valuetable[validx].vt = argspecs[argidx].vt; + } + if (argspecs[argidx].width == STAR_FIELD_VALUE) + { + validx = argspecs[argidx].width_pos - 1; + if (valuetable[validx].vt) + goto leave_einval; /* Already defined. */ + valuetable[validx].vt = VALTYPE_INT; + } + if (argspecs[argidx].precision == STAR_FIELD_VALUE) + { + validx = argspecs[argidx].precision_pos - 1; + if (valuetable[validx].vt) + goto leave_einval; /* Already defined. */ + valuetable[validx].vt = VALTYPE_INT; + } + } + + /* Read all the arguments. This will error out for unsupported + types and for not given positional arguments. */ + rc = read_values (valuetable, max_pos, vaargs); + if (rc) + goto leave_einval; + +/* for (validx=0; validx < max_pos; validx++) */ +/* fprintf (stderr, "%2d: vt=%d\n", validx, valuetable[validx].vt); */ + + /* Everything has been collected, go ahead with the formatting. */ + rc = do_format (outfnc, outfncarg, format, + argspecs, argspecs_len, valuetable, myerrno, &nbytes); + + goto leave; + + leave_einval: + errno = EINVAL; + leave_error: + rc = -1; + leave: + if (valuetable != valuetable_buffer) + free (valuetable); + if (argspecs != argspecs_buffer) + free (argspecs); + return rc; +} + + + + +/* A simple output handler utilizing stdio. */ +static int +plain_stdio_out (void *outfncarg, const char *buf, size_t buflen) +{ + FILE *fp = (FILE*)outfncarg; + + if ( fwrite (buf, buflen, 1, fp) != 1 ) + return -1; + return 0; +} + + +/* A replacement for printf. */ +int +estream_printf (const char *format, ...) +{ + int rc; + va_list arg_ptr; + + va_start (arg_ptr, format); + rc = estream_format (plain_stdio_out, stderr, format, arg_ptr); + va_end (arg_ptr); + + return rc; +} + +/* A replacement for fprintf. */ +int +estream_fprintf (FILE *fp, const char *format, ...) +{ + int rc; + va_list arg_ptr; + + va_start (arg_ptr, format); + rc = estream_format (plain_stdio_out, fp, format, arg_ptr); + va_end (arg_ptr); + + return rc; +} + +/* A replacement for vfprintf. */ +int +estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr) +{ + return estream_format (plain_stdio_out, fp, format, arg_ptr); +} + + + +/* Communication object used between estream_snprintf and + fixed_buffer_out. */ +struct fixed_buffer_parm_s +{ + size_t size; /* Size of the buffer. */ + size_t count; /* Number of bytes requested for output. */ + size_t used; /* Used size of the buffer. */ + char *buffer; /* Provided buffer. */ +}; + +/* A simple malloced buffer output handler. */ +static int +fixed_buffer_out (void *outfncarg, const char *buf, size_t buflen) +{ + struct fixed_buffer_parm_s *parm = outfncarg; + + parm->count += buflen; + + if (!parm->buffer) + ; + else if (parm->used + buflen < parm->size) + { + /* Handle the common case that everything fits into the buffer + separately. */ + memcpy (parm->buffer + parm->used, buf, buflen); + parm->used += buflen; + } + else + { + /* The slow version of above. */ + for ( ;buflen && parm->used < parm->size; buflen--) + parm->buffer[parm->used++] = *buf++; + } + + return 0; +} + + +/* A replacement for vsnprintf. */ +int +estream_vsnprintf (char *buf, size_t bufsize, + const char *format, va_list arg_ptr) +{ + struct fixed_buffer_parm_s parm; + int rc; + + parm.size = bufsize; + parm.count = 0; + parm.used = 0; + parm.buffer = bufsize?buf:NULL; + rc = estream_format (fixed_buffer_out, &parm, format, arg_ptr); + if (!rc) + rc = fixed_buffer_out (&parm, "", 1); /* Print terminating Nul. */ + if (rc == -1) + return -1; + if (bufsize && buf && parm.size && parm.count >= parm.size) + buf[parm.size-1] = 0; + + parm.count--; /* Do not count the trailing nul. */ + return (int)parm.count; /* Return number of bytes which would have + been written. */ +} + +/* A replacement for snprintf. */ +int +estream_snprintf (char *buf, size_t bufsize, const char *format, ...) +{ + int rc; + va_list arg_ptr; + + va_start (arg_ptr, format); + rc = estream_vsnprintf (buf, bufsize, format, arg_ptr); + va_end (arg_ptr); + + return rc; +} + + + +/* Communication object used between estream_asprintf and + dynamic_buffer_out. */ +struct dynamic_buffer_parm_s +{ + int error_flag; /* Internal helper. */ + size_t alloced; /* Allocated size of the buffer. */ + size_t used; /* Used size of the buffer. */ + char *buffer; /* Malloced buffer. */ +}; + +/* A simple malloced buffer output handler. */ +static int +dynamic_buffer_out (void *outfncarg, const char *buf, size_t buflen) +{ + struct dynamic_buffer_parm_s *parm = outfncarg; + + if (parm->error_flag) + { + /* Just in case some formatting routine did not checked for an + error. */ + errno = parm->error_flag; + return -1; + } + + if (parm->used + buflen >= parm->alloced) + { + char *p; + + parm->alloced += buflen + 512; + p = realloc (parm->buffer, parm->alloced); + if (!p) + { + parm->error_flag = errno ? errno : ENOMEM; + /* Wipe out what we already accumulated. This is useful in + case sensitive data is formated. */ + memset (parm->buffer, 0, parm->used); + return -1; + } + parm->buffer = p; + } + memcpy (parm->buffer + parm->used, buf, buflen); + parm->used += buflen; + + return 0; +} + + +/* A replacement for vasprintf. As with the BSD of vasprintf version -1 + will be returned on error and NULL stored at BUFP. On success the + number of bytes printed will be returned. */ +int +estream_vasprintf (char **bufp, const char *format, va_list arg_ptr) +{ + struct dynamic_buffer_parm_s parm; + int rc; + + parm.error_flag = 0; + parm.alloced = 512; + parm.used = 0; + parm.buffer = my_printf_malloc (parm.alloced); + if (!parm.buffer) + { + *bufp = NULL; + return -1; + } + + rc = estream_format (dynamic_buffer_out, &parm, format, arg_ptr); + if (!rc) + rc = dynamic_buffer_out (&parm, "", 1); /* Print terminating Nul. */ + /* Fixme: Should we shrink the resulting buffer? */ + if (rc != -1 && parm.error_flag) + { + rc = -1; + errno = parm.error_flag; + } + if (rc == -1) + { + memset (parm.buffer, 0, parm.used); + my_printf_free (parm.buffer); + *bufp = NULL; + return -1; + } + assert (parm.used); /* We have at least the terminating Nul. */ + *bufp = parm.buffer; + return parm.used - 1; /* Do not include that Nul. */ +} + +/* A replacement for asprintf. As with the BSD of asprintf version -1 + will be returned on error and NULL stored at BUFP. On success the + number of bytes printed will be returned. */ +int +estream_asprintf (char **bufp, const char *format, ...) +{ + int rc; + va_list arg_ptr; + + va_start (arg_ptr, format); + rc = estream_vasprintf (bufp, format, arg_ptr); + va_end (arg_ptr); + + return rc; +} + + diff --git a/common/estream-printf.h b/common/estream-printf.h new file mode 100644 index 0000000..3987b33 --- /dev/null +++ b/common/estream-printf.h @@ -0,0 +1,110 @@ +/* estream-printf.h - Versatile C-99 compliant printf formatting. + * Copyright (C) 2007 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream 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. + * + * Libestream is distributed in the hope that 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 Libestream; if not, see . + */ + +#ifndef ESTREAM_PRINTF_H +#define ESTREAM_PRINTF_H + +#include +#include + +/* To use this file with libraries the following macro is useful: + + #define _ESTREAM_EXT_SYM_PREFIX _foo_ + + This prefixes all external symbols with "_foo_". + + For the implementation of the code (estream-printf.c) the following + macros may be used to tune the implementation for certain systems: + + #define _ESTREAM_PRINTF_MALLOC foo_malloc + #define _ESTREAM_PRINTF_FREE foo_free + + Make estream_asprintf and estream_vasprintf use foo_malloc and + foo_free instead of the standard malloc and free functions to + allocate the memory returned to the caller. + + #define _ESTREAM_PRINTF_EXTRA_INCLUDE "foo.h" + + This includes the file "foo.h" which may provide prototypes for + the custom memory allocation functions. + */ + + +#ifdef _ESTREAM_EXT_SYM_PREFIX +#ifndef _ESTREAM_PREFIX +#define _ESTREAM_PREFIX1(x,y) x ## y +#define _ESTREAM_PREFIX2(x,y) _ESTREAM_PREFIX1(x,y) +#define _ESTREAM_PREFIX(x) _ESTREAM_PREFIX2(_ESTREAM_EXT_SYM_PREFIX,x) +#endif /*_ESTREAM_PREFIX*/ +#define estream_printf_out_t _ESTREAM_PREFIX(estream_printf_out_t) +#define estream_format _ESTREAM_PREFIX(estream_format) +#define estream_printf _ESTREAM_PREFIX(estream_printf) +#define estream_fprintf _ESTREAM_PREFIX(estream_fprintf) +#define estream_vfprintf _ESTREAM_PREFIX(estream_vfprintf) +#define estream_snprintf _ESTREAM_PREFIX(estream_snprintf) +#define estream_vsnprintf _ESTREAM_PREFIX(estream_vsnprintf) +#define estream_asprintf _ESTREAM_PREFIX(estream_asprintf) +#define estream_vasprintf _ESTREAM_PREFIX(estream_vasprintf) +#endif /*_ESTREAM_EXT_SYM_PREFIX*/ + +#ifndef _ESTREAM_GCC_A_PRINTF +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) +# define _ESTREAM_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) +#else +# define _ESTREAM_GCC_A_PRINTF( f, a ) +#endif +#endif /*_ESTREAM_GCC_A_PRINTF*/ + + +#ifdef __cplusplus +extern "C" +{ +#if 0 +} +#endif +#endif + + +typedef int (*estream_printf_out_t) + (void *outfncarg, const char *buf, size_t buflen); + +int estream_format (estream_printf_out_t outfnc, void *outfncarg, + const char *format, va_list vaargs) + _ESTREAM_GCC_A_PRINTF(3,0); +int estream_printf (const char *format, ...) + _ESTREAM_GCC_A_PRINTF(1,2); +int estream_fprintf (FILE *fp, const char *format, ... ) + _ESTREAM_GCC_A_PRINTF(2,3); +int estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr) + _ESTREAM_GCC_A_PRINTF(2,0); +int estream_snprintf (char *buf, size_t bufsize, const char *format, ...) + _ESTREAM_GCC_A_PRINTF(3,4); +int estream_vsnprintf (char *buf,size_t bufsize, + const char *format, va_list arg_ptr) + _ESTREAM_GCC_A_PRINTF(3,0); +int estream_asprintf (char **bufp, const char *format, ...) + _ESTREAM_GCC_A_PRINTF(2,3); +int estream_vasprintf (char **bufp, const char *format, va_list arg_ptr) + _ESTREAM_GCC_A_PRINTF(2,0); + + +#ifdef __cplusplus +} +#endif +#endif /*ESTREAM_PRINTF_H*/ diff --git a/common/estream.c b/common/estream.c new file mode 100644 index 0000000..2d68415 --- /dev/null +++ b/common/estream.c @@ -0,0 +1,3687 @@ +/* estream.c - Extended Stream I/O Library + * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream 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. + * + * Libestream is distributed in the hope that 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 Libestream; if not, see . + * + * ALTERNATIVELY, Libestream 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. + */ + +#ifdef USE_ESTREAM_SUPPORT_H +# include +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined(_WIN32) && !defined(HAVE_W32_SYSTEM) +# define HAVE_W32_SYSTEM 1 +# if defined(__MINGW32CE__) && !defined (HAVE_W32CE_SYSTEM) +# define HAVE_W32CE_SYSTEM +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_W32_SYSTEM +# include +#endif +#ifdef HAVE_W32CE_SYSTEM +# include /* ERRNO replacement. */ +#endif + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +# undef HAVE_PTH +# undef USE_GNU_PTH +#endif + +#ifdef HAVE_PTH +# include +#endif + +/* This is for the special hack to use estream.c in GnuPG. */ +#ifdef GNUPG_MAJOR_VERSION +# include "../common/util.h" +#endif + +#ifndef HAVE_MKSTEMP +int mkstemp (char *template); +#endif + +#ifndef HAVE_MEMRCHR +void *memrchr (const void *block, int c, size_t size); +#endif + +#include +#include + + + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#ifdef HAVE_W32CE_SYSTEM +# define _set_errno(a) gpg_err_set_errno ((a)) +/* Setmode is missing in cegcc but available since CE 5.0. */ +int _setmode (int handle, int mode); +# define setmode(a,b) _setmode ((a),(b)) +#else +# define _set_errno(a) do { errno = (a); } while (0) +#endif + +#ifdef HAVE_W32_SYSTEM +# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1)) +#else +# define IS_INVALID_FD(a) ((a) == -1) +#endif + + +/* Generally used types. */ + +typedef void *(*func_realloc_t) (void *mem, size_t size); +typedef void (*func_free_t) (void *mem); + + + + +/* Buffer management layer. */ + +#define BUFFER_BLOCK_SIZE BUFSIZ +#define BUFFER_UNREAD_SIZE 16 + + + +/* Locking. */ + +#ifdef HAVE_PTH +typedef pth_mutex_t estream_mutex_t; +#else /*!HAVE_PTH*/ +typedef void *estream_mutex_t; +#endif /*!HAVE_PTH*/ + +static inline void +dummy_mutex_call_void (estream_mutex_t mutex) +{ + (void)mutex; +} + +static inline int +dummy_mutex_call_int (estream_mutex_t mutex) +{ + (void)mutex; + return 0; +} + + +#ifdef HAVE_PTH + +static int estream_pth_killed; + +# define ESTREAM_MUTEX_INITIALIZER PTH_MUTEX_INIT +# define ESTREAM_MUTEX_LOCK(mutex) \ + (estream_pth_killed ? dummy_mutex_call_void ((mutex)) \ + : pth_mutex_acquire (&(mutex), 0, NULL)) +# define ESTREAM_MUTEX_UNLOCK(mutex) \ + (estream_pth_killed ? dummy_mutex_call_void ((mutex)) \ + : pth_mutex_release (&(mutex))) +# define ESTREAM_MUTEX_TRYLOCK(mutex) \ + (estream_pth_killed ? dummy_mutex_call_int ((mutex)) \ + : ((pth_mutex_acquire (&(mutex), 1, NULL) == TRUE)? 0:-1)) +# define ESTREAM_MUTEX_INITIALIZE(mutex) \ + (estream_pth_killed ? dummy_mutex_call_void ((mutex)) \ + : pth_mutex_init (&(mutex))) + +#else /*!HAVE_PTH*/ + +# define ESTREAM_MUTEX_INITIALIZER NULL +# define ESTREAM_MUTEX_LOCK(mutex) dummy_mutex_call_void ((mutex)) +# define ESTREAM_MUTEX_UNLOCK(mutex) dummy_mutex_call_void ((mutex)) +# define ESTREAM_MUTEX_TRYLOCK(mutex) dummy_mutex_call_int ((mutex)) +# define ESTREAM_MUTEX_INITIALIZE(mutex) dummy_mutex_call_void ((mutex)) + +#endif /*!HAVE_PTH*/ + +/* Primitive system I/O. */ + +#ifdef HAVE_PTH +# define ESTREAM_SYS_READ es_pth_read +# define ESTREAM_SYS_WRITE es_pth_write +# define ESTREAM_SYS_YIELD() \ + do { if (!estream_pth_killed) pth_yield (NULL); } while (0) +#else +# define ESTREAM_SYS_READ read +# define ESTREAM_SYS_WRITE write +# define ESTREAM_SYS_YIELD() do { } while (0) +#endif + +/* Misc definitions. */ + +#define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR) + +/* An internal stream object. */ + +struct estream_internal +{ + unsigned char buffer[BUFFER_BLOCK_SIZE]; + unsigned char unread_buffer[BUFFER_UNREAD_SIZE]; + estream_mutex_t lock; /* Lock. */ + void *cookie; /* Cookie. */ + void *opaque; /* Opaque data. */ + unsigned int modeflags; /* Flags for the backend. */ + char *printable_fname; /* Malloced filename for es_fname_get. */ + off_t offset; + es_cookie_read_function_t func_read; + es_cookie_write_function_t func_write; + es_cookie_seek_function_t func_seek; + es_cookie_close_function_t func_close; + int strategy; + int fd; + struct + { + unsigned int err: 1; + unsigned int eof: 1; + } indicators; + unsigned int deallocate_buffer: 1; + unsigned int is_stdstream:1; /* This is a standard stream. */ + unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ + unsigned int print_err: 1; /* Error in print_fun_writer. */ + unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */ + int print_errno; /* Errno from print_fun_writer. */ + size_t print_ntotal; /* Bytes written from in print_fun_writer. */ + FILE *print_fp; /* Stdio stream used by print_fun_writer. */ +}; + + +typedef struct estream_internal *estream_internal_t; + +#define ESTREAM_LOCK(stream) ESTREAM_MUTEX_LOCK (stream->intern->lock) +#define ESTREAM_UNLOCK(stream) ESTREAM_MUTEX_UNLOCK (stream->intern->lock) +#define ESTREAM_TRYLOCK(stream) ESTREAM_MUTEX_TRYLOCK (stream->intern->lock) + +/* Stream list. */ + +typedef struct estream_list *estream_list_t; + +struct estream_list +{ + estream_t car; + estream_list_t cdr; + estream_list_t *prev_cdr; +}; + +static estream_list_t estream_list; +static estream_mutex_t estream_list_lock; + +#define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock) +#define ESTREAM_LIST_UNLOCK ESTREAM_MUTEX_UNLOCK (estream_list_lock) + +/* File descriptors registered to be used as the standard file handles. */ +static int custom_std_fds[3]; +static unsigned char custom_std_fds_valid[3]; + + +#ifndef EOPNOTSUPP +# define EOPNOTSUPP ENOSYS +#endif + + +/* Local prototypes. */ +static void fname_set_internal (estream_t stream, const char *fname, int quote); + + + + +/* Macros. */ + +/* Calculate array dimension. */ +#ifndef DIM +#define DIM(array) (sizeof (array) / sizeof (*array)) +#endif + +#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) + + +/* Evaluate EXPRESSION, setting VARIABLE to the return code, if + VARIABLE is zero. */ +#define SET_UNLESS_NONZERO(variable, tmp_variable, expression) \ + do \ + { \ + tmp_variable = expression; \ + if ((! variable) && tmp_variable) \ + variable = tmp_variable; \ + } \ + while (0) + + +/* Malloc wrappers to overcome problems on some older OSes. */ +static void * +mem_alloc (size_t n) +{ + if (!n) + n++; + return malloc (n); +} + +static void * +mem_realloc (void *p, size_t n) +{ + if (!p) + return mem_alloc (n); + return realloc (p, n); +} + +static void +mem_free (void *p) +{ + if (p) + free (p); +} + + + +/* + * List manipulation. + */ + +/* Add STREAM to the list of registered stream objects. If + WITH_LOCKED_LIST is true we assumed that the list of streams is + already locked. */ +static int +es_list_add (estream_t stream, int with_locked_list) +{ + estream_list_t list_obj; + int ret; + + list_obj = mem_alloc (sizeof (*list_obj)); + if (! list_obj) + ret = -1; + else + { + if (!with_locked_list) + ESTREAM_LIST_LOCK; + list_obj->car = stream; + list_obj->cdr = estream_list; + list_obj->prev_cdr = &estream_list; + if (estream_list) + estream_list->prev_cdr = &list_obj->cdr; + estream_list = list_obj; + if (!with_locked_list) + ESTREAM_LIST_UNLOCK; + ret = 0; + } + + return ret; +} + +/* Remove STREAM from the list of registered stream objects. */ +static void +es_list_remove (estream_t stream, int with_locked_list) +{ + estream_list_t list_obj; + + if (!with_locked_list) + ESTREAM_LIST_LOCK; + for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) + if (list_obj->car == stream) + { + *list_obj->prev_cdr = list_obj->cdr; + if (list_obj->cdr) + list_obj->cdr->prev_cdr = list_obj->prev_cdr; + mem_free (list_obj); + break; + } + if (!with_locked_list) + ESTREAM_LIST_UNLOCK; +} + +/* Type of an stream-iterator-function. */ +typedef int (*estream_iterator_t) (estream_t stream); + +/* Iterate over list of registered streams, calling ITERATOR for each + of them. */ +static int +es_list_iterate (estream_iterator_t iterator) +{ + estream_list_t list_obj; + int ret = 0; + + ESTREAM_LIST_LOCK; + for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) + ret |= (*iterator) (list_obj->car); + ESTREAM_LIST_UNLOCK; + + return ret; +} + + + +/* + * I/O Helper + * + * Unfortunately our Pth emulation for Windows expects system handles + * for pth_read and pth_write. We use a simple approach to fix this: + * If the function returns an error we fall back to a vanilla read or + * write, assuming that we do I/O on a plain file where the operation + * can't block. + */ +#ifdef HAVE_PTH +static int +es_pth_read (int fd, void *buffer, size_t size) +{ + if (estream_pth_killed) + return read (fd, buffer, size); + else + { +# ifdef HAVE_W32_SYSTEM + int rc = pth_read (fd, buffer, size); + if (rc == -1 && errno == EINVAL) + rc = read (fd, buffer, size); + return rc; +# else /*!HAVE_W32_SYSTEM*/ + return pth_read (fd, buffer, size); +# endif /* !HAVE_W32_SYSTEM*/ + } +} + +static int +es_pth_write (int fd, const void *buffer, size_t size) +{ + if (estream_pth_killed) + return write (fd, buffer, size); + else + { +# ifdef HAVE_W32_SYSTEM + int rc = pth_write (fd, buffer, size); + if (rc == -1 && errno == EINVAL) + rc = write (fd, buffer, size); + return rc; +# else /*!HAVE_W32_SYSTEM*/ + return pth_write (fd, buffer, size); +# endif /* !HAVE_W32_SYSTEM*/ + } +} +#endif /*HAVE_PTH*/ + + + +static void +es_deinit (void) +{ + /* Flush all streams. */ + es_fflush (NULL); +} + + +/* A replacement for pth_kill. The reason we need this is that after + a pth_kill all our pth functions may not be used anymore. Thus + applications using estream and pth need to use this function + instead of a plain pth_kill. */ +int +es_pth_kill (void) +{ +#ifdef HAVE_PTH + int rc; + + rc = pth_kill (); + if (rc) + estream_pth_killed = 1; + return rc; +#else /*!HAVE_PTH*/ + return 0; +#endif /*!HAVE_PTH*/ +} + + +/* + * Initialization. + */ + +static int +es_init_do (void) +{ + static int initialized; + + if (!initialized) + { +#ifdef HAVE_PTH + if (estream_pth_killed) + initialized = 1; + else + { + if (!pth_init () && errno != EPERM ) + return -1; + if (pth_mutex_init (&estream_list_lock)) + initialized = 1; + } +#else + initialized = 1; +#endif + atexit (es_deinit); + } + return 0; +} + + + +/* + * I/O methods. + */ + +/* Implementation of Memory I/O. */ + +/* Cookie for memory objects. */ +typedef struct estream_cookie_mem +{ + unsigned int modeflags; /* Open flags. */ + unsigned char *memory; /* Allocated data buffer. */ + size_t memory_size; /* Allocated size of MEMORY. */ + size_t memory_limit; /* Caller supplied maximum allowed + allocation size or 0 for no limit. */ + size_t offset; /* Current offset in MEMORY. */ + size_t data_len; /* Used length of data in MEMORY. */ + size_t block_size; /* Block size. */ + struct { + unsigned int grow: 1; /* MEMORY is allowed to grow. */ + } flags; + func_realloc_t func_realloc; + func_free_t func_free; +} *estream_cookie_mem_t; + + +/* Create function for memory objects. DATA is either NULL or a user + supplied buffer with the initial content of the memory buffer. If + DATA is NULL, DATA_N and DATA_LEN need to be 0 as well. If DATA is + not NULL, DATA_N gives the allocated size of DATA and DATA_LEN the + used length in DATA. */ +static int +es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, + unsigned char *ES__RESTRICT data, size_t data_n, + size_t data_len, + size_t block_size, unsigned int grow, + func_realloc_t func_realloc, func_free_t func_free, + unsigned int modeflags, + size_t memory_limit) +{ + estream_cookie_mem_t mem_cookie; + int err; + + if (!data && (data_n || data_len)) + { + _set_errno (EINVAL); + return -1; + } + + mem_cookie = mem_alloc (sizeof (*mem_cookie)); + if (!mem_cookie) + err = -1; + else + { + mem_cookie->modeflags = modeflags; + mem_cookie->memory = data; + mem_cookie->memory_size = data_n; + mem_cookie->memory_limit = memory_limit; + mem_cookie->offset = 0; + mem_cookie->data_len = data_len; + mem_cookie->block_size = block_size; + mem_cookie->flags.grow = !!grow; + mem_cookie->func_realloc = func_realloc ? func_realloc : mem_realloc; + mem_cookie->func_free = func_free ? func_free : mem_free; + *cookie = mem_cookie; + err = 0; + } + + return err; +} + + +/* Read function for memory objects. */ +static ssize_t +es_func_mem_read (void *cookie, void *buffer, size_t size) +{ + estream_cookie_mem_t mem_cookie = cookie; + ssize_t ret; + + if (size > mem_cookie->data_len - mem_cookie->offset) + size = mem_cookie->data_len - mem_cookie->offset; + + if (size) + { + memcpy (buffer, mem_cookie->memory + mem_cookie->offset, size); + mem_cookie->offset += size; + } + + ret = size; + return ret; +} + + +/* Write function for memory objects. */ +static ssize_t +es_func_mem_write (void *cookie, const void *buffer, size_t size) +{ + estream_cookie_mem_t mem_cookie = cookie; + ssize_t ret; + size_t nleft; + + if (!size) + return 0; /* A flush is a NOP for memory objects. */ + + if (mem_cookie->modeflags & O_APPEND) + { + /* Append to data. */ + mem_cookie->offset = mem_cookie->data_len; + } + + assert (mem_cookie->memory_size >= mem_cookie->offset); + nleft = mem_cookie->memory_size - mem_cookie->offset; + + /* If we are not allowed to grow limit the size to the left space. */ + if (!mem_cookie->flags.grow && size > nleft) + size = nleft; + + /* Enlarge the memory buffer if needed. */ + if (size > nleft) + { + unsigned char *newbuf; + size_t newsize; + + if (!mem_cookie->memory_size) + newsize = size; /* Not yet allocated. */ + else + newsize = mem_cookie->memory_size + (size - nleft); + if (newsize < mem_cookie->offset) + { + _set_errno (EINVAL); + return -1; + } + + /* Round up to the next block length. BLOCK_SIZE should always + be set; we check anyway. */ + if (mem_cookie->block_size) + { + newsize += mem_cookie->block_size - 1; + if (newsize < mem_cookie->offset) + { + _set_errno (EINVAL); + return -1; + } + newsize /= mem_cookie->block_size; + newsize *= mem_cookie->block_size; + } + + /* Check for a total limit. */ + if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit) + { + _set_errno (ENOSPC); + return -1; + } + + newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); + if (!newbuf) + return -1; + + mem_cookie->memory = newbuf; + mem_cookie->memory_size = newsize; + + assert (mem_cookie->memory_size >= mem_cookie->offset); + nleft = mem_cookie->memory_size - mem_cookie->offset; + + assert (size <= nleft); + } + + memcpy (mem_cookie->memory + mem_cookie->offset, buffer, size); + if (mem_cookie->offset + size > mem_cookie->data_len) + mem_cookie->data_len = mem_cookie->offset + size; + mem_cookie->offset += size; + + ret = size; + return ret; +} + + +/* Seek function for memory objects. */ +static int +es_func_mem_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_mem_t mem_cookie = cookie; + off_t pos_new; + + switch (whence) + { + case SEEK_SET: + pos_new = *offset; + break; + + case SEEK_CUR: + pos_new = mem_cookie->offset += *offset; + break; + + case SEEK_END: + pos_new = mem_cookie->data_len += *offset; + break; + + default: + _set_errno (EINVAL); + return -1; + } + + if (pos_new > mem_cookie->memory_size) + { + size_t newsize; + void *newbuf; + + if (!mem_cookie->flags.grow) + { + _set_errno (ENOSPC); + return -1; + } + + newsize = pos_new + mem_cookie->block_size - 1; + if (newsize < pos_new) + { + _set_errno (EINVAL); + return -1; + } + newsize /= mem_cookie->block_size; + newsize *= mem_cookie->block_size; + + if (mem_cookie->memory_limit && newsize > mem_cookie->memory_limit) + { + _set_errno (ENOSPC); + return -1; + } + + newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); + if (!newbuf) + return -1; + + mem_cookie->memory = newbuf; + mem_cookie->memory_size = newsize; + } + + if (pos_new > mem_cookie->data_len) + { + /* Fill spare space with zeroes. */ + memset (mem_cookie->memory + mem_cookie->data_len, + 0, pos_new - mem_cookie->data_len); + mem_cookie->data_len = pos_new; + } + + mem_cookie->offset = pos_new; + *offset = pos_new; + + return 0; +} + + +/* Destroy function for memory objects. */ +static int +es_func_mem_destroy (void *cookie) +{ + estream_cookie_mem_t mem_cookie = cookie; + + if (cookie) + { + mem_cookie->func_free (mem_cookie->memory); + mem_free (mem_cookie); + } + return 0; +} + + +static es_cookie_io_functions_t estream_functions_mem = + { + es_func_mem_read, + es_func_mem_write, + es_func_mem_seek, + es_func_mem_destroy + }; + + + +/* Implementation of fd I/O. */ + +/* Cookie for fd objects. */ +typedef struct estream_cookie_fd +{ + int fd; /* The file descriptor we are using for actual output. */ + int no_close; /* If set we won't close the file descriptor. */ +} *estream_cookie_fd_t; + +/* Create function for fd objects. */ +static int +es_func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) +{ + estream_cookie_fd_t fd_cookie; + int err; + + fd_cookie = mem_alloc (sizeof (*fd_cookie)); + if (! fd_cookie) + err = -1; + else + { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#else + (void)modeflags; +#endif + fd_cookie->fd = fd; + fd_cookie->no_close = no_close; + *cookie = fd_cookie; + err = 0; + } + + return err; +} + +/* Read function for fd objects. */ +static ssize_t +es_func_fd_read (void *cookie, void *buffer, size_t size) + +{ + estream_cookie_fd_t file_cookie = cookie; + ssize_t bytes_read; + + if (IS_INVALID_FD (file_cookie->fd)) + { + ESTREAM_SYS_YIELD (); + bytes_read = 0; + } + else + { + do + bytes_read = ESTREAM_SYS_READ (file_cookie->fd, buffer, size); + while (bytes_read == -1 && errno == EINTR); + } + + return bytes_read; +} + +/* Write function for fd objects. */ +static ssize_t +es_func_fd_write (void *cookie, const void *buffer, size_t size) +{ + estream_cookie_fd_t file_cookie = cookie; + ssize_t bytes_written; + + if (IS_INVALID_FD (file_cookie->fd)) + { + ESTREAM_SYS_YIELD (); + bytes_written = size; /* Yeah: Success writing to the bit bucket. */ + } + else + { + do + bytes_written = ESTREAM_SYS_WRITE (file_cookie->fd, buffer, size); + while (bytes_written == -1 && errno == EINTR); + } + + return bytes_written; +} + +/* Seek function for fd objects. */ +static int +es_func_fd_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_fd_t file_cookie = cookie; + off_t offset_new; + int err; + + if (IS_INVALID_FD (file_cookie->fd)) + { + _set_errno (ESPIPE); + err = -1; + } + else + { + offset_new = lseek (file_cookie->fd, *offset, whence); + if (offset_new == -1) + err = -1; + else + { + *offset = offset_new; + err = 0; + } + } + + return err; +} + +/* Destroy function for fd objects. */ +static int +es_func_fd_destroy (void *cookie) +{ + estream_cookie_fd_t fd_cookie = cookie; + int err; + + if (fd_cookie) + { + if (IS_INVALID_FD (fd_cookie->fd)) + err = 0; + else + err = fd_cookie->no_close? 0 : close (fd_cookie->fd); + mem_free (fd_cookie); + } + else + err = 0; + + return err; +} + + +static es_cookie_io_functions_t estream_functions_fd = + { + es_func_fd_read, + es_func_fd_write, + es_func_fd_seek, + es_func_fd_destroy + }; + + + + +/* Implementation of FILE* I/O. */ + +/* Cookie for fp objects. */ +typedef struct estream_cookie_fp +{ + FILE *fp; /* The file pointer we are using for actual output. */ + int no_close; /* If set we won't close the file pointer. */ +} *estream_cookie_fp_t; + +/* Create function for fd objects. */ +static int +es_func_fp_create (void **cookie, FILE *fp, + unsigned int modeflags, int no_close) +{ + estream_cookie_fp_t fp_cookie; + int err; + + fp_cookie = mem_alloc (sizeof *fp_cookie); + if (!fp_cookie) + err = -1; + else + { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fileno (fp), O_BINARY); +#else + (void)modeflags; +#endif + fp_cookie->fp = fp; + fp_cookie->no_close = no_close; + *cookie = fp_cookie; + err = 0; + } + + return err; +} + +/* Read function for FILE* objects. */ +static ssize_t +es_func_fp_read (void *cookie, void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + ssize_t bytes_read; + + if (file_cookie->fp) + bytes_read = fread (buffer, 1, size, file_cookie->fp); + else + bytes_read = 0; + if (!bytes_read && ferror (file_cookie->fp)) + return -1; + return bytes_read; +} + +/* Write function for FILE* objects. */ +static ssize_t +es_func_fp_write (void *cookie, const void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + size_t bytes_written; + + + if (file_cookie->fp) + bytes_written = fwrite (buffer, 1, size, file_cookie->fp); + else + bytes_written = size; /* Successfully written to the bit bucket. */ + if (bytes_written != size) + return -1; + return bytes_written; +} + +/* Seek function for FILE* objects. */ +static int +es_func_fp_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_fp_t file_cookie = cookie; + long int offset_new; + + if (!file_cookie->fp) + { + _set_errno (ESPIPE); + return -1; + } + + if ( fseek (file_cookie->fp, (long int)*offset, whence) ) + { + /* fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", */ + /* errno,strerror (errno)); */ + return -1; + } + + offset_new = ftell (file_cookie->fp); + if (offset_new == -1) + { + /* fprintf (stderr, "\nftell failed: errno=%d (%s)\n", */ + /* errno,strerror (errno)); */ + return -1; + } + *offset = offset_new; + return 0; +} + +/* Destroy function for FILE* objects. */ +static int +es_func_fp_destroy (void *cookie) +{ + estream_cookie_fp_t fp_cookie = cookie; + int err; + + if (fp_cookie) + { + if (fp_cookie->fp) + { + fflush (fp_cookie->fp); + err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp); + } + else + err = 0; + mem_free (fp_cookie); + } + else + err = 0; + + return err; +} + + +static es_cookie_io_functions_t estream_functions_fp = + { + es_func_fp_read, + es_func_fp_write, + es_func_fp_seek, + es_func_fp_destroy + }; + + + + +/* Implementation of file I/O. */ + +/* Create function for file objects. */ +static int +es_func_file_create (void **cookie, int *filedes, + const char *path, unsigned int modeflags) +{ + estream_cookie_fd_t file_cookie; + int err; + int fd; + + err = 0; + fd = -1; + + file_cookie = mem_alloc (sizeof (*file_cookie)); + if (! file_cookie) + { + err = -1; + goto out; + } + + fd = open (path, modeflags, ES_DEFAULT_OPEN_MODE); + if (fd == -1) + { + err = -1; + goto out; + } +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#endif + + file_cookie->fd = fd; + file_cookie->no_close = 0; + *cookie = file_cookie; + *filedes = fd; + + out: + + if (err) + mem_free (file_cookie); + + return err; +} + + +static int +es_convert_mode (const char *mode, unsigned int *modeflags) +{ + unsigned int omode, oflags; + + switch (*mode) + { + case 'r': + omode = O_RDONLY; + oflags = 0; + break; + case 'w': + omode = O_WRONLY; + oflags = O_TRUNC | O_CREAT; + break; + case 'a': + omode = O_WRONLY; + oflags = O_APPEND | O_CREAT; + break; + default: + _set_errno (EINVAL); + return -1; + } + for (mode++; *mode; mode++) + { + switch (*mode) + { + case '+': + omode = O_RDWR; + break; + case 'b': + oflags |= O_BINARY; + break; + case 'x': + oflags |= O_EXCL; + break; + default: /* Ignore unknown flags. */ + break; + } + } + + *modeflags = (omode | oflags); + return 0; +} + + + +/* + * Low level stream functionality. + */ + +static int +es_fill (estream_t stream) +{ + size_t bytes_read = 0; + int err; + + if (!stream->intern->func_read) + { + _set_errno (EOPNOTSUPP); + err = -1; + } + else + { + es_cookie_read_function_t func_read = stream->intern->func_read; + ssize_t ret; + + ret = (*func_read) (stream->intern->cookie, + stream->buffer, stream->buffer_size); + if (ret == -1) + { + bytes_read = 0; + err = -1; + } + else + { + bytes_read = ret; + err = 0; + } + } + + if (err) + stream->intern->indicators.err = 1; + else if (!bytes_read) + stream->intern->indicators.eof = 1; + + stream->intern->offset += stream->data_len; + stream->data_len = bytes_read; + stream->data_offset = 0; + + return err; +} + +static int +es_flush (estream_t stream) +{ + es_cookie_write_function_t func_write = stream->intern->func_write; + int err; + + assert (stream->flags.writing); + + if (stream->data_offset) + { + size_t bytes_written; + size_t data_flushed; + ssize_t ret; + + if (! func_write) + { + err = EOPNOTSUPP; + goto out; + } + + /* Note: to prevent an endless loop caused by user-provided + write-functions that pretend to have written more bytes than + they were asked to write, we have to check for + "(stream->data_offset - data_flushed) > 0" instead of + "stream->data_offset - data_flushed". */ + + data_flushed = 0; + err = 0; + + while ((((ssize_t) (stream->data_offset - data_flushed)) > 0) && (! err)) + { + ret = (*func_write) (stream->intern->cookie, + stream->buffer + data_flushed, + stream->data_offset - data_flushed); + if (ret == -1) + { + bytes_written = 0; + err = -1; + } + else + bytes_written = ret; + + data_flushed += bytes_written; + if (err) + break; + } + + stream->data_flushed += data_flushed; + if (stream->data_offset == data_flushed) + { + stream->intern->offset += stream->data_offset; + stream->data_offset = 0; + stream->data_flushed = 0; + + /* Propagate flush event. */ + (*func_write) (stream->intern->cookie, NULL, 0); + } + } + else + err = 0; + + out: + + if (err) + stream->intern->indicators.err = 1; + + return err; +} + +/* Discard buffered data for STREAM. */ +static void +es_empty (estream_t stream) +{ + assert (!stream->flags.writing); + stream->data_len = 0; + stream->data_offset = 0; + stream->unread_data_len = 0; +} + +/* Initialize STREAM. */ +static void +es_initialize (estream_t stream, + void *cookie, int fd, es_cookie_io_functions_t functions, + unsigned int modeflags) +{ + stream->intern->cookie = cookie; + stream->intern->opaque = NULL; + stream->intern->offset = 0; + stream->intern->func_read = functions.func_read; + stream->intern->func_write = functions.func_write; + stream->intern->func_seek = functions.func_seek; + stream->intern->func_close = functions.func_close; + stream->intern->strategy = _IOFBF; + stream->intern->fd = fd; + stream->intern->print_err = 0; + stream->intern->print_errno = 0; + stream->intern->print_ntotal = 0; + stream->intern->print_fp = NULL; + stream->intern->indicators.err = 0; + stream->intern->indicators.eof = 0; + stream->intern->is_stdstream = 0; + stream->intern->stdstream_fd = 0; + stream->intern->deallocate_buffer = 0; + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; + + stream->data_len = 0; + stream->data_offset = 0; + stream->data_flushed = 0; + stream->unread_data_len = 0; + /* Depending on the modeflags we set whether we start in writing or + reading mode. This is required in case we are working on a + stream which is not seeekable (like stdout). Without this + pre-initialization we would do a seek at the first write call and + as this will fail no utput will be delivered. */ + if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) ) + stream->flags.writing = 1; + else + stream->flags.writing = 0; +} + +/* Deinitialize STREAM. */ +static int +es_deinitialize (estream_t stream) +{ + es_cookie_close_function_t func_close; + int err, tmp_err; + + if (stream->intern->print_fp) + { + int save_errno = errno; + fclose (stream->intern->print_fp); + stream->intern->print_fp = NULL; + _set_errno (save_errno); + } + + func_close = stream->intern->func_close; + + err = 0; + if (stream->flags.writing) + SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream)); + if (func_close) + SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); + + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; + + return err; +} + +/* Create a new stream object, initialize it. */ +static int +es_create (estream_t *stream, void *cookie, int fd, + es_cookie_io_functions_t functions, unsigned int modeflags, + int with_locked_list) +{ + estream_internal_t stream_internal_new; + estream_t stream_new; + int err; + + stream_new = NULL; + stream_internal_new = NULL; + + stream_new = mem_alloc (sizeof (*stream_new)); + if (! stream_new) + { + err = -1; + goto out; + } + + stream_internal_new = mem_alloc (sizeof (*stream_internal_new)); + if (! stream_internal_new) + { + err = -1; + goto out; + } + + stream_new->buffer = stream_internal_new->buffer; + stream_new->buffer_size = sizeof (stream_internal_new->buffer); + stream_new->unread_buffer = stream_internal_new->unread_buffer; + stream_new->unread_buffer_size = sizeof (stream_internal_new->unread_buffer); + stream_new->intern = stream_internal_new; + + ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock); + es_initialize (stream_new, cookie, fd, functions, modeflags); + + err = es_list_add (stream_new, with_locked_list); + if (err) + goto out; + + *stream = stream_new; + + out: + + if (err) + { + if (stream_new) + { + es_deinitialize (stream_new); + mem_free (stream_new); + } + } + + return err; +} + +/* Deinitialize a stream object and destroy it. */ +static int +es_destroy (estream_t stream, int with_locked_list) +{ + int err = 0; + + if (stream) + { + es_list_remove (stream, with_locked_list); + err = es_deinitialize (stream); + mem_free (stream->intern); + mem_free (stream); + } + + return err; +} + +/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in + unbuffered-mode, storing the amount of bytes read in + *BYTES_READ. */ +static int +es_read_nbf (estream_t ES__RESTRICT stream, + unsigned char *ES__RESTRICT buffer, + size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) +{ + es_cookie_read_function_t func_read = stream->intern->func_read; + size_t data_read; + ssize_t ret; + int err; + + data_read = 0; + err = 0; + + while (bytes_to_read - data_read) + { + ret = (*func_read) (stream->intern->cookie, + buffer + data_read, bytes_to_read - data_read); + if (ret == -1) + { + err = -1; + break; + } + else if (ret) + data_read += ret; + else + break; + } + + stream->intern->offset += data_read; + *bytes_read = data_read; + + return err; +} + +/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in + fully-buffered-mode, storing the amount of bytes read in + *BYTES_READ. */ +static int +es_read_fbf (estream_t ES__RESTRICT stream, + unsigned char *ES__RESTRICT buffer, + size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) +{ + size_t data_available; + size_t data_to_read; + size_t data_read; + int err; + + data_read = 0; + err = 0; + + while ((bytes_to_read - data_read) && (! err)) + { + if (stream->data_offset == stream->data_len) + { + /* Nothing more to read in current container, try to + fill container with new data. */ + err = es_fill (stream); + if (! err) + if (! stream->data_len) + /* Filling did not result in any data read. */ + break; + } + + if (! err) + { + /* Filling resulted in some new data. */ + + data_to_read = bytes_to_read - data_read; + data_available = stream->data_len - stream->data_offset; + if (data_to_read > data_available) + data_to_read = data_available; + + memcpy (buffer + data_read, + stream->buffer + stream->data_offset, data_to_read); + stream->data_offset += data_to_read; + data_read += data_to_read; + } + } + + *bytes_read = data_read; + + return err; +} + +/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in + line-buffered-mode, storing the amount of bytes read in + *BYTES_READ. */ +static int +es_read_lbf (estream_t ES__RESTRICT stream, + unsigned char *ES__RESTRICT buffer, + size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) +{ + int err; + + err = es_read_fbf (stream, buffer, bytes_to_read, bytes_read); + + return err; +} + +/* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER, storing + *the amount of bytes read in BYTES_READ. */ +static int +es_readn (estream_t ES__RESTRICT stream, + void *ES__RESTRICT buffer_arg, + size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) +{ + unsigned char *buffer = (unsigned char *)buffer_arg; + size_t data_read_unread, data_read; + int err; + + data_read_unread = 0; + data_read = 0; + err = 0; + + if (stream->flags.writing) + { + /* Switching to reading mode -> flush output. */ + err = es_flush (stream); + if (err) + goto out; + stream->flags.writing = 0; + } + + /* Read unread data first. */ + while ((bytes_to_read - data_read_unread) && stream->unread_data_len) + { + buffer[data_read_unread] + = stream->unread_buffer[stream->unread_data_len - 1]; + stream->unread_data_len--; + data_read_unread++; + } + + switch (stream->intern->strategy) + { + case _IONBF: + err = es_read_nbf (stream, + buffer + data_read_unread, + bytes_to_read - data_read_unread, &data_read); + break; + case _IOLBF: + err = es_read_lbf (stream, + buffer + data_read_unread, + bytes_to_read - data_read_unread, &data_read); + break; + case _IOFBF: + err = es_read_fbf (stream, + buffer + data_read_unread, + bytes_to_read - data_read_unread, &data_read); + break; + } + + out: + + if (bytes_read) + *bytes_read = data_read_unread + data_read; + + return err; +} + +/* Try to unread DATA_N bytes from DATA into STREAM, storing the + amount of bytes successfully unread in *BYTES_UNREAD. */ +static void +es_unreadn (estream_t ES__RESTRICT stream, + const unsigned char *ES__RESTRICT data, size_t data_n, + size_t *ES__RESTRICT bytes_unread) +{ + size_t space_left; + + space_left = stream->unread_buffer_size - stream->unread_data_len; + + if (data_n > space_left) + data_n = space_left; + + if (! data_n) + goto out; + + memcpy (stream->unread_buffer + stream->unread_data_len, data, data_n); + stream->unread_data_len += data_n; + stream->intern->indicators.eof = 0; + + out: + + if (bytes_unread) + *bytes_unread = data_n; +} + +/* Seek in STREAM. */ +static int +es_seek (estream_t ES__RESTRICT stream, off_t offset, int whence, + off_t *ES__RESTRICT offset_new) +{ + es_cookie_seek_function_t func_seek = stream->intern->func_seek; + int err, ret; + off_t off; + + if (! func_seek) + { + _set_errno (EOPNOTSUPP); + err = -1; + goto out; + } + + if (stream->flags.writing) + { + /* Flush data first in order to prevent flushing it to the wrong + offset. */ + err = es_flush (stream); + if (err) + goto out; + stream->flags.writing = 0; + } + + off = offset; + if (whence == SEEK_CUR) + { + off = off - stream->data_len + stream->data_offset; + off -= stream->unread_data_len; + } + + ret = (*func_seek) (stream->intern->cookie, &off, whence); + if (ret == -1) + { + err = -1; + goto out; + } + + err = 0; + es_empty (stream); + + if (offset_new) + *offset_new = off; + + stream->intern->indicators.eof = 0; + stream->intern->offset = off; + + out: + + if (err) + stream->intern->indicators.err = 1; + + return err; +} + +/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in + unbuffered-mode, storing the amount of bytes written in + *BYTES_WRITTEN. */ +static int +es_write_nbf (estream_t ES__RESTRICT stream, + const unsigned char *ES__RESTRICT buffer, + size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) +{ + es_cookie_write_function_t func_write = stream->intern->func_write; + size_t data_written; + ssize_t ret; + int err; + + if (bytes_to_write && (! func_write)) + { + err = EOPNOTSUPP; + goto out; + } + + data_written = 0; + err = 0; + + while (bytes_to_write - data_written) + { + ret = (*func_write) (stream->intern->cookie, + buffer + data_written, + bytes_to_write - data_written); + if (ret == -1) + { + err = -1; + break; + } + else + data_written += ret; + } + + stream->intern->offset += data_written; + *bytes_written = data_written; + + out: + + return err; +} + +/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in + fully-buffered-mode, storing the amount of bytes written in + *BYTES_WRITTEN. */ +static int +es_write_fbf (estream_t ES__RESTRICT stream, + const unsigned char *ES__RESTRICT buffer, + size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) +{ + size_t space_available; + size_t data_to_write; + size_t data_written; + int err; + + data_written = 0; + err = 0; + + while ((bytes_to_write - data_written) && (! err)) + { + if (stream->data_offset == stream->buffer_size) + /* Container full, flush buffer. */ + err = es_flush (stream); + + if (! err) + { + /* Flushing resulted in empty container. */ + + data_to_write = bytes_to_write - data_written; + space_available = stream->buffer_size - stream->data_offset; + if (data_to_write > space_available) + data_to_write = space_available; + + memcpy (stream->buffer + stream->data_offset, + buffer + data_written, data_to_write); + stream->data_offset += data_to_write; + data_written += data_to_write; + } + } + + *bytes_written = data_written; + + return err; +} + + +/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in + line-buffered-mode, storing the amount of bytes written in + *BYTES_WRITTEN. */ +static int +es_write_lbf (estream_t ES__RESTRICT stream, + const unsigned char *ES__RESTRICT buffer, + size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) +{ + size_t data_flushed = 0; + size_t data_buffered = 0; + unsigned char *nlp; + int err = 0; + + nlp = memrchr (buffer, '\n', bytes_to_write); + if (nlp) + { + /* Found a newline, directly write up to (including) this + character. */ + err = es_flush (stream); + if (!err) + err = es_write_nbf (stream, buffer, nlp - buffer + 1, &data_flushed); + } + + if (!err) + { + /* Write remaining data fully buffered. */ + err = es_write_fbf (stream, buffer + data_flushed, + bytes_to_write - data_flushed, &data_buffered); + } + + *bytes_written = data_flushed + data_buffered; + return err; +} + + +/* Write BYTES_TO_WRITE bytes from BUFFER into STREAM in, storing the + amount of bytes written in BYTES_WRITTEN. */ +static int +es_writen (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, + size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) +{ + size_t data_written; + int err; + + data_written = 0; + err = 0; + + if (!stream->flags.writing) + { + /* Switching to writing mode -> discard input data and seek to + position at which reading has stopped. We can do this only + if a seek function has been registered. */ + if (stream->intern->func_seek) + { + err = es_seek (stream, 0, SEEK_CUR, NULL); + if (err) + { + if (errno == ESPIPE) + err = 0; + else + goto out; + } + } + } + + switch (stream->intern->strategy) + { + case _IONBF: + err = es_write_nbf (stream, buffer, bytes_to_write, &data_written); + break; + + case _IOLBF: + err = es_write_lbf (stream, buffer, bytes_to_write, &data_written); + break; + + case _IOFBF: + err = es_write_fbf (stream, buffer, bytes_to_write, &data_written); + break; + } + + out: + + if (bytes_written) + *bytes_written = data_written; + if (data_written) + if (!stream->flags.writing) + stream->flags.writing = 1; + + return err; +} + + +static int +es_peek (estream_t ES__RESTRICT stream, unsigned char **ES__RESTRICT data, + size_t *ES__RESTRICT data_len) +{ + int err; + + if (stream->flags.writing) + { + /* Switching to reading mode -> flush output. */ + err = es_flush (stream); + if (err) + goto out; + stream->flags.writing = 0; + } + + if (stream->data_offset == stream->data_len) + { + /* Refill container. */ + err = es_fill (stream); + if (err) + goto out; + } + + if (data) + *data = stream->buffer + stream->data_offset; + if (data_len) + *data_len = stream->data_len - stream->data_offset; + err = 0; + + out: + + return err; +} + + +/* Skip SIZE bytes of input data contained in buffer. */ +static int +es_skip (estream_t stream, size_t size) +{ + int err; + + if (stream->data_offset + size > stream->data_len) + { + _set_errno (EINVAL); + err = -1; + } + else + { + stream->data_offset += size; + err = 0; + } + + return err; +} + + +static int +doreadline (estream_t ES__RESTRICT stream, size_t max_length, + char *ES__RESTRICT *ES__RESTRICT line, + size_t *ES__RESTRICT line_length) +{ + size_t space_left; + size_t line_size; + estream_t line_stream; + char *line_new; + void *line_stream_cookie; + char *newline; + unsigned char *data; + size_t data_len; + int err; + + line_new = NULL; + line_stream = NULL; + line_stream_cookie = NULL; + + err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0, + BUFFER_BLOCK_SIZE, 1, + mem_realloc, mem_free, + O_RDWR, + 0); + if (err) + goto out; + + err = es_create (&line_stream, line_stream_cookie, -1, + estream_functions_mem, O_RDWR, 0); + if (err) + goto out; + + space_left = max_length; + line_size = 0; + while (1) + { + if (max_length && (space_left == 1)) + break; + + err = es_peek (stream, &data, &data_len); + if (err || (! data_len)) + break; + + if (data_len > (space_left - 1)) + data_len = space_left - 1; + + newline = memchr (data, '\n', data_len); + if (newline) + { + data_len = (newline - (char *) data) + 1; + err = es_write (line_stream, data, data_len, NULL); + if (! err) + { + space_left -= data_len; + line_size += data_len; + es_skip (stream, data_len); + break; + } + } + else + { + err = es_write (line_stream, data, data_len, NULL); + if (! err) + { + space_left -= data_len; + line_size += data_len; + es_skip (stream, data_len); + } + } + if (err) + break; + } + if (err) + goto out; + + /* Complete line has been written to line_stream. */ + + if ((max_length > 1) && (! line_size)) + { + stream->intern->indicators.eof = 1; + goto out; + } + + err = es_seek (line_stream, 0, SEEK_SET, NULL); + if (err) + goto out; + + if (! *line) + { + line_new = mem_alloc (line_size + 1); + if (! line_new) + { + err = -1; + goto out; + } + } + else + line_new = *line; + + err = es_read (line_stream, line_new, line_size, NULL); + if (err) + goto out; + + line_new[line_size] = '\0'; + + if (! *line) + *line = line_new; + if (line_length) + *line_length = line_size; + + out: + + if (line_stream) + es_destroy (line_stream, 0); + else if (line_stream_cookie) + es_func_mem_destroy (line_stream_cookie); + + if (err) + { + if (! *line) + mem_free (line_new); + stream->intern->indicators.err = 1; + } + + return err; +} + + +/* Output fucntion used for estream_format. */ +static int +print_writer (void *outfncarg, const char *buf, size_t buflen) +{ + estream_t stream = outfncarg; + size_t nwritten; + int rc; + + nwritten = 0; + rc = es_writen (stream, buf, buflen, &nwritten); + stream->intern->print_ntotal += nwritten; + return rc; +} + + +/* The core of our printf function. This is called in locked state. */ +static int +es_print (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, va_list ap) +{ + int rc; + + stream->intern->print_ntotal = 0; + rc = estream_format (print_writer, stream, format, ap); + if (rc) + return -1; + return (int)stream->intern->print_ntotal; +} + + +static void +es_set_indicators (estream_t stream, int ind_err, int ind_eof) +{ + if (ind_err != -1) + stream->intern->indicators.err = ind_err ? 1 : 0; + if (ind_eof != -1) + stream->intern->indicators.eof = ind_eof ? 1 : 0; +} + + +static int +es_get_indicator (estream_t stream, int ind_err, int ind_eof) +{ + int ret = 0; + + if (ind_err) + ret = stream->intern->indicators.err; + else if (ind_eof) + ret = stream->intern->indicators.eof; + + return ret; +} + + +static int +es_set_buffering (estream_t ES__RESTRICT stream, + char *ES__RESTRICT buffer, int mode, size_t size) +{ + int err; + + /* Flush or empty buffer depending on mode. */ + if (stream->flags.writing) + { + err = es_flush (stream); + if (err) + goto out; + } + else + es_empty (stream); + + es_set_indicators (stream, -1, 0); + + /* Free old buffer in case that was allocated by this function. */ + if (stream->intern->deallocate_buffer) + { + stream->intern->deallocate_buffer = 0; + mem_free (stream->buffer); + stream->buffer = NULL; + } + + if (mode == _IONBF) + stream->buffer_size = 0; + else + { + void *buffer_new; + + if (buffer) + buffer_new = buffer; + else + { + if (!size) + size = BUFSIZ; + buffer_new = mem_alloc (size); + if (! buffer_new) + { + err = -1; + goto out; + } + } + + stream->buffer = buffer_new; + stream->buffer_size = size; + if (! buffer) + stream->intern->deallocate_buffer = 1; + } + stream->intern->strategy = mode; + err = 0; + + out: + + return err; +} + + +static off_t +es_offset_calculate (estream_t stream) +{ + off_t offset; + + offset = stream->intern->offset + stream->data_offset; + if (offset < stream->unread_data_len) + /* Offset undefined. */ + offset = 0; + else + offset -= stream->unread_data_len; + + return offset; +} + + +static void +es_opaque_ctrl (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque_new, + void **ES__RESTRICT opaque_old) +{ + if (opaque_old) + *opaque_old = stream->intern->opaque; + if (opaque_new) + stream->intern->opaque = opaque_new; +} + + +static int +es_get_fd (estream_t stream) +{ + return stream->intern->fd; +} + + + +/* API. */ + +int +es_init (void) +{ + int err; + + err = es_init_do (); + + return err; +} + +estream_t +es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + int fd; + + stream = NULL; + cookie = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + err = es_func_file_create (&cookie, &fd, path, modeflags); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0); + if (err) + goto out; + + if (stream && path) + fname_set_internal (stream, path, 1); + + out: + + if (err && create_called) + (*estream_functions_fd.func_close) (cookie); + + return stream; +} + + +estream_t +es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, + unsigned int grow, + func_realloc_t func_realloc, func_free_t func_free, + const char *ES__RESTRICT mode) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + + cookie = 0; + stream = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + err = es_func_mem_create (&cookie, data, data_n, data_len, + BUFFER_BLOCK_SIZE, grow, + func_realloc, func_free, modeflags, 0); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0); + + out: + + if (err && create_called) + (*estream_functions_mem.func_close) (cookie); + + return stream; +} + + +estream_t +es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) +{ + unsigned int modeflags; + estream_t stream = NULL; + void *cookie = NULL; + + /* Memory streams are always read/write. We use MODE only to get + the append flag. */ + if (es_convert_mode (mode, &modeflags)) + return NULL; + modeflags |= O_RDWR; + + + if (es_func_mem_create (&cookie, NULL, 0, 0, + BUFFER_BLOCK_SIZE, 1, + mem_realloc, mem_free, modeflags, + memlimit)) + return NULL; + + if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0)) + (*estream_functions_mem.func_close) (cookie); + + return stream; +} + + + +estream_t +es_fopencookie (void *ES__RESTRICT cookie, + const char *ES__RESTRICT mode, + es_cookie_io_functions_t functions) +{ + unsigned int modeflags; + estream_t stream; + int err; + + stream = NULL; + modeflags = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + err = es_create (&stream, cookie, -1, functions, modeflags, 0); + if (err) + goto out; + + out: + + return stream; +} + + +estream_t +do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + + stream = NULL; + cookie = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + err = es_func_fd_create (&cookie, filedes, modeflags, no_close); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, filedes, estream_functions_fd, + modeflags, with_locked_list); + + out: + + if (err && create_called) + (*estream_functions_fd.func_close) (cookie); + + return stream; +} + +estream_t +es_fdopen (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 0, 0); +} + +/* A variant of es_fdopen which does not close FILEDES at the end. */ +estream_t +es_fdopen_nc (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 1, 0); +} + + +estream_t +do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + + stream = NULL; + cookie = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + if (fp) + fflush (fp); + err = es_func_fp_create (&cookie, fp, modeflags, no_close); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp, + modeflags, with_locked_list); + + out: + + if (err && create_called) + (*estream_functions_fp.func_close) (cookie); + + return stream; +} + + +/* Create an estream from the stdio stream FP. This mechanism is + useful in case the stdio streams have special properties and may + not be mixed with fd based functions. This is for example the case + under Windows where the 3 standard streams are associated with the + console whereas a duped and fd-opened stream of one of this stream + won't be associated with the console. As this messes things up it + is easier to keep on using the standard I/O stream as a backend for + estream. */ +estream_t +es_fpopen (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 0, 0); +} + + +/* Same as es_fpopen but does not close FP at the end. */ +estream_t +es_fpopen_nc (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 1, 0); +} + + +/* Set custom standard descriptors to be used for stdin, stdout and + stderr. This function needs to be called before any of the + standard streams are accessed. */ +void +_es_set_std_fd (int no, int fd) +{ + ESTREAM_LIST_LOCK; + if (no >= 0 && no < 3 && !custom_std_fds_valid[no]) + { + custom_std_fds[no] = fd; + custom_std_fds_valid[no] = 1; + } + ESTREAM_LIST_UNLOCK; +} + + +/* Return the stream used for stdin, stdout or stderr. */ +estream_t +_es_get_std_stream (int fd) +{ + estream_list_t list_obj; + estream_t stream = NULL; + + fd %= 3; /* We only allow 0, 1 or 2 but we don't want to return an error. */ + ESTREAM_LIST_LOCK; + for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) + if (list_obj->car->intern->is_stdstream + && list_obj->car->intern->stdstream_fd == fd) + { + stream = list_obj->car; + break; + } + if (!stream) + { + /* Standard stream not yet created. We first try to create them + from registered file descriptors. */ + if (!fd && custom_std_fds_valid[0]) + stream = do_fdopen (custom_std_fds[0], "r", 1, 1); + else if (fd == 1 && custom_std_fds_valid[1]) + stream = do_fdopen (custom_std_fds[1], "a", 1, 1); + else if (custom_std_fds_valid[2]) + stream = do_fdopen (custom_std_fds[2], "a", 1, 1); + + if (!stream) + { + /* Second try is to use the standard C streams. */ + if (!fd) + stream = do_fpopen (stdin, "r", 1, 1); + else if (fd == 1) + stream = do_fpopen (stdout, "a", 1, 1); + else + stream = do_fpopen (stderr, "a", 1, 1); + } + + if (!stream) + { + /* Last try: Create a bit bucket. */ + stream = do_fpopen (NULL, fd? "a":"r", 0, 1); + if (!stream) + { + fprintf (stderr, "fatal: error creating a dummy estream" + " for %d: %s\n", fd, strerror (errno)); + abort(); + } + } + + stream->intern->is_stdstream = 1; + stream->intern->stdstream_fd = fd; + if (fd == 2) + es_set_buffering (stream, NULL, _IOLBF, 0); + fname_set_internal (stream, + fd == 0? "[stdin]" : + fd == 1? "[stdout]" : "[stderr]", 0); + } + ESTREAM_LIST_UNLOCK; + return stream; +} + + +estream_t +es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, + estream_t ES__RESTRICT stream) +{ + int err; + + if (path) + { + unsigned int modeflags; + int create_called; + void *cookie; + int fd; + + cookie = NULL; + create_called = 0; + + ESTREAM_LOCK (stream); + + es_deinitialize (stream); + + err = es_convert_mode (mode, &modeflags); + if (err) + goto leave; + + err = es_func_file_create (&cookie, &fd, path, modeflags); + if (err) + goto leave; + + create_called = 1; + es_initialize (stream, cookie, fd, estream_functions_fd, modeflags); + + leave: + + if (err) + { + if (create_called) + es_func_fd_destroy (cookie); + + es_destroy (stream, 0); + stream = NULL; + } + else + { + if (stream && path) + fname_set_internal (stream, path, 1); + ESTREAM_UNLOCK (stream); + } + } + else + { + /* FIXME? We don't support re-opening at the moment. */ + _set_errno (EINVAL); + es_deinitialize (stream); + es_destroy (stream, 0); + stream = NULL; + } + + return stream; +} + + +int +es_fclose (estream_t stream) +{ + int err; + + err = es_destroy (stream, 0); + + return err; +} + +int +es_fileno_unlocked (estream_t stream) +{ + return es_get_fd (stream); +} + + +void +es_flockfile (estream_t stream) +{ + ESTREAM_LOCK (stream); +} + + +int +es_ftrylockfile (estream_t stream) +{ + return ESTREAM_TRYLOCK (stream); +} + + +void +es_funlockfile (estream_t stream) +{ + ESTREAM_UNLOCK (stream); +} + + +int +es_fileno (estream_t stream) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_fileno_unlocked (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int +es_feof_unlocked (estream_t stream) +{ + return es_get_indicator (stream, 0, 1); +} + + +int +es_feof (estream_t stream) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_feof_unlocked (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int +es_ferror_unlocked (estream_t stream) +{ + return es_get_indicator (stream, 1, 0); +} + + +int +es_ferror (estream_t stream) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_ferror_unlocked (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +void +es_clearerr_unlocked (estream_t stream) +{ + es_set_indicators (stream, 0, 0); +} + + +void +es_clearerr (estream_t stream) +{ + ESTREAM_LOCK (stream); + es_clearerr_unlocked (stream); + ESTREAM_UNLOCK (stream); +} + + +static int +do_fflush (estream_t stream) +{ + int err; + + if (stream->flags.writing) + err = es_flush (stream); + else + { + es_empty (stream); + err = 0; + } + + return err; +} + + +int +es_fflush (estream_t stream) +{ + int err; + + if (stream) + { + ESTREAM_LOCK (stream); + err = do_fflush (stream); + ESTREAM_UNLOCK (stream); + } + else + err = es_list_iterate (do_fflush); + + return err ? EOF : 0; +} + + +int +es_fseek (estream_t stream, long int offset, int whence) +{ + int err; + + ESTREAM_LOCK (stream); + err = es_seek (stream, offset, whence, NULL); + ESTREAM_UNLOCK (stream); + + return err; +} + + +int +es_fseeko (estream_t stream, off_t offset, int whence) +{ + int err; + + ESTREAM_LOCK (stream); + err = es_seek (stream, offset, whence, NULL); + ESTREAM_UNLOCK (stream); + + return err; +} + + +long int +es_ftell (estream_t stream) +{ + long int ret; + + ESTREAM_LOCK (stream); + ret = es_offset_calculate (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +off_t +es_ftello (estream_t stream) +{ + off_t ret = -1; + + ESTREAM_LOCK (stream); + ret = es_offset_calculate (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +void +es_rewind (estream_t stream) +{ + ESTREAM_LOCK (stream); + es_seek (stream, 0L, SEEK_SET, NULL); + es_set_indicators (stream, 0, -1); + ESTREAM_UNLOCK (stream); +} + + +int +_es_getc_underflow (estream_t stream) +{ + int err; + unsigned char c; + size_t bytes_read; + + err = es_readn (stream, &c, 1, &bytes_read); + + return (err || (! bytes_read)) ? EOF : c; +} + + +int +_es_putc_overflow (int c, estream_t stream) +{ + unsigned char d = c; + int err; + + err = es_writen (stream, &d, 1, NULL); + + return err ? EOF : c; +} + + +int +es_fgetc (estream_t stream) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_getc_unlocked (stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int +es_fputc (int c, estream_t stream) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_putc_unlocked (c, stream); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int +es_ungetc (int c, estream_t stream) +{ + unsigned char data = (unsigned char) c; + size_t data_unread; + + ESTREAM_LOCK (stream); + es_unreadn (stream, &data, 1, &data_unread); + ESTREAM_UNLOCK (stream); + + return data_unread ? c : EOF; +} + + +int +es_read (estream_t ES__RESTRICT stream, + void *ES__RESTRICT buffer, size_t bytes_to_read, + size_t *ES__RESTRICT bytes_read) +{ + int err; + + if (bytes_to_read) + { + ESTREAM_LOCK (stream); + err = es_readn (stream, buffer, bytes_to_read, bytes_read); + ESTREAM_UNLOCK (stream); + } + else + err = 0; + + return err; +} + + +int +es_write (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, size_t bytes_to_write, + size_t *ES__RESTRICT bytes_written) +{ + int err; + + if (bytes_to_write) + { + ESTREAM_LOCK (stream); + err = es_writen (stream, buffer, bytes_to_write, bytes_written); + ESTREAM_UNLOCK (stream); + } + else + err = 0; + + return err; +} + + +size_t +es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems, + estream_t ES__RESTRICT stream) +{ + size_t ret, bytes; + + if (size * nitems) + { + ESTREAM_LOCK (stream); + es_readn (stream, ptr, size * nitems, &bytes); + ESTREAM_UNLOCK (stream); + + ret = bytes / size; + } + else + ret = 0; + + return ret; +} + + +size_t +es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t nitems, + estream_t ES__RESTRICT stream) +{ + size_t ret, bytes; + + if (size * nitems) + { + ESTREAM_LOCK (stream); + es_writen (stream, ptr, size * nitems, &bytes); + ESTREAM_UNLOCK (stream); + + ret = bytes / size; + } + else + ret = 0; + + return ret; +} + + +char * +es_fgets (char *ES__RESTRICT buffer, int length, estream_t ES__RESTRICT stream) +{ + unsigned char *s = (unsigned char*)buffer; + int c; + + if (!length) + return NULL; + + c = EOF; + ESTREAM_LOCK (stream); + while (length > 1 && (c = es_getc_unlocked (stream)) != EOF && c != '\n') + { + *s++ = c; + length--; + } + ESTREAM_UNLOCK (stream); + + if (c == EOF && s == (unsigned char*)buffer) + return NULL; /* Nothing read. */ + + if (c != EOF && length > 1) + *s++ = c; + + *s = 0; + return buffer; +} + + +int +es_fputs_unlocked (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream) +{ + size_t length; + int err; + + length = strlen (s); + err = es_writen (stream, s, length, NULL); + return err ? EOF : 0; +} + +int +es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream) +{ + size_t length; + int err; + + length = strlen (s); + ESTREAM_LOCK (stream); + err = es_writen (stream, s, length, NULL); + ESTREAM_UNLOCK (stream); + + return err ? EOF : 0; +} + + +ssize_t +es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr, size_t *ES__RESTRICT n, + estream_t ES__RESTRICT stream) +{ + char *line = NULL; + size_t line_n = 0; + int err; + + ESTREAM_LOCK (stream); + err = doreadline (stream, 0, &line, &line_n); + ESTREAM_UNLOCK (stream); + if (err) + goto out; + + if (*n) + { + /* Caller wants us to use his buffer. */ + + if (*n < (line_n + 1)) + { + /* Provided buffer is too small -> resize. */ + + void *p; + + p = mem_realloc (*lineptr, line_n + 1); + if (! p) + err = -1; + else + { + if (*lineptr != p) + *lineptr = p; + } + } + + if (! err) + { + memcpy (*lineptr, line, line_n + 1); + if (*n != line_n) + *n = line_n; + } + mem_free (line); + } + else + { + /* Caller wants new buffers. */ + *lineptr = line; + *n = line_n; + } + + out: + + return err ? err : (ssize_t)line_n; +} + + + +/* 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 or another error occurred; ERRNO is then 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 starts with the next + line. Note that MAX_LENGTH must be re-initialzied in this case. + + The caller initially needs to provide the address of a variable, + initialized to NULL, at ADDR_OF_BUFFER and don't change this value + anymore with the following invocations. LENGTH_OF_BUFFER should be + the address of a variable, initialized to 0, which is also + maintained by this function. Thus, both paramaters should be + considered the state of this function. + + Note: The returned buffer is allocated with enough extra space to + allow the caller to append a CR,LF,Nul. The buffer should be + released using es_free. + */ +ssize_t +es_read_line (estream_t stream, + 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 = mem_alloc (length); + *addr_of_buffer = buffer; + if (!buffer) + { + *length_of_buffer = 0; + if (max_length) + *max_length = 0; + return -1; + } + *length_of_buffer = length; + } + + if (length < 4) + { + /* This should never happen. If it does, the function has been + called with wrong arguments. */ + _set_errno (EINVAL); + return -1; + } + length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */ + + ESTREAM_LOCK (stream); + p = buffer; + while ((c = es_getc_unlocked (stream)) != EOF) + { + if (nbytes == length) + { + /* Enlarge the buffer. */ + if (maxlen && length > maxlen) + { + /* We are beyond our limit: Skip the rest of the line. */ + while (c != '\n' && (c=es_getc_unlocked (stream)) != 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 = mem_realloc (buffer, length); + if (!*addr_of_buffer) + { + int save_errno = errno; + mem_free (buffer); + *length_of_buffer = 0; + if (max_length) + *max_length = 0; + ESTREAM_UNLOCK (stream); + _set_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. */ + ESTREAM_UNLOCK (stream); + + return nbytes; +} + +/* Wrapper around free() to match the memory allocation system used + by estream. Should be used for all buffers returned to the caller + by libestream. */ +void +es_free (void *a) +{ + mem_free (a); +} + + +int +es_vfprintf_unlocked (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, + va_list ap) +{ + return es_print (stream, format, ap); +} + + +int +es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format, + va_list ap) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_print (stream, format, ap); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int +es_fprintf_unlocked (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, ...) +{ + int ret; + + va_list ap; + va_start (ap, format); + ret = es_print (stream, format, ap); + va_end (ap); + + return ret; +} + + +int +es_fprintf (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, ...) +{ + int ret; + + va_list ap; + va_start (ap, format); + ESTREAM_LOCK (stream); + ret = es_print (stream, format, ap); + ESTREAM_UNLOCK (stream); + va_end (ap); + + return ret; +} + +/* A variant of asprintf. The function returns the allocated buffer + or NULL on error; ERRNO is set in the error case. The caller + should use es_free to release the buffer. This function actually + belongs into estream-printf but we put it here as a convenience + and because es_free is required anyway. */ +char * +es_asprintf (const char *ES__RESTRICT format, ...) +{ + int rc; + va_list ap; + char *buf; + + va_start (ap, format); + rc = estream_vasprintf (&buf, format, ap); + va_end (ap); + if (rc < 0) + return NULL; + return buf; +} + + +/* A variant of vasprintf. The function returns the allocated buffer + or NULL on error; ERRNO is set in the error case. The caller + should use es_free to release the buffer. This function actually + belongs into estream-printf but we put it here as a convenience + and because es_free is required anyway. */ +char * +es_vasprintf (const char *ES__RESTRICT format, va_list ap) +{ + int rc; + char *buf; + + rc = estream_vasprintf (&buf, format, ap); + if (rc < 0) + return NULL; + return buf; +} + + +static int +tmpfd (void) +{ +#ifdef HAVE_W32_SYSTEM + int attempts, n; +#ifdef HAVE_W32CE_SYSTEM + wchar_t buffer[MAX_PATH+9+12+1]; +# define mystrlen(a) wcslen (a) + wchar_t *name, *p; +#else + char buffer[MAX_PATH+9+12+1]; +# define mystrlen(a) strlen (a) + char *name, *p; +#endif + HANDLE file; + int pid = GetCurrentProcessId (); + unsigned int value; + int i; + + n = GetTempPath (MAX_PATH+1, buffer); + if (!n || n > MAX_PATH || mystrlen (buffer) > MAX_PATH) + { + _set_errno (ENOENT); + return -1; + } + p = buffer + mystrlen (buffer); +#ifdef HAVE_W32CE_SYSTEM + wcscpy (p, L"_estream"); +#else + strcpy (p, "_estream"); +#endif + p += 8; + /* We try to create the directory but don't care about an error as + it may already exist and the CreateFile would throw an error + anyway. */ + CreateDirectory (buffer, NULL); + *p++ = '\\'; + name = p; + for (attempts=0; attempts < 10; attempts++) + { + p = name; + value = (GetTickCount () ^ ((pid<<16) & 0xffff0000)); + for (i=0; i < 8; i++) + { + *p++ = tohex (((value >> 28) & 0x0f)); + value <<= 4; + } +#ifdef HAVE_W32CE_SYSTEM + wcscpy (p, L".tmp"); +#else + strcpy (p, ".tmp"); +#endif + file = CreateFile (buffer, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + if (file != INVALID_HANDLE_VALUE) + { +#ifdef HAVE_W32CE_SYSTEM + int fd = (int)file; +#else + int fd = _open_osfhandle ((long)file, 0); + if (fd == -1) + { + CloseHandle (file); + return -1; + } +#endif + return fd; + } + Sleep (1); /* One ms as this is the granularity of GetTickCount. */ + } + _set_errno (ENOENT); + return -1; +#else /*!HAVE_W32_SYSTEM*/ + FILE *fp; + int fp_fd; + int fd; + + fp = NULL; + fd = -1; + + fp = tmpfile (); + if (! fp) + goto out; + + fp_fd = fileno (fp); + fd = dup (fp_fd); + + out: + + if (fp) + fclose (fp); + + return fd; +#endif /*!HAVE_W32_SYSTEM*/ +} + +estream_t +es_tmpfile (void) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + int fd; + + create_called = 0; + stream = NULL; + modeflags = O_RDWR | O_TRUNC | O_CREAT; + cookie = NULL; + + fd = tmpfd (); + if (fd == -1) + { + err = -1; + goto out; + } + + err = es_func_fd_create (&cookie, fd, modeflags, 0); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0); + + out: + + if (err) + { + if (create_called) + es_func_fd_destroy (cookie); + else if (fd != -1) + close (fd); + stream = NULL; + } + + return stream; +} + + +int +es_setvbuf (estream_t ES__RESTRICT stream, + char *ES__RESTRICT buf, int type, size_t size) +{ + int err; + + if ((type == _IOFBF || type == _IOLBF || type == _IONBF) + && (!buf || size || type == _IONBF)) + { + ESTREAM_LOCK (stream); + err = es_set_buffering (stream, buf, type, size); + ESTREAM_UNLOCK (stream); + } + else + { + _set_errno (EINVAL); + err = -1; + } + + return err; +} + + +void +es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf) +{ + ESTREAM_LOCK (stream); + es_set_buffering (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); + ESTREAM_UNLOCK (stream); +} + +void +es_opaque_set (estream_t stream, void *opaque) +{ + ESTREAM_LOCK (stream); + es_opaque_ctrl (stream, opaque, NULL); + ESTREAM_UNLOCK (stream); +} + + +void * +es_opaque_get (estream_t stream) +{ + void *opaque; + + ESTREAM_LOCK (stream); + es_opaque_ctrl (stream, NULL, &opaque); + ESTREAM_UNLOCK (stream); + + return opaque; +} + + +static void +fname_set_internal (estream_t stream, const char *fname, int quote) +{ + if (stream->intern->printable_fname + && !stream->intern->printable_fname_inuse) + { + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + } + if (stream->intern->printable_fname) + return; /* Can't change because it is in use. */ + + if (*fname != '[') + quote = 0; + else + quote = !!quote; + + stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1); + if (fname) + { + if (quote) + stream->intern->printable_fname[0] = '\\'; + strcpy (stream->intern->printable_fname+quote, fname); + } +} + + +/* Set the filename attribute of STREAM. There is no error return. + as long as STREAM is valid. This function is called internally by + functions which open a filename. */ +void +es_fname_set (estream_t stream, const char *fname) +{ + if (fname) + { + ESTREAM_LOCK (stream); + fname_set_internal (stream, fname, 1); + ESTREAM_UNLOCK (stream); + } +} + + +/* Return the filename attribute of STREAM. In case no filename has + been set, "[?]" will be returned. The returned file name is valid + as long as STREAM is valid. */ +const char * +es_fname_get (estream_t stream) +{ + const char *fname; + + ESTREAM_LOCK (stream); + fname = stream->intern->printable_fname; + if (fname) + stream->intern->printable_fname_inuse = 1; + ESTREAM_UNLOCK (stream); + if (!fname) + fname = "[?]"; + return fname; +} + + +/* Print a BUFFER to STREAM while replacing all control characters and + the characters in DELIMITERS by standard C escape sequences. + Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL + the number of bytes actually written are stored at this + address. */ +int +es_write_sanitized (estream_t ES__RESTRICT stream, + const void * ES__RESTRICT buffer, size_t length, + const char * delimiters, + size_t * ES__RESTRICT bytes_written) +{ + const unsigned char *p = buffer; + size_t count = 0; + int ret; + + ESTREAM_LOCK (stream); + for (; length; length--, p++, count++) + { + if (*p < 0x20 + || *p == 0x7f + || (delimiters + && (strchr (delimiters, *p) || *p == '\\'))) + { + es_putc_unlocked ('\\', stream); + count++; + if (*p == '\n') + { + es_putc_unlocked ('n', stream); + count++; + } + else if (*p == '\r') + { + es_putc_unlocked ('r', stream); + count++; + } + else if (*p == '\f') + { + es_putc_unlocked ('f', stream); + count++; + } + else if (*p == '\v') + { + es_putc_unlocked ('v', stream); + count++; + } + else if (*p == '\b') + { + es_putc_unlocked ('b', stream); + count++; + } + else if (!*p) + { + es_putc_unlocked('0', stream); + count++; + } + else + { + es_fprintf_unlocked (stream, "x%02x", *p); + count += 3; + } + } + else + { + es_putc_unlocked (*p, stream); + count++; + } + } + + if (bytes_written) + *bytes_written = count; + ret = es_ferror_unlocked (stream)? -1 : 0; + ESTREAM_UNLOCK (stream); + + return ret; +} + + +/* Write LENGTH bytes of BUFFER to STREAM as a hex encoded string. + RESERVED must be 0. Returns 0 on success or -1 on error. If + BYTES_WRITTEN is not NULL the number of bytes actually written are + stored at this address. */ +int +es_write_hexstring (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, size_t length, + int reserved, size_t *ES__RESTRICT bytes_written ) +{ + int ret; + const unsigned char *s; + size_t count = 0; + + (void)reserved; + +#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) + + if (!length) + return 0; + + ESTREAM_LOCK (stream); + + for (s = buffer; length; s++, length--) + { + es_putc_unlocked ( tohex ((*s>>4)&15), stream); + es_putc_unlocked ( tohex (*s&15), stream); + count += 2; + } + + if (bytes_written) + *bytes_written = count; + ret = es_ferror_unlocked (stream)? -1 : 0; + + ESTREAM_UNLOCK (stream); + + return ret; + +#undef tohex +} + + + +#ifdef GNUPG_MAJOR_VERSION +/* Special estream function to print an UTF8 string in the native + encoding. The interface is the same as es_write_sanitized, however + only one delimiter may be supported. + + THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG!. */ +int +es_write_sanitized_utf8_buffer (estream_t stream, + const void *buffer, size_t length, + const char *delimiters, size_t *bytes_written) +{ + 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) + { + int delim = delimiters? *delimiters : 0; + char *buf; + int ret; + + /*(utf8 conversion already does the control character quoting). */ + buf = utf8_to_native (p, length, delim); + if (bytes_written) + *bytes_written = strlen (buf); + ret = es_fputs (buf, stream); + xfree (buf); + return ret == EOF? ret : (int)i; + } + else + return es_write_sanitized (stream, p, length, delimiters, bytes_written); +} +#endif /*GNUPG_MAJOR_VERSION*/ diff --git a/common/estream.h b/common/estream.h new file mode 100644 index 0000000..69f19f4 --- /dev/null +++ b/common/estream.h @@ -0,0 +1,379 @@ +/* estream.h - Extended stream I/O Library + * Copyright (C) 2004, 2005, 2006, 2007, 2010 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream 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. + * + * Libestream is distributed in the hope that 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 Libestream; if not, see . + * + * ALTERNATIVELY, Libestream 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 ESTREAM_H +#define ESTREAM_H + +#include +#include +#include + +/* To use this file with libraries the following macro is useful: + + #define _ESTREAM_EXT_SYM_PREFIX _foo_ + + This prefixes all external symbols with "_foo_". + + */ + + +#ifdef _ESTREAM_EXT_SYM_PREFIX +#ifndef _ESTREAM_PREFIX +#define _ESTREAM_PREFIX1(x,y) x ## y +#define _ESTREAM_PREFIX2(x,y) _ESTREAM_PREFIX1(x,y) +#define _ESTREAM_PREFIX(x) _ESTREAM_PREFIX2(_ESTREAM_EXT_SYM_PREFIX,x) +#endif /*_ESTREAM_PREFIX*/ +#define es_fopen _ESTREAM_PREFIX(es_fopen) +#define es_mopen _ESTREAM_PREFIX(es_mopen) +#define es_fopenmem _ESTREAM_PREFIX(es_fopenmem) +#define es_fdopen _ESTREAM_PREFIX(es_fdopen) +#define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) +#define es_fpopen _ESTREAM_PREFIX(es_fpopen) +#define es_fpopen_nc _ESTREAM_PREFIX(es_fpopen_nc) +#define _es_set_std_fd _ESTREAM_PREFIX(_es_set_std_fd) +#define _es_get_std_stream _ESTREAM_PREFIX(_es_get_std_stream) +#define es_freopen _ESTREAM_PREFIX(es_freopen) +#define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) +#define es_fclose _ESTREAM_PREFIX(es_fclose) +#define es_fileno _ESTREAM_PREFIX(es_fileno) +#define es_fileno_unlocked _ESTREAM_PREFIX(es_fileno_unlocked) +#define es_flockfile _ESTREAM_PREFIX(es_flockfile) +#define es_ftrylockfile _ESTREAM_PREFIX(es_ftrylockfile) +#define es_funlockfile _ESTREAM_PREFIX(es_funlockfile) +#define es_feof _ESTREAM_PREFIX(es_feof) +#define es_feof_unlocked _ESTREAM_PREFIX(es_feof_unlocked) +#define es_ferror _ESTREAM_PREFIX(es_ferror) +#define es_ferror_unlocked _ESTREAM_PREFIX(es_ferror_unlocked) +#define es_clearerr _ESTREAM_PREFIX(es_clearerr) +#define es_clearerr_unlocked _ESTREAM_PREFIX(es_clearerr_unlocked) +#define es_fflush _ESTREAM_PREFIX(es_fflush) +#define es_fseek _ESTREAM_PREFIX(es_fseek) +#define es_fseeko _ESTREAM_PREFIX(es_fseeko) +#define es_ftell _ESTREAM_PREFIX(es_ftell) +#define es_ftello _ESTREAM_PREFIX(es_ftello) +#define es_rewind _ESTREAM_PREFIX(es_rewind) +#define es_fgetc _ESTREAM_PREFIX(es_fgetc) +#define es_fputc _ESTREAM_PREFIX(es_fputc) +#define _es_getc_underflow _ESTREAM_PREFIX(_es_getc_underflow) +#define _es_putc_overflow _ESTREAM_PREFIX(_es_putc_overflow) +#define es_ungetc _ESTREAM_PREFIX(es_ungetc) +#define es_read _ESTREAM_PREFIX(es_read) +#define es_write _ESTREAM_PREFIX(es_write) +#define es_write_sanitized _ESTREAM_PREFIX(es_write_sanitized) +#define es_write_hexstring _ESTREAM_PREFIX(es_write_hexstring) +#define es_fread _ESTREAM_PREFIX(es_fread) +#define es_fwrite _ESTREAM_PREFIX(es_fwrite) +#define es_fgets _ESTREAM_PREFIX(es_fgets) +#define es_fputs _ESTREAM_PREFIX(es_fputs) +#define es_fputs_unlocked _ESTREAM_PREFIX(es_fputs_unlocked) +#define es_getline _ESTREAM_PREFIX(es_getline) +#define es_read_line _ESTREAM_PREFIX(es_read_line) +#define es_free _ESTREAM_PREFIX(es_free) +#define es_fprintf _ESTREAM_PREFIX(es_fprintf) +#define es_fprintf_unlocked _ESTREAM_PREFIX(es_fprintf_unlocked) +#define es_vfprintf _ESTREAM_PREFIX(es_vfprint) +#define es_vfprintf_unlocked _ESTREAM_PREFIX(es_vfprint_unlocked) +#define es_setvbuf _ESTREAM_PREFIX(es_setvbuf) +#define es_setbuf _ESTREAM_PREFIX(es_setbuf) +#define es_tmpfile _ESTREAM_PREFIX(es_tmpfile) +#define es_opaque_set _ESTREAM_PREFIX(es_opaque_set) +#define es_opaque_get _ESTREAM_PREFIX(es_opaque_get) +#define es_fname_set _ESTREAM_PREFIX(es_fname_set) +#define es_fname_get _ESTREAM_PREFIX(es_fname_get) +#define es_write_sanitized_utf8_buffer \ + _ESTREAM_PREFIX(es_write_sanitized_utf8_buffer) +#endif /*_ESTREAM_EXT_SYM_PREFIX*/ + + +#ifdef __cplusplus +extern "C" +{ +#if 0 +} +#endif +#endif + + +/* Forward declaration for the (opaque) internal type. */ +struct estream_internal; + +/* The definition of this struct is entirely private. You must not + use it for anything. It is only here so some functions can be + implemented as macros. */ +struct es__stream +{ + /* The layout of this struct must never change. It may be grown, + but only if all functions which access the new members are + versioned. */ + + /* A pointer to the stream buffer. */ + unsigned char *buffer; + + /* The size of the buffer in bytes. */ + size_t buffer_size; + + /* The length of the usable data in the buffer, only valid when in + read mode (see flags). */ + size_t data_len; + + /* The current position of the offset pointer, valid in read and + write mode. */ + size_t data_offset; + + size_t data_flushed; + unsigned char *unread_buffer; + size_t unread_buffer_size; + + /* The number of unread bytes. */ + size_t unread_data_len; + + /* Various flags. */ + struct { + unsigned int writing: 1; + unsigned int reserved: 7; + } flags; + + /* A pointer to our internal data for this stream. */ + struct estream_internal *intern; +}; + +/* The opaque type for an estream. */ +typedef struct es__stream *estream_t; + + +typedef ssize_t (*es_cookie_read_function_t) (void *cookie, + void *buffer, size_t size); +typedef ssize_t (*es_cookie_write_function_t) (void *cookie, + const void *buffer, + size_t size); +typedef int (*es_cookie_seek_function_t) (void *cookie, + off_t *pos, int whence); +typedef int (*es_cookie_close_function_t) (void *cookie); + +typedef struct es_cookie_io_functions +{ + es_cookie_read_function_t func_read; + es_cookie_write_function_t func_write; + es_cookie_seek_function_t func_seek; + es_cookie_close_function_t func_close; +} es_cookie_io_functions_t; + + +#ifndef _ESTREAM_GCC_A_PRINTF +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) +# define _ESTREAM_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) +#else +# define _ESTREAM_GCC_A_PRINTF( f, a ) +#endif +#endif /*_ESTREAM_GCC_A_PRINTF*/ + + +#ifndef ES__RESTRICT +# if defined __GNUC__ && defined __GNUC_MINOR__ +# if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 92)) +# define ES__RESTRICT __restrict__ +# endif +# endif +#endif +#ifndef ES__RESTRICT +# define ES__RESTRICT +#endif + +int es_init (void); + +int es_pth_kill (void); + +estream_t es_fopen (const char *ES__RESTRICT path, + const char *ES__RESTRICT mode); +estream_t es_mopen (unsigned char *ES__RESTRICT data, + size_t data_n, size_t data_len, + unsigned int grow, + void *(*func_realloc) (void *mem, size_t size), + void (*func_free) (void *mem), + const char *ES__RESTRICT mode); +estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode); +estream_t es_fdopen (int filedes, const char *mode); +estream_t es_fdopen_nc (int filedes, const char *mode); +estream_t es_fpopen (FILE *fp, const char *mode); +estream_t es_fpopen_nc (FILE *fp, const char *mode); +estream_t es_freopen (const char *ES__RESTRICT path, + const char *ES__RESTRICT mode, + estream_t ES__RESTRICT stream); +estream_t es_fopencookie (void *ES__RESTRICT cookie, + const char *ES__RESTRICT mode, + es_cookie_io_functions_t functions); +int es_fclose (estream_t stream); +int es_fileno (estream_t stream); +int es_fileno_unlocked (estream_t stream); + +void _es_set_std_fd (int no, int fd); +estream_t _es_get_std_stream (int fd); + +#define es_stdin _es_get_std_stream (0) +#define es_stdout _es_get_std_stream (1) +#define es_stderr _es_get_std_stream (2) + + +void es_flockfile (estream_t stream); +int es_ftrylockfile (estream_t stream); +void es_funlockfile (estream_t stream); + +int es_feof (estream_t stream); +int es_feof_unlocked (estream_t stream); +int es_ferror (estream_t stream); +int es_ferror_unlocked (estream_t stream); +void es_clearerr (estream_t stream); +void es_clearerr_unlocked (estream_t stream); + +int es_fflush (estream_t stream); +int es_fseek (estream_t stream, long int offset, int whence); +int es_fseeko (estream_t stream, off_t offset, int whence); +long int es_ftell (estream_t stream); +off_t es_ftello (estream_t stream); +void es_rewind (estream_t stream); + +int es_fgetc (estream_t stream); +int es_fputc (int c, estream_t stream); + +int _es_getc_underflow (estream_t stream); +int _es_putc_overflow (int c, estream_t stream); + +#define es_getc_unlocked(stream) \ + (((!(stream)->flags.writing) \ + && ((stream)->data_offset < (stream)->data_len) \ + && (! (stream)->unread_data_len)) \ + ? ((int) (stream)->buffer[((stream)->data_offset)++]) \ + : _es_getc_underflow ((stream))) + +#define es_putc_unlocked(c, stream) \ + (((stream)->flags.writing \ + && ((stream)->data_offset < (stream)->buffer_size) \ + && (c != '\n')) \ + ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c))) \ + : _es_putc_overflow ((c), (stream))) + +#define es_getc(stream) es_fgetc (stream) +#define es_putc(c, stream) es_fputc (c, stream) + +int es_ungetc (int c, estream_t stream); + +int es_read (estream_t ES__RESTRICT stream, + void *ES__RESTRICT buffer, size_t bytes_to_read, + size_t *ES__RESTRICT bytes_read); +int es_write (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, size_t bytes_to_write, + size_t *ES__RESTRICT bytes_written); +int es_write_sanitized (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, size_t length, + const char *delimiters, + size_t *ES__RESTRICT bytes_written); +int es_write_hexstring (estream_t ES__RESTRICT stream, + const void *ES__RESTRICT buffer, size_t length, + int reserved, size_t *ES__RESTRICT bytes_written); + +size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems, + estream_t ES__RESTRICT stream); +size_t es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t memb, + estream_t ES__RESTRICT stream); + +char *es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream); +int es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream); +int es_fputs_unlocked (const char *ES__RESTRICT s, + estream_t ES__RESTRICT stream); + +ssize_t es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr, + size_t *ES__RESTRICT n, + estream_t stream); +ssize_t es_read_line (estream_t stream, + char **addr_of_buffer, size_t *length_of_buffer, + size_t *max_length); +void es_free (void *a); + +int es_fprintf (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(2,3); +int es_fprintf_unlocked (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(2,3); + +int es_vfprintf (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, va_list ap) + _ESTREAM_GCC_A_PRINTF(2,0); +int es_vfprintf_unlocked (estream_t ES__RESTRICT stream, + const char *ES__RESTRICT format, va_list ap) + _ESTREAM_GCC_A_PRINTF(2,0); + +int es_setvbuf (estream_t ES__RESTRICT stream, + char *ES__RESTRICT buf, int mode, size_t size); +void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf); + +estream_t es_tmpfile (void); + +void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque); +void *es_opaque_get (estream_t stream); + +void es_fname_set (estream_t stream, const char *fname); +const char *es_fname_get (estream_t stream); + + +#ifdef GNUPG_MAJOR_VERSION +int es_write_sanitized_utf8_buffer (estream_t stream, + const void *buffer, size_t length, + const char *delimiters, + size_t *bytes_written); +#endif /*GNUPG_MAJOR_VERSION*/ + +#ifdef __cplusplus +} +#endif +#endif /*ESTREAM_H*/ diff --git a/common/exaudit.awk b/common/exaudit.awk new file mode 100644 index 0000000..270e148 --- /dev/null +++ b/common/exaudit.awk @@ -0,0 +1,43 @@ +# exaudit.awk - Extract audit event codes from audit.h +# Copyright (C) 2007 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 3 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, see . + +BEGIN { + print "# Output of exaudit.awk - DO NOT EDIT." + topheader = 0; + okay = 0; + code = 0; +} + +topheader == 0 && /^\/\*/ { topheader = 1 } +topheader == 1 { print $0 } +topheader == 1 && /\*\// { topheader = 2; print "" } + +/AUDIT_NULL_EVENT/ { okay = 1 } +!okay { next } +/AUDIT_LAST_EVENT/ { exit } +/AUDIT_[A-Za-z_]+/ { + sub (/[,\/\*]+/, "", $1); + desc = tolower (substr($1,7)); + gsub (/_/," ",desc); + printf "%d\t%s\t%s\n", code, $1, desc; + code++; +} + +END { + print "# end of audit codes." +} diff --git a/common/exechelp.c b/common/exechelp.c new file mode 100644 index 0000000..cd9ba7b --- /dev/null +++ b/common/exechelp.c @@ -0,0 +1,1033 @@ +/* exechelp.c - fork and exec helpers + * Copyright (C) 2004, 2007, 2008, 2009 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 3 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, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + +#ifdef USE_GNU_PTH +#include +#endif +#ifndef HAVE_W32_SYSTEM +#include +#endif + +#ifdef HAVE_GETRLIMIT +#include +#include +#endif /*HAVE_GETRLIMIT*/ + +#ifdef HAVE_STAT +# include +#endif + + +#include "util.h" +#include "i18n.h" +#include "sysutils.h" +#include "exechelp.h" + +/* Define to 1 do enable debugging. */ +#define DEBUG_W32_SPAWN 1 + + +/* We have the usual problem here: Some modules are linked against pth + and some are not. However we want to use pth_fork and pth_waitpid + here. Using a weak symbol works but is not portable - we should + provide a an explicit dummy pth module instead of using the + pragma. */ +#ifndef _WIN32 +#pragma weak pth_fork +#pragma weak pth_waitpid +#endif + +#ifdef HAVE_W32_SYSTEM +/* It seems Vista doesn't grok X_OK and so fails access() tests. + Previous versions interpreted X_OK as F_OK anyway, so we'll just + use F_OK directly. */ +#undef X_OK +#define X_OK F_OK +#endif /* HAVE_W32_SYSTEM */ + + +#ifdef HAVE_W32_SYSTEM +/* We assume that a HANDLE can be represented by an int which should + be true for all i386 systems (HANDLE is defined as void *) and + these are the only systems for which Windows is available. Further + we assume that -1 denotes an invalid handle. */ +# define fd_to_handle(a) ((HANDLE)(a)) +# define handle_to_fd(a) ((int)(a)) +# define pid_to_handle(a) ((HANDLE)(a)) +# define handle_to_pid(a) ((int)(a)) +#endif + + +/* Return the maximum number of currently allowed open file + descriptors. Only useful on POSIX systems but returns a value on + other systems too. */ +int +get_max_fds (void) +{ + int max_fds = -1; +#ifdef HAVE_GETRLIMIT + struct rlimit rl; + +# ifdef RLIMIT_NOFILE + if (!getrlimit (RLIMIT_NOFILE, &rl)) + max_fds = rl.rlim_max; +# endif + +# ifdef RLIMIT_OFILE + if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl)) + max_fds = rl.rlim_max; + +# endif +#endif /*HAVE_GETRLIMIT*/ + +#ifdef _SC_OPEN_MAX + if (max_fds == -1) + { + long int scres = sysconf (_SC_OPEN_MAX); + if (scres >= 0) + max_fds = scres; + } +#endif + +#ifdef _POSIX_OPEN_MAX + if (max_fds == -1) + max_fds = _POSIX_OPEN_MAX; +#endif + +#ifdef OPEN_MAX + if (max_fds == -1) + max_fds = OPEN_MAX; +#endif + + if (max_fds == -1) + max_fds = 256; /* Arbitrary limit. */ + + return max_fds; +} + + +/* Close all file descriptors starting with descriptor FIRST. If + EXCEPT is not NULL, it is expected to be a list of file descriptors + which shall not be closed. This list shall be sorted in ascending + order with the end marked by -1. */ +void +close_all_fds (int first, int *except) +{ + int max_fd = get_max_fds (); + int fd, i, except_start; + + if (except) + { + except_start = 0; + for (fd=first; fd < max_fd; fd++) + { + for (i=except_start; except[i] != -1; i++) + { + if (except[i] == fd) + { + /* If we found the descriptor in the exception list + we can start the next compare run at the next + index because the exception list is ordered. */ + except_start = i + 1; + break; + } + } + if (except[i] == -1) + close (fd); + } + } + else + { + for (fd=first; fd < max_fd; fd++) + close (fd); + } + + errno = 0; +} + + +/* Returns an array with all currently open file descriptors. The end + of the array is marked by -1. The caller needs to release this + array using the *standard free* and not with xfree. This allow the + use of this fucntion right at startup even before libgcrypt has + been initialized. Returns NULL on error and sets ERRNO + accordingly. */ +int * +get_all_open_fds (void) +{ + int *array; + size_t narray; + int fd, max_fd, idx; +#ifndef HAVE_STAT + array = calloc (1, sizeof *array); + if (array) + array[0] = -1; +#else /*HAVE_STAT*/ + struct stat statbuf; + + max_fd = get_max_fds (); + narray = 32; /* If you change this change also t-exechelp.c. */ + array = calloc (narray, sizeof *array); + if (!array) + return NULL; + + /* Note: The list we return is ordered. */ + for (idx=0, fd=0; fd < max_fd; fd++) + if (!(fstat (fd, &statbuf) == -1 && errno == EBADF)) + { + if (idx+1 >= narray) + { + int *tmp; + + narray += (narray < 256)? 32:256; + tmp = realloc (array, narray * sizeof *array); + if (!tmp) + { + free (array); + return NULL; + } + array = tmp; + } + array[idx++] = fd; + } + array[idx] = -1; +#endif /*HAVE_STAT*/ + return array; +} + + + +#ifdef HAVE_W32_SYSTEM +/* Helper function to build_w32_commandline. */ +static char * +build_w32_commandline_copy (char *buffer, const char *string) +{ + char *p = buffer; + const char *s; + + if (!*string) /* Empty string. */ + p = stpcpy (p, "\"\""); + else if (strpbrk (string, " \t\n\v\f\"")) + { + /* Need top do some kind of quoting. */ + p = stpcpy (p, "\""); + for (s=string; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (p, string); + + return p; +} + +/* Build a command line for use with W32's CreateProcess. On success + CMDLINE gets the address of a newly allocated string. */ +static gpg_error_t +build_w32_commandline (const char *pgmname, const char * const *argv, + char **cmdline) +{ + int i, n; + const char *s; + char *buf, *p; + + *cmdline = NULL; + n = 0; + s = pgmname; + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + for (i=0; (s=argv[i]); i++) + { + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + } + n++; + + buf = p = xtrymalloc (n); + if (!buf) + return gpg_error_from_syserror (); + + p = build_w32_commandline_copy (p, pgmname); + for (i=0; argv[i]; i++) + { + *p++ = ' '; + p = build_w32_commandline_copy (p, argv[i]); + } + + *cmdline= buf; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +/* Create pipe where the write end is inheritable. */ +static int +create_inheritable_pipe (int filedes[2]) +{ + HANDLE r, w, h; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + if (!CreatePipe (&r, &w, &sec_attr, 0)) + return -1; + + if (!DuplicateHandle (GetCurrentProcess(), w, + GetCurrentProcess(), &h, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + { + log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; + } + CloseHandle (w); + w = h; + + filedes[0] = handle_to_fd (r); + filedes[1] = handle_to_fd (w); + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +static HANDLE +w32_open_null (int for_write) +{ + HANDLE hfile; + + hfile = CreateFile ("nul", + for_write? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (hfile == INVALID_HANDLE_VALUE) + log_debug ("can't open `nul': %s\n", w32_strerror (-1)); + return hfile; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifndef HAVE_W32_SYSTEM +/* The exec core used right after the fork. This will never return. */ +static void +do_exec (const char *pgmname, const char *argv[], + int fd_in, int fd_out, int fd_err, + void (*preexec)(void) ) +{ + char **arg_list; + int i, j; + int fds[3]; + + fds[0] = fd_in; + fds[1] = fd_out; + fds[2] = fd_err; + + /* Create the command line argument array. */ + i = 0; + if (argv) + while (argv[i]) + i++; + arg_list = xcalloc (i+2, sizeof *arg_list); + arg_list[0] = strrchr (pgmname, '/'); + if (arg_list[0]) + arg_list[0]++; + else + arg_list[0] = xstrdup (pgmname); + if (argv) + for (i=0,j=1; argv[i]; i++, j++) + arg_list[j] = (char*)argv[i]; + + /* Assign /dev/null to unused FDs. */ + for (i=0; i <= 2; i++) + { + if (fds[i] == -1 ) + { + fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY); + if (fds[i] == -1) + log_fatal ("failed to open `%s': %s\n", + "/dev/null", strerror (errno)); + } + } + + /* Connect the standard files. */ + for (i=0; i <= 2; i++) + { + if (fds[i] != i && dup2 (fds[i], i) == -1) + log_fatal ("dup2 std%s failed: %s\n", + i==0?"in":i==1?"out":"err", strerror (errno)); + } + + /* Close all other files. */ + close_all_fds (3, NULL); + + if (preexec) + preexec (); + execv (pgmname, arg_list); + /* No way to print anything, as we have closed all streams. */ + _exit (127); +} +#endif /*!HAVE_W32_SYSTEM*/ + + +/* Portable function to create a pipe. Under Windows the write end is + inheritable. */ +gpg_error_t +gnupg_create_inbound_pipe (int filedes[2]) +{ + gpg_error_t err = 0; +#if HAVE_W32_SYSTEM + int fds[2]; + + filedes[0] = filedes[1] = -1; + err = gpg_error (GPG_ERR_GENERAL); + if (!create_inheritable_pipe (fds)) + { + filedes[0] = _open_osfhandle (fds[0], 0); + if (filedes[0] == -1) + { + log_error ("failed to translate osfhandle %p\n", (void*)fds[0]); + CloseHandle (fd_to_handle (fds[1])); + } + else + { + filedes[1] = _open_osfhandle (fds[1], 1); + if (filedes[1] == -1) + { + log_error ("failed to translate osfhandle %p\n", (void*)fds[1]); + close (filedes[0]); + filedes[0] = -1; + CloseHandle (fd_to_handle (fds[1])); + } + else + err = 0; + } + } +#else + if (pipe (filedes) == -1) + { + err = gpg_error_from_syserror (); + filedes[0] = filedes[1] = -1; + } +#endif + return err; +} + + +/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to + stdin, write the output to OUTFILE, return a new stream in + STATUSFILE for stderr and the pid of the process in PID. The + arguments for the process are expected in the NULL terminated array + ARGV. The program name itself should not be included there. If + PREEXEC is not NULL, that function will be called right before the + exec. Calling gnupg_wait_process is required. + + FLAGS is a bit vector with just one bit defined for now: + + Bit 7: If set the process will be started as a background process. + This flag is only useful under W32 systems, so that no new + console is created and pops up a console window when + starting the server + + Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to + error problems this actually allows SetForegroundWindow for + childs of this process. + + Returns 0 on success or an error code. */ +gpg_error_t +gnupg_spawn_process (const char *pgmname, const char *argv[], + FILE *infile, FILE *outfile, + void (*preexec)(void), unsigned int flags, + FILE **statusfile, pid_t *pid) +{ +#ifdef HAVE_W32_SYSTEM + gpg_error_t err; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int cr_flags; + char *cmdline; + int fd, fdout, rp[2]; + + (void)preexec; + + /* Setup return values. */ + *statusfile = NULL; + *pid = (pid_t)(-1); + fflush (infile); + rewind (infile); + fd = _get_osfhandle (fileno (infile)); + fdout = _get_osfhandle (fileno (outfile)); + if (fd == -1 || fdout == -1) + log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Build the command line. */ + err = build_w32_commandline (pgmname, argv, &cmdline); + if (err) + return err; + + /* Create a pipe. */ + if (create_inheritable_pipe (rp)) + { + err = gpg_error (GPG_ERR_GENERAL); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + xfree (cmdline); + return err; + } + + /* Start the process. Note that we can't run the PREEXEC function + because this would change our own environment. */ + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + si.hStdInput = fd_to_handle (fd); + si.hStdOutput = fd_to_handle (fdout); + si.hStdError = fd_to_handle (rp[1]); + + cr_flags = (CREATE_DEFAULT_ERROR_MODE + | ((flags & 128)? DETACHED_PROCESS : 0) + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED); +/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ + if (!CreateProcess (pgmname, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + xfree (cmdline); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + return gpg_error (GPG_ERR_GENERAL); + } + xfree (cmdline); + cmdline = NULL; + + /* Close the other end of the pipe. */ + CloseHandle (fd_to_handle (rp[1])); + +/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + /* Fixme: For unknown reasons AllowSetForegroundWindow returns an + invalid argument error if we pass the correct processID to + it. As a workaround we use -1 (ASFW_ANY). */ + if ( (flags & 64) ) + gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/); + + /* Process has been created suspended; resume it now. */ + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + + { + int x; + + x = _open_osfhandle (rp[0], 0); + if (x == -1) + log_error ("failed to translate osfhandle %p\n", (void*)rp[0] ); + else + *statusfile = fdopen (x, "r"); + } + if (!*statusfile) + { + err = gpg_error_from_syserror (); + log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err)); + CloseHandle (pi.hProcess); + return err; + } + + *pid = handle_to_pid (pi.hProcess); + return 0; + +#else /* !HAVE_W32_SYSTEM */ + gpg_error_t err; + int fd, fdout, rp[2]; + + (void)flags; /* Currently not used. */ + + *statusfile = NULL; + *pid = (pid_t)(-1); + fflush (infile); + rewind (infile); + fd = fileno (infile); + fdout = fileno (outfile); + if (fd == -1 || fdout == -1) + log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); + + if (pipe (rp) == -1) + { + err = gpg_error_from_syserror (); + log_error (_("error creating a pipe: %s\n"), strerror (errno)); + return err; + } + +#ifdef USE_GNU_PTH + *pid = pth_fork? pth_fork () : fork (); +#else + *pid = fork (); +#endif + if (*pid == (pid_t)(-1)) + { + err = gpg_error_from_syserror (); + log_error (_("error forking process: %s\n"), strerror (errno)); + close (rp[0]); + close (rp[1]); + return err; + } + + if (!*pid) + { + gcry_control (GCRYCTL_TERM_SECMEM); + /* Run child. */ + do_exec (pgmname, argv, fd, fdout, rp[1], preexec); + /*NOTREACHED*/ + } + + /* Parent. */ + close (rp[1]); + + *statusfile = fdopen (rp[0], "r"); + if (!*statusfile) + { + err = gpg_error_from_syserror (); + log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno)); + kill (*pid, SIGTERM); + *pid = (pid_t)(-1); + return err; + } + + return 0; +#endif /* !HAVE_W32_SYSTEM */ +} + + + +/* Simplified version of gnupg_spawn_process. This function forks and + then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout + and ERRFD to stderr (any of them may be -1 to connect them to + /dev/null). The arguments for the process are expected in the NULL + terminated array ARGV. The program name itself should not be + included there. Calling gnupg_wait_process is required. + + Returns 0 on success or an error code. */ +gpg_error_t +gnupg_spawn_process_fd (const char *pgmname, const char *argv[], + int infd, int outfd, int errfd, pid_t *pid) +{ +#ifdef HAVE_W32_SYSTEM + gpg_error_t err; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; + STARTUPINFO si; + char *cmdline; + int i; + HANDLE stdhd[3]; + + /* Setup return values. */ + *pid = (pid_t)(-1); + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Build the command line. */ + err = build_w32_commandline (pgmname, argv, &cmdline); + if (err) + return err; + + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + stdhd[0] = infd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE; + stdhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; + stdhd[2] = errfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; + si.hStdInput = infd == -1? stdhd[0] : (void*)_get_osfhandle (infd); + si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd); + si.hStdError = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd); + +/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */ + if (!CreateProcess (pgmname, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED | DETACHED_PROCESS), + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + err = gpg_error (GPG_ERR_GENERAL); + } + else + err = 0; + xfree (cmdline); + for (i=0; i < 3; i++) + if (stdhd[i] != INVALID_HANDLE_VALUE) + CloseHandle (stdhd[i]); + if (err) + return err; + +/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + /* Process has been created suspended; resume it now. */ + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + + *pid = handle_to_pid (pi.hProcess); + return 0; + +#else /* !HAVE_W32_SYSTEM */ + gpg_error_t err; + +#ifdef USE_GNU_PTH + *pid = pth_fork? pth_fork () : fork (); +#else + *pid = fork (); +#endif + if (*pid == (pid_t)(-1)) + { + err = gpg_error_from_syserror (); + log_error (_("error forking process: %s\n"), strerror (errno)); + return err; + } + + if (!*pid) + { + gcry_control (GCRYCTL_TERM_SECMEM); + /* Run child. */ + do_exec (pgmname, argv, infd, outfd, errfd, NULL); + /*NOTREACHED*/ + } + + return 0; +#endif /* !HAVE_W32_SYSTEM */ +} + + +/* Wait for the process identified by PID to terminate. PGMNAME should + be the same as supplied to the spawn function and is only used for + diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL + for any failures of the spawned program or other error codes. If + EXITCODE is not NULL the exit code of the process is stored at this + address or -1 if it could not be retrieved. */ +gpg_error_t +gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode) +{ + gpg_err_code_t ec; + +#ifdef HAVE_W32_SYSTEM + HANDLE proc = fd_to_handle (pid); + int code; + DWORD exc; + + if (exitcode) + *exitcode = -1; + + if (pid == (pid_t)(-1)) + return gpg_error (GPG_ERR_INV_VALUE); + + /* FIXME: We should do a pth_waitpid here. However this has not yet + been implemented. A special W32 pth system call would even be + better. */ + code = WaitForSingleObject (proc, INFINITE); + switch (code) + { + case WAIT_FAILED: + log_error (_("waiting for process %d to terminate failed: %s\n"), + (int)pid, w32_strerror (-1)); + ec = GPG_ERR_GENERAL; + break; + + case WAIT_OBJECT_0: + if (!GetExitCodeProcess (proc, &exc)) + { + log_error (_("error getting exit code of process %d: %s\n"), + (int)pid, w32_strerror (-1) ); + ec = GPG_ERR_GENERAL; + } + else if (exc) + { + log_error (_("error running `%s': exit status %d\n"), + pgmname, (int)exc ); + if (exitcode) + *exitcode = (int)exc; + ec = GPG_ERR_GENERAL; + } + else + { + if (exitcode) + *exitcode = 0; + ec = 0; + } + CloseHandle (proc); + break; + + default: + log_error ("WaitForSingleObject returned unexpected " + "code %d for pid %d\n", code, (int)pid ); + ec = GPG_ERR_GENERAL; + break; + } + +#else /* !HAVE_W32_SYSTEM */ + int i, status; + + if (exitcode) + *exitcode = -1; + + if (pid == (pid_t)(-1)) + return gpg_error (GPG_ERR_INV_VALUE); + +#ifdef USE_GNU_PTH + i = pth_waitpid ? pth_waitpid (pid, &status, 0) : waitpid (pid, &status, 0); +#else + while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) + ; +#endif + if (i == (pid_t)(-1)) + { + log_error (_("waiting for process %d to terminate failed: %s\n"), + (int)pid, strerror (errno)); + ec = gpg_err_code_from_errno (errno); + } + else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) + { + log_error (_("error running `%s': probably not installed\n"), pgmname); + ec = GPG_ERR_CONFIGURATION; + } + else if (WIFEXITED (status) && WEXITSTATUS (status)) + { + + if (!exitcode) + log_error (_("error running `%s': exit status %d\n"), pgmname, + WEXITSTATUS (status)); + else + *exitcode = WEXITSTATUS (status); + ec = GPG_ERR_GENERAL; + } + else if (!WIFEXITED (status)) + { + log_error (_("error running `%s': terminated\n"), pgmname); + ec = GPG_ERR_GENERAL; + } + else + { + if (exitcode) + *exitcode = 0; + ec = 0; + } +#endif /* !HAVE_W32_SYSTEM */ + + return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); +} + + +/* Spawn a new process and immediatley detach from it. The name of + the program to exec is PGMNAME and its arguments are in ARGV (the + programname is automatically passed as first argument). + Environment strings in ENVP are set. An error is returned if + pgmname is not executable; to make this work it is necessary to + provide an absolute file name. All standard file descriptors are + connected to /dev/null. */ +gpg_error_t +gnupg_spawn_process_detached (const char *pgmname, const char *argv[], + const char *envp[] ) +{ +#ifdef HAVE_W32_SYSTEM + gpg_error_t err; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int cr_flags; + char *cmdline; + + + /* FIXME: We don't make use of ENVP yet. It is currently only used + to pass the GPG_AGENT_INFO variable to gpg-agent. As the default + on windows is to use a standard socket, this does not really + matter. */ + (void)envp; + + if (access (pgmname, X_OK)) + return gpg_error_from_syserror (); + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Build the command line. */ + err = build_w32_commandline (pgmname, argv, &cmdline); + if (err) + return err; + + /* Start the process. */ + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + + cr_flags = (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_NEW_PROCESS_GROUP + | DETACHED_PROCESS); +/* log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", */ +/* pgmname, cmdline); */ + if (!CreateProcess (pgmname, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + FALSE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); + xfree (cmdline); + return gpg_error (GPG_ERR_GENERAL); + } + xfree (cmdline); + cmdline = NULL; + +/* log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */ +/* " dwProcessID=%d dwThreadId=%d\n", */ +/* pi.hProcess, pi.hThread, */ +/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + CloseHandle (pi.hThread); + + return 0; + +#else + pid_t pid; + int i; + + if (getuid() != geteuid()) + return gpg_error (GPG_ERR_BUG); + + if (access (pgmname, X_OK)) + return gpg_error_from_syserror (); + +#ifdef USE_GNU_PTH + pid = pth_fork? pth_fork () : fork (); +#else + pid = fork (); +#endif + if (pid == (pid_t)(-1)) + { + log_error (_("error forking process: %s\n"), strerror (errno)); + return gpg_error_from_syserror (); + } + if (!pid) + { + pid_t pid2; + + gcry_control (GCRYCTL_TERM_SECMEM); + if (setsid() == -1 || chdir ("/")) + _exit (1); + pid2 = fork (); /* Double fork to let init takes over the new child. */ + if (pid2 == (pid_t)(-1)) + _exit (1); + if (pid2) + _exit (0); /* Let the parent exit immediately. */ + + if (envp) + for (i=0; envp[i]; i++) + putenv (xstrdup (envp[i])); + + do_exec (pgmname, argv, -1, -1, -1, NULL); + + /*NOTREACHED*/ + } + + if (waitpid (pid, NULL, 0) == -1) + log_error ("waitpid failed in gnupg_spawn_process_detached: %s", + strerror (errno)); + + return 0; +#endif /* !HAVE_W32_SYSTEM*/ +} diff --git a/common/exechelp.h b/common/exechelp.h new file mode 100644 index 0000000..0efee29 --- /dev/null +++ b/common/exechelp.h @@ -0,0 +1,97 @@ +/* exechelp.h - Definitions for the fork and exec helpers + * Copyright (C) 2004, 2009 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_EXECHELP_H +#define GNUPG_COMMON_EXECHELP_H + +/* Return the maximum number of currently allowed file descriptors. + Only useful on POSIX systems. */ +int get_max_fds (void); + + +/* Close all file descriptors starting with descriptor FIRST. If + EXCEPT is not NULL, it is expected to be a list of file descriptors + which are not to close. This list shall be sorted in ascending + order with its end marked by -1. */ +void close_all_fds (int first, int *except); + + +/* Returns an array with all currently open file descriptors. The end + of the array is marked by -1. The caller needs to release this + array using the *standard free* and not with xfree. This allow the + use of this fucntion right at startup even before libgcrypt has + been initialized. Returns NULL on error and sets ERRNO accordingly. */ +int *get_all_open_fds (void); + + +/* Portable function to create a pipe. Under Windows the write end is + inheritable. */ +gpg_error_t gnupg_create_inbound_pipe (int filedes[2]); + + +/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to + stdin, write the output to OUTFILE, return a new stream in + STATUSFILE for stderr and the pid of the process in PID. The + arguments for the process are expected in the NULL terminated array + ARGV. The program name itself should not be included there. If + PREEXEC is not NULL, that function will be called right before the + exec. FLAGS is currently only useful for W32, see the source for + details. Calling gnupg_wait_process is required. Returns 0 on + success or an error code. */ +gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], + FILE *infile, FILE *outfile, + void (*preexec)(void), unsigned int flags, + FILE **statusfile, pid_t *pid); + + +/* Simplified version of gnupg_spawn_process. This function forks and + then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout + and ERRFD to stderr (any of them may be -1 to connect them to + /dev/null). The arguments for the process are expected in the NULL + terminated array ARGV. The program name itself should not be + included there. Calling gnupg_wait_process is required. Returns 0 + on success or an error code. */ +gpg_error_t gnupg_spawn_process_fd (const char *pgmname, + const char *argv[], + int infd, int outfd, int errfd, + pid_t *pid); + + +/* Wait for the process identified by PID to terminate. PGMNAME should + be the same as supplied to the spawn fucntion and is only used for + diagnostics. Returns 0 if the process succeded, GPG_ERR_GENERAL + for any failures of the spawned program or other error codes. If + EXITCODE is not NULL the exit code of the process is stored at this + address or -1 if it could not be retrieved. */ +gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode); + + +/* Spawn a new process and immediatley detach from it. The name of + the program to exec is PGMNAME and its arguments are in ARGV (the + programname is automatically passed as first argument). + Environment strings in ENVP are set. An error is returned if + pgmname is not executable; to make this work it is necessary to + provide an absolute file name. */ +gpg_error_t gnupg_spawn_process_detached (const char *pgmname, + const char *argv[], + const char *envp[] ); + + + +#endif /*GNUPG_COMMON_EXECHELP_H*/ diff --git a/common/exstatus.awk b/common/exstatus.awk new file mode 100644 index 0000000..ea48e81 --- /dev/null +++ b/common/exstatus.awk @@ -0,0 +1,40 @@ +# exstatus.awk - Extract status codes from status.h +# Copyright (C) 2007 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 3 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, see . + +BEGIN { + print "# Created by exstatus.awk - DO NOT EDIT." + topheader = 0; + code = 0; +} + +topheader == 0 && /^\/\*/ { topheader = 1 } +topheader == 1 { print $0 } +topheader == 1 && /\*\// { topheader = 2; print "" } + +/^[ \t]+STATUS_[A-Za-z_]+/ { + sub (/[,\/\*]+/, "", $1); + desc = substr($1,8); + printf "%d\t%s\t%s\n", code, $1, desc; + code++; +} + + +END { + print "# end of status codes." +} + diff --git a/common/gc-opt-flags.h b/common/gc-opt-flags.h new file mode 100644 index 0000000..261fe87 --- /dev/null +++ b/common/gc-opt-flags.h @@ -0,0 +1,40 @@ +/* gc-opt-flags.h - gpgconf constants used by the backends. + * Copyright (C) 2004, 2007 Free Software Foundation, Inc. + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef GNUPG_GC_OPT_FLAGS_H +#define GNUPG_GC_OPT_FLAGS_H + +/* Public option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE + EXISTING FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. See + gnupg/tools/gpgconf-comp.c for details. */ + +#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) + + +#endif /*GNUPG_GC_OPT_FLAGS_H*/ diff --git a/common/get-passphrase.c b/common/get-passphrase.c new file mode 100644 index 0000000..0900794 --- /dev/null +++ b/common/get-passphrase.c @@ -0,0 +1,262 @@ +/* get-passphrase.c - Ask for a passphrase via the agent + * Copyright (C) 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "i18n.h" +#include "asshelp.h" +#include "membuf.h" +#include "sysutils.h" +#include "get-passphrase.h" + +/* The context used by this process to ask for the passphrase. */ +static assuan_context_t agent_ctx; +static struct +{ + gpg_err_source_t errsource; + int verbosity; + const char *homedir; + const char *agent_program; + const char *lc_ctype; + const char *lc_messages; + session_env_t session_env; + const char *pinentry_user_data; +} agentargs; + + +/* Set local variable to be used for a possible agent startup. Note + that the strings are just pointers and should not anymore be + modified by the caller. */ +void +gnupg_prepare_get_passphrase (gpg_err_source_t errsource, + int verbosity, + const char *homedir, + const char *agent_program, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env) +{ + agentargs.errsource = errsource; + agentargs.verbosity = verbosity; + agentargs.homedir = homedir; + agentargs.agent_program = agent_program; + agentargs.lc_ctype = opt_lc_ctype; + agentargs.lc_messages = opt_lc_messages; + agentargs.session_env = session_env; +} + + +/* Try to connect to the agent via socket or fork it off and work by + pipes. Handle the server's initial greeting. */ +static gpg_error_t +start_agent (void) +{ + gpg_error_t err; + + /* Fixme: This code is not thread safe, thus we don't build it with + pth. We will need a context for each thread or serialize the + access to the agent. */ + if (agent_ctx) + return 0; + + err = start_new_gpg_agent (&agent_ctx, + agentargs.errsource, + agentargs.homedir, + agentargs.agent_program, + agentargs.lc_ctype, + agentargs.lc_messages, + agentargs.session_env, + agentargs.verbosity, 0, NULL, NULL); + if (!err) + { + /* Tell the agent that we support Pinentry notifications. No + error checking so that it will work with older agents. */ + assuan_transact (agent_ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + } + + return err; +} + + +/* This is the default inquiry callback. It merely handles the + Pinentry notification. */ +static gpg_error_t +default_inq_cb (void *opaque, const char *line) +{ + (void)opaque; + + if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17])) + { + gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10)); + /* We do not return errors to avoid breaking other code. */ + } + else + log_debug ("ignoring gpg-agent inquiry `%s'\n", line); + + return 0; +} + + +static gpg_error_t +membuf_data_cb (void *opaque, const void *buffer, size_t length) +{ + membuf_t *data = opaque; + + if (buffer) + put_membuf (data, buffer, length); + return 0; +} + + +/* Ask for a passphrase via gpg-agent. On success the caller needs to + free the string stored at R_PASSPHRASE. On error NULL will be + stored at R_PASSPHRASE and an appropriate gpg error code is + returned. With REPEAT set to 1, gpg-agent will ask the user to + repeat the just entered passphrase. CACHE_ID is a gpg-agent style + passphrase cache id or NULL. ERR_MSG is a error message to be + presented to the user (e.g. "bad passphrase - try again") or NULL. + PROMPT is the prompt string to label the entry box, it may be NULL + for a default one. DESC_MSG is a longer description to be + displayed above the entry box, if may be NULL for a default one. + If USE_SECMEM is true, the returned passphrase is retruned in + secure memory. The length of all these strings is limited; they + need to fit in their encoded form into a standard Assuan line (i.e + less then about 950 characters). All strings shall be UTF-8. */ +gpg_error_t +gnupg_get_passphrase (const char *cache_id, + const char *err_msg, + const char *prompt, + const char *desc_msg, + int repeat, + int check_quality, + int use_secmem, + char **r_passphrase) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + const char *arg1 = NULL; + char *arg2 = NULL; + char *arg3 = NULL; + char *arg4 = NULL; + membuf_t data; + + *r_passphrase = NULL; + + err = start_agent (); + if (err) + return err; + + /* Check that the gpg-agent understands the repeat option. */ + if (assuan_transact (agent_ctx, + "GETINFO cmd_has_option GET_PASSPHRASE repeat", + NULL, NULL, NULL, NULL, NULL, NULL)) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + arg1 = cache_id && *cache_id? cache_id:NULL; + if (err_msg && *err_msg) + if (!(arg2 = percent_plus_escape (err_msg))) + goto no_mem; + if (prompt && *prompt) + if (!(arg3 = percent_plus_escape (prompt))) + goto no_mem; + if (desc_msg && *desc_msg) + if (!(arg4 = percent_plus_escape (desc_msg))) + goto no_mem; + + snprintf (line, DIM(line)-1, + "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s", + check_quality? "--check ":"", + repeat, + arg1? arg1:"X", + arg2? arg2:"X", + arg3? arg3:"X", + arg4? arg4:"X"); + line[DIM(line)-1] = 0; + xfree (arg2); + xfree (arg3); + xfree (arg4); + + if (use_secmem) + init_membuf_secure (&data, 64); + else + init_membuf (&data, 64); + err = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, NULL, NULL, NULL); + + /* Older Pinentries return the old assuan error code for canceled + which gets translated bt libassuan to GPG_ERR_ASS_CANCELED and + not to the code for a user cancel. Fix this here. */ + if (err && gpg_err_source (err) + && gpg_err_code (err) == GPG_ERR_ASS_CANCELED) + err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED); + + if (err) + { + void *p; + size_t n; + + p = get_membuf (&data, &n); + if (p) + wipememory (p, n); + xfree (p); + } + else + { + put_membuf (&data, "", 1); + *r_passphrase = get_membuf (&data, NULL); + if (!*r_passphrase) + err = gpg_error_from_syserror (); + } + return err; + no_mem: + err = gpg_error_from_syserror (); + xfree (arg2); + xfree (arg3); + xfree (arg4); + return err; +} + + +/* Flush the passphrase cache with Id CACHE_ID. */ +gpg_error_t +gnupg_clear_passphrase (const char *cache_id) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + + if (!cache_id || !*cache_id) + return 0; + + err = start_agent (); + if (err) + return err; + + snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id); + line[DIM(line)-1] = 0; + return assuan_transact (agent_ctx, line, NULL, NULL, + default_inq_cb, NULL, NULL, NULL); +} diff --git a/common/get-passphrase.h b/common/get-passphrase.h new file mode 100644 index 0000000..603ac81 --- /dev/null +++ b/common/get-passphrase.h @@ -0,0 +1,45 @@ +/* get-passphrase.h - Definitions to ask for a passphrase via the agent. + * Copyright (C) 2009 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_GET_PASSPHRASE_H +#define GNUPG_COMMON_GET_PASSPHRASE_H + +#include "session-env.h" + +void gnupg_prepare_get_passphrase (gpg_err_source_t errsource, + int verbosity, + const char *homedir, + const char *agent_program, + const char *opt_lc_ctype, + const char *opt_lc_messages, + session_env_t session_env); + +gpg_error_t gnupg_get_passphrase (const char *cache_id, + const char *err_msg, + const char *prompt, + const char *desc_msg, + int repeat, + int check_quality, + int use_secmem, + char **r_passphrase); + +gpg_error_t gnupg_clear_passphrase (const char *cache_id); + + +#endif /*GNUPG_COMMON_GET_PASSPHRASE_H*/ diff --git a/common/gettime.c b/common/gettime.c new file mode 100644 index 0000000..1b4e435 --- /dev/null +++ b/common/gettime.c @@ -0,0 +1,592 @@ +/* gettime.c - Wrapper for time functions + * Copyright (C) 1998, 2002, 2007 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 3 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, see . + */ + +#include +#include +#include +#include +#ifdef HAVE_LANGINFO_H +#include +#endif + +#include "util.h" +#include "i18n.h" + +static unsigned long timewarp; +static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode; + +/* Correction used to map to real Julian days. */ +#define JD_DIFF 1721060L + + +/* 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 + snprintf (timebuf, 16, "%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 reality. 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; +} + +/* Scan am ISO timestamp and return an Epoch based timestamp. The only + supported format is "yyyymmddThhmmss" delimited by white space, nul, a + colon or a comma. Returns (time_t)(-1) for an invalid string. */ +time_t +isotime2epoch (const char *string) +{ + const char *s; + int year, month, day, hour, minu, sec; + struct tm tmbuf; + int i; + + if (!*string) + return (time_t)(-1); + for (s=string, i=0; i < 8; i++, s++) + if (!digitp (s)) + return (time_t)(-1); + if (*s != 'T') + return (time_t)(-1); + for (s++, i=9; i < 15; i++, s++) + if (!digitp (s)) + return (time_t)(-1); + if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ',')) + return (time_t)(-1); /* Wrong delimiter. */ + + year = atoi_4 (string); + month = atoi_2 (string + 4); + day = atoi_2 (string + 6); + hour = atoi_2 (string + 9); + minu = atoi_2 (string + 11); + sec = atoi_2 (string + 13); + + /* Basic checks. */ + if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 + || hour > 23 || minu > 59 || sec > 61 ) + return (time_t)(-1); + + memset (&tmbuf, 0, sizeof tmbuf); + tmbuf.tm_sec = sec; + tmbuf.tm_min = minu; + tmbuf.tm_hour = hour; + tmbuf.tm_mday = day; + tmbuf.tm_mon = month-1; + tmbuf.tm_year = year - 1900; + tmbuf.tm_isdst = -1; + return timegm (&tmbuf); +} + + +/* Convert an Epoch time to an iso time stamp. */ +void +epoch2isotime (gnupg_isotime_t timebuf, time_t atime) +{ + 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 + snprintf (timebuf, 16, "%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); + } +} + + + + +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 GMT + */ +const char * +isotimestamp (u32 stamp) +{ + static char buffer[25+5]; + struct tm *tp; + time_t atime = stamp; + + if (atime < 0) + { + strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??"); + } + else + { + tp = gmtime ( &atime ); + sprintf (buffer,"%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); + } + 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; +} + + + +static int +days_per_year (int y) +{ + int s ; + + s = !(y % 4); + if ( !(y % 100)) + if ((y%400)) + s = 0; + return s ? 366 : 365; +} + +static int +days_per_month (int y, int m) +{ + int s; + + switch(m) + { + case 1: case 3: case 5: case 7: case 8: case 10: case 12: + return 31 ; + case 2: + s = !(y % 4); + if (!(y % 100)) + if ((y % 400)) + s = 0; + return s? 29 : 28 ; + case 4: case 6: case 9: case 11: + return 30; + } + BUG(); +} + + +/* Convert YEAR, MONTH and DAY into the Julian date. We assume that + it is already noon. We do not support dates before 1582-10-15. */ +static unsigned long +date2jd (int year, int month, int day) +{ + unsigned long jd; + + jd = 365L * year + 31 * (month-1) + day + JD_DIFF; + if (month < 3) + year-- ; + else + jd -= (4 * month + 23) / 10; + + jd += year / 4 - ((year / 100 + 1) *3) / 4; + + return jd ; +} + +/* Convert a Julian date back to YEAR, MONTH and DAY. Return day of + the year or 0 on error. This function uses some more or less + arbitrary limits, most important is that days before 1582 are not + supported. */ +static int +jd2date (unsigned long jd, int *year, int *month, int *day) +{ + int y, m, d; + long delta; + + if (!jd) + return 0 ; + if (jd < 1721425 || jd > 2843085) + return 0; + + y = (jd - JD_DIFF) / 366; + d = m = 1; + + while ((delta = jd - date2jd (y, m, d)) > days_per_year (y)) + y++; + + m = (delta / 31) + 1; + while( (delta = jd - date2jd (y, m, d)) > days_per_month (y,m)) + if (++m > 12) + { + m = 1; + y++; + } + + d = delta + 1 ; + if (d > days_per_month (y, m)) + { + d = 1; + m++; + } + if (m > 12) + { + m = 1; + y++; + } + + if (year) + *year = y; + if (month) + *month = m; + if (day) + *day = d ; + + return (jd - date2jd (y, 1, 1)) + 1; +} + + +/* Check that the 15 bytes in ATIME represent a valid ISO time. Note + that this function does not expect a string but a plain 15 byte + isotime buffer. */ +gpg_error_t +check_isotime (const gnupg_isotime_t atime) +{ + int i; + const char *s; + + if (!*atime) + return gpg_error (GPG_ERR_NO_VALUE); + + for (s=atime, i=0; i < 8; i++, s++) + if (!digitp (s)) + return gpg_error (GPG_ERR_INV_TIME); + if (*s != 'T') + return gpg_error (GPG_ERR_INV_TIME); + for (s++, i=9; i < 15; i++, s++) + if (!digitp (s)) + return gpg_error (GPG_ERR_INV_TIME); + return 0; +} + + +void +dump_isotime (const gnupg_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); +} + + +/* Add SECONDS to ATIME. SECONDS may not be negative and is limited + to about the equivalent of 62 years which should be more then + enough for our purposes. */ +gpg_error_t +add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds) +{ + gpg_error_t err; + int year, month, day, hour, minute, sec, ndays; + unsigned long jd; + + err = check_isotime (atime); + if (err) + return err; + + if (nseconds < 0 || nseconds >= (0x7fffffff - 61) ) + return gpg_error (GPG_ERR_INV_VALUE); + + year = atoi_4 (atime+0); + month = atoi_2 (atime+4); + day = atoi_2 (atime+6); + hour = atoi_2 (atime+9); + minute= atoi_2 (atime+11); + sec = atoi_2 (atime+13); + + if (year <= 1582) /* The julian date functions don't support this. */ + return gpg_error (GPG_ERR_INV_VALUE); + + sec += nseconds; + minute += sec/60; + sec %= 60; + hour += minute/60; + minute %= 60; + ndays = hour/24; + hour %= 24; + + jd = date2jd (year, month, day) + ndays; + jd2date (jd, &year, &month, &day); + + if (year > 9999 || month > 12 || day > 31 + || year < 0 || month < 1 || day < 1) + return gpg_error (GPG_ERR_INV_VALUE); + + snprintf (atime, 16, "%04d%02d%02dT%02d%02d%02d", + year, month, day, hour, minute, sec); + return 0; +} + + +gpg_error_t +add_days_to_isotime (gnupg_isotime_t atime, int ndays) +{ + gpg_error_t err; + int year, month, day, hour, minute, sec; + unsigned long jd; + + err = check_isotime (atime); + if (err) + return err; + + if (ndays < 0 || ndays >= 9999*366 ) + return gpg_error (GPG_ERR_INV_VALUE); + + year = atoi_4 (atime+0); + month = atoi_2 (atime+4); + day = atoi_2 (atime+6); + hour = atoi_2 (atime+9); + minute= atoi_2 (atime+11); + sec = atoi_2 (atime+13); + + if (year <= 1582) /* The julian date functions don't support this. */ + return gpg_error (GPG_ERR_INV_VALUE); + + jd = date2jd (year, month, day) + ndays; + jd2date (jd, &year, &month, &day); + + if (year > 9999 || month > 12 || day > 31 + || year < 0 || month < 1 || day < 1) + return gpg_error (GPG_ERR_INV_VALUE); + + snprintf (atime, 16, "%04d%02d%02dT%02d%02d%02d", + year, month, day, hour, minute, sec); + return 0; +} diff --git a/common/gpgrlhelp.c b/common/gpgrlhelp.c new file mode 100644 index 0000000..28459aa --- /dev/null +++ b/common/gpgrlhelp.c @@ -0,0 +1,91 @@ +/* gpgrlhelp.c - A readline wrapper. + * Copyright (C) 2006 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 3 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, see . + */ + +/* This module may by used by applications to initializes readline + support. It is required so that we can have hooks in other parts + of libcommon without actually requiring to link against + libreadline. It works along with ttyio.c which is a proper part of + libcommon. */ + +#include +#include +#include + +#ifdef HAVE_LIBREADLINE +#define GNUPG_LIBREADLINE_H_INCLUDED +#include +#include +#include +#endif + +#include "util.h" +#include "common-defs.h" + + +#ifdef HAVE_LIBREADLINE +static void +set_completer (rl_completion_func_t *completer) +{ + rl_attempted_completion_function = completer; + rl_inhibit_completion = 0; +} + +static void +inhibit_completion (int value) +{ + rl_inhibit_completion = value; +} + +static void +cleanup_after_signal (void) +{ + rl_free_line_state (); + rl_cleanup_after_signal (); +} + +static void +init_stream (FILE *fp) +{ + rl_catch_signals = 0; + rl_instream = rl_outstream = fp; + rl_inhibit_completion = 1; +} + +#endif /*HAVE_LIBREADLINE*/ + + +/* Initialize our readline code. This should be called as early as + possible as it is actually a constructur. */ +void +gnupg_rl_initialize (void) +{ +#ifdef HAVE_LIBREADLINE + tty_private_set_rl_hooks (init_stream, + set_completer, + inhibit_completion, + cleanup_after_signal, + readline, + add_history); + rl_readline_name = "GnuPG"; +#endif +} + + + + diff --git a/common/helpfile.c b/common/helpfile.c new file mode 100644 index 0000000..34b6bdc --- /dev/null +++ b/common/helpfile.c @@ -0,0 +1,262 @@ +/* helpfile.c - GnuPG's helpfile feature + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include + + +#include "util.h" +#include "i18n.h" +#include "membuf.h" + + +/* Try to find KEY in the file FNAME. */ +static char * +findkey_fname (const char *key, const char *fname) +{ + gpg_error_t err = 0; + FILE *fp; + int lnr = 0; + int c; + char *p, line[256]; + int in_item = 0; + membuf_t mb = MEMBUF_ZERO; + + fp = fopen (fname, "r"); + if (!fp) + { + if (errno != ENOENT) + { + err = gpg_error_from_syserror (); + log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err)); + } + return NULL; + } + + while (fgets (line, DIM(line)-1, fp)) + { + lnr++; + + if (!*line || line[strlen(line)-1] != '\n') + { + /* Eat until end of line. */ + while ( (c=getc (fp)) != EOF && c != '\n') + ; + err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG + : GPG_ERR_INCOMPLETE_LINE); + log_error (_("file `%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + } + else + line[strlen(line)-1] = 0; /* Chop the LF. */ + + again: + if (!in_item) + { + /* Allow for empty lines and spaces while not in an item. */ + for (p=line; spacep (p); p++) + ; + if (!*p || *p == '#') + continue; + if (*line != '.' || spacep(line+1)) + { + log_info (_("file `%s', line %d: %s\n"), + fname, lnr, _("ignoring garbage line")); + continue; + } + trim_trailing_spaces (line); + in_item = 1; + if (!strcmp (line+1, key)) + { + /* Found. Start collecting. */ + init_membuf (&mb, 1024); + } + continue; + } + + /* If in an item only allow for comments in the first column + and provide ". " as an escape sequence to allow for + leading dots and hash marks in the actual text. */ + if (*line == '#') + continue; + if (*line == '.') + { + if (spacep(line+1)) + p = line + 2; + else + { + trim_trailing_spaces (line); + in_item = 0; + if (is_membuf_ready (&mb)) + break; /* Yep, found and collected the item. */ + if (!line[1]) + continue; /* Just an end of text dot. */ + goto again; /* A new key line. */ + } + } + else + p = line; + + if (is_membuf_ready (&mb)) + { + put_membuf_str (&mb, p); + put_membuf (&mb, "\n", 1); + } + + } + if ( !err && ferror (fp) ) + { + err = gpg_error_from_syserror (); + log_error (_("error reading `%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + } + + fclose (fp); + if (is_membuf_ready (&mb)) + { + /* We have collected something. */ + if (err) + { + xfree (get_membuf (&mb, NULL)); + return NULL; + } + else + { + put_membuf (&mb, "", 1); /* Terminate string. */ + return get_membuf (&mb, NULL); + } + } + else + return NULL; +} + + +/* Try the help files depending on the locale. */ +static char * +findkey_locale (const char *key, const char *locname, + int only_current_locale, const char *dirname) +{ + const char *s; + char *fname, *ext, *p; + char *result; + + fname = xtrymalloc (strlen (dirname) + 6 + strlen (locname) + 4 + 1); + if (!fname) + return NULL; + ext = stpcpy (stpcpy (fname, dirname), "/help."); + /* Search with locale name and territory. ("help.LL_TT.txt") */ + if (strchr (locname, '_')) + { + strcpy (stpcpy (ext, locname), ".txt"); + result = findkey_fname (key, fname); + } + else + result = NULL; /* No territory. */ + + if (!result) + { + /* Search with just the locale name - if any. ("help.LL.txt") */ + if (*locname) + { + for (p=ext, s=locname; *s && *s != '_';) + *p++ = *s++; + strcpy (p, ".txt"); + result = findkey_fname (key, fname); + } + else + result = NULL; + } + + if (!result && (!only_current_locale || !*locname) ) + { + /* Last try: Search in file without any locale info. ("help.txt") */ + strcpy (ext, "txt"); + result = findkey_fname (key, fname); + } + + xfree (fname); + return result; +} + + +/* Return a malloced help text as identified by KEY. The system takes + the string from an UTF-8 encoded file to be created by an + administrator or as distributed with GnuPG. On a GNU or Unix + system the entry is searched in these files: + + /etc/gnupg/help.LL.txt + /etc/gnupg/help.txt + /usr/share/gnupg/help.LL.txt + /usr/share/gnupg/help.txt + + Here LL denotes the two digit language code of the current locale. + If ONLY_CURRENT_LOCALE is set, the fucntion won;t fallback to the + english valiant ("help.txt") unless that locale has been requested. + + The help file needs to be encoded in UTF-8, lines with a '#' in the + first column are comment lines and entirely ignored. Help keys are + identified by a key consisting of a single word with a single dot + as the first character. All key lines listed without any + intervening lines (except for comment lines) lead to the same help + text. Lines following the key lines make up the actual hep texts. + +*/ + +char * +gnupg_get_help_string (const char *key, int only_current_locale) +{ + static const char *locname; + char *result; + + if (!locname) + { + char *buffer, *p; + int count = 0; + const char *s = gnupg_messages_locale_name (); + buffer = xtrystrdup (s); + if (!buffer) + locname = ""; + else + { + for (p = buffer; *p; p++) + if (*p == '.' || *p == '@' || *p == '/' /*(safeguard)*/) + *p = 0; + else if (*p == '_') + { + if (count++) + *p = 0; /* Also cut at a underscore in the territory. */ + } + locname = buffer; + } + } + + if (!key || !*key) + return NULL; + + result = findkey_locale (key, locname, only_current_locale, + gnupg_sysconfdir ()); + if (!result) + result = findkey_locale (key, locname, only_current_locale, + gnupg_datadir ()); + + if (result) + trim_trailing_spaces (result); + + return result; +} diff --git a/common/homedir.c b/common/homedir.c new file mode 100644 index 0000000..5f2e31e --- /dev/null +++ b/common/homedir.c @@ -0,0 +1,449 @@ +/* homedir.c - Setup the home directory. + * Copyright (C) 2004, 2006, 2007 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 3 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, see . + */ + +#include +#include +#include +#include + +#ifdef HAVE_W32_SYSTEM +#include +#ifndef CSIDL_APPDATA +#define CSIDL_APPDATA 0x001a +#endif +#ifndef CSIDL_LOCAL_APPDATA +#define CSIDL_LOCAL_APPDATA 0x001c +#endif +#ifndef CSIDL_COMMON_APPDATA +#define CSIDL_COMMON_APPDATA 0x0023 +#endif +#ifndef CSIDL_FLAG_CREATE +#define CSIDL_FLAG_CREATE 0x8000 +#endif +#endif /*HAVE_W32_SYSTEM*/ + + + +#include "util.h" +#include "sysutils.h" + + +/* This is a helper function to load a Windows function from either of + one DLLs. */ +#ifdef HAVE_W32_SYSTEM +static HRESULT +w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e) +{ + static int initialized; + static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR); + + if (!initialized) + { + static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL }; + void *handle; + int i; + + initialized = 1; + + for (i=0, handle = NULL; !handle && dllnames[i]; i++) + { + handle = dlopen (dllnames[i], RTLD_LAZY); + if (handle) + { + func = dlsym (handle, "SHGetFolderPathA"); + if (!func) + { + dlclose (handle); + handle = NULL; + } + } + } + } + + if (func) + return func (a,b,c,d,e); + else + return -1; +} +#endif /*HAVE_W32_SYSTEM*/ + + +/* Get the standard home directory. In general this function should + not be used as it does not consider a registry value (under W32) or + the GNUPGHOME environment variable. It is better to use + default_homedir(). */ +const char * +standard_homedir (void) +{ +#ifdef HAVE_W32_SYSTEM + static const char *dir; + + if (!dir) + { + char path[MAX_PATH]; + + /* It might be better to use LOCAL_APPDATA because this is + defined as "non roaming" and thus more likely to be kept + locally. For private keys this is desired. However, given + that many users copy private keys anyway forth and back, + using a system roaming services might be better than to let + them do it manually. A security conscious user will anyway + use the registry entry to have better control. */ + if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, + NULL, 0, path) >= 0) + { + char *tmp = xmalloc (strlen (path) + 6 +1); + strcpy (stpcpy (tmp, path), "\\gnupg"); + dir = tmp; + + /* Try to create the directory if it does not yet exists. */ + if (access (dir, F_OK)) + CreateDirectory (dir, NULL); + } + else + dir = GNUPG_DEFAULT_HOMEDIR; + } + return dir; +#else/*!HAVE_W32_SYSTEM*/ + return GNUPG_DEFAULT_HOMEDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +/* Set up the default home directory. The usual --homedir option + should be parsed later. */ +const char * +default_homedir (void) +{ + const char *dir; + + dir = getenv ("GNUPGHOME"); +#ifdef HAVE_W32_SYSTEM + if (!dir || !*dir) + { + static const char *saved_dir; + + if (!saved_dir) + { + if (!dir || !*dir) + { + char *tmp; + + tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", + "HomeDir"); + if (tmp && !*tmp) + { + xfree (tmp); + tmp = NULL; + } + if (tmp) + saved_dir = tmp; + } + + if (!saved_dir) + saved_dir = standard_homedir (); + } + dir = saved_dir; + } +#endif /*HAVE_W32_SYSTEM*/ + if (!dir || !*dir) + dir = GNUPG_DEFAULT_HOMEDIR; + + return dir; +} + + +#ifdef HAVE_W32_SYSTEM +static const char * +w32_rootdir (void) +{ + static int got_dir; + static char dir[MAX_PATH+5]; + + if (!got_dir) + { + char *p; + + if ( !GetModuleFileName ( NULL, dir, MAX_PATH) ) + { + log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0)); + *dir = 0; + } + got_dir = 1; + p = strrchr (dir, DIRSEP_C); + if (p) + *p = 0; + else + { + log_debug ("bad filename `%s' returned for this process\n", dir); + *dir = 0; + } + } + + if (*dir) + return dir; + /* Fallback to the hardwired value. */ + return GNUPG_LIBEXECDIR; +} + +static const char * +w32_commondir (void) +{ + static char *dir; + + if (!dir) + { + char path[MAX_PATH]; + + if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, + NULL, 0, path) >= 0) + { + char *tmp = xmalloc (strlen (path) + 4 +1); + strcpy (stpcpy (tmp, path), "\\GNU"); + dir = tmp; + /* No auto create of the directory. Either the installer or + the admin has to create these directories. */ + } + else + { + /* Ooops: Not defined - probably an old Windows version. + Use the installation directory instead. */ + dir = xstrdup (w32_rootdir ()); + } + } + + return dir; +} +#endif /*HAVE_W32_SYSTEM*/ + + + + +/* Return the name of the sysconfdir. This is a static string. This + function is required because under Windows we can't simply compile + it in. */ +const char * +gnupg_sysconfdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_commondir (); + s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_SYSCONFDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_bindir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_BINDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the name of the libexec directory. The name is allocated in + a static area on the first use. This function won't fail. */ +const char * +gnupg_libexecdir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_LIBEXECDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +const char * +gnupg_libdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "lib" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_LIBDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +const char * +gnupg_datadir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "share" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_DATADIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_localedir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "share" DIRSEP_S "locale"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return LOCALEDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the default socket name used by DirMngr. */ +const char * +dirmngr_socket_name (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + char s1[MAX_PATH]; + const char *s2; + + /* We need something akin CSIDL_COMMON_PROGRAMS, but local + (non-roaming). */ + if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0) + strcpy (s1, "C:\\WINDOWS"); + s2 = DIRSEP_S "S.dirmngr"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return "/var/run/dirmngr/socket"; +#endif /*!HAVE_W32_SYSTEM*/ +} + + + +/* Return the file name of a helper tool. WHICH is one of the + GNUPG_MODULE_NAME_foo constants. */ +const char * +gnupg_module_name (int which) +{ + const char *s, *s2; + +#define X(a,b) do { \ + static char *name; \ + if (!name) \ + { \ + s = gnupg_ ## a (); \ + s2 = DIRSEP_S b EXEEXT_S; \ + name = xmalloc (strlen (s) + strlen (s2) + 1); \ + strcpy (stpcpy (name, s), s2); \ + } \ + return name; \ + } while (0) + + switch (which) + { + case GNUPG_MODULE_NAME_AGENT: +#ifdef GNUPG_DEFAULT_AGENT + return GNUPG_DEFAULT_AGENT; +#else + X(bindir, "gpg-agent"); +#endif + + case GNUPG_MODULE_NAME_PINENTRY: +#ifdef GNUPG_DEFAULT_PINENTRY + return GNUPG_DEFAULT_PINENTRY; +#else + X(bindir, "pinentry"); +#endif + + case GNUPG_MODULE_NAME_SCDAEMON: +#ifdef GNUPG_DEFAULT_SCDAEMON + return GNUPG_DEFAULT_SCDAEMON; +#else + X(bindir, "scdaemon"); +#endif + + case GNUPG_MODULE_NAME_DIRMNGR: +#ifdef GNUPG_DEFAULT_DIRMNGR + return GNUPG_DEFAULT_DIRMNGR; +#else + X(bindir, "dirmngr"); +#endif + + case GNUPG_MODULE_NAME_PROTECT_TOOL: +#ifdef GNUPG_DEFAULT_PROTECT_TOOL + return GNUPG_DEFAULT_PROTECT_TOOL; +#else + X(libexecdir, "gpg-protect-tool"); +#endif + + case GNUPG_MODULE_NAME_CHECK_PATTERN: + X(libexecdir, "gpg-check-pattern"); + + case GNUPG_MODULE_NAME_GPGSM: + X(bindir, "gpgsm"); + + case GNUPG_MODULE_NAME_GPG: + X(bindir, "gpg2"); + + case GNUPG_MODULE_NAME_CONNECT_AGENT: + X(bindir, "gpg-connect-agent"); + + case GNUPG_MODULE_NAME_GPGCONF: + X(bindir, "gpgconf"); + + default: + BUG (); + } +#undef X +} diff --git a/common/http.c b/common/http.c new file mode 100644 index 0000000..c12bd2b --- /dev/null +++ b/common/http.c @@ -0,0 +1,2068 @@ +/* http.c - HTTP protocol handler + * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, + * 2009 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 3 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, see . + */ + +/* Simple HTTP client implementation. We try to keep the code as + self-contained as possible. There are some contraints however: + + - stpcpy is required + - fixme: list other requirements. + + + - With HTTP_USE_ESTREAM defined, all I/O is done through estream. + - With HTTP_USE_GNUTLS support for https is provided (this also + requires estream). + - With HTTP_NO_WSASTARTUP the socket initialization is not done + under Windows. This is useful if the socket layer has already + been initialized elsewhere. This also avoids the installation of + an exit handler to cleanup the socket layer. +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_W32_SYSTEM +# include +#else /*!HAVE_W32_SYSTEM*/ +# include +# include +# include +# include +# include +# include +# include +#endif /*!HAVE_W32_SYSTEM*/ + +#ifdef HTTP_USE_GNUTLS +# include +/* For non-understandable reasons GNUTLS dropped the _t suffix from + all types. yes, ISO-C might be read as this but there are still + other name space conflicts and using _t is actually a Good + Thing. */ +typedef gnutls_session gnutls_session_t; +typedef gnutls_transport_ptr gnutls_transport_ptr_t; +#endif /*HTTP_USE_GNUTLS*/ + +#ifdef TEST +#undef USE_DNS_SRV +#endif + +#include "util.h" +#include "i18n.h" +#include "http.h" +#ifdef USE_DNS_SRV +#include "srv.h" +#else /*!USE_DNS_SRV*/ +/* If we are not compiling with SRV record support we provide stub + data structures. */ +#ifndef MAXDNAME +#define MAXDNAME 1025 +#endif +struct srventry +{ + unsigned short priority; + unsigned short weight; + unsigned short port; + int run_count; + char target[MAXDNAME]; +}; +#endif/*!USE_DNS_SRV*/ + + +#ifdef HAVE_W32_SYSTEM +#define sock_close(a) closesocket(a) +#else +#define sock_close(a) close(a) +#endif + +#ifndef EAGAIN +#define EAGAIN EWOULDBLOCK +#endif + +#define HTTP_PROXY_ENV "http_proxy" +#define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */ +#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "01234567890@" \ + "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~" + +/* Define a prefix to map stream functions to the estream library. */ +#ifdef HTTP_USE_ESTREAM +#define P_ES(a) es_ ## a +#else +#define P_ES(a) a +#endif +#ifndef HTTP_USE_GNUTLS +typedef void * gnutls_session_t; +#endif +#if defined(HTTP_USE_GNUTLS) && !defined(HTTP_USE_ESTREAM) +#error Use of GNUTLS also requires support for Estream +#endif + +static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part); +static int remove_escapes (char *string); +static int insert_escapes (char *buffer, const char *string, + const char *special); +static uri_tuple_t parse_tuple (char *string); +static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy, + const char *srvtag,strlist_t headers); +static char *build_rel_path (parsed_uri_t uri); +static gpg_error_t parse_response (http_t hd); + +static int connect_server (const char *server, unsigned short port, + unsigned int flags, const char *srvtag); +static gpg_error_t write_server (int sock, const char *data, size_t length); + +#ifdef HTTP_USE_ESTREAM +static ssize_t cookie_read (void *cookie, void *buffer, size_t size); +static ssize_t cookie_write (void *cookie, const void *buffer, size_t size); +static int cookie_close (void *cookie); + +static es_cookie_io_functions_t cookie_functions = + { + cookie_read, + cookie_write, + NULL, + cookie_close + }; + +struct cookie_s +{ + int fd; /* File descriptor or -1 if already closed. */ + gnutls_session_t tls_session; /* TLS session context or NULL if not used. */ + int keep_socket; /* Flag to communicate with teh close handler. */ +}; +typedef struct cookie_s *cookie_t; + +#endif /*HTTP_USE_ESTREAM*/ + +#ifdef HTTP_USE_GNUTLS +static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int); +#endif /*HTTP_USE_GNUTLS*/ + + +/* An object to save header lines. */ +struct header_s +{ + struct header_s *next; + char *value; /* The value of the header (malloced). */ + char name[1]; /* The name of the header (canonicalized). */ +}; +typedef struct header_s *header_t; + + +/* Our handle context. */ +struct http_context_s +{ + unsigned int status_code; + int sock; + int in_data; +#ifdef HTTP_USE_ESTREAM + estream_t fp_read; + estream_t fp_write; + void *write_cookie; +#else /*!HTTP_USE_ESTREAM*/ + FILE *fp_read; + FILE *fp_write; +#endif /*!HTTP_USE_ESTREAM*/ + void *tls_context; + int is_http_0_9; + parsed_uri_t uri; + http_req_t req_type; + char *buffer; /* Line buffer. */ + size_t buffer_size; + unsigned int flags; + header_t headers; /* Received headers. */ +}; + + + + +#if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP) + +#if GNUPG_MAJOR_VERSION == 1 +#define REQ_WINSOCK_MAJOR 1 +#define REQ_WINSOCK_MINOR 1 +#else +#define REQ_WINSOCK_MAJOR 2 +#define REQ_WINSOCK_MINOR 2 +#endif + + +static void +deinit_sockets (void) +{ + WSACleanup(); +} + +static void +init_sockets (void) +{ + static int initialized; + static WSADATA wsdata; + + if (initialized) + return; + + if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) ) + { + log_error ("error initializing socket library: ec=%d\n", + (int)WSAGetLastError () ); + return; + } + if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR + || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR ) + { + log_error ("socket library version is %x.%x - but %d.%d needed\n", + LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion), + REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR); + WSACleanup(); + return; + } + atexit ( deinit_sockets ); + initialized = 1; +} +#endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/ + + + +/* + * Helper function to create an HTTP header with hex encoded data. A + * new buffer is returned. This buffer is the concatenation of the + * string PREFIX, the hex-encoded DATA of length LEN and the string + * SUFFIX. On error NULL is returned and ERRNO set. + */ +static char * +make_header_line (const char *prefix, const char *suffix, + const void *data, size_t len ) +{ + static unsigned char bintoasc[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + const unsigned int *s = data; + char *buffer, *p; + + buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1); + if (!buffer) + return NULL; + p = stpcpy (buffer, prefix); + for ( ; len >= 3 ; len -= 3, s += 3 ) + { + *p++ = bintoasc[(s[0] >> 2) & 077]; + *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077]; + *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077]; + *p++ = bintoasc[s[2]&077]; + } + if ( len == 2 ) + { + *p++ = bintoasc[(s[0] >> 2) & 077]; + *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077]; + *p++ = bintoasc[((s[1]<<2)&074)]; + *p++ = '='; + } + else if ( len == 1 ) + { + *p++ = bintoasc[(s[0] >> 2) & 077]; + *p++ = bintoasc[(s[0] <<4)&060]; + *p++ = '='; + *p++ = '='; + } + strcpy (p, suffix); + return buffer; +} + + + + +void +http_register_tls_callback ( gpg_error_t (*cb) (http_t, void *, int) ) +{ +#ifdef HTTP_USE_GNUTLS + tls_callback = (gpg_error_t (*) (http_t, gnutls_session_t, int))cb; +#else + (void)cb; +#endif +} + + + +/* Start a HTTP retrieval and return on success in R_HD a context + pointer for completing the the request and to wait for the + response. */ +gpg_error_t +http_open (http_t *r_hd, http_req_t reqtype, const char *url, + const char *auth, unsigned int flags, const char *proxy, + void *tls_context, const char *srvtag,strlist_t headers) +{ + gpg_error_t err; + http_t hd; + + *r_hd = NULL; + + if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST)) + return gpg_error (GPG_ERR_INV_ARG); + + /* Create the handle. */ + hd = xtrycalloc (1, sizeof *hd); + if (!hd) + return gpg_error_from_syserror (); + hd->sock = -1; + hd->req_type = reqtype; + hd->flags = flags; + hd->tls_context = tls_context; + + err = http_parse_uri (&hd->uri, url); + if (!err) + err = send_request (hd, auth, proxy, srvtag, headers); + + if (err) + { + if (!hd->fp_read && !hd->fp_write && hd->sock != -1) + sock_close (hd->sock); + if (hd->fp_read) + P_ES(fclose) (hd->fp_read); + if (hd->fp_write) + P_ES(fclose) (hd->fp_write); + http_release_parsed_uri (hd->uri); + xfree (hd); + } + else + *r_hd = hd; + return err; +} + + +void +http_start_data (http_t hd) +{ + if (!hd->in_data) + { +#ifdef HTTP_USE_ESTREAM + es_fputs ("\r\n", hd->fp_write); + es_fflush (hd->fp_write); +#else + fflush (hd->fp_write); + write_server (hd->sock, "\r\n", 2); +#endif + hd->in_data = 1; + } + else + P_ES(fflush) (hd->fp_write); +} + + +gpg_error_t +http_wait_response (http_t hd) +{ + gpg_error_t err; + + /* Make sure that we are in the data. */ + http_start_data (hd); + + /* We dup the socket, to cope with the fact that fclose closes the + underlying socket. In TLS mode we don't do that because we can't + close the socket gnutls is working on; instead we make sure that + the fclose won't close the socket in this case. */ +#ifdef HTTP_USE_ESTREAM + if (hd->write_cookie) + { + /* The write cookie is only set in the TLS case. */ + cookie_t cookie = hd->write_cookie; + cookie->keep_socket = 1; + } + else +#endif /*HTTP_USE_ESTREAM*/ + { +#ifdef HAVE_W32_SYSTEM + HANDLE handle = (HANDLE)hd->sock; + if (!DuplicateHandle (GetCurrentProcess(), handle, + GetCurrentProcess(), &handle, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + return gpg_error_from_syserror (); + hd->sock = (int)handle; +#else + hd->sock = dup (hd->sock); +#endif + if (hd->sock == -1) + return gpg_error_from_syserror (); + } + P_ES(fclose) (hd->fp_write); + hd->fp_write = NULL; +#ifdef HTTP_USE_ESTREAM + hd->write_cookie = NULL; +#endif + + if (!(hd->flags & HTTP_FLAG_NO_SHUTDOWN)) + shutdown (hd->sock, 1); + hd->in_data = 0; + +#ifdef HTTP_USE_ESTREAM + { + cookie_t cookie; + + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + return gpg_error_from_syserror (); + cookie->fd = hd->sock; + if (hd->uri->use_tls) + cookie->tls_session = hd->tls_context; + + hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); + if (!hd->fp_read) + { + xfree (cookie); + return gpg_error_from_syserror (); + } + } +#else /*!HTTP_USE_ESTREAM*/ + hd->fp_read = fdopen (hd->sock, "r"); + if (!hd->fp_read) + return gpg_error_from_syserror (); +#endif /*!HTTP_USE_ESTREAM*/ + + err = parse_response (hd); + return err; +} + + +/* Convenience function to send a request and wait for the response. + Closes the handle on error. If PROXY is not NULL, this value will + be used as an HTTP proxy and any enabled $http_proxy gets + ignored. */ +gpg_error_t +http_open_document (http_t *r_hd, const char *document, + const char *auth, unsigned int flags, const char *proxy, + void *tls_context, const char *srvtag,strlist_t headers) +{ + gpg_error_t err; + + err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags, + proxy, tls_context, srvtag, headers); + if (err) + return err; + + err = http_wait_response (*r_hd); + if (err) + http_close (*r_hd, 0); + + return err; +} + + +void +http_close (http_t hd, int keep_read_stream) +{ + if (!hd) + return; + if (!hd->fp_read && !hd->fp_write && hd->sock != -1) + sock_close (hd->sock); + if (hd->fp_read && !keep_read_stream) + P_ES(fclose) (hd->fp_read); + if (hd->fp_write) + P_ES(fclose) (hd->fp_write); + http_release_parsed_uri (hd->uri); + while (hd->headers) + { + header_t tmp = hd->headers->next; + xfree (hd->headers->value); + xfree (hd->headers); + hd->headers = tmp; + } + xfree (hd->buffer); + xfree (hd); +} + + +#ifdef HTTP_USE_ESTREAM +estream_t +http_get_read_ptr (http_t hd) +{ + return hd?hd->fp_read:NULL; +} +estream_t +http_get_write_ptr (http_t hd) +{ + return hd?hd->fp_write:NULL; +} +#else /*!HTTP_USE_ESTREAM*/ +FILE * +http_get_read_ptr (http_t hd) +{ + return hd?hd->fp_read:NULL; +} +FILE * +http_get_write_ptr (http_t hd) +{ + return hd?hd->fp_write:NULL; +} +#endif /*!HTTP_USE_ESTREAM*/ +unsigned int +http_get_status_code (http_t hd) +{ + return hd?hd->status_code:0; +} + + + +/* + * Parse an URI and put the result into the newly allocated RET_URI. + * The caller must always use release_parsed_uri() to releases the + * resources (even on error). + */ +gpg_error_t +http_parse_uri (parsed_uri_t * ret_uri, const char *uri) +{ + *ret_uri = xcalloc (1, sizeof **ret_uri + strlen (uri)); + strcpy ((*ret_uri)->buffer, uri); + return do_parse_uri (*ret_uri, 0); +} + +void +http_release_parsed_uri (parsed_uri_t uri) +{ + if (uri) + { + uri_tuple_t r, r2; + + for (r = uri->query; r; r = r2) + { + r2 = r->next; + xfree (r); + } + xfree (uri); + } +} + + +static gpg_error_t +do_parse_uri (parsed_uri_t uri, int only_local_part) +{ + uri_tuple_t *tail; + char *p, *p2, *p3, *pp; + int n; + + p = uri->buffer; + n = strlen (uri->buffer); + + /* Initialize all fields to an empty string or an empty list. */ + uri->scheme = uri->host = uri->path = p + n; + uri->port = 0; + uri->params = uri->query = NULL; + uri->use_tls = 0; + + /* A quick validity check. */ + if (strspn (p, VALID_URI_CHARS) != n) + return gpg_error (GPG_ERR_BAD_URI); /* Invalid characters found. */ + + if (!only_local_part) + { + /* Find the scheme. */ + if (!(p2 = strchr (p, ':')) || p2 == p) + return gpg_error (GPG_ERR_BAD_URI); /* No scheme. */ + *p2++ = 0; + for (pp=p; *pp; pp++) + *pp = tolower (*(unsigned char*)pp); + uri->scheme = p; + if (!strcmp (uri->scheme, "http")) + uri->port = 80; +#ifdef HTTP_USE_GNUTLS + else if (!strcmp (uri->scheme, "https")) + { + uri->port = 443; + uri->use_tls = 1; + } +#endif + else + return gpg_error (GPG_ERR_INV_URI); /* Unsupported scheme */ + + p = p2; + + /* Find the hostname */ + if (*p != '/') + return gpg_error (GPG_ERR_INV_URI); /* Does not start with a slash. */ + + p++; + if (*p == '/') /* There seems to be a hostname. */ + { + p++; + if ((p2 = strchr (p, '/'))) + *p2++ = 0; + + /* Check for username/password encoding */ + if ((p3 = strchr (p, '@'))) + { + uri->auth = p; + *p3++ = '\0'; + p = p3; + } + + for (pp=p; *pp; pp++) + *pp = tolower (*(unsigned char*)pp); + + /* Handle an IPv6 literal */ + if( *p == '[' && (p3=strchr( p, ']' )) ) + { + *p3++ = '\0'; + /* worst case, uri->host should have length 0, points to \0 */ + uri->host = p + 1; + p = p3; + } + else + uri->host = p; + + if ((p3 = strchr (p, ':'))) + { + *p3++ = '\0'; + uri->port = atoi (p3); + } + + if ((n = remove_escapes (uri->host)) < 0) + return gpg_error (GPG_ERR_BAD_URI); + if (n != strlen (uri->host)) + return gpg_error (GPG_ERR_BAD_URI); /* Hostname incudes a Nul. */ + p = p2 ? p2 : NULL; + } + } /* End global URI part. */ + + /* Parse the pathname part */ + if (!p || !*p) + return 0; /* We don't have a path. Okay. */ + + /* TODO: Here we have to check params. */ + + /* Do we have a query part? */ + if ((p2 = strchr (p, '?'))) + *p2++ = 0; + + uri->path = p; + if ((n = remove_escapes (p)) < 0) + return gpg_error (GPG_ERR_BAD_URI); + if (n != strlen (p)) + return gpg_error (GPG_ERR_BAD_URI); /* Path includes a Nul. */ + p = p2 ? p2 : NULL; + + if (!p || !*p) + return 0; /* We don't have a query string. Okay. */ + + /* Now parse the query string. */ + tail = &uri->query; + for (;;) + { + uri_tuple_t elem; + + if ((p2 = strchr (p, '&'))) + *p2++ = 0; + if (!(elem = parse_tuple (p))) + return gpg_error (GPG_ERR_BAD_URI); + *tail = elem; + tail = &elem->next; + + if (!p2) + break; /* Ready. */ + p = p2; + } + + return 0; +} + + +/* + * Remove all %xx escapes; this is done in-place. Returns: New length + * of the string. + */ +static int +remove_escapes (char *string) +{ + int n = 0; + unsigned char *p, *s; + + for (p = s = (unsigned char*)string; *s; s++) + { + if (*s == '%') + { + if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2])) + { + s++; + *p = *s >= '0' && *s <= '9' ? *s - '0' : + *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10; + *p <<= 4; + s++; + *p |= *s >= '0' && *s <= '9' ? *s - '0' : + *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10; + p++; + n++; + } + else + { + *p++ = *s++; + if (*s) + *p++ = *s++; + if (*s) + *p++ = *s++; + if (*s) + *p = 0; + return -1; /* Bad URI. */ + } + } + else + { + *p++ = *s; + n++; + } + } + *p = 0; /* Make sure to keep a string terminator. */ + return n; +} + + +static int +insert_escapes (char *buffer, const char *string, + const char *special) +{ + const unsigned char *s = (const unsigned char*)string; + int n = 0; + + for (; *s; s++) + { + if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s)) + { + if (buffer) + *(unsigned char*)buffer++ = *s; + n++; + } + else + { + if (buffer) + { + sprintf (buffer, "%%%02X", *s); + buffer += 3; + } + n += 3; + } + } + return n; +} + + +/* Allocate a new string from STRING using standard HTTP escaping as + well as escaping of characters given in SPECIALS. A common pattern + for SPECIALS is "%;?&=". However it depends on the needs, for + example "+" and "/: often needs to be escaped too. Returns NULL on + failure and sets ERRNO. */ +char * +http_escape_string (const char *string, const char *specials) +{ + int n; + char *buf; + + n = insert_escapes (NULL, string, specials); + buf = xtrymalloc (n+1); + if (buf) + { + insert_escapes (buf, string, specials); + buf[n] = 0; + } + return buf; +} + + + +static uri_tuple_t +parse_tuple (char *string) +{ + char *p = string; + char *p2; + int n; + uri_tuple_t tuple; + + if ((p2 = strchr (p, '='))) + *p2++ = 0; + if ((n = remove_escapes (p)) < 0) + return NULL; /* Bad URI. */ + if (n != strlen (p)) + return NULL; /* Name with a Nul in it. */ + tuple = xtrycalloc (1, sizeof *tuple); + if (!tuple) + return NULL; /* Out of core. */ + tuple->name = p; + if (!p2) /* We have only the name, so we assume an empty value string. */ + { + tuple->value = p + strlen (p); + tuple->valuelen = 0; + tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */ + } + else /* Name and value. */ + { + if ((n = remove_escapes (p2)) < 0) + { + xfree (tuple); + return NULL; /* Bad URI. */ + } + tuple->value = p2; + tuple->valuelen = n; + } + return tuple; +} + + +/* + * Send a HTTP request to the server + * Returns 0 if the request was successful + */ +static gpg_error_t +send_request (http_t hd, const char *auth, + const char *proxy,const char *srvtag,strlist_t headers) +{ + gnutls_session_t tls_session; + gpg_error_t err; + const char *server; + char *request, *p; + unsigned short port; + const char *http_proxy = NULL; + char *proxy_authstr = NULL; + char *authstr = NULL; + int save_errno; + + tls_session = hd->tls_context; + if (hd->uri->use_tls && !tls_session) + { + log_error ("TLS requested but no GNUTLS context provided\n"); + return gpg_error (GPG_ERR_INTERNAL); + } + + server = *hd->uri->host ? hd->uri->host : "localhost"; + port = hd->uri->port ? hd->uri->port : 80; + + if ( (proxy && *proxy) + || ( (hd->flags & HTTP_FLAG_TRY_PROXY) + && (http_proxy = getenv (HTTP_PROXY_ENV)) + && *http_proxy )) + { + parsed_uri_t uri; + + if (proxy) + http_proxy = proxy; + + err = http_parse_uri (&uri, http_proxy); + if (err) + { + log_error ("invalid HTTP proxy (%s): %s\n", + http_proxy, gpg_strerror (err)); + http_release_parsed_uri (uri); + return gpg_error (GPG_ERR_CONFIGURATION); + + } + + if (uri->auth) + { + remove_escapes (uri->auth); + proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", + "\r\n", + uri->auth, strlen(uri->auth)); + if (!proxy_authstr) + { + err = gpg_error_from_syserror (); + http_release_parsed_uri (uri); + return err; + } + } + + hd->sock = connect_server (*uri->host ? uri->host : "localhost", + uri->port ? uri->port : 80, + hd->flags, srvtag); + save_errno = errno; + http_release_parsed_uri (uri); + } + else + { + hd->sock = connect_server (server, port, hd->flags, srvtag); + save_errno = errno; + } + + if (hd->sock == -1) + { + xfree (proxy_authstr); + return (save_errno + ? gpg_error_from_errno (save_errno) + : gpg_error (GPG_ERR_NOT_FOUND)); + } + +#ifdef HTTP_USE_GNUTLS + if (hd->uri->use_tls) + { + int rc; + + gnutls_transport_set_ptr (tls_session, (gnutls_transport_ptr_t)hd->sock); + do + { + rc = gnutls_handshake (tls_session); + } + while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN); + if (rc < 0) + { + log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc)); + xfree (proxy_authstr); + return gpg_error (GPG_ERR_NETWORK); + } + + if (tls_callback) + { + err = tls_callback (hd, tls_session, 0); + if (err) + { + log_info ("TLS connection authentication failed: %s\n", + gpg_strerror (err)); + xfree (proxy_authstr); + return err; + } + } + } +#endif /*HTTP_USE_GNUTLS*/ + + if (auth || hd->uri->auth) + { + char *myauth; + + if (auth) + { + myauth = xtrystrdup (auth); + if (!myauth) + { + xfree (proxy_authstr); + return gpg_error_from_syserror (); + } + remove_escapes (myauth); + } + else + { + remove_escapes (hd->uri->auth); + myauth = hd->uri->auth; + } + + authstr = make_header_line ("Authorization: Basic %s", "\r\n", + myauth, strlen (myauth)); + if (auth) + xfree (myauth); + + if (!authstr) + { + xfree (proxy_authstr); + return gpg_error_from_syserror (); + } + } + + p = build_rel_path (hd->uri); + if (!p) + return gpg_error_from_syserror (); + + request = xtrymalloc (2 * strlen (server) + + strlen (p) + + (authstr?strlen(authstr):0) + + (proxy_authstr?strlen(proxy_authstr):0) + + 100); + if (!request) + { + err = gpg_error_from_syserror (); + xfree (p); + xfree (authstr); + xfree (proxy_authstr); + return err; + } + + if (http_proxy && *http_proxy) + { + sprintf (request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + server, port, *p == '/' ? "" : "/", p, + authstr ? authstr : "", + proxy_authstr ? proxy_authstr : ""); + } + else + { + char portstr[35]; + + if (port == 80) + *portstr = 0; + else + sprintf (portstr, ":%u", port); + + sprintf (request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + *p == '/' ? "" : "/", p, server, portstr, + authstr? authstr:""); + } + xfree (p); + + +#ifdef HTTP_USE_ESTREAM + /* First setup estream so that we can write even the first line + using estream. This is also required for the sake of gnutls. */ + { + cookie_t cookie; + + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + { + err = gpg_error_from_syserror (); + goto leave; + } + cookie->fd = hd->sock; + if (hd->uri->use_tls) + { + cookie->tls_session = tls_session; + hd->write_cookie = cookie; + } + + hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); + if (!hd->fp_write) + { + xfree (cookie); + err = gpg_error_from_syserror (); + } + else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + err = gpg_error_from_syserror (); + else + err = 0; + + if(err==0) + for(;headers;headers=headers->next) + { + if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) + || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) + { + err = gpg_error_from_syserror (); + break; + } + } + } + + leave: + +#else /*!HTTP_USE_ESTREAM*/ + /* We send out the start of the request through our own send + function and only then assign a stdio stream. This allows for + better error reporting that through standard stdio means. */ + err = write_server (hd->sock, request, strlen (request)); + + if(err==0) + for(;headers;headers=headers->next) + { + err = write_server( hd->sock, headers->d, strlen(headers->d) ); + if(err) + break; + err = write_server( hd->sock, "\r\n", 2 ); + if(err) + break; + } + + if (!err) + { + hd->fp_write = fdopen (hd->sock, "w"); + if (!hd->fp_write) + err = gpg_error_from_syserror (); + } + +#endif /*!HTTP_USE_ESTREAM*/ + + xfree (request); + xfree (authstr); + xfree (proxy_authstr); + + return err; +} + + +/* + * Build the relative path from the parsed URI. Minimal + * implementation. May return NULL in case of memory failure; errno + * is then set accordingly. + */ +static char * +build_rel_path (parsed_uri_t uri) +{ + uri_tuple_t r; + char *rel_path, *p; + int n; + + /* Count the needed space. */ + n = insert_escapes (NULL, uri->path, "%;?&"); + /* TODO: build params. */ + for (r = uri->query; r; r = r->next) + { + n++; /* '?'/'&' */ + n += insert_escapes (NULL, r->name, "%;?&="); + if (!r->no_value) + { + n++; /* '=' */ + n += insert_escapes (NULL, r->value, "%;?&="); + } + } + n++; + + /* Now allocate and copy. */ + p = rel_path = xtrymalloc (n); + if (!p) + return NULL; + n = insert_escapes (p, uri->path, "%;?&"); + p += n; + /* TODO: add params. */ + for (r = uri->query; r; r = r->next) + { + *p++ = r == uri->query ? '?' : '&'; + n = insert_escapes (p, r->name, "%;?&="); + p += n; + if (!r->no_value) + { + *p++ = '='; + /* TODO: Use valuelen. */ + n = insert_escapes (p, r->value, "%;?&="); + p += n; + } + } + *p = 0; + return rel_path; +} + + + +/* + 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. If MAX_LENGTH is zero on return, the line has been + truncated. If the returned buffer is NULL, not enough memory was + enable to increase it, the return value will also be 0 and some + bytes might have been lost which should be no problem becuase + out-of-memory is pretty fatal for most applications. + + If a line has been truncated, the file pointer is internally moved + forward to the end of the line. + + Note: The returned buffer is allocated with enough extra space to + append a CR,LF,Nul + */ +static size_t +my_read_line ( +#ifdef HTTP_USE_ESTREAM + estream_t fp, +#else + FILE *fp, +#endif + 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; + char *p; + + if (!buffer) /* Must allocate a new buffer. */ + { + length = 256; + buffer = xtrymalloc (length); + *addr_of_buffer = buffer; + if (!buffer) + { + *length_of_buffer = *max_length = 0; + return 0; + } + *length_of_buffer = length; + } + + length -= 3; /* Reserve 3 bytes (cr,lf,eol). */ + p = buffer; + while ((c = P_ES(getc) (fp)) != EOF) + { + if (nbytes == length) /* Increase the buffer. */ + { + if (length > maxlen) /* Limit reached. */ + { + /* Skip the rest of the line. */ + while (c != '\n' && (c = P_ES(getc) (fp)) != EOF) + ; + *p++ = '\n'; /* Always append a LF (we reserved some space). */ + nbytes++; + *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 0; + } + buffer = *addr_of_buffer; + *length_of_buffer = length; + length -= 3; /* And re-adjust for the reservation. */ + p = buffer + nbytes; + } + *p++ = c; + nbytes++; + if (c == '\n') + break; + } + *p = 0; /* Make sure the line is a string. */ + + return nbytes; +} + + +/* Transform a header name into a standard capitalized format; e.g. + "Content-Type". Conversion stops at the colon. As usual we don't + use the localized versions of ctype.h. */ +static void +capitalize_header_name (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'; + } +} + + +/* Store an HTTP header line in LINE away. Line continuation is + supported as well as merging of headers with the same name. This + function may modify LINE. */ +static gpg_error_t +store_header (http_t hd, char *line) +{ + size_t n; + char *p, *value; + header_t h; + + n = strlen (line); + if (n && line[n-1] == '\n') + { + line[--n] = 0; + if (n && line[n-1] == '\r') + line[--n] = 0; + } + if (!n) /* we are never called to hit this. */ + return gpg_error (GPG_ERR_BUG); + if (*line == ' ' || *line == '\t') + { + /* Continuation. This won't happen too often as it is not + recommended. We use a straightforward implementaion. */ + if (!hd->headers) + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); + n += strlen (hd->headers->value); + p = xtrymalloc (n+1); + if (!p) + return gpg_error_from_syserror (); + strcpy (stpcpy (p, hd->headers->value), line); + xfree (hd->headers->value); + hd->headers->value = p; + return 0; + } + + capitalize_header_name (line); + p = strchr (line, ':'); + if (!p) + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); + *p++ = 0; + while (*p == ' ' || *p == '\t') + p++; + value = p; + + for (h=hd->headers; h; h = h->next) + if ( !strcmp (h->name, line) ) + break; + if (h) + { + /* We have already seen a line with that name. Thus we assume + it is a comma separated list and merge them. */ + p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1); + if (!p) + return gpg_error_from_syserror (); + strcpy (stpcpy (stpcpy (p, h->value), ","), value); + xfree (h->value); + h->value = p; + return 0; + } + + /* Append a new header. */ + h = xtrymalloc (sizeof *h + strlen (line)); + if (!h) + return gpg_error_from_syserror (); + strcpy (h->name, line); + h->value = xtrymalloc (strlen (value)+1); + if (!h->value) + { + xfree (h); + return gpg_error_from_syserror (); + } + strcpy (h->value, value); + h->next = hd->headers; + hd->headers = h; + + return 0; +} + + +/* Return the header NAME from the last response. The returned value + is valid as along as HD has not been closed and no othe request has + been send. If the header was not found, NULL is returned. Name + must be canonicalized, that is the first letter of each dash + delimited part must be uppercase and all other letters lowercase. + Note that the context must have been opened with the + HTTP_FLAG_NEED_HEADER. */ +const char * +http_get_header (http_t hd, const char *name) +{ + header_t h; + + for (h=hd->headers; h; h = h->next) + if ( !strcmp (h->name, name) ) + return h->value; + return NULL; +} + + + +/* + * Parse the response from a server. + * Returns: Errorcode and sets some files in the handle + */ +static gpg_error_t +parse_response (http_t hd) +{ + char *line, *p, *p2; + size_t maxlen, len; + + /* Delete old header lines. */ + while (hd->headers) + { + header_t tmp = hd->headers->next; + xfree (hd->headers->value); + xfree (hd->headers); + hd->headers = tmp; + } + + /* Wait for the status line. */ + do + { + maxlen = MAX_LINELEN; + len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); + line = hd->buffer; + if (!line) + return gpg_error_from_syserror (); /* Out of core. */ + if (!maxlen) + return gpg_error (GPG_ERR_TRUNCATED); /* Line has been truncated. */ + if (!len) + return gpg_error (GPG_ERR_EOF); + if ( (hd->flags & HTTP_FLAG_LOG_RESP) ) + log_info ("RESP: `%.*s'\n", + (int)strlen(line)-(*line&&line[1]?2:0),line); + } + while (!*line); + + if ((p = strchr (line, '/'))) + *p++ = 0; + if (!p || strcmp (line, "HTTP")) + return 0; /* Assume http 0.9. */ + + if ((p2 = strpbrk (p, " \t"))) + { + *p2++ = 0; + p2 += strspn (p2, " \t"); + } + if (!p2) + return 0; /* Also assume http 0.9. */ + p = p2; + /* TODO: Add HTTP version number check. */ + if ((p2 = strpbrk (p, " \t"))) + *p2++ = 0; + if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1]) + || !isdigit ((unsigned int)p[2]) || p[3]) + { + /* Malformed HTTP status code - assume http 0.9. */ + hd->is_http_0_9 = 1; + hd->status_code = 200; + return 0; + } + hd->status_code = atoi (p); + + /* Skip all the header lines and wait for the empty line. */ + do + { + maxlen = MAX_LINELEN; + len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); + line = hd->buffer; + if (!line) + return gpg_error_from_syserror (); /* Out of core. */ + /* Note, that we can silently ignore truncated lines. */ + if (!len) + return gpg_error (GPG_ERR_EOF); + /* Trim line endings of empty lines. */ + if ((*line == '\r' && line[1] == '\n') || *line == '\n') + *line = 0; + if ( (hd->flags & HTTP_FLAG_LOG_RESP) ) + log_info ("RESP: `%.*s'\n", + (int)strlen(line)-(*line&&line[1]?2:0),line); + if ( (hd->flags & HTTP_FLAG_NEED_HEADER) && *line ) + { + gpg_error_t err = store_header (hd, line); + if (err) + return err; + } + } + while (len && *line); + + return 0; +} + +#if 0 +static int +start_server () +{ + struct sockaddr_in mya; + struct sockaddr_in peer; + int fd, client; + fd_set rfds; + int addrlen; + int i; + + if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1) + { + log_error ("socket() failed: %s\n", strerror (errno)); + return -1; + } + i = 1; + if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i))) + log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno)); + + mya.sin_family = AF_INET; + memset (&mya.sin_addr, 0, sizeof (mya.sin_addr)); + mya.sin_port = htons (11371); + + if (bind (fd, (struct sockaddr *) &mya, sizeof (mya))) + { + log_error ("bind to port 11371 failed: %s\n", strerror (errno)); + sock_close (fd); + return -1; + } + + if (listen (fd, 5)) + { + log_error ("listen failed: %s\n", strerror (errno)); + sock_close (fd); + return -1; + } + + for (;;) + { + FD_ZERO (&rfds); + FD_SET (fd, &rfds); + + if (select (fd + 1, &rfds, NULL, NULL, NULL) <= 0) + continue; /* ignore any errors */ + + if (!FD_ISSET (fd, &rfds)) + continue; + + addrlen = sizeof peer; + client = accept (fd, (struct sockaddr *) &peer, &addrlen); + if (client == -1) + continue; /* oops */ + + log_info ("connect from %s\n", inet_ntoa (peer.sin_addr)); + + fflush (stdout); + fflush (stderr); + if (!fork ()) + { + int c; + FILE *fp; + + fp = fdopen (client, "r"); + while ((c = getc (fp)) != EOF) + putchar (c); + fclose (fp); + exit (0); + } + sock_close (client); + } + + + return 0; +} +#endif + +/* Actually connect to a server. Returns the file descriptor or -1 on + error. ERRNO is set on error. */ +static int +connect_server (const char *server, unsigned short port, + unsigned int flags, const char *srvtag) +{ + int sock = -1; + int srvcount = 0; + int hostfound = 0; + int srv, connected; + int last_errno = 0; + struct srventry *serverlist = NULL; + + /* Not currently using the flags */ + (void)flags; + +#ifdef HAVE_W32_SYSTEM + unsigned long inaddr; + +#ifndef HTTP_NO_WSASTARTUP + init_sockets (); +#endif + /* Win32 gethostbyname doesn't handle IP addresses internally, so we + try inet_addr first on that platform only. */ + inaddr = inet_addr(server); + if ( inaddr != INADDR_NONE ) + { + struct sockaddr_in addr; + + memset(&addr,0,sizeof(addr)); + + sock = socket(AF_INET,SOCK_STREAM,0); + if ( sock==INVALID_SOCKET ) + { + log_error("error creating socket: ec=%d\n",(int)WSAGetLastError()); + return -1; + } + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr)); + + if (!connect (sock,(struct sockaddr *)&addr,sizeof(addr)) ) + return sock; + sock_close(sock); + return -1; + } +#endif /*HAVE_W32_SYSTEM*/ + +#ifdef USE_DNS_SRV + /* Do the SRV thing */ + if (srvtag) + { + /* We're using SRV, so append the tags. */ + if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME) + { + char srvname[MAXDNAME]; + + stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag), + "._tcp."), server); + srvcount = getsrv (srvname, &serverlist); + } + } +#endif /*USE_DNS_SRV*/ + + if (!serverlist) + { + /* Either we're not using SRV, or the SRV lookup failed. Make + up a fake SRV record. */ + serverlist = xtrycalloc (1, sizeof *serverlist); + if (!serverlist) + return -1; /* Out of core. */ + serverlist->port = port; + strncpy (serverlist->target, server, MAXDNAME); + serverlist->target[MAXDNAME-1] = '\0'; + srvcount = 1; + } + +#ifdef HAVE_GETADDRINFO + connected = 0; + for (srv=0; srv < srvcount && !connected; srv++) + { + struct addrinfo hints, *res, *ai; + char portstr[35]; + + sprintf (portstr, "%hu", port); + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res)) + continue; /* Not found - try next one. */ + hostfound = 1; + + for (ai = res; ai && !connected; ai = ai->ai_next) + { + if (sock != -1) + sock_close (sock); + sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock == -1) + { + int save_errno = errno; + log_error ("error creating socket: %s\n", strerror (errno)); + freeaddrinfo (res); + xfree (serverlist); + errno = save_errno; + return -1; + } + + if (connect (sock, ai->ai_addr, ai->ai_addrlen)) + last_errno = errno; + else + connected = 1; + } + freeaddrinfo (res); + } +#else /* !HAVE_GETADDRINFO */ + connected = 0; + for (srv=0; srv < srvcount && !connected; srv++) + { + int i; + struct hostent *host = NULL; + struct sockaddr_in addr; + + /* Note: This code is not thread-safe. */ + + memset (&addr, 0, sizeof (addr)); + host = gethostbyname (serverlist[srv].target); + if (!host) + continue; + hostfound = 1; + + if (sock != -1) + sock_close (sock); + sock = socket (host->h_addrtype, SOCK_STREAM, 0); + if (sock == -1) + { + log_error (_("error creating socket: %s\n"), strerror (errno)); + xfree (serverlist); + return -1; + } + + addr.sin_family = host->h_addrtype; + if (addr.sin_family != AF_INET) + { + log_error ("unknown address family for `%s'\n", + serverlist[srv].target); + xfree (serverlist); + return -1; + } + addr.sin_port = htons (serverlist[srv].port); + if (host->h_length != 4) + { + log_error ("illegal address length for `%s'\n", + serverlist[srv].target); + xfree (serverlist); + return -1; + } + + /* Try all A records until one responds. */ + for (i = 0; host->h_addr_list[i] && !connected; i++) + { + memcpy (&addr.sin_addr, host->h_addr_list[i], host->h_length); + if (connect (sock, (struct sockaddr *) &addr, sizeof (addr))) + last_errno = errno; + else + { + connected = 1; + break; + } + } + } +#endif /* !HAVE_GETADDRINFO */ + + xfree (serverlist); + + if (!connected) + { +#ifdef HAVE_W32_SYSTEM + log_error ("can't connect to `%s': %s%sec=%d\n", + server, + hostfound? "":_("host not found"), + hostfound? "":" - ", (int)WSAGetLastError()); +#else + log_error ("can't connect to `%s': %s\n", + server, + hostfound? strerror (last_errno):"host not found"); +#endif + if (sock != -1) + sock_close (sock); + errno = last_errno; + return -1; + } + return sock; +} + + +static gpg_error_t +write_server (int sock, const char *data, size_t length) +{ + int nleft; + + nleft = length; + while (nleft > 0) + { +#ifdef HAVE_W32_SYSTEM + int nwritten; + + nwritten = send (sock, data, nleft, 0); + if ( nwritten == SOCKET_ERROR ) + { + log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); + return gpg_error (GPG_ERR_NETWORK); + } +#else /*!HAVE_W32_SYSTEM*/ + int nwritten = write (sock, data, nleft); + if (nwritten == -1) + { + if (errno == EINTR) + continue; + if (errno == EAGAIN) + { + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 50000; + select (0, NULL, NULL, NULL, &tv); + continue; + } + log_info ("network write failed: %s\n", strerror (errno)); + return gpg_error_from_syserror (); + } +#endif /*!HAVE_W32_SYSTEM*/ + nleft -= nwritten; + data += nwritten; + } + + return 0; +} + + + +#ifdef HTTP_USE_ESTREAM +/* Read handler for estream. */ +static ssize_t +cookie_read (void *cookie, void *buffer, size_t size) +{ + cookie_t c = cookie; + int nread; + +#ifdef HTTP_USE_GNUTLS + if (c->tls_session) + { + again: + nread = gnutls_record_recv (c->tls_session, buffer, size); + if (nread < 0) + { + if (nread == GNUTLS_E_INTERRUPTED) + goto again; + if (nread == GNUTLS_E_AGAIN) + { + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 50000; + select (0, NULL, NULL, NULL, &tv); + goto again; + } + if (nread == GNUTLS_E_REHANDSHAKE) + goto again; /* A client is allowed to just ignore this request. */ + log_info ("TLS network read failed: %s\n", gnutls_strerror (nread)); + errno = EIO; + return -1; + } + } + else +#endif /*HTTP_USE_GNUTLS*/ + { + do + { +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to use recv for a socket. */ + nread = recv (c->fd, buffer, size, 0); +#else + nread = read (c->fd, buffer, size); +#endif + } + while (nread == -1 && errno == EINTR); + } + + return nread; +} + +/* Write handler for estream. */ +static ssize_t +cookie_write (void *cookie, const void *buffer, size_t size) +{ + cookie_t c = cookie; + int nwritten = 0; + +#ifdef HTTP_USE_GNUTLS + if (c->tls_session) + { + int nleft = size; + while (nleft > 0) + { + nwritten = gnutls_record_send (c->tls_session, buffer, nleft); + if (nwritten <= 0) + { + if (nwritten == GNUTLS_E_INTERRUPTED) + continue; + if (nwritten == GNUTLS_E_AGAIN) + { + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 50000; + select (0, NULL, NULL, NULL, &tv); + continue; + } + log_info ("TLS network write failed: %s\n", + gnutls_strerror (nwritten)); + errno = EIO; + return -1; + } + nleft -= nwritten; + buffer += nwritten; + } + } + else +#endif /*HTTP_USE_GNUTLS*/ + { + if ( write_server (c->fd, buffer, size) ) + { + errno = EIO; + nwritten = -1; + } + else + nwritten = size; + } + + return nwritten; +} + +/* Close handler for estream. */ +static int +cookie_close (void *cookie) +{ + cookie_t c = cookie; + + if (!c) + return 0; + +#ifdef HTTP_USE_GNUTLS + if (c->tls_session && !c->keep_socket) + { + gnutls_bye (c->tls_session, GNUTLS_SHUT_RDWR); + } +#endif /*HTTP_USE_GNUTLS*/ + if (c->fd != -1 && !c->keep_socket) + sock_close (c->fd); + + xfree (c); + return 0; +} +#endif /*HTTP_USE_ESTREAM*/ + + + + +/**** Test code ****/ +#ifdef TEST + +static gpg_error_t +verify_callback (http_t hd, void *tls_context, int reserved) +{ + log_info ("verification of certificates skipped\n"); + return 0; +} + + + +/* static void */ +/* my_gnutls_log (int level, const char *text) */ +/* { */ +/* fprintf (stderr, "gnutls:L%d: %s", level, text); */ +/* } */ + +int +main (int argc, char **argv) +{ + int rc; + parsed_uri_t uri; + uri_tuple_t r; + http_t hd; + int c; + gnutls_session_t tls_session = NULL; +#ifdef HTTP_USE_GNUTLS + gnutls_certificate_credentials certcred; + const int certprio[] = { GNUTLS_CRT_X509, 0 }; +#endif /*HTTP_USE_GNUTLS*/ + header_t hdr; + +#ifdef HTTP_USE_ESTREAM + es_init (); +#endif + log_set_prefix ("http-test", 1 | 4); + if (argc == 1) + { + /*start_server (); */ + return 0; + } + + if (argc != 2) + { + fprintf (stderr, "usage: http-test uri\n"); + return 1; + } + argc--; + argv++; + +#ifdef HTTP_USE_GNUTLS + rc = gnutls_global_init (); + if (rc) + log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc)); + rc = gnutls_certificate_allocate_credentials (&certcred); + if (rc) + log_error ("gnutls_certificate_allocate_credentials failed: %s\n", + gnutls_strerror (rc)); +/* rc = gnutls_certificate_set_x509_trust_file */ +/* (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */ +/* if (rc) */ +/* log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */ +/* gnutls_strerror (rc)); */ + rc = gnutls_init (&tls_session, GNUTLS_CLIENT); + if (rc) + log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc)); + rc = gnutls_set_default_priority (tls_session); + if (rc) + log_error ("gnutls_set_default_priority failed: %s\n", + gnutls_strerror (rc)); + rc = gnutls_certificate_type_set_priority (tls_session, certprio); + if (rc) + log_error ("gnutls_certificate_type_set_priority failed: %s\n", + gnutls_strerror (rc)); + rc = gnutls_credentials_set (tls_session, GNUTLS_CRD_CERTIFICATE, certcred); + if (rc) + log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc)); +/* gnutls_global_set_log_function (my_gnutls_log); */ +/* gnutls_global_set_log_level (4); */ + + http_register_tls_callback (verify_callback); +#endif /*HTTP_USE_GNUTLS*/ + + rc = http_parse_uri (&uri, *argv); + if (rc) + { + log_error ("`%s': %s\n", *argv, gpg_strerror (rc)); + http_release_parsed_uri (uri); + return 1; + } + + printf ("Scheme: %s\n", uri->scheme); + printf ("Host : %s\n", uri->host); + printf ("Port : %u\n", uri->port); + printf ("Path : %s\n", uri->path); + for (r = uri->params; r; r = r->next) + { + printf ("Params: %s", r->name); + if (!r->no_value) + { + printf ("=%s", r->value); + if (strlen (r->value) != r->valuelen) + printf (" [real length=%d]", (int) r->valuelen); + } + putchar ('\n'); + } + for (r = uri->query; r; r = r->next) + { + printf ("Query : %s", r->name); + if (!r->no_value) + { + printf ("=%s", r->value); + if (strlen (r->value) != r->valuelen) + printf (" [real length=%d]", (int) r->valuelen); + } + putchar ('\n'); + } + http_release_parsed_uri (uri); + uri = NULL; + + rc = http_open_document (&hd, *argv, NULL, + HTTP_FLAG_NO_SHUTDOWN | HTTP_FLAG_NEED_HEADER, + NULL, tls_session); + if (rc) + { + log_error ("can't get `%s': %s\n", *argv, gpg_strerror (rc)); + return 1; + } + log_info ("open_http_document succeeded; status=%u\n", + http_get_status_code (hd)); + for (hdr = hd->headers; hdr; hdr = hdr->next) + printf ("HDR: %s: %s\n", hdr->name, hdr->value); + switch (http_get_status_code (hd)) + { + case 200: + while ((c = P_ES(getc) (http_get_read_ptr (hd))) != EOF) + putchar (c); + break; + case 301: + case 302: + printf ("Redirected to `%s'\n", http_get_header (hd, "Location")); + break; + } + http_close (hd, 0); + +#ifdef HTTP_USE_GNUTLS + gnutls_deinit (tls_session); + gnutls_certificate_free_credentials (certcred); + gnutls_global_deinit (); +#endif /*HTTP_USE_GNUTLS*/ + + return 0; +} +#endif /*TEST*/ + + +/* +Local Variables: +compile-command: "gcc -I.. -I../gl -DTEST -DHAVE_CONFIG_H -Wall -O2 -g -o http-test http.c -L. -lcommon -L../jnlib -ljnlib -lgcrypt -lpth -lgnutls" +End: +*/ diff --git a/common/http.h b/common/http.h new file mode 100644 index 0000000..28a5304 --- /dev/null +++ b/common/http.h @@ -0,0 +1,116 @@ +/* http.h - HTTP protocol handler + * Copyright (C) 1999, 2000, 2001, 2003, + * 2006 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 3 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, see . + */ +#ifndef GNUPG_COMMON_HTTP_H +#define GNUPG_COMMON_HTTP_H + +#include +#ifdef HTTP_USE_ESTREAM +#include "estream.h" +#endif + +struct uri_tuple_s { + struct uri_tuple_s *next; + const char *name; /* A pointer into name. */ + char *value; /* A pointer to value (a Nul is always appended). */ + size_t valuelen; /* The real length of the value; we need it + because the value may contain embedded Nuls. */ + int no_value; /* True if no value has been given in the URL. */ +}; +typedef struct uri_tuple_s *uri_tuple_t; + +struct parsed_uri_s +{ + /* All these pointers point into BUFFER; most stuff is not escaped. */ + char *scheme; /* Pointer to the scheme string (lowercase). */ + int use_tls; /* Whether TLS should be used. */ + char *auth; /* username/password for basic auth */ + char *host; /* Host (converted to lowercase). */ + unsigned short port; /* Port (always set if the host is set). */ + char *path; /* Path. */ + uri_tuple_t params; /* ";xxxxx" */ + uri_tuple_t query; /* "?xxx=yyy" */ + char buffer[1]; /* Buffer which holds a (modified) copy of the URI. */ +}; +typedef struct parsed_uri_s *parsed_uri_t; + +typedef enum + { + HTTP_REQ_GET = 1, + HTTP_REQ_HEAD = 2, + HTTP_REQ_POST = 3 + } +http_req_t; + +/* We put the flag values into an enum, so that gdb can display them. */ +enum + { + HTTP_FLAG_TRY_PROXY = 1, + HTTP_FLAG_NO_SHUTDOWN = 2, + HTTP_FLAG_LOG_RESP = 4, + HTTP_FLAG_NEED_HEADER = 8 + }; + +struct http_context_s; +typedef struct http_context_s *http_t; + +void http_register_tls_callback (gpg_error_t (*cb) (http_t, void *, int)); + +gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri); + +void http_release_parsed_uri (parsed_uri_t uri); + +gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, + const char *url, + const char *auth, + unsigned int flags, + const char *proxy, + void *tls_context, + const char *srvtag, + strlist_t headers); + +void http_start_data (http_t hd); + +gpg_error_t http_wait_response (http_t hd); + +void http_close (http_t hd, int keep_read_stream); + +gpg_error_t http_open_document (http_t *r_hd, + const char *document, + const char *auth, + unsigned int flags, + const char *proxy, + void *tls_context, + const char *srvtag, + strlist_t headers); + +#ifdef HTTP_USE_ESTREAM +estream_t http_get_read_ptr (http_t hd); +estream_t http_get_write_ptr (http_t hd); +#else /*!HTTP_USE_ESTREAM*/ +FILE *http_get_read_ptr (http_t hd); +FILE *http_get_write_ptr (http_t hd); +#endif /*!HTTP_USE_ESTREAM*/ +unsigned int http_get_status_code (http_t hd); +const char *http_get_header (http_t hd, const char *name); + +char *http_escape_string (const char *string, const char *specials); + + +#endif /*GNUPG_COMMON_HTTP_H*/ diff --git a/common/i18n.c b/common/i18n.c new file mode 100644 index 0000000..db5ddf5 --- /dev/null +++ b/common/i18n.c @@ -0,0 +1,107 @@ +/* i18n.c - gettext initialization + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#ifdef HAVE_LOCALE_H +#include +#endif +#ifdef HAVE_LANGINFO_CODESET +#include +#endif + +#include "util.h" +#include "i18n.h" + + +void +i18n_init (void) +{ +#ifdef USE_SIMPLE_GETTEXT + bindtextdomain (PACKAGE_GT, gnupg_localedir ()); +#else +# ifdef ENABLE_NLS + setlocale (LC_ALL, "" ); + bindtextdomain (PACKAGE_GT, LOCALEDIR); + textdomain (PACKAGE_GT); +# endif +#endif +} + + +/* The Assuan agent protocol requires us to transmit utf-8 strings + thus we need a way to temporary switch gettext from native to + utf8. */ +char * +i18n_switchto_utf8 (void) +{ +#ifdef USE_SIMPLE_GETTEXT + gettext_select_utf8 (1); + return NULL; +#elif defined(ENABLE_NLS) + char *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. + Note that bind_textdomain_codeset does only return on memory + errors but not if a codeset is not available. Thus we don't + bother printing a diagnostic here. */ + orig_codeset = xstrdup (orig_codeset); + if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) + { + xfree (orig_codeset); + orig_codeset = NULL; + } + } + return orig_codeset; +#else + return NULL; +#endif +} + +/* Switch back to the saved codeset. */ +void +i18n_switchback (char *saved_codeset) +{ +#ifdef USE_SIMPLE_GETTEXT + (void)saved_codeset; + gettext_select_utf8 (0); +#elif defined(ENABLE_NLS) + if (saved_codeset) + { + bind_textdomain_codeset (PACKAGE_GT, saved_codeset); + xfree (saved_codeset); + } +#else + (void)saved_codeset; +#endif +} + + +/* Gettext variant which temporary switches to utf-8 for string. */ +const char * +i18n_utf8 (const char *string) +{ + char *saved = i18n_switchto_utf8 (); + const char *result = _(string); + i18n_switchback (saved); + return result; +} diff --git a/common/i18n.h b/common/i18n.h new file mode 100644 index 0000000..7405f9a --- /dev/null +++ b/common/i18n.h @@ -0,0 +1,47 @@ +/* i18n.h + * Copyright (C) 1998, 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. + */ + +#ifndef GNUPG_COMMON_I18N_H +#define GNUPG_COMMON_I18N_H + + +#ifdef USE_SIMPLE_GETTEXT +# include "../jnlib/w32help.h" +# 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) +# define ngettext(a,b,c) ((c)==1? (a):(b)) +# endif +#endif /*!USE_SIMPLE_GETTEXT*/ + +void i18n_init (void); +char *i18n_switchto_utf8 (void); +void i18n_switchback (char *saved_codeset); +const char *i18n_utf8 (const char *string); + + +#endif /*GNUPG_COMMON_I18N_H*/ diff --git a/common/init.c b/common/init.c new file mode 100644 index 0000000..5425ace --- /dev/null +++ b/common/init.c @@ -0,0 +1,71 @@ +/* init.c - Various initializations + * Copyright (C) 2007 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 3 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, see . + */ + +#include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + +#ifdef HAVE_W32_SYSTEM +#include +#endif +#ifdef HAVE_PTH +#include +#endif + +#include "estream.h" +#include "util.h" + + +/* This function is to be used early at program startup to make sure + that some subsystems are initialized. This is in particular + important for W32 to initialize the sockets so that our socket + emulation code used directly as well as in libassuan may be used. + It should best be called before any I/O is done so that setup + required for logging is ready. CAUTION: This might be called while + running suid(root). */ +void +init_common_subsystems (void) +{ + /* Try to auto set the character set. */ + set_native_charset (NULL); + +#ifdef HAVE_W32_SYSTEM + /* For W32 we need to initialize the socket layer. This is because + we use recv and send in libassuan as well as at some other + places. If we are building with PTH we let pth_init do it. We + can't do much on error so we ignore them. An error would anyway + later pop up if one of the socket functions is used. */ +# ifdef HAVE_PTH + pth_init (); +# else + { + WSADATA wsadat; + + WSAStartup (0x202, &wsadat); + } +# endif /*!HAVE_PTH*/ +#endif + + /* Initialize the Estream library. */ + es_init (); +} + diff --git a/common/init.h b/common/init.h new file mode 100644 index 0000000..14dfa7b --- /dev/null +++ b/common/init.h @@ -0,0 +1,26 @@ +/* init.h - Definitions for init fucntions. + * Copyright (C) 2007 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_INIT_H +#define GNUPG_COMMON_INIT_H + +void init_common_subsystems (void); + + +#endif /*GNUPG_COMMON_INIT_H*/ diff --git a/common/iobuf.c b/common/iobuf.c new file mode 100644 index 0000000..04b17ff --- /dev/null +++ b/common/iobuf.c @@ -0,0 +1,2595 @@ +/* iobuf.c - File Handling for OpenPGP. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, + * 2007, 2008, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_W32_SYSTEM +# include +#endif +#ifdef __riscos__ +# include +# include +#endif /* __riscos__ */ + +#include "util.h" +#include "sysutils.h" +#include "iobuf.h" + +/*-- Begin configurable part. --*/ + +/* The size of the internal buffers. + NOTE: If you change this value you MUST also adjust the regression + test "armored_key_8192" in armor.test! */ +#define IOBUF_BUFFER_SIZE 8192 + +/* We don't want to use the STDIO based backend. If you change this + be aware that there is no fsync support for the stdio backend. */ +#undef FILE_FILTER_USES_STDIO + +/*-- End configurable part. --*/ + + +/* Under W32 the default is to use the setmode call. Define a macro + which allows us to enable this call. */ +#ifdef HAVE_W32_SYSTEM +# define USE_SETMODE 1 +#endif /*HAVE_W32_SYSTEM*/ + + +/* Definition of constants and macros used by our file filter + implementation. What we define here are 3 macros to make the + appropriate calls: + + my_fileno + Is expanded to fileno(a) if using a stdion backend and to a if we + are using the low-level backend. + + my_fopen + Is defined to fopen for the stdio backend and to direct_open if + we are using the low-evel backend. + + my_fopen_ro + Is defined to fopen for the stdio backend and to fd_cache_open if + we are using the low-evel backend. + + fp_or_fd_t + Is the type we use for the backend stream or file descriptor. + + INVALID_FP, FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT + Are macros defined depending on the used backend. + +*/ +#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 *fp_or_fd_t; +# define INVALID_FP NULL +# define FILEP_OR_FD_FOR_STDIN (stdin) +# define FILEP_OR_FD_FOR_STDOUT (stdout) +#else /*!FILE_FILTER_USES_STDIO*/ +# define my_fopen_ro(a,b) fd_cache_open ((a),(b)) +# define my_fopen(a,b) direct_open ((a),(b)) +# ifdef HAVE_W32_SYSTEM + /* (We assume that a HANDLE first into an int.) */ +# define my_fileno(a) ((int)(a)) + typedef HANDLE fp_or_fd_t; +# 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 /*!HAVE_W32_SYSTEM*/ +# define my_fileno(a) (a) + typedef int fp_or_fd_t; +# define INVALID_FP (-1) +# define FILEP_OR_FD_FOR_STDIN (0) +# define FILEP_OR_FD_FOR_STDOUT (1) +# endif /*!HAVE_W32_SYSTEM*/ +#endif /*!FILE_FILTER_USES_STDIO*/ + +/* The context used by the file filter. */ +typedef struct +{ + fp_or_fd_t fp; /* Open file pointer or 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; + + +/* If we are not using stdio as the backend we make use of a "close + cache". */ +#ifndef FILE_FILTER_USES_STDIO +struct close_cache_s +{ + struct close_cache_s *next; + fp_or_fd_t fp; + char fname[1]; +}; +typedef struct close_cache_s *close_cache_t; +static close_cache_t close_cache; +#endif /*!FILE_FILTER_USES_STDIO*/ + + + +#ifdef HAVE_W32_SYSTEM +typedef struct +{ + int sock; + int keep_open; + int no_cache; + int eof_seen; + int print_only_name; /* Flag indicating that fname is not a real file. */ + char fname[1]; /* Name of the file */ +} +sock_filter_ctx_t; +#endif /*HAVE_W32_SYSTEM*/ + +/* 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 + +/* The context we use for the block filter (used to handle OpenPGP + length information header). */ +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; /* First character of a partial header (which is > 0). */ + int eof; +} +block_filter_ctx_t; + + +/* Global flag to tell whether special file names are enabled. See + gpg.c for an explanation of these file names. FIXME: it does not + belong into the iobuf subsystem. */ +static int special_names_enabled; + +/* Local prototypes. */ +static int underflow (iobuf_t a); +static int translate_file_handle (int fd, int for_write); + + + +#ifndef FILE_FILTER_USES_STDIO +/* This is a replacement for strcmp. Under W32 it does not + distinguish between backslash and slash. */ +static int +fd_cache_strcmp (const char *a, const char *b) +{ +#ifdef HAVE_DOSISH_SYSTEM + for (; *a && *b; a++, b++) + { + if (*a != *b && !((*a == '/' && *b == '\\') + || (*a == '\\' && *b == '/')) ) + break; + } + return *(const unsigned char *)a - *(const unsigned char *)b; +#else + return strcmp (a, b); +#endif +} + +/* + * Invalidate (i.e. close) a cached iobuf + */ +static int +fd_cache_invalidate (const char *fname) +{ + close_cache_t cc; + int rc = 0; + + 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 && !fd_cache_strcmp (cc->fname, fname)) + { + if (DBG_IOBUF) + log_debug (" did (%s)\n", cc->fname); +#ifdef HAVE_W32_SYSTEM + if (!CloseHandle (cc->fp)) + rc = -1; +#else + rc = close (cc->fp); +#endif + cc->fp = INVALID_FP; + } + } + return rc; +} + + +/* Try to sync changes to the disk. This is to avoid data loss during + a system crash in write/close/rename cycle on some file + systems. */ +static int +fd_cache_synchronize (const char *fname) +{ + int err = 0; + +#ifdef HAVE_FSYNC + close_cache_t cc; + + if (DBG_IOBUF) + log_debug ("fd_cache_synchronize (%s)\n", fname); + + for (cc=close_cache; cc; cc = cc->next ) + { + if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) + { + if (DBG_IOBUF) + log_debug (" did (%s)\n", cc->fname); + + err = fsync (cc->fp); + } + } +#else + (void)fname; +#endif /*HAVE_FSYNC*/ + + return err; +} + + +static fp_or_fd_t +direct_open (const char *fname, const char *mode) +{ +#ifdef HAVE_W32_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 shared mode which is + * something new for MS applications ;-) + */ + if (strchr (mode, '+')) + { + if (fd_cache_invalidate (fname)) + return INVALID_FP; + da = GENERIC_READ | GENERIC_WRITE; + cd = OPEN_EXISTING; + sm = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else if (strchr (mode, 'w')) + { + if (fd_cache_invalidate (fname)) + return INVALID_FP; + 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 /*!HAVE_W32_SYSTEM*/ + 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, '+')) + { + if (fd_cache_invalidate (fname)) + return INVALID_FP; + oflag = O_RDWR; + } + else if (strchr (mode, 'w')) + { + if (fd_cache_invalidate (fname)) + return INVALID_FP; + oflag = O_WRONLY | O_CREAT | O_TRUNC; + } + else + { + oflag = O_RDONLY; + } +#ifdef O_BINARY + if (strchr (mode, 'b')) + oflag |= O_BINARY; +#endif + /* No we need to distinguish between POSIX and RISC OS. */ +#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 /*!HAVE_W32_SYSTEM*/ +} + + +/* + * 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, fp_or_fd_t fp) +{ + close_cache_t cc; + + assert (fp); + if (!fname || !*fname) + { +#ifdef HAVE_W32_SYSTEM + CloseHandle (fp); +#else + close (fp); +#endif + if (DBG_IOBUF) + log_debug ("fd_cache_close (%d) real\n", (int)fp); + return; + } + /* try to reuse a slot */ + for (cc = close_cache; cc; cc = cc->next) + { + if (cc->fp == INVALID_FP && !fd_cache_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 fp_or_fd_t +fd_cache_open (const char *fname, const char *mode) +{ + close_cache_t cc; + + assert (fname); + for (cc = close_cache; cc; cc = cc->next) + { + if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) + { + fp_or_fd_t fp = cc->fp; + cc->fp = INVALID_FP; + if (DBG_IOBUF) + log_debug ("fd_cache_open (%s) using cached fp\n", fname); +#ifdef HAVE_W32_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; + fp_or_fd_t f = a->fp; + size_t size = *ret_len; + size_t nbytes = 0; + int rc = 0; + + (void)chain; /* Not used. */ + +#ifdef FILE_FILTER_USES_STDIO + if (control == IOBUFCTRL_UNDERFLOW) + { + assert (size); /* We need a buffer. */ + if (feof (f)) + { + /* On terminals you could easily read as many EOFs as you + call fread() or fgetc() repeatly. Every call will block + until you press CTRL-D. So we catch this case before we + call fread() again. */ + rc = -1; + *ret_len = 0; + } + 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_syserror (); + 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_syserror (); + 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); /* We need a buffer. */ + if (a->eof_seen) + { + rc = -1; + *ret_len = 0; + } + else + { +#ifdef HAVE_W32_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_syserror (); + 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_W32_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_syserror (); + 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_W32_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 HAVE_W32_SYSTEM +/* Because network sockets are special objects under Lose32 we have to + use a dedicated filter for them. */ +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; + + (void)chain; + + 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 /*HAVE_W32_SYSTEM*/ + +/**************** + * 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 * buffer, + size_t * ret_len) +{ + block_filter_ctx_t *a = opaque; + char *buf = (char *)buffer; + 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; + a->partial = 2; + if (!a->size) + { + a->eof = 1; + if (!n) + rc = -1; + break; + } + } + 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 + BUG (); + } + + 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_syserror (); + a->buflen = 0; + nbytes -= n; + } + if ((n = nbytes) > blen) + n = blen; + if (n && iobuf_write (chain, p, n)) + rc = gpg_error_from_syserror (); + 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 + BUG (); + } + 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_syserror (); + } + xfree (a->buffer); + a->buffer = NULL; + a->buflen = 0; + } + else + BUG (); + } + 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?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?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_W32_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_W32_SYSTEM) || defined(__riscos__) + remove_name = xstrdup (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_W32_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, IOBUF_BUFFER_SIZE); + + 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 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 (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; +} + + +/* This fucntion returns true if FNAME indicates a PIPE (stdout or + stderr) or a special file name if those are enabled. */ +int +iobuf_is_pipe_filename (const char *fname) +{ + if (!fname || (*fname=='-' && !fname[1]) ) + return 1; + return check_special_filename (fname) != -1; +} + + +/* Either open the file specified by the file descriptor FD or - if FD + is -1, the file with name FNAME. As of now MODE is assumed to be + "rb" if FNAME is used. In contrast to iobuf_fdopen the file + descriptor FD will not be closed during an iobuf_close. */ +iobuf_t +iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode) +{ + iobuf_t a; + + if (fd == -1) + a = iobuf_open (fname); + else + { + int fd2; + + fd2 = dup (fd); + if (fd2 == -1) + a = NULL; + else + a = iobuf_fdopen (fd2, mode); + } + return a; +} + + +/**************** + * 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; + fp_or_fd_t 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, IOBUF_BUFFER_SIZE); + 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; + fp_or_fd_t fp; + file_filter_ctx_t *fcx; + size_t len; + +#ifdef FILE_FILTER_USES_STDIO + if (!(fp = fdopen (fd, mode))) + return NULL; +#else + fp = (fp_or_fd_t) fd; +#endif + a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE); + 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 HAVE_W32_SYSTEM + sock_filter_ctx_t *scx; + size_t len; + + a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE); + scx = xmalloc (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; + fp_or_fd_t 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, IOBUF_BUFFER_SIZE); + 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?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, IOBUF_BUFFER_SIZE); + 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?a->desc:"?"); + + return a; +} +#endif + +iobuf_t +iobuf_openrw (const char *fname) +{ + iobuf_t a; + fp_or_fd_t 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, IOBUF_BUFFER_SIZE); + 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?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 ? 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 HAVE_W32_SYSTEM + 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 + if (fd_cache_invalidate (ptrval)) + return -1; +#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? 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 HAVE_W32_SYSTEM + else if (!a->chain && a->filter == sock_filter) + { + sock_filter_ctx_t *b = a->filter_ov; + b->no_cache = intval; + return 0; + } +#endif + } + else if (cmd == 4) + { + /* Do a fsync on the open fd and return any errors to the caller + of iobuf_ioctl. Note that we work on a file name here. */ + if (DBG_IOBUF) + log_debug ("iobuf-*.*: ioctl `%s' fsync\n", + ptrval? (const char*)ptrval:""); + + if (!a && !intval && ptrval) + { +#ifndef FILE_FILTER_USES_STDIO + return fd_cache_synchronize (ptrval); +#else + 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?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. + */ +static 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?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?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_syserror (); + } + 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 in underflow (!len)\n", + a->no, a->subno); + 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 */ + unsigned char *newbuf; + size_t newsize = a->d.size + IOBUF_BUFFER_SIZE; + + 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; + + 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, void *buffer, unsigned int buflen) +{ + unsigned char *buf = (unsigned char *)buffer; + int c, n; + + if (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 int 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, const void *buffer, unsigned int buflen) +{ + const unsigned char *buf = (const unsigned char *)buffer; + 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 A. IF OVERFLOW is not NULL it + will be set to true if the file is larger than what off_t can cope + with. The function return 0 on error or on overflow condition. */ +off_t +iobuf_get_filelength (iobuf_t a, int *overflow) +{ + struct stat st; + + if (overflow) + *overflow = 0; + + 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; + fp_or_fd_t fp = b->fp; + +#if defined(HAVE_W32_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) + ulong size; + static int (* __stdcall get_file_size_ex) (void *handle, + LARGE_INTEGER *r_size); + static int get_file_size_ex_initialized; + + if (!get_file_size_ex_initialized) + { + void *handle; + + handle = dlopen ("kernel32.dll", RTLD_LAZY); + if (handle) + { + get_file_size_ex = dlsym (handle, "GetFileSizeEx"); + if (!get_file_size_ex) + dlclose (handle); + } + get_file_size_ex_initialized = 1; + } + + if (get_file_size_ex) + { + /* This is a newer system with GetFileSizeEx; we use this + then because it seem that GetFileSize won't return a + proper error in case a file is larger than 4GB. */ + LARGE_INTEGER exsize; + + if (get_file_size_ex (fp, &exsize)) + { + if (!exsize.u.HighPart) + return exsize.u.LowPart; + if (overflow) + *overflow = 1; + return 0; + } + } + else + { + if ((size=GetFileSize (fp, NULL)) != 0xffffffff) + return size; + } + log_error ("GetFileSize for handle %p failed: %s\n", + fp, w32_strerror (0)); +#else + if ( !fstat(my_fileno(fp), &st) ) + return st.st_size; + log_error("fstat() failed: %s\n", strerror(errno) ); +#endif + break/*the for loop*/; + } + + return 0; +} + + +/* Return the file descriptor of the underlying file or -1 if it is + not available. */ +int +iobuf_get_fd (iobuf_t a) +{ + if (a->directfp) + return fileno ( (FILE*)a->directfp ); + + for ( ; a; a = a->chain ) + if (!a->chain && a->filter == file_filter) + { + file_filter_ctx_t *b = a->filter_ov; + fp_or_fd_t fp = b->fp; + + return my_fileno (fp); + } + + return -1; +} + + + +/**************** + * 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_W32_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; +} + + +/**************** + * 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); + } +} + + + +/**************** + * 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 = (char *)*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 = (unsigned char *)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 = (unsigned char *)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; +} + +static int +translate_file_handle (int fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM +# ifdef FILE_FILTER_USES_STDIO + fd = translate_sys2libc_fd (fd, for_write); +# else + { + int x; + + (void)for_write; + + 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 +#else + (void)for_write; +#endif + return fd; +} + + +void +iobuf_skip_rest (iobuf_t a, unsigned long n, int partial) +{ + if ( partial ) + { + for (;;) + { + if (a->nofast || a->d.start >= a->d.len) + { + if (iobuf_readbyte (a) == -1) + { + break; + } + } + else + { + unsigned long count = a->d.len - a->d.start; + a->nbytes += count; + a->d.start = a->d.len; + } + } + } + else + { + unsigned long remaining = n; + while (remaining > 0) + { + if (a->nofast || a->d.start >= a->d.len) + { + if (iobuf_readbyte (a) == -1) + { + break; + } + --remaining; + } + else + { + unsigned long count = a->d.len - a->d.start; + if (count > remaining) + { + count = remaining; + } + a->nbytes += count; + a->d.start += count; + remaining -= count; + } + } + } +} diff --git a/common/iobuf.h b/common/iobuf.h new file mode 100644 index 0000000..8a3671e --- /dev/null +++ b/common/iobuf.h @@ -0,0 +1,162 @@ +/* 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 3 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, see . + */ + +#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; +typedef struct iobuf_struct *IOBUF; /* Compatibility with gpg 1.4. */ + +/* 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 */ +}; + +#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); +int iobuf_is_pipe_filename (const char *fname); +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, void *buf, unsigned buflen); +void iobuf_unread (iobuf_t a, const unsigned char *buf, unsigned int 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, const void *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); + +off_t iobuf_get_filelength (iobuf_t a, int *overflow); +#define IOBUF_FILELENGTH_LIMIT 0xffffffff +int iobuf_get_fd (iobuf_t a); +const char *iobuf_get_real_fname (iobuf_t a); +const char *iobuf_get_fname (iobuf_t a); + +void iobuf_set_partial_block_mode (iobuf_t a, size_t len); + +void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); + + +/* 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/keyserver.h b/common/keyserver.h new file mode 100644 index 0000000..6455e8c --- /dev/null +++ b/common/keyserver.h @@ -0,0 +1,42 @@ +/* keyserver.h - Public definitions for gpg keyserver helpers. + * 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_KEYSERVER_H +#define GNUPG_COMMON_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 */ +#define KEYSERVER_TIMEOUT 10 /* timeout while accessing keyserver */ + +/* Must be 127 due to shell internal magic. */ +#define KEYSERVER_SCHEME_NOT_FOUND 127 + +#endif /*GNUPG_COMMON_KEYSERVER_H*/ diff --git a/common/localename.c b/common/localename.c new file mode 100644 index 0000000..cb7fcc2 --- /dev/null +++ b/common/localename.c @@ -0,0 +1,116 @@ +/* localename.c - Determine the current selected locale. + Copyright (C) 1995-1999, 2000-2003, 2007, + 2008 Free Software Foundation, Inc. + + This program 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, + 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 Lesser General Public + License along with this program; if not, see . +*/ +/* Written by Ulrich Drepper , 1995. */ +/* Win32 code written by Tor Lillqvist . */ +/* Modified for GpgOL use by Werner Koch , 2005. */ +/* Modified for GnuPG use by Werner Koch , 2007 */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif + +#include "../jnlib/w32help.h" + +/* 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 + +/* Use a dummy value for LC_MESSAGES in case it is not defined. This + works becuase we always test for HAVE_LC_MESSAGES and the core + fucntion takes the category as a string as well. */ +#ifndef HAVE_LC_MESSAGES +#define LC_MESSAGES 0 +#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. */ + +#ifndef HAVE_W32_SYSTEM +static const char * +do_nl_locale_name (int category, const char *categoryname) +{ + const char *retval; + + /* 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 + (void)categoryname; + 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; +} +#endif /* HAVE_W32_SYSTEM */ + + + +/* Return the locale used for translatable messages. The standard C + and POSIX are locale names are mapped to an empty string. If a + locale can't be found an empty string will be returned. */ +const char * +gnupg_messages_locale_name (void) +{ + const char *s; + +#ifdef HAVE_W32_SYSTEM + /* We use the localname function from ../jnlib/w32-gettext.c. */ + s = gettext_localename (); +#else + s = do_nl_locale_name (LC_MESSAGES, "LC_MESSAGES"); +#endif + if (!s) + s = ""; + else if (!strcmp (s, "C") || !strcmp (s, "POSIX")) + s = ""; + + return s; +} + diff --git a/common/membuf.c b/common/membuf.c new file mode 100644 index 0000000..737930b --- /dev/null +++ b/common/membuf.c @@ -0,0 +1,118 @@ +/* membuf.c - A simple implementation of a dynamic buffer. + * Copyright (C) 2001, 2003, 2009 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 3 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, see . + */ + +#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; +} + +/* Same as init_membuf but allocates the buffer in secure memory. */ +void +init_membuf_secure (membuf_t *mb, int initiallen) +{ + mb->len = 0; + mb->size = initiallen; + mb->out_of_core = 0; + mb->buf = xtrymalloc_secure (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 ? errno : ENOMEM; + /* Wipe out what we already accumulated. This is required + in case we are storing sensitive data here. The membuf + API does not provide another way to cleanup after an + error. */ + wipememory (mb->buf, mb->len); + return; + } + mb->buf = p; + } + memcpy (mb->buf + mb->len, buf, len); + mb->len += len; +} + + +void +put_membuf_str (membuf_t *mb, const char *string) +{ + put_membuf (mb, string, strlen (string)); +} + + +void * +get_membuf (membuf_t *mb, size_t *len) +{ + char *p; + + if (mb->out_of_core) + { + if (mb->buf) + { + wipememory (mb->buf, mb->len); + xfree (mb->buf); + mb->buf = NULL; + } + errno = mb->out_of_core; + return NULL; + } + + p = mb->buf; + if (len) + *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 new file mode 100644 index 0000000..75b506d --- /dev/null +++ b/common/membuf.h @@ -0,0 +1,47 @@ +/* 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 3 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, see . + */ + +#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; + +/* Return the current length of the membuf. */ +#define get_membuf_len(a) ((a)->len) +#define is_membuf_ready(a) ((a)->buf || (a)->out_of_core) +#define MEMBUF_ZERO { 0, 0, NULL, 0} + +void init_membuf (membuf_t *mb, int initiallen); +void init_membuf_secure (membuf_t *mb, int initiallen); +void put_membuf (membuf_t *mb, const void *buf, size_t len); +void put_membuf_str (membuf_t *mb, const char *string); +void *get_membuf (membuf_t *mb, size_t *len); + + +#endif /*GNUPG_COMMON_MEMBUF_H*/ diff --git a/common/miscellaneous.c b/common/miscellaneous.c new file mode 100644 index 0000000..1c88068 --- /dev/null +++ b/common/miscellaneous.c @@ -0,0 +1,241 @@ +/* miscellaneous.c - Stuff not fitting elsewhere + * Copyright (C) 2003, 2006 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 3 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, see . + */ + +#include +#include +#include + +#define JNLIB_NEED_LOG_LOGV +#include "util.h" +#include "iobuf.h" +#include "i18n.h" + + +/* Used by libgcrypt for logging. */ +static void +my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) +{ + (void)dummy; + + /* Map 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); +} + + +/* This function is called by libgcrypt on a fatal error. */ +static void +my_gcry_fatalerror_handler (void *opaque, int rc, const char *text) +{ + (void)opaque; + + log_fatal ("libgcrypt problem: %s\n", text ? text : gpg_strerror (rc)); + abort (); +} + + +/* This function is called by libgcrypt if it ran out of core and + there is no way to return that error to the caller. We do our own + function here to make use of our logging functions. */ +static int +my_gcry_outofcore_handler (void *opaque, size_t req_n, unsigned int flags) +{ + static int been_here; /* Used to protect against recursive calls. */ + + (void)opaque; + + if (!been_here) + { + been_here = 1; + if ( (flags & 1) ) + log_fatal (_("out of core in secure memory " + "while allocating %lu bytes"), (unsigned long)req_n); + else + log_fatal (_("out of core while allocating %lu bytes"), + (unsigned long)req_n); + } + return 0; /* Let libgcrypt call its own fatal error handler. + Actually this will turn out to be + my_gcry_fatalerror_handler. */ +} + + +/* Setup libgcrypt to use our own logging functions. Should be used + early at startup. */ +void +setup_libgcrypt_logging (void) +{ + gcry_set_log_handler (my_gcry_logger, NULL); + gcry_set_fatalerror_handler (my_gcry_fatalerror_handler, NULL); + gcry_set_outofcore_handler (my_gcry_outofcore_handler, NULL); +} + + + +/* 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; +} + +/* fixme: Globally replace it by print_sanitized_buffer. */ +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); +} + +/* Write LENGTH bytes of BUFFER to FP as a hex encoded string. + RESERVED must be 0. */ +void +print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved) +{ +#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) + const unsigned char *s; + + (void)reserved; + + for (s = buffer; length; s++, length--) + { + putc ( tohex ((*s>>4)&15), fp); + putc ( tohex (*s&15), fp); + } +#undef tohex +} + +char * +make_printable_string (const void *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; + int overflow; + + 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 ( iobuf_is_pipe_filename (s) || !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_syserror (); + return 0; + } + + if ( iobuf_get_filelength( a, &overflow ) < 4 && !overflow) { + *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; +} + + +/* Try match against each substring of multistr, delimited by | */ +int +match_multistr (const char *multistr,const char *match) +{ + do + { + size_t seglen = strcspn (multistr,"|"); + if (!seglen) + break; + /* Using the localized strncasecmp! */ + if (strncasecmp(multistr,match,seglen)==0) + return 1; + multistr += seglen; + if (*multistr == '|') + multistr++; + } + while (*multistr); + + return 0; +} + + diff --git a/common/mkstrtable.awk b/common/mkstrtable.awk new file mode 100644 index 0000000..56e9bb8 --- /dev/null +++ b/common/mkstrtable.awk @@ -0,0 +1,185 @@ +# mkstrtable.awk +# Copyright (C) 2003, 2004 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, see . +# +# As a special exception, g10 Code GmbH gives unlimited permission to +# copy, distribute and modify the C source files that are the output +# of mkstrtable.awk. You need not follow the terms of the GNU General +# Public License when using or distributing such scripts, even though +# portions of the text of mkstrtable.awk appear in them. The GNU +# General Public License (GPL) does govern all other use of the material +# that constitutes the mkstrtable.awk program. +# +# Certain portions of the mkstrtable.awk source text are designed to be +# copied (in certain cases, depending on the input) into the output of +# mkstrtable.awk. We call these the "data" portions. The rest of the +# mkstrtable.awk source text consists of comments plus executable code +# that decides which of the data portions to output in any given case. +# We call these comments and executable code the "non-data" portions. +# mkstrtable.h never copies any of the non-data portions into its output. +# +# This special exception to the GPL applies to versions of mkstrtable.awk +# released by g10 Code GmbH. When you make and distribute a modified version +# of mkstrtable.awk, you may extend this special exception to the GPL to +# apply to your modified version as well, *unless* your modified version +# has the potential to copy into its output some of the text that was the +# non-data portion of the version that you started with. (In other words, +# unless your change moves or copies text from the non-data portions to the +# data portions.) If your modification has such potential, you must delete +# any notice of this special exception to the GPL from your modified version. + +# This script outputs a source file that does define the following +# symbols: +# +# static const char msgstr[]; +# A string containing all messages in the list. +# +# static const int msgidx[]; +# A list of index numbers, one for each message, that points to the +# beginning of the string in msgstr. +# +# msgidxof (code); +# A macro that maps code numbers to idx numbers. If a DEFAULT MESSAGE +# is provided (see below), its index will be returned for unknown codes. +# Otherwise -1 is returned for codes that do not appear in the list. +# You can lookup the message with code CODE with: +# msgstr + msgidx[msgidxof (code)]. +# +# The input file has the following format: +# CODE1 ... MESSAGE1 (code nr, , something, , msg) +# CODE2 ... MESSAGE2 (code nr, , something, , msg) +# ... +# CODEn ... MESSAGEn (code nr, , something, , msg) +# ... DEFAULT-MESSAGE (, something, , fall-back msg) +# +# Comments (starting with # and ending at the end of the line) are removed, +# as is trailing whitespace. The last line is optional; if no DEFAULT +# MESSAGE is given, msgidxof will return the number -1 for unknown +# index numbers. +# +# The field to be used is specified with the variable "textidx" on +# the command line. It defaults to 2. +# +# The variable nogettext can be set to 1 to suppress gettext markers. +# +# The variable prefix can be used to prepend a string to each message. +# +# The variable namespace can be used to prepend a string to each +# variable and macro name. + +BEGIN { + FS = "[\t]+"; +# cpos holds the current position in the message string. + cpos = 0; +# msg holds the number of messages. + msg = 0; + print "/* Output of mkstrtable.awk. DO NOT EDIT. */"; + print ""; + header = 1; + if (textidx == 0) + textidx = 2; +# nogettext can be set to 1 to suppress gettext noop markers. +} + +/^#/ { next; } + +header { + if ($1 ~ /^[0123456789]+$/) + { + print "/* The purpose of this complex string table is to produce"; + print " optimal code with a minimum of relocations. */"; + print ""; + print "static const char " namespace "msgstr[] = "; + header = 0; + } + else + print; +} + +!header { + sub (/\#.+/, ""); + sub (/[ ]+$/, ""); # Strip trailing space and tab characters. + + if (/^$/) + next; + +# Print the string msgstr line by line. We delay output by one line to be able +# to treat the last line differently (see END). + if (last_msgstr) + { + if (nogettext) + print " \"" last_msgstr "\" \"\\0\""; + else + print " gettext_noop (\"" last_msgstr "\") \"\\0\""; + } + last_msgstr = prefix $textidx; + +# Remember the error code and msgidx of each error message. + code[msg] = $1; + pos[msg] = cpos; + cpos += length (last_msgstr) + 1; + msg++; + + if ($1 == "") + { + has_default = 1; + exit; + } +} +END { + if (has_default) + coded_msgs = msg - 1; + else + coded_msgs = msg; + + if (nogettext) + print " \"" prefix last_msgstr "\";"; + else + print " gettext_noop (\"" prefix last_msgstr "\");"; + print ""; + print "static const int " namespace "msgidx[] ="; + print " {"; + for (i = 0; i < coded_msgs; i++) + print " " pos[i] ","; + print " " pos[coded_msgs]; + print " };"; + print ""; + print "#define " namespace "msgidxof(code) (0 ? -1 \\"; + +# Gather the ranges. + skip = code[0]; + start = code[0]; + stop = code[0]; + for (i = 1; i < coded_msgs; i++) + { + if (code[i] == stop + 1) + stop++; + else + { + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + skip += code[i] - stop - 1; + start = code[i]; + stop = code[i]; + } + } + print " : ((code >= " start ") && (code <= " stop ")) ? (code - " \ + skip ") \\"; + if (has_default) + print " : " stop + 1 " - " skip ")"; + else + print " : -1)"; + + } diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h new file mode 100644 index 0000000..e8121b1 --- /dev/null +++ b/common/openpgpdefs.h @@ -0,0 +1,87 @@ +/* openpgpdefs.h - Constants from the OpenPGP standard (rfc2440) + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_OPENPGPDEFS_H +#define GNUPG_COMMON_OPENPGPDEFS_H + +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. */ + PKT_ONEPASS_SIG = 4, /* One pass sig packet. */ + PKT_SECRET_KEY = 5, /* Secret key. */ + PKT_PUBLIC_KEY = 6, /* Public key. */ + PKT_SECRET_SUBKEY = 7, /* Secret subkey. */ + PKT_COMPRESSED = 8, /* Compressed data packet. */ + PKT_ENCRYPTED = 9, /* Conventional encrypted data. */ + PKT_MARKER = 10, /* Marker packet. */ + PKT_PLAINTEXT = 11, /* Literal data packet. */ + PKT_RING_TRUST = 12, /* Keyring trust packet. */ + PKT_USER_ID = 13, /* User id packet. */ + PKT_PUBLIC_SUBKEY = 14, /* Public subkey. */ + 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 (GnuPG specific). */ + PKT_GPG_CONTROL = 63 /* internal control packet (GnuPG specific). */ + } +pkttype_t; + + +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_SIGNATURE = 32, /* Embedded signature. */ + + SIGSUBPKT_FLAG_CRITICAL = 128 + } +sigsubpkttype_t; + + +#endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ diff --git a/common/percent.c b/common/percent.c new file mode 100644 index 0000000..e0c3592 --- /dev/null +++ b/common/percent.c @@ -0,0 +1,229 @@ +/* percent.c - Percent escaping + * Copyright (C) 2008, 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" + + +/* Create a newly alloced string from STRING with all spaces and + control characters converted to plus signs or %xx sequences. The + function returns the new string or NULL in case of a malloc + failure. + + Note that we also escape the quote character to work around a bug + in the mingw32 runtime which does not correcty handle command line + quoting. We correctly double the quote mark when calling a program + (i.e. gpg-protect-tool), but the pre-main code does not notice the + double quote as an escaped quote. We do this also on POSIX systems + for consistency. */ +char * +percent_plus_escape (const char *string) +{ + char *buffer, *p; + const char *s; + size_t length; + + for (length=1, s=string; *s; s++) + { + if (*s == '+' || *s == '\"' || *s == '%' + || *(const unsigned char *)s < 0x20) + length += 3; + else + length++; + } + + buffer = p = xtrymalloc (length); + if (!buffer) + return NULL; + + for (s=string; *s; s++) + { + if (*s == '+' || *s == '\"' || *s == '%' + || *(const unsigned char *)s < 0x20) + { + snprintf (p, 4, "%%%02X", *(unsigned char *)s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; + + return buffer; + +} + + +/* Do the percent and plus/space unescaping from STRING to BUFFER and + return the length of the valid buffer. Plus unescaping is only + done if WITHPLUS is true. An escaped Nul character will be + replaced by NULREPL. */ +static size_t +do_unescape (unsigned char *buffer, const unsigned char *string, + int withplus, int nulrepl) +{ + unsigned char *p = buffer; + + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + *p = xtoi_2 (string); + if (!*p) + *p = nulrepl; + string++; + } + else if (*string == '+' && withplus) + *p = ' '; + else + *p = *string; + p++; + string++; + } + + return (p - buffer); +} + + +/* Count space required after unescaping STRING. Note that this will + never be larger than strlen (STRING). */ +static size_t +count_unescape (const unsigned char *string) +{ + size_t n = 0; + + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + string++; + } + string++; + n++; + } + + return n; +} + + +/* Helper. */ +static char * +do_plus_or_plain_unescape (const char *string, int withplus, int nulrepl) +{ + size_t nbytes, n; + char *newstring; + + nbytes = count_unescape (string); + newstring = xtrymalloc (nbytes+1); + if (newstring) + { + n = do_unescape (newstring, string, withplus, nulrepl); + assert (n == nbytes); + newstring[n] = 0; + } + return newstring; +} + + +/* Create a new allocated string from STRING with all "%xx" sequences + decoded and all plus signs replaced by a space. Embedded Nul + characters are replaced by the value of NULREPL. The function + returns the new string or NULL in case of a malloc failure. */ +char * +percent_plus_unescape (const char *string, int nulrepl) +{ + return do_plus_or_plain_unescape (string, 1, nulrepl); +} + + +/* Create a new allocated string from STRING with all "%xx" sequences + decoded. Embedded Nul characters are replaced by the value of + NULREPL. The function returns the new string or NULL in case of a + malloc failure. */ +char * +percent_unescape (const char *string, int nulrepl) +{ + return do_plus_or_plain_unescape (string, 0, nulrepl); +} + + +static size_t +do_unescape_inplace (char *string, int withplus, int nulrepl) +{ + unsigned char *p, *p0; + + p = p0 = string; + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + *p = xtoi_2 (string); + if (!*p) + *p = nulrepl; + string++; + } + else if (*string == '+' && withplus) + *p = ' '; + else + *p = *string; + p++; + string++; + } + + return (p - p0); +} + + +/* Perform percent and plus unescaping in STRING and return the new + valid length of the string. Embedded Nul characters are replaced + by the value of NULREPL. A terminating Nul character is not + inserted; the caller might want to call this function this way: + + foo[percent_plus_unescape_inplace (foo, 0)] = 0; + */ +size_t +percent_plus_unescape_inplace (char *string, int nulrepl) +{ + return do_unescape_inplace (string, 1, nulrepl); +} + + +/* Perform percent unescaping in STRING and return the new valid + length of the string. Embedded Nul characters are replaced by the + value of NULREPL. A terminating Nul character is not inserted; the + caller might want to call this function this way: + + foo[percent_unescape_inplace (foo, 0)] = 0; + */ +size_t +percent_unescape_inplace (char *string, int nulrepl) +{ + return do_unescape_inplace (string, 0, nulrepl); +} + diff --git a/common/pka.c b/common/pka.c new file mode 100644 index 0000000..918f19e --- /dev/null +++ b/common/pka.c @@ -0,0 +1,323 @@ +/* pka.c - DNS Public Key Association RR access + * Copyright (C) 2005, 2009 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 3 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, see . + */ + +#include + +#include +#include +#include + +#ifdef USE_DNS_PKA +#include +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif +#endif /* USE_DNS_PKA */ +#ifdef USE_ADNS +# include +# ifndef HAVE_ADNS_FREE +# define adns_free free +# endif +#endif + +#include "util.h" +#include "pka.h" + +#ifdef USE_DNS_PKA +/* Parse the TXT resource record. Format is: + + v=pka1;fpr=a4d94e92b0986ab5ee9dcd755de249965b0358a2;uri=string + + For simplicity white spaces are not allowed. Because we expect to + use a new RRTYPE for this in the future we define the TXT really + strict for simplicity: No white spaces, case sensitivity of the + names, order must be as given above. Only URI is optional. + + This function modifies BUFFER. On success 0 is returned, the 20 + byte fingerprint stored at FPR and BUFFER contains the URI or an + empty string. +*/ +static int +parse_txt_record (char *buffer, unsigned char *fpr) +{ + char *p, *pend; + int i; + + p = buffer; + pend = strchr (p, ';'); + if (!pend) + return -1; + *pend++ = 0; + if (strcmp (p, "v=pka1")) + return -1; /* Wrong or missing version. */ + + p = pend; + pend = strchr (p, ';'); + if (pend) + *pend++ = 0; + if (strncmp (p, "fpr=", 4)) + return -1; /* Missing fingerprint part. */ + p += 4; + for (i=0; i < 20 && hexdigitp (p) && hexdigitp (p+1); i++, p += 2) + fpr[i] = xtoi_2 (p); + if (i != 20) + return -1; /* Fingerprint consists not of exactly 40 hexbytes. */ + + p = pend; + if (!p || !*p) + { + *buffer = 0; + return 0; /* Success (no URI given). */ + } + if (strncmp (p, "uri=", 4)) + return -1; /* Unknown part. */ + p += 4; + /* There is an URI, copy it to the start of the buffer. */ + while (*p) + *buffer++ = *p++; + *buffer = 0; + return 0; +} + + +/* For the given email ADDRESS lookup the PKA information in the DNS. + + On success the 20 byte SHA-1 fingerprint is stored at FPR and the + URI will be returned in an allocated buffer. Note that the URI + might be an zero length string as this information is optional. + Caller must xfree the returned string. + + On error NULL is returned and the 20 bytes at FPR are not + defined. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ +#ifdef USE_ADNS + int rc; + adns_state state; + const char *domain; + char *name; + adns_answer *answer = NULL; + char *buffer = NULL; + + domain = strrchr (address, '@'); + if (!domain || domain == address || !domain[1]) + return NULL; /* Invalid mail address given. */ + name = xtrymalloc (strlen (address) + 5 + 1); + if (!name) + return NULL; + memcpy (name, address, domain - address); + strcpy (stpcpy (name + (domain-address), "._pka."), domain+1); + + rc = adns_init (&state, adns_if_noerrprint, NULL); + if (rc) + { + log_error ("error initializing adns: %s\n", strerror (errno)); + xfree (name); + return NULL; + } + + rc = adns_synchronous (state, name, adns_r_txt, adns_qf_quoteok_query, + &answer); + xfree (name); + if (rc) + { + log_error ("DNS query failed: %s\n", strerror (errno)); + adns_finish (state); + return NULL; + } + if (answer->status != adns_s_ok + || answer->type != adns_r_txt || !answer->nrrs) + { + /* log_error ("DNS query returned an error: %s (%s)\n", */ + /* adns_strerror (answer->status), */ + /* adns_errabbrev (answer->status)); */ + adns_free (answer); + adns_finish (state); + return NULL; + } + + /* We use a PKA records iff there is exactly one record. */ + if (answer->nrrs == 1 && answer->rrs.manyistr[0]->i != -1) + { + buffer = xtrystrdup (answer->rrs.manyistr[0]->str); + if (parse_txt_record (buffer, fpr)) + { + xfree (buffer); + buffer = NULL; /* Not a valid gpg trustdns RR. */ + } + } + + adns_free (answer); + adns_finish (state); + return buffer; + +#else /*!USE_ADNS*/ + union + { + signed char p[PACKETSZ]; + HEADER h; + } answer; + int anslen; + int qdcount, ancount; + int rc; + unsigned char *p, *pend; + const char *domain; + char *name; + + + domain = strrchr (address, '@'); + if (!domain || domain == address || !domain[1]) + return NULL; /* invalid mail address given. */ + + name = xtrymalloc (strlen (address) + 5 + 1); + if (!name) + return NULL; + memcpy (name, address, domain - address); + strcpy (stpcpy (name + (domain-address), "._pka."), domain+1); + + anslen = res_query (name, C_IN, T_TXT, answer.p, PACKETSZ); + xfree (name); + if (anslen < sizeof(HEADER)) + return NULL; /* DNS resolver returned a too short answer. */ + if ( (rc=answer.h.rcode) != NOERROR ) + return NULL; /* DNS resolver returned an error. */ + + /* We assume that PACKETSZ is large enough and don't do dynmically + expansion of the buffer. */ + if (anslen > PACKETSZ) + return NULL; /* DNS resolver returned a too long answer */ + + qdcount = ntohs (answer.h.qdcount); + ancount = ntohs (answer.h.ancount); + + if (!ancount) + return NULL; /* Got no answer. */ + + p = answer.p + sizeof (HEADER); + pend = answer.p + anslen; /* Actually points directly behind the buffer. */ + + while (qdcount-- && p < pend) + { + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc + QFIXEDSZ; + } + + if (ancount > 1) + return NULL; /* more than one possible gpg trustdns record - none used. */ + + while (ancount-- && p <= pend) + { + unsigned int type, class, txtlen, n; + char *buffer, *bufp; + + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc; + if (p >= pend - 10) + return NULL; /* RR too short. */ + + type = *p++ << 8; + type |= *p++; + class = *p++ << 8; + class |= *p++; + p += 4; + txtlen = *p++ << 8; + txtlen |= *p++; + if (type != T_TXT || class != C_IN) + return NULL; /* Answer does not match the query. */ + + buffer = bufp = xmalloc (txtlen + 1); + while (txtlen && p < pend) + { + for (n = *p++, txtlen--; txtlen && n && p < pend; txtlen--, n--) + *bufp++ = *p++; + } + *bufp = 0; + if (parse_txt_record (buffer, fpr)) + { + xfree (buffer); + return NULL; /* Not a valid gpg trustdns RR. */ + } + return buffer; + } + + return NULL; +#endif /*!USE_ADNS*/ +} + +#else /* !USE_DNS_PKA */ + +/* Dummy version of the function if we can't use the resolver + functions. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ + return NULL; +} +#endif /* !USE_DNS_PKA */ + + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + unsigned char fpr[20]; + char *uri; + int i; + + if (argc < 2) + { + fprintf (stderr, "usage: pka mail-addresses\n"); + return 1; + } + argc--; + argv++; + + for (; argc; argc--, argv++) + { + uri = get_pka_info ( *argv, fpr ); + printf ("%s", *argv); + if (uri) + { + putchar (' '); + for (i=0; i < 20; i++) + printf ("%02X", fpr[i]); + if (*uri) + printf (" %s", uri); + xfree (uri); + } + putchar ('\n'); + } + return 0; +} +#endif /* TEST */ + +/* +Local Variables: +compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv ../tools/no-libgcrypt.o ../jnlib/libjnlib.a" +End: +*/ diff --git a/common/pka.h b/common/pka.h new file mode 100644 index 0000000..98c29ec --- /dev/null +++ b/common/pka.h @@ -0,0 +1,25 @@ +/* pka.h - DNS Public Key Association RR access definitions + * Copyright (C) 2006 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 3 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, see . + */ +#ifndef GNUPG_COMMON_PKA_H +#define GNUPG_COMMON_PKA_H + +char *get_pka_info (const char *address, unsigned char *fpr); + + +#endif /*GNUPG_COMMON_PKA_H*/ diff --git a/common/session-env.c b/common/session-env.c new file mode 100644 index 0000000..10f5dfe --- /dev/null +++ b/common/session-env.c @@ -0,0 +1,385 @@ +/* se4ssiobn-env.c - session environment helper functions. + * Copyright (C) 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "session-env.h" + + +struct variable_s +{ + char *value; /* Pointer into NAME to the Nul terminated value. */ + int is_default; /* The value is a default one. */ + char name[1]; /* Nul terminated Name and space for the value. */ +}; + + + +/* The session environment object. */ +struct session_environment_s +{ + size_t arraysize; /* Allocated size or ARRAY. */ + size_t arrayused; /* Used size of ARRAY. */ + struct variable_s **array; /* Array of variables. NULL slots are unused. */ +}; + + +/* A list of environment vribales we pass from the acual user + (e.g. gpgme) down to the pinentry. We do not handle the locale + settings because they do not only depend on envvars. */ +static struct +{ + const char *name; + const char *assname; /* Name used by Assuan or NULL. */ +} stdenvnames[] = { + { "GPG_TTY", "ttyname" }, /* GnuPG specific envvar. */ + { "TERM", "ttytype" }, /* Used to set ttytype. */ + { "DISPLAY", "display" }, /* The X-Display. */ + { "XAUTHORITY","xauthority"}, /* Xlib Authentication. */ + { "XMODIFIERS" }, /* Used by Xlib to select X input + modules (eg "@im=SCIM"). */ + { "GTK_IM_MODULE" }, /* Used by gtk to select gtk input + modules (eg "scim-bridge"). */ + { "QT_IM_MODULE" }, /* Used by Qt to select qt input + modules (eg "xim"). */ + { "PINENTRY_USER_DATA", "pinentry-user-data"} + /* Used for communication with + non-standard Pinentries. */ +}; + + +/* Track last allocated arraysize of all objects ever created. If + nothing has ever been allocated we use INITIAL_ARRAYSIZE and we + will never use more than MAXDEFAULT_ARRAYSIZE for initial + allocation. Note that this is not reentrant if used with a + preemptive thread model. */ +static size_t lastallocatedarraysize; +#define INITIAL_ARRAYSIZE 8 /* Let's use the number of stdenvnames. */ +#define CHUNK_ARRAYSIZE 10 +#define MAXDEFAULT_ARRAYSIZE (INITIAL_ARRAYSIZE + CHUNK_ARRAYSIZE * 5) + + +/* Return the names of standard environment variables one after the + other. The caller needs to set the value at the address of + ITERATOR initally to 0 and then call this function until it returns + NULL. */ +const char * +session_env_list_stdenvnames (int *iterator, const char **r_assname) +{ + int idx = *iterator; + + if (idx < 0 || idx >= DIM (stdenvnames)) + return NULL; + *iterator = idx + 1; + if (r_assname) + *r_assname = stdenvnames[idx].assname; + return stdenvnames[idx].name; +} + + +/* Create a new session environment object. Return NULL and sets + ERRNO on failure. */ +session_env_t +session_env_new (void) +{ + session_env_t se; + + se = xtrycalloc (1, sizeof *se); + if (se) + { + se->arraysize = (lastallocatedarraysize? + lastallocatedarraysize : INITIAL_ARRAYSIZE); + se->array = xtrycalloc (se->arraysize, sizeof *se->array); + if (!se->array) + { + xfree (se); + se = NULL; + } + } + + return se; +} + + +/* Release a session environment object. */ +void +session_env_release (session_env_t se) +{ + int idx; + + if (!se) + return; + + if (se->arraysize > INITIAL_ARRAYSIZE + && se->arraysize <= MAXDEFAULT_ARRAYSIZE + && se->arraysize > lastallocatedarraysize) + lastallocatedarraysize = se->arraysize; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx]) + xfree (se->array[idx]); + xfree (se->array); + xfree (se); +} + + +static gpg_error_t +delete_var (session_env_t se, const char *name) +{ + int idx; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + xfree (se->array[idx]); + se->array[idx] = NULL; + } + return 0; +} + + +static gpg_error_t +update_var (session_env_t se, const char *string, size_t namelen, + const char *explicit_value, int set_default) +{ + int idx; + int freeidx = -1; + const char *value; + size_t valuelen; + struct variable_s *var; + + if (explicit_value) + value = explicit_value; + else + value = string + namelen + 1; + valuelen = strlen (value); + + for (idx=0; idx < se->arrayused; idx++) + { + if (!se->array[idx]) + freeidx = idx; + else if (!strncmp (se->array[idx]->name, string, namelen) + && strlen (se->array[idx]->name) == namelen) + { + if (strlen (se->array[idx]->value) == valuelen) + { + /* The new value has the same length. We can update it + in-place. */ + memcpy (se->array[idx]->value, value, valuelen); + se->array[idx]->is_default = !!set_default; + return 0; + } + /* Prepare for update. */ + freeidx = idx; + } + } + + if (freeidx == -1) + { + if (se->arrayused == se->arraysize) + { + /* Reallocate the array. */ + size_t newsize; + struct variable_s **newarray; + + newsize = se->arraysize + CHUNK_ARRAYSIZE; + newarray = xtrycalloc (newsize, sizeof *newarray); + if (!newarray) + return gpg_error_from_syserror (); + for (idx=0; idx < se->arrayused; idx++) + newarray[idx] = se->array[idx]; + se->arraysize = newsize; + xfree (se->array); + se->array = newarray; + } + freeidx = se->arrayused++; + } + + /* Allocate new memory and return an error if that didn't worked. + Allocating it first allows us to keep the old value; it doesn't + matter that arrayused has already been incremented in case of a + new entry - it will then pint to a NULL slot. */ + var = xtrymalloc (sizeof *var + namelen + 1 + valuelen); + if (!var) + return gpg_error_from_syserror (); + var->is_default = !!set_default; + memcpy (var->name, string, namelen); + var->name[namelen] = '\0'; + var->value = var->name + namelen + 1; + strcpy (var->value, value); + + xfree (se->array[freeidx]); + se->array[freeidx] = var; + return 0; +} + + +/* Set or update an environment variable of the session environment. + String is similar to the putval(3) function but it is reentrant and + takes a copy. In particular it exhibits this behaviour: + + Delete envvar NAME + = Set envvar NAME to the empty string + = Set envvar NAME to VALUE + + On success 0 is returned; on error an gpg-error code. */ +gpg_error_t +session_env_putenv (session_env_t se, const char *string) +{ + const char *s; + + if (!string || !*string) + return gpg_error (GPG_ERR_INV_VALUE); + s = strchr (string, '='); + if (s == string) + return gpg_error (GPG_ERR_INV_VALUE); + if (!s) + return delete_var (se, string); + else + return update_var (se, string, s - string, NULL, 0); +} + + +/* Same as session_env_putenv but with name and value given as distict + values. */ +gpg_error_t +session_env_setenv (session_env_t se, const char *name, const char *value) +{ + if (!name || !*name) + return gpg_error (GPG_ERR_INV_VALUE); + if (!value) + return delete_var (se, name); + else + return update_var (se, name, strlen (name), value, 0); +} + + + + +/* Return the value of the environment variable NAME from the SE + object. If the variable does not exist, NULL is returned. The + returned value is valid as long as SE is valid and as long it has + not been removed or updated by a call to session_env_putenv. The + caller MUST not change the returned value. */ +char * +session_env_getenv (session_env_t se, const char *name) +{ + int idx; + + if (!se || !name || !*name) + return NULL; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + return se->array[idx]->is_default? NULL : se->array[idx]->value; + return NULL; +} + + +/* Return the value of the environment variable NAME from the SE + object. The returned value is valid as long as SE is valid and as + long it has not been removed or updated by a call to + session_env_putenv. If the variable does not exist, the fucntion + tries to return the value trough a call to getenv; if that returns + a value, this value is recorded and and used. If no value could be + found, returns NULL. The caller must not change the returned + value. */ +char * +session_env_getenv_or_default (session_env_t se, const char *name, + int *r_default) +{ + int idx; + char *defvalue; + + if (r_default) + *r_default = 0; + if (!se || !name || !*name) + return NULL; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + if (r_default && se->array[idx]->is_default) + *r_default = 1; + return se->array[idx]->value; + } + + /* Get the default value with and additional fallback for GPG_TTY. */ + defvalue = getenv (name); + if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") && ttyname (0)) + defvalue = ttyname (0); + if (defvalue) + { + /* Record the default value for later use so that we are safe + from later modifications of the environment. We need to take + a copy to better cope with the rules of putenv(3). We ignore + the error of the update function because we can't return an + explicit error anyway and the following scan would then fail + anyway. */ + update_var (se, name, strlen (name), defvalue, 1); + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + if (r_default && se->array[idx]->is_default) + *r_default = 1; + return se->array[idx]->value; + } + } + + return NULL; +} + + +/* List the entire environment stored in SE. The caller initially + needs to set the value of ITERATOR to 0 and then call this function + until it returns NULL. The value is retruned at R_VALUE. If + R_DEFAULT is not NULL, the default flag is stored on return. The + default flag indicates that the value has been taken from the + process' environment. The caller must not change the returned + name or value. */ +char * +session_env_listenv (session_env_t se, int *iterator, + const char **r_value, int *r_default) +{ + int idx = *iterator; + + if (!se || idx < 0) + return NULL; + + for (; idx < se->arrayused; idx++) + if (se->array[idx]) + { + *iterator = idx+1; + if (r_default) + *r_default = se->array[idx]->is_default; + if (r_value) + *r_value = se->array[idx]->value; + return se->array[idx]->name; + } + return NULL; +} + + diff --git a/common/session-env.h b/common/session-env.h new file mode 100644 index 0000000..031fe1d --- /dev/null +++ b/common/session-env.h @@ -0,0 +1,43 @@ +/* session-env.h - Definitions for session environment functions + * Copyright (C) 2009 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_SESSION_ENV_H +#define GNUPG_COMMON_SESSION_ENV_H + +struct session_environment_s; +typedef struct session_environment_s *session_env_t; + +const char *session_env_list_stdenvnames (int *iterator, + const char **r_assname); + +session_env_t session_env_new (void); +void session_env_release (session_env_t se); + +gpg_error_t session_env_putenv (session_env_t se, const char *string); +gpg_error_t session_env_setenv (session_env_t se, + const char *name, const char *value); + +char *session_env_getenv (session_env_t se, const char *name); +char *session_env_getenv_or_default (session_env_t se, const char *name, + int *r_default); +char *session_env_listenv (session_env_t se, int *iterator, + const char **r_value, int *r_default); + + +#endif /*GNUPG_COMMON_SESSION_ENV_H*/ diff --git a/common/sexp-parse.h b/common/sexp-parse.h new file mode 100644 index 0000000..b3213a6 --- /dev/null +++ b/common/sexp-parse.h @@ -0,0 +1,128 @@ +/* sexp-parse.h - S-Exp helper functions + * Copyright (C) 2002, 2003, 2007 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 3 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, see . + */ + +#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 condition. */ +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; +} + +/* Format VALUE for use as the length indicatior of an S-expression. + The caller needs to provide a buffer HELP_BUFFER wth a length of + HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with + the formatted length string. The colon and a trailing nul are + appended. HELP_BUFLEN must be at least 3 - a more useful value is + 15. If LENGTH is not NULL, the LENGTH of the resulting string + (excluding the terminating nul) is stored at that address. */ +static inline char * +smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length) +{ + char *p = help_buffer + help_buflen; + + if (help_buflen >= 3) + { + *--p = 0; + *--p = ':'; + do + { + *--p = '0' + (value % 10); + value /= 10; + } + while (value && p > help_buffer); + } + + if (length) + *length = (help_buffer + help_buflen) - p; + return p; +} + + +#endif /*SEXP_PARSE_H*/ diff --git a/common/sexputil.c b/common/sexputil.c new file mode 100644 index 0000000..1e59187 --- /dev/null +++ b/common/sexputil.c @@ -0,0 +1,429 @@ +/* sexputil.c - Utility functions for S-expressions. + * Copyright (C) 2005, 2007, 2009 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 3 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, see . + */ + +/* This file implements a few utility functions useful when working + with canonical encrypted S-expresions (i.e. not the S-exprssion + objects from libgcrypt). */ + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif + +#include "util.h" +#include "tlv.h" +#include "sexp-parse.h" + + +/* Helper function to create a a canonical encoded S-expression from a + Libgcrypt S-expression object. The function returns 0 on success + and the malloced canonical S-expression is stored at R_BUFFER and + the allocated length at R_BUFLEN. On error an error code is + returned and (NULL, 0) stored at R_BUFFER and R_BUFLEN. If the + allocated buffer length is not required, NULL by be used for + R_BUFLEN. */ +gpg_error_t +make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen) +{ + size_t len; + unsigned char *buf; + + *r_buffer = NULL; + if (r_buflen) + *r_buflen = 0;; + + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); + if (!len) + return gpg_error (GPG_ERR_BUG); + buf = xtrymalloc (len); + if (!buf) + return gpg_error_from_syserror (); + len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len); + if (!len) + return gpg_error (GPG_ERR_BUG); + + *r_buffer = buf; + if (r_buflen) + *r_buflen = len; + + return 0; +} + + +/* Return the so called "keygrip" which is the SHA-1 hash of the + public key parameters expressed in a way depended on the algorithm. + + KEY is expected to be an canonical encoded S-expression with a + public or private key. KEYLEN is the length of that buffer. + + GRIP must be at least 20 bytes long. On success 0 is returned, on + error an error code. */ +gpg_error_t +keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, + unsigned char *grip) +{ + gpg_error_t err; + gcry_sexp_t sexp; + + if (!grip) + return gpg_error (GPG_ERR_INV_VALUE); + err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen); + if (err) + return err; + if (!gcry_pk_get_keygrip (sexp, grip)) + err = gpg_error (GPG_ERR_INTERNAL); + gcry_sexp_release (sexp); + return err; +} + + +/* Compare two simple S-expressions like "(3:foo)". Returns 0 if they + are identical or !0 if they are not. Not that this function can't + be used for sorting. */ +int +cmp_simple_canon_sexp (const unsigned char *a_orig, + const unsigned char *b_orig) +{ + const char *a = (const char *)a_orig; + const char *b = (const char *)b_orig; + unsigned long n1, n2; + char *endp; + + if (!a && !b) + return 0; /* Both are NULL, they are identical. */ + if (!a || !b) + return 1; /* One is NULL, they are not identical. */ + if (*a != '(' || *b != '(') + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + + a++; + n1 = strtoul (a, &endp, 10); + a = endp; + b++; + n2 = strtoul (b, &endp, 10); + b = endp; + + if (*a != ':' || *b != ':' ) + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + if (n1 != n2) + return 1; /* Not the same. */ + + for (a++, b++; n1; n1--, a++, b++) + if (*a != *b) + return 1; /* Not the same. */ + return 0; +} + + +/* Create a simple S-expression from the hex string at LIBNE. Returns + a newly allocated buffer with that canonical encoded S-expression + or NULL in case of an error. On return the number of characters + scanned in LINE will be stored at NSCANNED. This fucntions stops + converting at the first character not representing a hexdigit. Odd + numbers of hex digits are allowed; a leading zero is then + assumed. If no characters have been found, NULL is returned.*/ +unsigned char * +make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) +{ + size_t n, len; + const char *s; + unsigned char *buf; + unsigned char *p; + char numbuf[50], *numbufp; + size_t numbuflen; + + for (n=0, s=line; hexdigitp (s); s++, n++) + ; + if (nscanned) + *nscanned = n; + if (!n) + return NULL; + len = ((n+1) & ~0x01)/2; + numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen); + buf = xtrymalloc (1 + numbuflen + len + 1 + 1); + if (!buf) + return NULL; + buf[0] = '('; + p = (unsigned char *)stpcpy ((char *)buf+1, numbufp); + s = line; + if ((n&1)) + { + *p++ = xtoi_1 (s); + s++; + n--; + } + for (; n > 1; n -=2, s += 2) + *p++ = xtoi_2 (s); + *p++ = ')'; + *p = 0; /* (Not really neaded.) */ + + return buf; +} + + +/* Return the hash algorithm from a KSBA sig-val. SIGVAL is a + canonical encoded S-expression. Return 0 if the hash algorithm is + not encoded in SIG-VAL or it is not supported by libgcrypt. */ +int +hash_algo_from_sigval (const unsigned char *sigval) +{ + const unsigned char *s = sigval; + size_t n; + int depth; + char buffer[50]; + + if (!s || *s != '(') + return 0; /* Invalid S-expression. */ + s++; + n = snext (&s); + if (!n) + return 0; /* Invalid S-expression. */ + if (!smatch (&s, n, "sig-val")) + return 0; /* Not a sig-val. */ + if (*s != '(') + return 0; /* Invalid S-expression. */ + s++; + /* Skip over the algo+parameter list. */ + depth = 1; + if (sskip (&s, &depth) || depth) + return 0; /* Invalid S-expression. */ + if (*s != '(') + return 0; /* No futher list. */ + /* Check whether this is (hash ALGO). */ + s++; + n = snext (&s); + if (!n) + return 0; /* Invalid S-expression. */ + if (!smatch (&s, n, "hash")) + return 0; /* Not a "hash" keyword. */ + n = snext (&s); + if (!n || n+1 >= sizeof (buffer)) + return 0; /* Algorithm string is missing or too long. */ + memcpy (buffer, s, n); + buffer[n] = 0; + + return gcry_md_map_name (buffer); +} + + +/* Create a public key S-expression for an RSA public key from the + modulus M with length MLEN and the public exponent E with length + ELEN. Returns a newly allocated buffer of NULL in case of a memory + allocation problem. If R_LEN is not NULL, the length of the + canonical S-expression is stored there. */ +unsigned char * +make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen, + const void *e_arg, size_t elen, + size_t *r_len) +{ + const unsigned char *m = m_arg; + const unsigned char *e = e_arg; + int m_extra = 0; + int e_extra = 0; + char mlen_str[35]; + char elen_str[35]; + unsigned char *keybuf, *p; + const char const part1[] = "(10:public-key(3:rsa(1:n"; + const char const part2[] = ")(1:e"; + const char const part3[] = ")))"; + + /* Remove leading zeroes. */ + for (; mlen && !*m; mlen--, m++) + ; + for (; elen && !*e; elen--, e++) + ; + + /* Insert a leading zero if the number would be zero or interpreted + as negative. */ + if (!mlen || (m[0] & 0x80)) + m_extra = 1; + if (!elen || (e[0] & 0x80)) + e_extra = 1; + + /* Build the S-expression. */ + snprintf (mlen_str, sizeof mlen_str, "%u:", (unsigned int)mlen+m_extra); + snprintf (elen_str, sizeof elen_str, "%u:", (unsigned int)elen+e_extra); + + keybuf = xtrymalloc (strlen (part1) + strlen (mlen_str) + mlen + m_extra + + strlen (part2) + strlen (elen_str) + elen + e_extra + + strlen (part3) + 1); + if (!keybuf) + return NULL; + + p = stpcpy (keybuf, part1); + p = stpcpy (p, mlen_str); + if (m_extra) + *p++ = 0; + memcpy (p, m, mlen); + p += mlen; + p = stpcpy (p, part2); + p = stpcpy (p, elen_str); + if (e_extra) + *p++ = 0; + memcpy (p, e, elen); + p += elen; + p = stpcpy (p, part3); + + if (r_len) + *r_len = p - keybuf; + + return keybuf; +} + + +/* Return the so parameters of a public RSA key expressed as an + canonical encoded S-expression. */ +gpg_error_t +get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, + unsigned char const **r_n, size_t *r_nlen, + unsigned char const **r_e, size_t *r_elen) +{ + gpg_error_t err; + const unsigned char *buf, *tok; + size_t buflen, toklen; + int depth, last_depth1, last_depth2; + const unsigned char *rsa_n = NULL; + const unsigned char *rsa_e = NULL; + size_t rsa_n_len, rsa_e_len; + + *r_n = NULL; + *r_nlen = 0; + *r_e = NULL; + *r_elen = 0; + + buf = keydata; + buflen = keydatalen; + depth = 0; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen)) + return gpg_error (GPG_ERR_BAD_PUBKEY); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen)) + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + + last_depth1 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth1) + { + if (tok) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && toklen == 1) + { + const unsigned char **mpi; + size_t *mpi_len; + + switch (*tok) + { + case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; + case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; + default: mpi = NULL; mpi_len = NULL; break; + } + if (mpi && *mpi) + return gpg_error (GPG_ERR_DUP_VALUE); + + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && mpi) + { + /* Strip off leading zero bytes and save. */ + for (;toklen && !*tok; toklen--, tok++) + ; + *mpi = tok; + *mpi_len = toklen; + } + } + + /* Skip to the end of the list. */ + last_depth2 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth2) + ; + if (err) + return err; + } + + if (err) + return err; + + if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len) + return gpg_error (GPG_ERR_BAD_PUBKEY); + + *r_n = rsa_n; + *r_nlen = rsa_n_len; + *r_e = rsa_e; + *r_elen = rsa_e_len; + return 0; +} + + +/* Return the algo of a public RSA expressed as an canonical encoded + S-expression. On error the algo is set to 0. */ +gpg_error_t +get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, + int *r_algo) +{ + gpg_error_t err; + const unsigned char *buf, *tok; + size_t buflen, toklen; + int depth; + + *r_algo = 0; + + buf = keydata; + buflen = keydatalen; + depth = 0; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen)) + return gpg_error (GPG_ERR_BAD_PUBKEY); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok) + return gpg_error (GPG_ERR_BAD_PUBKEY); + + if (toklen == 3 && !memcmp ("rsa", tok, toklen)) + *r_algo = GCRY_PK_RSA; + else if (toklen == 3 && !memcmp ("dsa", tok, toklen)) + *r_algo = GCRY_PK_DSA; + else if (toklen == 3 && !memcmp ("elg", tok, toklen)) + *r_algo = GCRY_PK_ELG; + else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen)) + *r_algo = GCRY_PK_ECDSA; + else + return gpg_error (GPG_ERR_PUBKEY_ALGO); + + return 0; +} diff --git a/common/signal.c b/common/signal.c new file mode 100644 index 0000000..98859a4 --- /dev/null +++ b/common/signal.c @@ -0,0 +1,262 @@ +/* signal.c - signal handling + * Copyright (C) 1998, 1999, 2000, 2001, 2002, + * 2005 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" + + +#ifndef HAVE_DOSISH_SYSTEM +static volatile int caught_fatal_sig; +static volatile int caught_sigusr1; +#endif +static void (*cleanup_fnc)(void); + + +#ifndef HAVE_DOSISH_SYSTEM +static void +init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) +{ +# 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*/ + +#ifndef HAVE_DOSISH_SYSTEM +static const char * +get_signal_name( int signum ) +{ + /* Note that we can't use strsignal(), because it is not + reentrant. */ +#if HAVE_DECL_SYS_SIGLIST && defined(NSIG) + return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?"; +#else + return NULL; +#endif +} +#endif /*!HAVE_DOSISH_SYSTEM*/ + +#ifndef HAVE_DOSISH_SYSTEM +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, ": signal ", 9 ); + s = get_signal_name(sig); + if (s) + write (2, s, strlen(s) ); + else + { + /* We are in a signal handler so we can't use any kind of printf + even not sprintf. So we use a straightforward algorithm. We + got a report that on one particular system, raising a signal + while in this handler, the parameter SIG get sclobbered and + things are messed up because we modify its value. Although + this is a bug in that system, we will protect against it. */ + if (sig < 0 || sig >= 100000) + write (2, "?", 1); + else + { + int i, value, any=0; + + for (value=sig,i=10000; i; i /= 10) + { + if (value >= i || ((any || i==1) && !(value/i))) + { + write (2, "0123456789"+(value/i), 1); + if ((value/i)) + any = 1; + value %= i; + } + } + } + } + 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 ); +} +#endif /*!HAVE_DOSISH_SYSTEM*/ + +#ifndef HAVE_DOSISH_SYSTEM +static RETSIGTYPE +got_usr_signal (int sig) +{ + (void)sig; + caught_sigusr1 = 1; +} +#endif /*!HAVE_DOSISH_SYSTEM*/ + +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 new file mode 100644 index 0000000..3598b35 --- /dev/null +++ b/common/simple-pwquery.c @@ -0,0 +1,690 @@ +/* simple-pwquery.c - A simple password query client for gpg-agent + * Copyright (C) 2002, 2004, 2007 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 3 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, see . + */ + +/* 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 +#ifdef HAVE_W32_SYSTEM +#include +#else +#include +#include +#endif +#ifdef HAVE_LOCALE_H +#include +#endif + +#define JNLIB_NEED_AFLOCAL +#include "../jnlib/mischelp.h" +#ifdef HAVE_W32_SYSTEM +#include "../jnlib/w32-afunix.h" +#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 + + +/* Name of the socket to be used if GPG_AGENT_INFO has not been + set. No default socket is used if this is NULL. */ +static char *default_gpg_agent_info; + + + + + + +#ifndef HAVE_STPCPY +static char * +my_stpcpy(char *a,const char *b) +{ + while( *b ) + *a++ = *b++; + *a = 0; + + return (char*)a; +} +#define stpcpy(a,b) my_stpcpy((a), (b)) +#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) + { +#ifdef HAVE_W32_SYSTEM + nwritten = send (fd, buf, nleft, 0); +#else + nwritten = write (fd, buf, nleft); +#endif + 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) + { +#ifdef HAVE_W32_SYSTEM + int n = recv (fd, buf, nleft, 0); +#else + int n = read (fd, buf, nleft); +#endif + 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; + char *dft_xauthority = NULL; + char *dft_pinentry_user_data = 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"); +#ifndef HAVE_W32_SYSTEM + if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) + dft_ttyname = ttyname (0); +#endif + 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*/ + + /* Send the XAUTHORITY variable. */ + dft_xauthority = getenv ("XAUTHORITY"); + if (dft_xauthority) + { + /* We ignore errors here because older gpg-agents don't support + this option. */ + agent_send_option (fd, "xauthority", dft_xauthority); + } + + /* Send the PINENTRY_USER_DATA variable. */ + dft_pinentry_user_data = getenv ("PINENTRY_USER_DATA"); + if (dft_pinentry_user_data) + { + /* We ignore errors here because older gpg-agents don't support + this option. */ + agent_send_option (fd, "pinentry-user-data", dft_pinentry_user_data); + } + + 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 ) + infostr = default_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, PATHSEP_C)) || 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 != PATHSEP_C) + 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; + } + +#ifdef HAVE_W32_SYSTEM + fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); +#else + fd = socket (AF_UNIX, SOCK_STREAM, 0); +#endif + if (fd == -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 = SUN_LEN (&client_addr); + +#ifdef HAVE_W32_SYSTEM + rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len ); +#else + rc = connect (fd, (struct sockaddr*)&client_addr, len ); +#endif + if (rc == -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 = (unsigned char *)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; +} + + +/* Set the name of the default socket to NAME. */ +int +simple_pw_set_socket (const char *name) +{ + spwq_free (default_gpg_agent_info); + if (name) + { + default_gpg_agent_info = spwq_malloc (strlen (name) + 4 + 1); + if (!default_gpg_agent_info) + return SPWQ_OUT_OF_CORE; + /* We don't know the PID thus we use 0. */ + strcpy (stpcpy (default_gpg_agent_info, name), + PATHSEP_S "0" PATHSEP_S "1"); + } + else + default_gpg_agent_info = NULL; + + return 0; +} + + +/* Ask the gpg-agent for a passphrase and present the user with a + DESCRIPTION, a PROMPT and optionally 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 OPT_CHECK is true + gpg-agent is asked to apply some checks on the passphrase security. + If ERRORCODE is not NULL it should point a variable receiving an + errorcode; this error code 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 opt_check, + 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 + 10 + + 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; + if (opt_check) + p = stpcpy (p, "--check "); + 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') ) + || ((nread > 4 && !memcmp (pw, "ERR ", 4) + && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) ) + { + /* 111 is the old Assuan code for canceled which might still + be in use by old installations. 99 is GPG_ERR_CANCELED as + used by modern gpg-agents; 0xffff is used to mask out the + error source. */ +#ifdef SPWQ_USE_LOGGING + log_info (_("canceled by user\n") ); +#endif + *errorcode = 0; /* Special error code to indicate Cancel. */ + } + else if (nread > 4 && !memcmp (pw, "ERR ", 4)) + { + switch ( (strtoul (pw+4, NULL, 0) & 0xffff) ) + { + case 85: rc = SPWQ_NO_PIN_ENTRY; break; + default: rc = SPWQ_GENERAL_ERROR; break; + } + } + 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_secure_free (pw); + return result; +} + + +/* Ask the gpg-agent to clear the passphrase for the cache ID CACHEID. */ +int +simple_pwclear (const char *cacheid) +{ + char line[500]; + char *p; + + /* We need not more than 50 characters for the command and the + terminating nul. */ + if (strlen (cacheid) * 3 > sizeof (line) - 50) + return SPWQ_PROTOCOL_ERROR; + + strcpy (line, "CLEAR_PASSPHRASE "); + p = line + 17; + p = copy_and_escape (p, cacheid); + *p++ = '\n'; + *p++ = '\0'; + + return simple_query (line); +} + + +/* Perform the simple query QUERY (which must be new-line and 0 + terminated) and return the error code. */ +int +simple_query (const char *query) +{ + int fd = -1; + int nread; + char response[500]; + int rc; + + rc = agent_open (&fd); + if (rc) + goto leave; + + rc = writen (fd, query, strlen (query)); + if (rc) + goto leave; + + /* get response */ + nread = readline (fd, response, 499); + if (nread < 0) + { + rc = -nread; + goto leave; + } + if (nread < 3) + { + rc = SPWQ_PROTOCOL_ERROR; + goto leave; + } + + if (response[0] == 'O' && response[1] == 'K') + /* OK, do nothing. */; + else if ((nread > 7 && !memcmp (response, "ERR 111", 7) + && (response[7] == ' ' || response[7] == '\n') ) + || ((nread > 4 && !memcmp (response, "ERR ", 4) + && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) + { + /* 111 is the old Assuan code for canceled which might still + be in use by old installations. 99 is GPG_ERR_CANCELED as + used by modern gpg-agents; 0xffff is used to mask out the + error source. */ +#ifdef SPWQ_USE_LOGGING + log_info (_("canceled by user\n") ); +#endif + } + else + { +#ifdef SPWQ_USE_LOGGING + log_error (_("problem with the agent\n")); +#endif + rc = SPWQ_ERR_RESPONSE; + } + + leave: + if (fd != -1) + close (fd); + return rc; +} diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h new file mode 100644 index 0000000..8de9b1b --- /dev/null +++ b/common/simple-pwquery.h @@ -0,0 +1,115 @@ +/* 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 3 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, see . + */ + +#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 OPT_CHECK is true + gpg-agent is asked to apply some checks on the passphrase security. + 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 opt_check, + int *errorcode); + +/* Ask the gpg-agent to clear the passphrase for the cache ID CACHEID. */ +int simple_pwclear (const char *cacheid); + +/* Perform the simple query QUERY (which must be new-line and 0 + terminated) and return the error code. */ +int simple_query (const char *query); + +/* Set the name of the standard socket to be used if GPG_AGENT_INFO is + not defined. The use of this function is optional but if it needs + to be called before any other function. Returns 0 on success. */ +int simple_pw_set_socket (const char *name); + +#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 +#define SPWQ_NO_PIN_ENTRY 8 + + +/* We often need to map error codes to gpg-error style error codes. + To have a consistent mapping this macro may be used to implemt the + mapping function. */ +#define MAP_SPWQ_ERROR_IMPL \ + static gpg_error_t \ + map_spwq_error (int err) \ + { \ + switch (err) \ + { \ + case 0: \ + return 0; \ + case SPWQ_OUT_OF_CORE: \ + return gpg_error_from_errno (ENOMEM); \ + case SPWQ_IO_ERROR: \ + return gpg_error_from_errno (EIO); \ + case SPWQ_PROTOCOL_ERROR: \ + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); \ + case SPWQ_ERR_RESPONSE: \ + return gpg_error (GPG_ERR_INV_RESPONSE); \ + case SPWQ_NO_AGENT: \ + return gpg_error (GPG_ERR_NO_AGENT); \ + case SPWQ_SYS_ERROR: \ + return gpg_error_from_syserror (); \ + case SPWQ_NO_PIN_ENTRY: \ + return gpg_error (GPG_ERR_NO_PIN_ENTRY); \ + case SPWQ_GENERAL_ERROR: \ + default: \ + return gpg_error (GPG_ERR_GENERAL); \ + } \ + } +/* End of MAP_SPWQ_ERROR_IMPL. */ + + +#endif /*SIMPLE_PWQUERY_H*/ diff --git a/common/srv.c b/common/srv.c new file mode 100644 index 0000000..f3831b4 --- /dev/null +++ b/common/srv.c @@ -0,0 +1,321 @@ +/* srv.c - DNS SRV code + * Copyright (C) 2003, 2009 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 3 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, see . + */ + +#include +#include +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif +#include +#include +#include +#include +#ifdef USE_ADNS +# include +# ifndef HAVE_ADNS_FREE +# define adns_free free +# endif +#endif + +#include "util.h" +#include "srv.h" + +/* Not every installation has gotten around to supporting SRVs + yet... */ +#ifndef T_SRV +#define T_SRV 33 +#endif + +static int +priosort(const void *a,const void *b) +{ + const struct srventry *sa=a,*sb=b; + if(sa->priority>sb->priority) + return 1; + else if(sa->prioritypriority) + return -1; + else + return 0; +} + + +int +getsrv (const char *name,struct srventry **list) +{ + int srvcount=0; + u16 count; + int i, rc; + + *list = NULL; + +#ifdef USE_ADNS + { + adns_state state; + adns_answer *answer = NULL; + + rc = adns_init (&state, adns_if_noerrprint, NULL); + if (rc) + { + log_error ("error initializing adns: %s\n", strerror (errno)); + return -1; + } + + rc = adns_synchronous (state, name, adns_r_srv, adns_qf_quoteok_query, + &answer); + if (rc) + { + log_error ("DNS query failed: %s\n", strerror (errno)); + adns_finish (state); + return -1; + } + if (answer->status != adns_s_ok + || answer->type != adns_r_srv || !answer->nrrs) + { + /* log_error ("DNS query returned an error or no records: %s (%s)\n", */ + /* adns_strerror (answer->status), */ + /* adns_errabbrev (answer->status)); */ + adns_free (answer); + adns_finish (state); + return 0; + } + + for (count = 0; count < answer->nrrs; count++) + { + struct srventry *srv = NULL; + struct srventry *newlist; + + if (strlen (answer->rrs.srvha[count].ha.host) >= MAXDNAME) + { + log_info ("hostname in SRV record too long - skipped\n"); + continue; + } + + newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry)); + if (!newlist) + goto fail; + *list = newlist; + memset (&(*list)[srvcount], 0, sizeof(struct srventry)); + srv = &(*list)[srvcount]; + srvcount++; + + srv->priority = answer->rrs.srvha[count].priority; + srv->weight = answer->rrs.srvha[count].weight; + srv->port = answer->rrs.srvha[count].port; + strcpy (srv->target, answer->rrs.srvha[count].ha.host); + } + + adns_free (answer); + adns_finish (state); + } +#else /*!USE_ADNS*/ + { + unsigned char answer[2048]; + HEADER *header = (HEADER *)answer; + unsigned char *pt, *emsg; + int r; + u16 dlen; + + r = res_query (name, C_IN, T_SRV, answer, sizeof answer); + if (r < sizeof (HEADER) || r > sizeof answer) + return -1; + if (header->rcode != NOERROR || !(count=ntohs (header->ancount))) + return 0; /* Error or no record found. */ + + emsg = &answer[r]; + pt = &answer[sizeof(HEADER)]; + + /* Skip over the query */ + rc = dn_skipname (pt, emsg); + if (rc == -1) + goto fail; + + pt += rc + QFIXEDSZ; + + while (count-- > 0 && pt < emsg) + { + struct srventry *srv=NULL; + u16 type,class; + struct srventry *newlist; + + newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry)); + if (!newlist) + goto fail; + *list = newlist; + memset(&(*list)[srvcount],0,sizeof(struct srventry)); + srv=&(*list)[srvcount]; + srvcount++; + + rc = dn_skipname(pt,emsg); /* the name we just queried for */ + if (rc == -1) + goto fail; + pt+=rc; + + /* Truncated message? */ + if((emsg-pt)<16) + goto fail; + + type=*pt++ << 8; + type|=*pt++; + /* We asked for SRV and got something else !? */ + if(type!=T_SRV) + goto fail; + + class=*pt++ << 8; + class|=*pt++; + /* We asked for IN and got something else !? */ + if(class!=C_IN) + goto fail; + + pt+=4; /* ttl */ + dlen=*pt++ << 8; + dlen|=*pt++; + srv->priority=*pt++ << 8; + srv->priority|=*pt++; + srv->weight=*pt++ << 8; + srv->weight|=*pt++; + srv->port=*pt++ << 8; + srv->port|=*pt++; + + /* Get the name. 2782 doesn't allow name compression, but + dn_expand still works to pull the name out of the + packet. */ + rc = dn_expand(answer,emsg,pt,srv->target,MAXDNAME); + if (rc == 1 && srv->target[0] == 0) /* "." */ + { + xfree(*list); + *list = NULL; + return 0; + } + if (rc == -1) + goto fail; + pt += rc; + /* Corrupt packet? */ + if (dlen != rc+6) + goto fail; + } + } +#endif /*!USE_ADNS*/ + + /* Now we have an array of all the srv records. */ + + /* Order by priority */ + qsort(*list,srvcount,sizeof(struct srventry),priosort); + + /* For each priority, move the zero-weighted items first. */ + for (i=0; i < srvcount; i++) + { + int j; + + for (j=i;j < srvcount && (*list)[i].priority == (*list)[j].priority; j++) + { + if((*list)[j].weight==0) + { + /* Swap j with i */ + if(j!=i) + { + struct srventry temp; + + memcpy (&temp,&(*list)[j],sizeof(struct srventry)); + memcpy (&(*list)[j],&(*list)[i],sizeof(struct srventry)); + memcpy (&(*list)[i],&temp,sizeof(struct srventry)); + } + + break; + } + } + } + + /* Run the RFC-2782 weighting algorithm. We don't need very high + quality randomness for this, so regular libc srand/rand is + sufficient. Fixme: It is a bit questionaly to reinitalize srand + - better use a gnupg fucntion for this. */ + srand(time(NULL)*getpid()); + + for (i=0; i < srvcount; i++) + { + int j; + float prio_count=0,chose; + + for (j=i; j < srvcount && (*list)[i].priority == (*list)[j].priority; j++) + { + prio_count+=(*list)[j].weight; + (*list)[j].run_count=prio_count; + } + + chose=prio_count*rand()/RAND_MAX; + + for (j=i;j. + */ + +#ifndef GNUPG_COMMON_SRV_H +#define GNUPG_COMMON_SRV_H + +#ifdef USE_DNS_SRV +# ifdef _WIN32 +# include +# else +# include +# include +# include +# endif /* !_WIN32 */ +#endif /* USE_DNS_SRV */ + + +#ifndef MAXDNAME +#define MAXDNAME 1025 +#endif + +struct srventry +{ + unsigned short priority; + unsigned short weight; + unsigned short port; + int run_count; + char target[MAXDNAME]; +}; + +int getsrv(const char *name,struct srventry **list); + +#endif /*GNUPG_COMMON_SRV_H*/ diff --git a/common/ssh-utils.c b/common/ssh-utils.c new file mode 100644 index 0000000..e2de802 --- /dev/null +++ b/common/ssh-utils.c @@ -0,0 +1,187 @@ +/* ssh-utils.c - Secure Shell helper functions + * Copyright (C) 2011 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "ssh-utils.h" + + + +/* Return the Secure Shell type fingerprint for KEY. The length of + the fingerprint is returned at R_LEN and the fingerprint itself at + R_FPR. In case of a error code is returned and NULL stored at + R_FPR. This function is usually called via the ssh_get_fingerprint + macro which makes sure to use the correct value for ERRSOURCE. */ +static gpg_error_t +get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, + gpg_err_source_t errsource, int as_string) +{ + gpg_error_t err; + gcry_sexp_t list = NULL; + gcry_sexp_t l2 = NULL; + const char *s; + char *name = NULL; + int idx; + const char *elems; + gcry_md_hd_t md = NULL; + + *r_fpr = NULL; + *r_len = 0; + + /* Check that the first element is valid. */ + list = gcry_sexp_find_token (key, "public-key", 0); + if (!list) + list = gcry_sexp_find_token (key, "private-key", 0); + if (!list) + list = gcry_sexp_find_token (key, "protected-private-key", 0); + if (!list) + list = gcry_sexp_find_token (key, "shadowed-private-key", 0); + if (!list) + { + err = gpg_err_make (errsource, GPG_ERR_UNKNOWN_SEXP); + goto leave; + } + + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + l2 = NULL; + + name = gcry_sexp_nth_string (list, 0); + if (!name) + { + err = gpg_err_make (errsource, GPG_ERR_INV_SEXP); + goto leave; + } + + err = gcry_md_open (&md, GCRY_MD_MD5, 0); + if (err) + goto leave; + + switch (gcry_pk_map_name (name)) + { + case GCRY_PK_RSA: + elems = "en"; + gcry_md_write (md, "\0\0\0\x07ssh-rsa", 11); + break; + case GCRY_PK_DSA: + elems = "pqgy"; + gcry_md_write (md, "\0\0\0\x07ssh-dss", 11); + break; + default: + elems = ""; + err = gpg_err_make (errsource, GPG_ERR_PUBKEY_ALGO); + break; + } + if (err) + goto leave; + + for (idx = 0, s = elems; *s; s++, idx++) + { + gcry_mpi_t a; + unsigned char *buf; + size_t buflen; + + l2 = gcry_sexp_find_token (list, s, 1); + if (!l2) + { + err = gpg_err_make (errsource, GPG_ERR_INV_SEXP); + goto leave; + } + a = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l2); + l2 = NULL; + if (!a) + { + err = gpg_err_make (errsource, GPG_ERR_INV_SEXP); + goto leave; + } + + err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, &buf, &buflen, a); + gcry_mpi_release (a); + if (err) + goto leave; + gcry_md_write (md, buf, buflen); + gcry_free (buf); + } + + *r_fpr = gcry_malloc (as_string? 61:20); + if (!*r_fpr) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + goto leave; + } + + if (as_string) + { + bin2hexcolon (gcry_md_read (md, GCRY_MD_MD5), 16, *r_fpr); + *r_len = 3*16+1; + strlwr (*r_fpr); + } + else + { + memcpy (*r_fpr, gcry_md_read (md, GCRY_MD_MD5), 16); + *r_len = 16; + } + err = 0; + + leave: + gcry_free (name); + gcry_sexp_release (l2); + gcry_md_close (md); + gcry_sexp_release (list); + return err; +} + +/* Return the Secure Shell type fingerprint for KEY. The length of + the fingerprint is returned at R_LEN and the fingerprint itself at + R_FPR. In case of an error an error code is returned and NULL + stored at R_FPR. This function is usually called via the + ssh_get_fingerprint macro which makes sure to use the correct value + for ERRSOURCE. */ +gpg_error_t +_ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, + gpg_err_source_t errsource) +{ + return get_fingerprint (key, r_fpr, r_len, errsource, 0); +} + + +/* Return the Secure Shell type fingerprint for KEY as a string. The + fingerprint is mallcoed and stored at R_FPRSTR. In case of an + error an error code is returned and NULL stored at R_FPRSTR. This + function is usually called via the ssh_get_fingerprint_string macro + which makes sure to use the correct value for ERRSOURCE. */ +gpg_error_t +_ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr, + gpg_err_source_t errsource) +{ + gpg_error_t err; + size_t dummy; + void *string; + + err = get_fingerprint (key, &string, &dummy, errsource, 1); + *r_fprstr = string; + return err; +} diff --git a/common/ssh-utils.h b/common/ssh-utils.h new file mode 100644 index 0000000..1813c8b --- /dev/null +++ b/common/ssh-utils.h @@ -0,0 +1,36 @@ +/* ssh-utils.c - Secure Shell helper function definitions + * Copyright (C) 2011 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_SSH_UTILS_H +#define GNUPG_COMMON_SSH_UTILS_H + + +gpg_error_t _ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, + gpg_err_source_t errsource); +#define ssh_get_fingerprint(a,b,c) \ + _ssh_get_fingerprint ((a), (b), (c), GPG_ERR_SOURCE_DEFAULT) + +gpg_error_t _ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr, + gpg_err_source_t errsource); +#define ssh_get_fingerprint_string(a,b) \ + _ssh_get_fingerprint_string ((a), (b), GPG_ERR_SOURCE_DEFAULT) + + + +#endif /*GNUPG_COMMON_SSH_UTILS_H*/ diff --git a/common/status-codes.h b/common/status-codes.h new file mode 100644 index 0000000..5f59b49 --- /dev/null +++ b/common/status-codes.h @@ -0,0 +1,206 @@ +/* Output of mkstrtable.awk. DO NOT EDIT. */ + +/* status.h - Status codes + * Copyright (C) 2007 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 3 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, see . + */ + +/* The purpose of this complex string table is to produce + optimal code with a minimum of relocations. */ + +static const char statusstr_msgstr[] = + "ENTER" "\0" + "LEAVE" "\0" + "ABORT" "\0" + "GOODSIG" "\0" + "BADSIG" "\0" + "ERRSIG" "\0" + "BADARMOR" "\0" + "RSA_OR_IDEA" "\0" + "TRUST_UNDEFINED" "\0" + "TRUST_NEVER" "\0" + "TRUST_MARGINAL" "\0" + "TRUST_FULLY" "\0" + "TRUST_ULTIMATE" "\0" + "NEED_PASSPHRASE" "\0" + "VALIDSIG" "\0" + "SIG_ID" "\0" + "ENC_TO" "\0" + "NODATA" "\0" + "BAD_PASSPHRASE" "\0" + "NO_PUBKEY" "\0" + "NO_SECKEY" "\0" + "NEED_PASSPHRASE_SYM" "\0" + "DECRYPTION_INFO" "\0" + "DECRYPTION_FAILED" "\0" + "DECRYPTION_OKAY" "\0" + "MISSING_PASSPHRASE" "\0" + "GOOD_PASSPHRASE" "\0" + "GOODMDC" "\0" + "BADMDC" "\0" + "ERRMDC" "\0" + "IMPORTED" "\0" + "IMPORT_OK" "\0" + "IMPORT_PROBLEM" "\0" + "IMPORT_RES" "\0" + "IMPORT_CHECK" "\0" + "FILE_START" "\0" + "FILE_DONE" "\0" + "FILE_ERROR" "\0" + "BEGIN_DECRYPTION" "\0" + "END_DECRYPTION" "\0" + "BEGIN_ENCRYPTION" "\0" + "END_ENCRYPTION" "\0" + "BEGIN_SIGNING" "\0" + "DELETE_PROBLEM" "\0" + "GET_BOOL" "\0" + "GET_LINE" "\0" + "GET_HIDDEN" "\0" + "GOT_IT" "\0" + "PROGRESS" "\0" + "SIG_CREATED" "\0" + "SESSION_KEY" "\0" + "NOTATION_NAME" "\0" + "NOTATION_DATA" "\0" + "POLICY_URL" "\0" + "BEGIN_STREAM" "\0" + "END_STREAM" "\0" + "KEY_CREATED" "\0" + "USERID_HINT" "\0" + "UNEXPECTED" "\0" + "INV_RECP" "\0" + "INV_SGNR" "\0" + "NO_RECP" "\0" + "NO_SGNR" "\0" + "ALREADY_SIGNED" "\0" + "KEYEXPIRED" "\0" + "KEYREVOKED" "\0" + "SIGEXPIRED" "\0" + "EXPSIG" "\0" + "EXPKEYSIG" "\0" + "ATTRIBUTE" "\0" + "REVKEYSIG" "\0" + "NEWSIG" "\0" + "SIG_SUBPACKET" "\0" + "PLAINTEXT" "\0" + "PLAINTEXT_LENGTH" "\0" + "KEY_NOT_CREATED" "\0" + "NEED_PASSPHRASE_PIN" "\0" + "CARDCTRL" "\0" + "SC_OP_FAILURE" "\0" + "SC_OP_SUCCESS" "\0" + "BACKUP_KEY_CREATED" "\0" + "PKA_TRUST_BAD" "\0" + "PKA_TRUST_GOOD" "\0" + "TRUNCATED" "\0" + "ERROR" "\0" + "SUCCESS"; + +static const int statusstr_msgidx[] = + { + 0, + 6, + 12, + 18, + 26, + 33, + 40, + 49, + 61, + 77, + 89, + 104, + 116, + 131, + 147, + 156, + 163, + 170, + 177, + 192, + 202, + 212, + 232, + 248, + 266, + 282, + 301, + 317, + 325, + 332, + 339, + 348, + 358, + 373, + 384, + 397, + 408, + 418, + 429, + 446, + 461, + 478, + 493, + 507, + 522, + 531, + 540, + 551, + 558, + 567, + 579, + 591, + 605, + 619, + 630, + 643, + 654, + 666, + 678, + 689, + 698, + 707, + 715, + 723, + 738, + 749, + 760, + 771, + 778, + 788, + 798, + 808, + 815, + 829, + 839, + 856, + 872, + 892, + 901, + 915, + 929, + 948, + 962, + 977, + 987, + 993, + + }; + +#define statusstr_msgidxof(code) (0 ? -1 \ + : ((code >= 0) && (code <= 85)) ? (code - 0) \ + : -1) diff --git a/common/status.c b/common/status.c new file mode 100644 index 0000000..7b9f4a3 --- /dev/null +++ b/common/status.c @@ -0,0 +1,66 @@ +/* status.c - status code helper functions + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include + +#include "util.h" +#include "status.h" +#include "status-codes.h" + + +/* Return the status string for code NO. */ +const char * +get_status_string ( int no ) +{ + int idx = statusstr_msgidxof (no); + if (idx == -1) + return "?"; + else + return statusstr_msgstr + statusstr_msgidx[idx]; +} + + +const char * +get_inv_recpsgnr_code (gpg_error_t err) +{ + const char *errstr; + + switch (gpg_err_code (err)) + { + case GPG_ERR_NO_PUBKEY: errstr = "1"; break; + case GPG_ERR_AMBIGUOUS_NAME: errstr = "2"; break; + case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break; + case GPG_ERR_CERT_REVOKED: errstr = "4"; break; + case GPG_ERR_CERT_EXPIRED: errstr = "5"; break; + case GPG_ERR_NO_CRL_KNOWN: errstr = "6"; break; + case GPG_ERR_CRL_TOO_OLD: errstr = "7"; break; + case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break; + + case GPG_ERR_UNUSABLE_SECKEY: + case GPG_ERR_NO_SECKEY: errstr = "9"; break; + + case GPG_ERR_NOT_TRUSTED: errstr = "10"; break; + case GPG_ERR_MISSING_CERT: errstr = "11"; break; + case GPG_ERR_MISSING_ISSUER_CERT: errstr = "12"; break; + default: errstr = "0"; break; + } + + return errstr; +} diff --git a/common/status.h b/common/status.h new file mode 100644 index 0000000..cfb64ca --- /dev/null +++ b/common/status.h @@ -0,0 +1,137 @@ +/* status.h - Status codes + * Copyright (C) 2007 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_STATUS_H +#define GNUPG_COMMON_STATUS_H + +enum + { + STATUS_ENTER, + STATUS_LEAVE, + STATUS_ABORT, + + STATUS_GOODSIG, + STATUS_BADSIG, + STATUS_ERRSIG, + + STATUS_BADARMOR, + + STATUS_RSA_OR_IDEA, + + STATUS_TRUST_UNDEFINED, + STATUS_TRUST_NEVER, + STATUS_TRUST_MARGINAL, + STATUS_TRUST_FULLY, + STATUS_TRUST_ULTIMATE, + + 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_INFO, + 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_IMPORT_CHECK, + + STATUS_FILE_START, + STATUS_FILE_DONE, + STATUS_FILE_ERROR, + + STATUS_BEGIN_DECRYPTION, + STATUS_END_DECRYPTION, + STATUS_BEGIN_ENCRYPTION, + STATUS_END_ENCRYPTION, + STATUS_BEGIN_SIGNING, + + 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_HINT, + STATUS_UNEXPECTED, + STATUS_INV_RECP, + STATUS_INV_SGNR, + STATUS_NO_RECP, + STATUS_NO_SGNR, + + STATUS_ALREADY_SIGNED, + STATUS_KEYEXPIRED, + STATUS_KEYREVOKED, + STATUS_SIGEXPIRED, + STATUS_EXPSIG, + STATUS_EXPKEYSIG, + + STATUS_ATTRIBUTE, + + STATUS_REVKEYSIG, + + STATUS_NEWSIG, + STATUS_SIG_SUBPACKET, + + STATUS_PLAINTEXT, + STATUS_PLAINTEXT_LENGTH, + STATUS_KEY_NOT_CREATED, + STATUS_NEED_PASSPHRASE_PIN, + + STATUS_CARDCTRL, + STATUS_SC_OP_FAILURE, + STATUS_SC_OP_SUCCESS, + + STATUS_BACKUP_KEY_CREATED, + + STATUS_PKA_TRUST_BAD, + STATUS_PKA_TRUST_GOOD, + + STATUS_TRUNCATED, + STATUS_ERROR, + STATUS_SUCCESS +}; + + +const char *get_status_string (int code); +const char *get_inv_recpsgnr_code (gpg_error_t err); + + +#endif /*GNUPG_COMMON_STATUS_H*/ diff --git a/common/sysutils.c b/common/sysutils.c new file mode 100644 index 0000000..8e0c75c --- /dev/null +++ b/common/sysutils.c @@ -0,0 +1,492 @@ +/* sysutils.c - system helpers + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, + * 2007, 2008 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 3 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, see . + */ + +#include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +# undef HAVE_PTH +# undef USE_GNU_PTH +#endif + +#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 +#ifdef HAVE_W32_SYSTEM +# define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */ +# include +#endif +#ifdef HAVE_PTH +# include +#endif +#include + +#include "util.h" +#include "i18n.h" + +#include "sysutils.h" + +#define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) + + +#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 this 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; + /* Although this marker is guessable it is not easy to use + * 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 + + +/* Wrapper around the usual sleep fucntion. This one won't wake up + before the sleep time has really elapsed. When build with Pth it + merely calls pth_sleep and thus suspends only the current + thread. */ +void +gnupg_sleep (unsigned int seconds) +{ +#ifdef HAVE_PTH + /* With Pth we force a regular sleep for seconds == 0 so that also + the process will give up its timeslot. */ + if (!seconds) + { +# ifdef HAVE_W32_SYSTEM + Sleep (0); +# else + sleep (0); +# endif + } + pth_sleep (seconds); +#else + /* Fixme: make sure that a sleep won't wake up to early. */ +# ifdef HAVE_W32_SYSTEM + Sleep (seconds*1000); +# else + sleep (seconds); +# endif +#endif +} + + +/* This function is a NOP for POSIX systems but required under Windows + as the file handles as returned by OS calls (like CreateFile) are + different from the libc file descriptors (like open). This function + translates system file handles to libc file handles. FOR_WRITE + gives the direction of the handle. */ +int +translate_sys2libc_fd (gnupg_fd_t fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + int x; + + if (fd == GNUPG_INVALID_FD) + return -1; + + /* Note that _open_osfhandle is currently defined to take and return + a long. */ + x = _open_osfhandle ((long)fd, for_write ? 1 : 0); + if (x == -1) + log_error ("failed to translate osfhandle %p\n", (void *) fd); + return x; +#else /*!HAVE_W32_SYSTEM */ + (void)for_write; + return fd; +#endif +} + +/* This is the same as translate_sys2libc_fd but takes an integer + which is assumed to be such an system handle. */ +int +translate_sys2libc_fd_int (int fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + if (fd <= 2) + return fd; /* Do not do this for error, stdin, stdout, stderr. */ + + return translate_sys2libc_fd ((void*)fd, for_write); +#else + (void)for_write; + return fd; +#endif +} + + + +/* Replacement for tmpfile(). This is required because the tmpfile + function of Windows' runtime library is broken, insecure, ignores + TMPDIR and so on. In addition we create a file with an inheritable + handle. */ +FILE * +gnupg_tmpfile (void) +{ +#ifdef HAVE_W32_SYSTEM + int attempts, n; + char buffer[MAX_PATH+7+12+1]; + char *name, *p; + HANDLE file; + int pid = GetCurrentProcessId (); + unsigned int value; + int i; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = TRUE; + + n = GetTempPath (MAX_PATH+1, buffer); + if (!n || n > MAX_PATH || strlen (buffer) > MAX_PATH) + { + errno = ENOENT; + return NULL; + } + p = buffer + strlen (buffer); + p = stpcpy (p, "_gnupg"); + /* We try to create the directory but don't care about an error as + it may already exist and the CreateFile would throw an error + anyway. */ + CreateDirectory (buffer, NULL); + *p++ = '\\'; + name = p; + for (attempts=0; attempts < 10; attempts++) + { + p = name; + value = (GetTickCount () ^ ((pid<<16) & 0xffff0000)); + for (i=0; i < 8; i++) + { + *p++ = tohex (((value >> 28) & 0x0f)); + value <<= 4; + } + strcpy (p, ".tmp"); + file = CreateFile (buffer, + GENERIC_READ | GENERIC_WRITE, + 0, + &sec_attr, + CREATE_NEW, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + if (file != INVALID_HANDLE_VALUE) + { + FILE *fp; + int fd = _open_osfhandle ((long)file, 0); + if (fd == -1) + { + CloseHandle (file); + return NULL; + } + fp = fdopen (fd, "w+b"); + if (!fp) + { + int save = errno; + close (fd); + errno = save; + return NULL; + } + return fp; + } + Sleep (1); /* One ms as this is the granularity of GetTickCount. */ + } + errno = ENOENT; + return NULL; +#else /*!HAVE_W32_SYSTEM*/ + return tmpfile (); +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Make sure that the standard file descriptors are opened. Obviously + some folks close them before an exec and the next file we open will + get one of them assigned and thus any output (i.e. diagnostics) end + up in that file (e.g. the trustdb). Not actually a gpg problem as + this will hapen with almost all utilities when called in a wrong + way. However we try to minimize the damage here and raise + awareness of the problem. + + Must be called before we open any files! */ +void +gnupg_reopen_std (const char *pgmname) +{ +#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM) + struct stat statbuf; + int did_stdin = 0; + int did_stdout = 0; + int did_stderr = 0; + FILE *complain; + + if (fstat (STDIN_FILENO, &statbuf) == -1 && errno ==EBADF) + { + if (open ("/dev/null",O_RDONLY) == STDIN_FILENO) + did_stdin = 1; + else + did_stdin = 2; + } + + if (fstat (STDOUT_FILENO, &statbuf) == -1 && errno == EBADF) + { + if (open ("/dev/null",O_WRONLY) == STDOUT_FILENO) + did_stdout = 1; + else + did_stdout = 2; + } + + if (fstat (STDERR_FILENO, &statbuf)==-1 && errno==EBADF) + { + if (open ("/dev/null", O_WRONLY) == STDERR_FILENO) + did_stderr = 1; + else + did_stderr = 2; + } + + /* It's hard to log this sort of thing since the filehandle we would + complain to may be closed... */ + if (!did_stderr) + complain = stderr; + else if (!did_stdout) + complain = stdout; + else + complain = NULL; + + if (complain) + { + if (did_stdin == 1) + fprintf (complain, "%s: WARNING: standard input reopened\n", pgmname); + if (did_stdout == 1) + fprintf (complain, "%s: WARNING: standard output reopened\n", pgmname); + if (did_stderr == 1) + fprintf (complain, "%s: WARNING: standard error reopened\n", pgmname); + + if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2) + fprintf(complain,"%s: fatal: unable to reopen standard input," + " output, or error\n", pgmname); + } + + if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2) + exit (3); +#else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */ + (void)pgmname; +#endif +} + + +/* Hack required for Windows. */ +void +gnupg_allow_set_foregound_window (pid_t pid) +{ + if (!pid) + log_info ("%s called with invalid pid %lu\n", + "gnupg_allow_set_foregound_window", (unsigned long)pid); +#ifdef HAVE_W32_SYSTEM + else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid)) + log_info ("AllowSetForegroundWindow(%lu) failed: %s\n", + (unsigned long)pid, w32_strerror (-1)); +#endif +} diff --git a/common/sysutils.h b/common/sysutils.h new file mode 100644 index 0000000..fd4340f --- /dev/null +++ b/common/sysutils.h @@ -0,0 +1,59 @@ +/* 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 3 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, see . + */ + +#ifndef GNUPG_COMMON_SYSUTILS_H +#define GNUPG_COMMON_SYSUTILS_H + +/* Because we use system handles and not libc low level file + descriptors on W32, we need to declare them as HANDLE (which + actually is a plain pointer). This is required to eventually + support 64 bits Windows systems. */ +#ifdef HAVE_W32_SYSTEM +typedef void *gnupg_fd_t; +#define GNUPG_INVALID_FD ((void*)(-1)) +#define INT2FD(s) ((void *)(s)) +#define FD2INT(h) ((unsigned int)(h)) +#else +typedef int gnupg_fd_t; +#define GNUPG_INVALID_FD (-1) +#define INT2FD(s) (s) +#define FD2INT(h) (h) +#endif + + +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);*/ +void gnupg_sleep (unsigned int seconds); +int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); +int translate_sys2libc_fd_int (int fd, int for_write); +FILE *gnupg_tmpfile (void); +void gnupg_reopen_std (const char *pgmname); +void gnupg_allow_set_foregound_window (pid_t pid); + + +#ifdef HAVE_W32_SYSTEM + +#include "../jnlib/w32help.h" + +#endif /*HAVE_W32_SYSTEM*/ + +#endif /*GNUPG_COMMON_SYSUTILS_H*/ diff --git a/common/t-b64.c b/common/t-b64.c new file mode 100644 index 0000000..a230dc0 --- /dev/null +++ b/common/t-b64.c @@ -0,0 +1,182 @@ +/* t-b64.c - Module tests for b64enc.c and b64dec.c + * Copyright (C) 2008 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 3 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, see . + */ + +/* + + As of now this is only a test program for manual tests. + + */ + + + +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + errcount++; \ + } while(0) + +static int verbose; +static int errcount; + +static void +test_b64enc_pgp (const char *string) +{ + gpg_error_t err; + struct b64state state; + + if (!string) + string = "a"; + + err = b64enc_start (&state, stdout, "PGP MESSAGE"); + if (err) + fail (1); + + err = b64enc_write (&state, string, strlen (string)); + if (err) + fail (2); + + err = b64enc_finish (&state); + if (err) + fail (3); + + pass (); +} + + +static void +test_b64enc_file (const char *fname) +{ + gpg_error_t err; + struct b64state state; + FILE *fp; + char buffer[50]; + size_t nread; + + fp = fname ? fopen (fname, "r") : stdin; + if (!fp) + { + fprintf (stderr, "%s:%d: can't open `%s': %s\n", + __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno)); + fail (0); + } + + err = b64enc_start (&state, stdout, "DATA"); + if (err) + fail (1); + + while ( (nread = fread (buffer, 1, sizeof buffer, fp)) ) + { + err = b64enc_write (&state, buffer, nread); + if (err) + fail (2); + } + + err = b64enc_finish (&state); + if (err) + fail (3); + + fclose (fp); + pass (); +} + +static void +test_b64dec_file (const char *fname) +{ + gpg_error_t err; + struct b64state state; + FILE *fp; + char buffer[50]; + size_t nread, nbytes; + + fp = fname ? fopen (fname, "r") : stdin; + if (!fp) + { + fprintf (stderr, "%s:%d: can't open `%s': %s\n", + __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno)); + fail (0); + } + + err = b64dec_start (&state, ""); + if (err) + fail (1); + + while ( (nread = fread (buffer, 1, sizeof buffer, fp)) ) + { + err = b64dec_proc (&state, buffer, nread, &nbytes); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_EOF) + break; + fail (2); + } + else if (nbytes) + fwrite (buffer, 1, nbytes, stdout); + } + + err = b64dec_finish (&state); + if (err) + fail (3); + + fclose (fp); + pass (); +} + + + +int +main (int argc, char **argv) +{ + int do_encode = 0; + int do_decode = 0; + + if (argc) + { argc--; argv++; } + if (argc && !strcmp (argv[0], "--verbose")) + { + verbose = 1; + argc--; argv++; + } + + if (argc && !strcmp (argv[0], "--encode")) + { + do_encode = 1; + argc--; argv++; + } + else if (argc && !strcmp (argv[0], "--decode")) + { + do_decode = 1; + argc--; argv++; + } + + if (do_encode) + test_b64enc_file (argc? *argv: NULL); + else if (do_decode) + test_b64dec_file (argc? *argv: NULL); + else + test_b64enc_pgp (argc? *argv: NULL); + + return !!errcount; +} + diff --git a/common/t-convert.c b/common/t-convert.c new file mode 100644 index 0000000..4b04f3a --- /dev/null +++ b/common/t-convert.c @@ -0,0 +1,461 @@ +/* t-convert.c - Module test for convert.c + * Copyright (C) 2006, 2008 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 3 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, see . + */ + +#include +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + + +static void +test_hex2bin (void) +{ + static const char *valid[] = { + "00112233445566778899aabbccddeeff11223344", + "00112233445566778899AABBCCDDEEFF11223344", + "00112233445566778899AABBCCDDEEFF11223344 blah", + "00112233445566778899AABBCCDDEEFF11223344\tblah", + "00112233445566778899AABBCCDDEEFF11223344\nblah", + NULL + }; + static const char *invalid[] = { + "00112233445566778899aabbccddeeff1122334", + "00112233445566778899AABBCCDDEEFF1122334", + "00112233445566778899AABBCCDDEEFG11223344", + "00 112233445566778899aabbccddeeff11223344", + "00:112233445566778899aabbccddeeff11223344", + ":00112233445566778899aabbccddeeff11223344", + "0:0112233445566778899aabbccddeeff11223344", + "00112233445566778899aabbccddeeff11223344:", + "00112233445566778899aabbccddeeff112233445", + "00112233445566778899aabbccddeeff1122334455", + "00112233445566778899aabbccddeeff11223344blah", + NULL + }; + static const char *valid2[] = { + "00", + "00 x", + NULL + }; + static const char *invalid2[] = { + "", + "0", + "00:", + "00x", + " 00", + NULL + }; + unsigned char buffer[20]; + int len; + int i; + + + for (i=0; valid[i]; i++) + { + len = hex2bin (valid[i], buffer, sizeof buffer); + if (len < 0) + fail (i); + if (memcmp (buffer, ("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa" + "\xbb\xcc\xdd\xee\xff\x11\x22\x33\x44"), 20)) + fail (i); + } + if (hex2bin (valid[0], buffer, sizeof buffer) != 40) + fail (0); + if (hex2bin (valid[2], buffer, sizeof buffer) != 41) + fail (0); + + for (i=0; invalid[i]; i++) + { + len = hex2bin (invalid[i], buffer, sizeof buffer); + if (!(len < 0)) + fail (i); + } + + for (i=0; valid2[i]; i++) + { + len = hex2bin (valid2[i], buffer, 1); + if (len < 0) + fail (i); + if (memcmp (buffer, "\x00", 1)) + fail (i); + } + if (hex2bin (valid2[0], buffer, 1) != 2) + fail (0); + if (hex2bin (valid2[1], buffer, 1) != 3) + fail (0); + + for (i=0; invalid2[i]; i++) + { + len = hex2bin (invalid2[i], buffer, 1); + if (!(len < 0)) + fail (i); + } +} + + + +static void +test_hexcolon2bin (void) +{ + static const char *valid[] = { + "00112233445566778899aabbccddeeff11223344", + "00112233445566778899AABBCCDDEEFF11223344", + "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "00112233445566778899AABBCCDDEEFF11223344 blah", + "00112233445566778899AABBCCDDEEFF11223344\tblah", + "00112233445566778899AABBCCDDEEFF11223344\nblah", + NULL + }; + static const char *invalid[] = { + "00112233445566778899aabbccddeeff1122334", + "00112233445566778899AABBCCDDEEFF1122334", + "00112233445566778899AABBCCDDEEFG11223344", + ":00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44:", + "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:3344", + "00:1122:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "0011:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "00 11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "00:11 22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:11:22:33:44", + "00112233445566778899aabbccddeeff112233445", + "00112233445566778899aabbccddeeff1122334455", + "00112233445566778899aabbccddeeff11223344blah", + NULL + }; + static const char *valid2[] = { + "00", + "00 x", + NULL + }; + static const char *invalid2[] = { + "", + "0", + "00:", + ":00", + "0:0", + "00x", + " 00", + NULL + }; + unsigned char buffer[20]; + int len; + int i; + + + for (i=0; valid[i]; i++) + { + len = hexcolon2bin (valid[i], buffer, sizeof buffer); + if (len < 0) + fail (i); + if (memcmp (buffer, ("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa" + "\xbb\xcc\xdd\xee\xff\x11\x22\x33\x44"), 20)) + fail (i); + } + if (hexcolon2bin (valid[0], buffer, sizeof buffer) != 40) + fail (0); + if (hexcolon2bin (valid[3], buffer, sizeof buffer) != 41) + fail (0); + + for (i=0; invalid[i]; i++) + { + len = hexcolon2bin (invalid[i], buffer, sizeof buffer); + if (!(len < 0)) + fail (i); + } + + for (i=0; valid2[i]; i++) + { + len = hexcolon2bin (valid2[i], buffer, 1); + if (len < 0) + fail (i); + if (memcmp (buffer, "\x00", 1)) + fail (i); + } + if (hexcolon2bin (valid2[0], buffer, 1) != 2) + fail (0); + if (hexcolon2bin (valid2[1], buffer, 1) != 3) + fail (0); + + for (i=0; invalid2[i]; i++) + { + len = hexcolon2bin (invalid2[i], buffer, 1); + if (!(len < 0)) + fail (i); + } + + +} + + + +static void +test_bin2hex (void) +{ + char stuff[20+1] = ("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa" + "\xbb\xcc\xdd\xee\xff\x01\x10\x02\xa3"); + char hexstuff[] = "00112233445566778899AABBCCDDEEFF011002A3"; + char buffer[2*20+1]; + char *p; + + p = bin2hex (stuff, 20, buffer); + if (!p) + fail (0); + if (p != buffer) + fail (0); + if (strcmp (buffer, hexstuff)) + fail (0); + + p = bin2hex (stuff, 20, NULL); + if (!p) + fail (0); + if (strcmp (p, hexstuff)) + fail (0); + + p = bin2hex (stuff, (size_t)(-1), NULL); + if (p) + fail (0); + if (errno != ENOMEM) + fail (1); +} + + +static void +test_bin2hexcolon (void) +{ + char stuff[20+1] = ("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa" + "\xbb\xcc\xdd\xee\xff\x01\x10\x02\xa3"); + char hexstuff[] = ("00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF" + ":01:10:02:A3"); + char buffer[3*20+1]; + char *p; + + p = bin2hexcolon (stuff, 20, buffer); + if (!p) + fail (0); + if (p != buffer) + fail (0); + if (strcmp (buffer, hexstuff)) + fail (0); + + p = bin2hexcolon (stuff, 20, NULL); + if (!p) + fail (0); + if (strcmp (p, hexstuff)) + fail (0); + + p = bin2hexcolon (stuff, (size_t)(-1), NULL); + if (p) + fail (0); + if (errno != ENOMEM) + fail (1); +} + + + +static void +test_hex2str (void) +{ + static struct { + const char *hex; + const char *str; + int off; + int no_alloc_test; + } tests[] = { + /* Simple tests. */ + { "112233445566778899aabbccddeeff1122", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122 blah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\tblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\nblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + /* Valid tests yielding an empty string. */ + { "00", + "", + 2 }, + { "00 x", + "", + 2 }, + { "", + "", + 0 }, + { " ", + "", + 0 }, + /* Test trailing Nul feature. */ + { "112233445566778899aabbccddeeff112200", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + { "112233445566778899aabbccddeeff112200 ", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + /* Test buffer size. (buffer is of length 20) */ + { "6162636465666768696A6b6c6D6e6f70717273", + "abcdefghijklmnopqrs", + 38 }, + { "6162636465666768696A6b6c6D6e6f7071727300", + "abcdefghijklmnopqrs", + 40 }, + { "6162636465666768696A6b6c6D6e6f7071727374", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737400", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737475", + NULL, + 0, 1 }, + + /* Invalid tests. */ + { "112233445566778899aabbccddeeff1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFF1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFG11223344", NULL, 0 }, + { "0:0112233445566778899aabbccddeeff11223344", NULL, 0 }, + { "112233445566778899aabbccddeeff11223344:", NULL, 0 }, + { "112233445566778899aabbccddeeff112233445", NULL, 0 }, + { "112233445566778899aabbccddeeff1122334455", NULL, 0, 1 }, + { "112233445566778899aabbccddeeff11223344blah", NULL, 0 }, + { "0", NULL, 0 }, + { "00:", NULL, 0 }, + { "00x", NULL, 0 }, + + { NULL, NULL, 0 } + }; + + int idx; + char buffer[20]; + const char *tail; + size_t count; + char *result; + + for (idx=0; tests[idx].hex; idx++) + { + tail = hex2str (tests[idx].hex, buffer, sizeof buffer, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, buffer)) + fail (idx); + else if (tail - tests[idx].hex != tests[idx].off) + fail (idx); + else if (strlen (buffer) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + } + } + + /* Same tests again using in-place conversion. */ + for (idx=0; tests[idx].hex; idx++) + { + char tmpbuf[100]; + + assert (strlen (tests[idx].hex)+1 < sizeof tmpbuf); + strcpy (tmpbuf, tests[idx].hex); + + /* Note: we still need to use 20 as buffer length because our + tests assume that. */ + tail = hex2str (tmpbuf, tmpbuf, 20, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, tmpbuf)) + fail (idx); + else if (tail - tmpbuf != tests[idx].off) + fail (idx); + else if (strlen (tmpbuf) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + if (strcmp (tmpbuf, tests[idx].hex)) + fail (idx); /* Buffer was modified. */ + } + } + + /* Test the allocation variant. */ + for (idx=0; tests[idx].hex; idx++) + { + if (tests[idx].no_alloc_test) + continue; + + result = hex2str_alloc (tests[idx].hex, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!result) + fail (idx); + else if (strcmp (tests[idx].str, result)) + fail (idx); + else if (count != tests[idx].off) + fail (idx); + } + else + { + /* Bad case test. */ + if (result) + fail (idx); + } + xfree (result); + } +} + + + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_hex2bin (); + test_hexcolon2bin (); + test_bin2hex (); + test_bin2hexcolon (); + test_hex2str (); + + return 0; +} + diff --git a/common/t-exechelp.c b/common/t-exechelp.c new file mode 100644 index 0000000..600379b --- /dev/null +++ b/common/t-exechelp.c @@ -0,0 +1,188 @@ +/* t-exechelp.c - Module test for exechelp.c + * Copyright (C) 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "exechelp.h" + +static int verbose; + + +static void +print_open_fds (int *array) +{ + int n; + + for (n=0; array[n] != -1; n++) + ; + printf ("open file descriptors: %d", n); + if (verbose) + { + putchar (' '); + putchar (' '); + putchar ('('); + for (n=0; array[n] != -1; n++) + printf ("%d%s", array[n], array[n+1] == -1?"":" "); + putchar (')'); + } + putchar ('\n'); +} + + +static int * +xget_all_open_fds (void) +{ + int *array; + + array = get_all_open_fds (); + if (!array) + { + fprintf (stderr, "%s:%d: get_all_open_fds failed: %s\n", + __FILE__, __LINE__, strerror (errno)); + exit (1); + } + return array; +} + + +/* That is a very crude test. To do a proper test we would need to + fork a test process and best return information by some other means + than file descriptors. */ +static void +test_close_all_fds (void) +{ + int max_fd = get_max_fds (); + int *array; + int fd; + int initial_count, count, n; +#if 0 + char buffer[100]; + + snprintf (buffer, sizeof buffer, "/bin/ls -l /proc/%d/fd", (int)getpid ()); + system (buffer); +#endif + + printf ("max. file descriptors: %d\n", max_fd); + array = xget_all_open_fds (); + print_open_fds (array); + for (initial_count=n=0; array[n] != -1; n++) + initial_count++; + free (array); + + /* Some dups to get more file descriptors and close one. */ + dup (1); + dup (1); + fd = dup (1); + dup (1); + close (fd); + + array = xget_all_open_fds (); + if (verbose) + print_open_fds (array); + for (count=n=0; array[n] != -1; n++) + count++; + if (count != initial_count+3) + { + fprintf (stderr, "%s:%d: dup or close failed\n", + __FILE__, __LINE__); + exit (1); + } + free (array); + + /* Close the non standard ones. */ + close_all_fds (3, NULL); + + /* Get a list to check whether they are all closed. */ + array = xget_all_open_fds (); + if (verbose) + print_open_fds (array); + for (count=n=0; array[n] != -1; n++) + count++; + if (count > initial_count) + { + fprintf (stderr, "%s:%d: not all files were closed\n", + __FILE__, __LINE__); + exit (1); + } + initial_count = count; + free (array); + + /* Now let's check the realloc we use. We do this and the next + tests only if we are allowed to open enought descriptors. */ + if (get_max_fds () > 32) + { + int except[] = { 20, 23, 24, -1 }; + + for (n=initial_count; n < 31; n++) + dup (1); + array = xget_all_open_fds (); + if (verbose) + print_open_fds (array); + free (array); + for (n=0; n < 5; n++) + { + dup (1); + array = xget_all_open_fds (); + if (verbose) + print_open_fds (array); + free (array); + } + + /* Check whether the except list works. */ + close_all_fds (3, except); + array = xget_all_open_fds (); + if (verbose) + print_open_fds (array); + for (count=n=0; array[n] != -1; n++) + count++; + free (array); + + if (count != initial_count + DIM(except)-1) + { + fprintf (stderr, "%s:%d: close_all_fds failed\n", + __FILE__, __LINE__); + exit (1); + } + } + +} + + +int +main (int argc, char **argv) +{ + if (argc) + { argc--; argv++; } + if (argc && !strcmp (argv[0], "--verbose")) + { + verbose = 1; + argc--; argv++; + } + + test_close_all_fds (); + + return 0; +} + diff --git a/common/t-gettime.c b/common/t-gettime.c new file mode 100644 index 0000000..a4401d8 --- /dev/null +++ b/common/t-gettime.c @@ -0,0 +1,103 @@ +/* t-gettime.c - Module test for gettime.c + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + errcount++; \ + } while(0) + +static int verbose; +static int errcount; +#define INVALID ((time_t)(-1)) + + +static void +test_isotime2epoch (void) +{ + struct { const char *string; time_t expected; } array [] = { + { "19700101T000001", 1 }, + { "19700101T235959", 86399 }, + { "19980815T143712", 903191832 }, + { "19700101T000000", 0 }, + { "19691231T235959", INVALID }, + { "19000101T000000", INVALID }, + { "", INVALID }, + { "19000101T00000", INVALID }, + { "20010101t123456", INVALID }, + { "20010101T123456", 978352496 }, + { "20070629T160000", 1183132800 }, + { "20070629T160000:", 1183132800 }, + { "20070629T160000,", 1183132800 }, + { "20070629T160000 ", 1183132800 }, + { "20070629T160000\n", 1183132800 }, + { "20070629T160000.", INVALID }, + { NULL, 0 } + }; + int idx; + time_t val; + gnupg_isotime_t tbuf; + + for (idx=0; array[idx].string; idx++) + { + val = isotime2epoch (array[idx].string); + if (val != array[idx].expected ) + { + fail (idx); + if (verbose) + fprintf (stderr, "string `%s' exp: %ld got: %ld\n", + array[idx].string, (long)array[idx].expected, + (long)val); + } + if (array[idx].expected != INVALID) + { + epoch2isotime (tbuf, val); + if (strlen (tbuf) != 15) + { + if (verbose) + fprintf (stderr, "string `%s', time-t %ld, revert: `%s'\n", + array[idx].string, (long)val, tbuf); + fail (idx); + } + if (strncmp (array[idx].string, tbuf, 15)) + fail (idx); + } + } +} + + + + +int +main (int argc, char **argv) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + + test_isotime2epoch (); + + return !!errcount; +} + diff --git a/common/t-helpfile.c b/common/t-helpfile.c new file mode 100644 index 0000000..fa5d27a --- /dev/null +++ b/common/t-helpfile.c @@ -0,0 +1,67 @@ +/* t-helpfile.c - Module test for helpfile.c + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include +#include + +#include "util.h" +#include "i18n.h" + +/* #define pass() do { ; } while(0) */ +/* #define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ */ +/* __FILE__,__LINE__, (a)); \ */ +/* errcount++; \ */ +/* } while(0) */ + +static int verbose; +static int errcount; + + + +int +main (int argc, char **argv) +{ + char *result; + + if (argc) + { argc--; argv++; } + i18n_init (); + if (argc && !strcmp (argv[0], "--verbose")) + { + verbose = 1; + argc--; argv++; + } + + result = gnupg_get_help_string (argc? argv[0]:NULL, 0); + if (!result) + { + fprintf (stderr, + "Error: nothing found for `%s'\n", argc?argv[0]:"(null)"); + errcount++; + } + else + { + printf ("key `%s' result=`%s'\n", argc?argv[0]:"(null)", result); + xfree (result); + } + + return !!errcount; +} + diff --git a/common/t-percent.c b/common/t-percent.c new file mode 100644 index 0000000..b8641b9 --- /dev/null +++ b/common/t-percent.c @@ -0,0 +1,115 @@ +/* t-percent.c - Module test for percent.c + * Copyright (C) 2008 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 3 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, see . + */ + +#include +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + +static void +test_percent_plus_escape (void) +{ + static struct { + const char *string; + const char *expect; + } tbl[] = { + { + "", + "" + }, { + "a", + "a", + }, { + " ", + "+", + }, { + " ", + "++" + }, { + "+ +", + "%2B+%2B" + }, { + "\" \"", + "%22+%22" + }, { + "%22", + "%2522" + }, { + "%% ", + "%25%25+" + }, { + "\n ABC\t", + "%0A+ABC%09" + }, { NULL, NULL } + }; + char *buf, *buf2; + int i; + size_t len; + + for (i=0; tbl[i].string; i++) + { + buf = percent_plus_escape (tbl[i].string); + if (!buf) + { + fprintf (stderr, "out of core: %s\n", strerror (errno)); + exit (2); + } + if (strcmp (buf, tbl[i].expect)) + fail (i); + buf2 = percent_plus_unescape (buf, 0); + if (!buf2) + { + fprintf (stderr, "out of core: %s\n", strerror (errno)); + exit (2); + } + if (strcmp (buf2, tbl[i].string)) + fail (i); + xfree (buf2); + /* Now test the inplace conversion. */ + len = percent_plus_unescape_inplace (buf, 0); + buf[len] = 0; + if (strcmp (buf, tbl[i].string)) + fail (i); + xfree (buf); + } +} + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + /* FIXME: We escape_unescape is not tested - only + percent_plus_unescape. */ + test_percent_plus_escape (); + + return 0; +} + diff --git a/common/t-session-env.c b/common/t-session-env.c new file mode 100644 index 0000000..94b6683 --- /dev/null +++ b/common/t-session-env.c @@ -0,0 +1,294 @@ +/* t-session-env.c - Module test for session-env.c + * Copyright (C) 2009 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "session-env.h" + +#define pass() do { ; } while(0) +#define fail(e) do { fprintf (stderr, "%s:%d: function failed: %s\n", \ + __FILE__,__LINE__, gpg_strerror (e)); \ + exit (1); \ + } while(0) + +static int verbose; + +static void +listall (session_env_t se) +{ + int iterator = 0; + const char *name, *value; + int def; + + if (verbose) + printf ("environment of %p\n", se); + while ( (name = session_env_listenv (se, &iterator, &value, &def)) ) + if (verbose) + printf (" %s%s=%s\n", def? "[def] ":" ", name, value); + +} + + +static void +show_stdnames (void) +{ + const char *name, *assname; + int iterator = 0; + + printf ("Known envvars:"); + while ((name = session_env_list_stdenvnames (&iterator, &assname))) + { + printf ( " %s", name); + if (assname) + printf ( "(%s)", assname); + } + putchar('\n'); +} + + +static void +test_all (void) +{ + gpg_error_t err; + session_env_t se_0, se; + const char *s, *s2; + int idx; + + se_0 = session_env_new (); + if (!se_0) + fail (gpg_error_from_syserror ()); + se = session_env_new (); + if (!se) + fail (gpg_error_from_syserror ()); + + err = session_env_putenv (se, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_VALUE) + fail (err); + err = session_env_putenv (se, ""); + if (gpg_err_code (err) != GPG_ERR_INV_VALUE) + fail (err); + err = session_env_putenv (se, "="); + if (gpg_err_code (err) != GPG_ERR_INV_VALUE) + fail (err); + + /* Delete some nonexistant variables. */ + err = session_env_putenv (se, "A"); + if (err) + fail (err); + err = session_env_putenv (se, "a"); + if (err) + fail (err); + err = session_env_putenv (se, "_aaaa aaaaaasssssssssssss\nddd"); + if (err) + fail (err); + + /* Create a few variables. */ + err = session_env_putenv (se, "EMPTY="); + if (err) + fail (err); + err = session_env_putenv (se, "foo=value_of_foo"); + if (err) + fail (err); + err = session_env_putenv (se, "bar=the value_of_bar"); + if (err) + fail (err); + err = session_env_putenv (se, "baz=this-is-baz"); + if (err) + fail (err); + err = session_env_putenv (se, "BAZ=this-is-big-baz"); + if (err) + fail (err); + + listall (se); + + /* Update one. */ + err = session_env_putenv (se, "baz=this-is-another-baz"); + if (err) + fail (err); + + listall (se); + + /* Delete one. */ + err = session_env_putenv (se, "bar"); + if (err) + fail (err); + + listall (se); + + /* Insert a new one. */ + err = session_env_putenv (se, "FOO=value_of_foo"); + if (err) + fail (err); + + listall (se); + + /* Retrieve a default one. */ + s = session_env_getenv_or_default (se, "HOME", NULL); + if (!s) + { + fprintf (stderr, "failed to get default of HOME\n"); + exit (1); + } + + s = session_env_getenv (se, "HOME"); + if (s) + fail(0); /* This is a default value, thus we should not see it. */ + + s = session_env_getenv_or_default (se, "HOME", NULL); + if (!s) + fail(0); /* But here we should see it. */ + + /* Add a few more. */ + err = session_env_putenv (se, "X1=A value"); + if (err) + fail (err); + err = session_env_putenv (se, "X2=Another value"); + if (err) + fail (err); + err = session_env_putenv (se, "X3=A value"); + if (err) + fail (err); + + listall (se); + + /* Check that we can overwrite a default value. */ + err = session_env_putenv (se, "HOME=/this/is/my/new/home"); + if (err) + fail (err); + /* And that we get this string back. */ + s = session_env_getenv (se, "HOME"); + if (!s) + fail (0); + if (strcmp (s, "/this/is/my/new/home")) + fail (0); + /* A new get default should return the very same string. */ + s2 = session_env_getenv_or_default (se, "HOME", NULL); + if (!s2) + fail (0); + if (s2 != s) + fail (0); + + listall (se); + + /* Check that the other object is clean. */ + { + int iterator = 0; + + if (session_env_listenv (se_0, &iterator, NULL, NULL)) + fail (0); + } + + + session_env_release (se); + + /* Use a new session for quick mass test. */ + se = session_env_new (); + if (!se) + fail (gpg_error_from_syserror ()); + + /* Create. */ + for (idx=0; idx < 500; idx++) + { + char buf[100]; + + snprintf (buf, sizeof buf, "FOO_%d=Value for %x", idx, idx); + err = session_env_putenv (se, buf); + if (err) + fail (err); + } + err = session_env_setenv (se, "TEST1", "value1"); + if (err) + fail (err); + err = session_env_setenv (se, "TEST1", "value1-updated"); + if (err) + fail (err); + + listall (se); + + /* Delete all. */ + for (idx=0; idx < 500; idx++) + { + char buf[100]; + + snprintf (buf, sizeof buf, "FOO_%d", idx); + err = session_env_putenv (se, buf); + if (err) + fail (err); + } + err = session_env_setenv (se, "TEST1", NULL); + if (err) + fail (err); + + /* Check that all are deleted. */ + { + int iterator = 0; + + if (session_env_listenv (se, &iterator, NULL, NULL)) + fail (0); + } + + /* Add a few strings again. */ + for (idx=0; idx < 500; idx++) + { + char buf[100]; + + if (!(idx % 10)) + { + if ( !(idx % 3)) + snprintf (buf, sizeof buf, "FOO_%d=", idx); + else + snprintf (buf, sizeof buf, "FOO_%d=new value for %x", idx, idx); + err = session_env_putenv (se, buf); + if (err) + fail (err); + } + } + + listall (se); + + session_env_release (se); + + session_env_release (se_0); +} + + + +int +main (int argc, char **argv) +{ + if (argc) + { argc--; argv++; } + if (argc && !strcmp (argv[0], "--verbose")) + { + verbose = 1; + argc--; argv++; + } + + + show_stdnames (); + test_all (); + + return 0; +} + diff --git a/common/t-sexputil.c b/common/t-sexputil.c new file mode 100644 index 0000000..05da162 --- /dev/null +++ b/common/t-sexputil.c @@ -0,0 +1,192 @@ +/* t-sexputil.c - Module test for sexputil.c + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + + +static void +test_hash_algo_from_sigval (void) +{ + int algo; + /* A real world example. */ + unsigned char example1_rsa_sha1[] = + ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61" + "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E" + "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89" + "\x7A\x69\x11\x43\xE9\xD2\x23\x21\x25\x64\xA6\xB0\x56\xEF\xB4\xE9" + "\x06\xB2\x44\xF6\x80\x1E\xFF\x41\x23\xEB\xC9\xFA\xFD\x09\xBF\x9C" + "\x8E\xCF\x7F\xC3\x7F\x3A\x40\x48\x89\xDC\xBA\xB7\xDB\x9E\xF1\xBA" + "\x7C\x08\xEA\x74\x1D\x49\xE7\x65\xEF\x67\x79\xBC\x23\xD9\x49\xCD" + "\x05\x99\xD3\xD8\xB7\x7B\xC7\x0E\xF2\xB3\x01\x48\x0F\xC8\xEB\x05" + "\x7B\xFB\x61\xCC\x41\x04\x74\x6D\x33\x84\xB1\xE6\x6A\xD8\x0F\xBC" + "\x27\xAC\x43\x45\xFA\x04\xD1\x22\x29\x29\x28\x34\x3A\x68\x61\x73" + "\x68\x34\x3A\x73\x68\x61\x31\x29\x29"); + /* The same but without the hash algo. */ + unsigned char example1_rsa[] = + ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61" + "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E" + "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89" + "\x7A\x69\x11\x43\xE9\xD2\x23\x21\x25\x64\xA6\xB0\x56\xEF\xB4\xE9" + "\x06\xB2\x44\xF6\x80\x1E\xFF\x41\x23\xEB\xC9\xFA\xFD\x09\xBF\x9C" + "\x8E\xCF\x7F\xC3\x7F\x3A\x40\x48\x89\xDC\xBA\xB7\xDB\x9E\xF1\xBA" + "\x7C\x08\xEA\x74\x1D\x49\xE7\x65\xEF\x67\x79\xBC\x23\xD9\x49\xCD" + "\x05\x99\xD3\xD8\xB7\x7B\xC7\x0E\xF2\xB3\x01\x48\x0F\xC8\xEB\x05" + "\x7B\xFB\x61\xCC\x41\x04\x74\x6D\x33\x84\xB1\xE6\x6A\xD8\x0F\xBC" + "\x27\xAC\x43\x45\xFA\x04\xD1\x22\x29\x29\x29"); + + algo = hash_algo_from_sigval (example1_rsa_sha1); + if (algo != GCRY_MD_SHA1) + fail (0); + algo = hash_algo_from_sigval (example1_rsa); + if (algo) + fail (0); +} + + +static void +test_make_canon_sexp_from_rsa_pk (void) +{ + struct { + unsigned char *m; + size_t mlen; + unsigned char *e; + size_t elen; + unsigned char *result; + size_t resultlen; + gpg_err_code_t reverr; /* Expected error from the reverse fucntion. */ + } tests[] = { + { + "\x82\xB4\x12\x48\x08\x48\xC0\x76\xAA\x8E\xF1\xF8\x7F\x5E\x9B\x89" + "\xA9\x62\x92\xA2\x16\x1B\xF5\x9F\xE1\x41\xF3\xF0\x42\xB5\x5C\x46" + "\xB8\x83\x9F\x39\x97\x73\xFF\xC5\xB2\xF4\x59\x5F\xBA\xC7\x0E\x03" + "\x9D\x27\xC0\x86\x37\x31\x46\xE0\xA1\xFE\xA1\x41\xD4\xE3\xE9\xB3" + "\x9B\xD5\x84\x65\xA5\x37\x35\x34\x07\x58\xB6\xBA\x21\xCA\x21\x72" + "\x4C\xF3\xFC\x91\x47\xD1\x3C\x1D\xA5\x9C\x38\x4D\x58\x39\x92\x16" + "\xB1\xE5\x43\xFE\xB5\x46\x4B\x43\xD1\x47\xB0\xE8\x2A\xDB\xF8\x34" + "\xB0\x5A\x22\x3D\x14\xBB\xEA\x63\x65\xA7\xF1\xF2\xF8\x97\x74\xA7", + 128, + "\x40\x00\x00\x81", + 4, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x32\x39\x3a\x00\x82\xb4\x12" + "\x48\x08\x48\xc0\x76\xaa\x8e\xf1\xf8\x7f\x5e\x9b\x89\xa9\x62\x92" + "\xa2\x16\x1b\xf5\x9f\xe1\x41\xf3\xf0\x42\xb5\x5c\x46\xb8\x83\x9f" + "\x39\x97\x73\xff\xc5\xb2\xf4\x59\x5f\xba\xc7\x0e\x03\x9d\x27\xc0" + "\x86\x37\x31\x46\xe0\xa1\xfe\xa1\x41\xd4\xe3\xe9\xb3\x9b\xd5\x84" + "\x65\xa5\x37\x35\x34\x07\x58\xb6\xba\x21\xca\x21\x72\x4c\xf3\xfc" + "\x91\x47\xd1\x3c\x1d\xa5\x9c\x38\x4d\x58\x39\x92\x16\xb1\xe5\x43" + "\xfe\xb5\x46\x4b\x43\xd1\x47\xb0\xe8\x2a\xdb\xf8\x34\xb0\x5a\x22" + "\x3d\x14\xbb\xea\x63\x65\xa7\xf1\xf2\xf8\x97\x74\xa7\x29\x28\x31" + "\x3a\x65\x34\x3a\x40\x00\x00\x81\x29\x29\x29", + 171 + }, + { + "\x63\xB4\x12\x48\x08\x48\xC0\x76\xAA\x8E\xF1\xF8\x7F\x5E\x9B\x89", + 16, + "\x03", + 1, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x36\x3a\x63\xb4\x12\x48\x08" + "\x48\xc0\x76\xaa\x8e\xf1\xf8\x7f\x5e\x9b\x89\x29\x28\x31\x3a\x65" + "\x31\x3a\x03\x29\x29\x29", + 54, + }, + { + "", + 0, + "", + 0, + "\x28\x31\x30\x3a\x70\x75\x62\x6c\x69\x63\x2d\x6b\x65\x79\x28\x33" + "\x3a\x72\x73\x61\x28\x31\x3a\x6e\x31\x3a\x00\x29\x28\x31\x3a\x65" + "\x31\x3a\x00\x29\x29\x29", + 38, + GPG_ERR_BAD_PUBKEY + }, + { + NULL + } + }; + int idx; + gpg_error_t err; + unsigned char *sexp; + size_t length; + const unsigned char *rsa_n, *rsa_e; + size_t rsa_n_len, rsa_e_len; + + for (idx=0; tests[idx].m; idx++) + { + sexp = make_canon_sexp_from_rsa_pk (tests[idx].m, tests[idx].mlen, + tests[idx].e, tests[idx].elen, + &length); + if (!sexp) + { + fprintf (stderr, "%s:%d: out of core\n", __FILE__, __LINE__); + exit (1); + } + + if (length != tests[idx].resultlen) + fail (idx); + if (memcmp (sexp, tests[idx].result, tests[idx].resultlen)) + fail (idx); + + /* Test the reverse function. */ + err = get_rsa_pk_from_canon_sexp (sexp, length, + &rsa_n, &rsa_n_len, + &rsa_e, &rsa_e_len); + if (gpg_err_code (err) != tests[idx].reverr) + fail (idx); + if (!err) + { + if (tests[idx].mlen != rsa_n_len) + fail (idx); + if (memcmp (tests[idx].m, rsa_n, rsa_n_len)) + fail (idx); + if (tests[idx].elen != rsa_e_len) + fail (idx); + if (memcmp (tests[idx].e, rsa_e, rsa_e_len)) + fail (idx); + } + + xfree (sexp); + } +} + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_hash_algo_from_sigval (); + test_make_canon_sexp_from_rsa_pk (); + + return 0; +} + diff --git a/common/t-ssh-utils.c b/common/t-ssh-utils.c new file mode 100644 index 0000000..a8a63cf --- /dev/null +++ b/common/t-ssh-utils.c @@ -0,0 +1,233 @@ +/* t-ssh-utils.c - Module test for ssh-utils.c + * Copyright (C) 2011 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 3 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "ssh-utils.h" + + +static struct { const char *key; const char *fpr; } sample_keys[] = { + { "(protected-private-key " + "(rsa " + "(n #" + "00D88E47BCE0DA99D6180E8A9F4E6A673CC16F5BB6CF930E0E868BAABA715A8E1D3E2BEA" + "5477170E1F6CAFC0F8907B9892993C70AC476BBB301669F68EE0593532FB522DD60755A3" + "2F8B08649E856271A7F9BCB25F29554DF11707F812EA377683A99DD4698C4DBF797A0ABF" + "43C8EBB364B9FFC9EE78CBEA348C590507A4EA390312153DDD905EC4F1A63D5DA56C08FD" + "C3F6E5707BFC5DBDC09D19723B1AC6E466906F13AA2ECDBD258148F86C980D45CF233415" + "38C5857C2CF0B4C9AB2B4E6A4517FF084FDB009A33553A68907A29691B6FAE994E864F78" + "7B83F714730BEDB0AF1723D636E034D73EB7EC9BA127BB4BE80FD805813E3F45E7FAE514" + "AD2ECA9607#)" + "(e \"#\")" + "(protected openpgp-s2k3-sha1-aes-cbc " + "(" + "(sha1 #B5847F9A2DB4E0C5# \"5242880\")" + "#342D81BDE21301F18FDCE169A99A47C5#)" + "#23512602219EC7A97DBA89347CCD59D2072D80CE3F7DD6C97A058B83DAB3C829D97DF5" + "DFE9181F27DBF58258C4CDBD562A5B20BB5BC35EDCA7B1E57B8CDBF92D798F46EE5567BD" + "8A67EF3BE09908A49D41AA166A3398B64227BC75021C69A8FE8354E2903EF52DC91B1FE3" + "EF9558E5C2D34CF38BFC29E99A49AE30B0C22CE81EE14FC71E986E7C7CB5FCF807433FDA" + "EF1D00985767265BA0BE333754E44CCF622CBB98A029D78A6A9AADBC24613127B6448350" + "23DA355ED31CF089DD11A7FC6003CEEB53FB327A05604D053C99996F9E01CB355983F66E" + "7BEB9687A9277BBF440ED5FAF1A8396C9B06C9B47BA7A994E1931B08DAD34449952CD343" + "9A691477682C324EA07CCCE5DF0F0E9DAEFAE3A4717AACA6DC18ED91DD5A820C924BD36B" + "B3BA85BD63B3180C7F94EE58956940621280B9628FA5CC560BB14331AF1A7B5B499F8F03" + "0ED464ABD4E26C5FD610697EDD0FD1203983E73418F3776568A613D3CEFF17199473052A" + "18807A6F5C52A2A643185801D087EE4DC930ABEEB67C5B8A1CB2F29D0ACBD855972BEC0B" + "DE6E52387CFCC54B4C2B87EE947C97173BFCAE3E2658EB819D87F542C9A9FE6C410D08F5" + "3CD5451FB50253F4A848DFE136B3A5861D58B76A26A7E3E4E7A8F8D4BD5B80430674A6B9" + "A2C8EDD53DB37865D1ACBB07E1758DFF64A944E0126F948BF088C0FC0C3607E39522EC94" + "91483A90D9498D7F6C3C8720124C7E3F6E271E78E1CFFB4EF64F070F7424F30372A07D02" + "2355D8B17BB0DEBCBE101F621E0526551A35A56830D74E0F5BD6313DF114D1E46D4844AA" + "E4EB6268637D04B27D200D7F40AFA9AD2CFAA5415E5FC08358FFA79A9E743CCDF6668FE5" + "D79FA03D61941E57244F066A31F1C9D6A34DC62BC738C52B604F00B19EB9FD0173F3B139" + "42932066B7DC94DC4C563392F798A1CE2D5D75B8FF93E440433263CFB7016143A9923CD9" + "634E964A8056946F462B06F320F44449D85B07FA26A324505C858274F89EDBD8346950DE" + "5F#)" + "(protected-at \"20110720T135431\")" + ")" + "(comment passphrase_is_abc)" + ")", + "c7:c6:a7:ec:04:6c:87:59:54:f2:88:58:09:e0:f2:b1" + }, + { + "(protected-private-key " + "(dsa " + "(p #00FC7DC086F4517079BCCFA7FD229477FE88B0231038DFC21B29CCBD74C6F6FE04FD" + "7248C0473D5028BE106D7A7C8F54B269225789E781763527D1432CD46E416C2D14DDCA70" + "27DA4B92D1E222B5BDF4B9C8C761CACCFBD108F7729412E8835653BE5073447287A6BDEB" + "4645A5411752405EE7F503E44B1DFDCA6054CD3C44630B#)" + "(q #00D498505BF0E7EE01239EB51F2B400B8EF6329B17#)" + "(g #00A127B3DD5106F0A463312E42ECB83790E6F3BEA7AC3FAF7A42FB2C00F376323676" + "C9E48984F0D4AC3FE5856F1C2765E9BC3C8A5C9C9CD3166C057E82569D187C48591AA66B" + "8966BFF2B827BE36BD0BA4B895B42136F1381D52DDA708B2A3D181F648228DFFFEB153DA" + "ACCAEBB51EF08A7807CD628024CEFF96FEE97DE95C8CBE#)" + "(y #008E2B0915A3A299D83B4333C848C5D312F25903773E8C4D50691CAF81C3B768FA41" + "7D19F0FD437B377CCF51D3AE598649656D4D74D210CDBC2B76209B16EAAFCB14D6F4D691" + "20164885852AF1CEBB4D8602AD6755DFA7163645B4DB7926CD44D2DD9F840BFEF57F3DB0" + "933C85EB6B0AAC20BC67E73F47B8DDBEC8EFAA64286EF1#)" + "(protected openpgp-s2k3-sha1-aes-cbc " + "(" + "(sha1 \"ü¿jy²üa4\" \"5242880\")" + "#FF12BEE0B03F842349717AE1AB6D7AC2#)" + "#95570487C8B5C49492D4E662259F2CF9B6D7E64F728F17A1FE1B2DA616E5976FE32861E" + "C4B1F0DA03D9006C432CF2136871266E9444377ACEF04340B36B4550B5C1E4CC69AD4380" + "A709FB0DAA5104A8B#)" + "(protected-at \"20110720T142801\")" + ")" + "(comment sample_dsa_passphrase_is_abc)" + ")", + "2d:b1:70:1a:04:9e:41:a3:ce:27:a5:c7:22:fe:3a:a3" + }, + { + NULL, + NULL + } +}; + + + +static char * +read_file (const char *fname, size_t *r_length) +{ + FILE *fp; + char *buf; + size_t buflen; + struct stat st; + + fp = fopen (fname, "rb"); + if (!fp) + { + fprintf (stderr, "%s:%d: can't open `%s': %s\n", + __FILE__, __LINE__, fname, strerror (errno)); + exit (1); + } + + if (fstat (fileno(fp), &st)) + { + fprintf (stderr, "%s:%d: can't stat `%s': %s\n", + __FILE__, __LINE__, fname, strerror (errno)); + exit (1); + } + + buflen = st.st_size; + buf = xmalloc (buflen+1); + if (fread (buf, buflen, 1, fp) != 1) + { + fprintf (stderr, "%s:%d: error reading `%s': %s\n", + __FILE__, __LINE__, fname, strerror (errno)); + exit (1); + } + fclose (fp); + + *r_length = buflen; + return buf; +} + + +static gcry_sexp_t +read_key (const char *fname) +{ + gpg_error_t err; + char *buf; + size_t buflen; + gcry_sexp_t key; + + buf = read_file (fname, &buflen); + + err = gcry_sexp_sscan (&key, NULL, buf, buflen); + if (err) + { + fprintf (stderr, "%s:%d: gcry_sexp_sscan failed: %s\n", + __FILE__, __LINE__, gpg_strerror (err)); + exit (1); \ + } + + xfree (buf); + return key; +} + + +int +main (int argc, char **argv) +{ + gpg_error_t err; + gcry_sexp_t key; + char *string; + int idx; + + if (argc == 2) + { + key = read_key (argv[1]); + err = ssh_get_fingerprint_string (key, &string); + if (err) + { + fprintf (stderr, "%s:%d: error getting fingerprint: %s\n", + __FILE__, __LINE__, gpg_strerror (err)); + exit (1); + } + puts (string); + xfree (string); + gcry_sexp_release (key); + } + else + { + for (idx=0; sample_keys[idx].key; idx++) + { + err = gcry_sexp_sscan (&key, NULL, sample_keys[idx].key, + strlen (sample_keys[idx].key)); + if (err) + { + fprintf (stderr, "%s:%d: gcry_sexp_sscan failed for " + "sample key %d: %s\n", + __FILE__, __LINE__, idx, gpg_strerror (err)); + exit (1); + } + + err = ssh_get_fingerprint_string (key, &string); + gcry_sexp_release (key); + if (err) + { + fprintf (stderr, "%s:%d: error getting fingerprint for " + "sample key %d: %s\n", + __FILE__, __LINE__, idx, gpg_strerror (err)); + exit (1); + } + + if (strcmp (string, sample_keys[idx].fpr)) + { + fprintf (stderr, "%s:%d: fingerprint mismatch for " + "sample key %d\n", + __FILE__, __LINE__, idx); + fprintf (stderr, "want: %s\n got: %s\n", + sample_keys[idx].fpr, string); + exit (1); + } + xfree (string); + } + } + + return 0; +} diff --git a/common/t-sysutils.c b/common/t-sysutils.c new file mode 100644 index 0000000..45d359e --- /dev/null +++ b/common/t-sysutils.c @@ -0,0 +1,85 @@ +/* t-sysutils.c - Module test for sysutils.c + * Copyright (C) 2007 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 3 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, see . + */ + +#include +#include +#include + +#include "util.h" +#include "sysutils.h" + +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + errcount++; \ + } while(0) + +static int verbose; +static int errcount; + + +static void +test_gnupg_tmpfile (void) +{ + FILE *fparr[10]; + int fparridx; + int idx; + FILE *fp; + char buffer[100]; + +#define ASTRING "fooooooooooooooo\n" /* Needs to be shorter than BUFFER. */ + + for (fparridx=0; fparridx < DIM (fparr); fparridx++) + { + fp = gnupg_tmpfile (); + fparr[fparridx] = fp; + if (!fp) + fail (fparridx); + else + { + fputs ( ASTRING, fp); + rewind (fp); + if (!fgets (buffer, sizeof (buffer), fp)) + fail (fparridx); + if (strcmp (buffer, ASTRING)) + fail (fparridx); + if (fgets (buffer, sizeof (buffer), fp)) + fail (fparridx); + } + } + for (idx=0; idx < fparridx; idx++) + { + if (fparr[idx]) + fclose (fparr[idx]); + } +} + + + +int +main (int argc, char **argv) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + + test_gnupg_tmpfile (); + + return !!errcount; +} + diff --git a/common/tlv.c b/common/tlv.c new file mode 100644 index 0000000..c687564 --- /dev/null +++ b/common/tlv.c @@ -0,0 +1,305 @@ +/* tlv.c - Tag-Length-Value Utilities + * Copyright (C) 2003, 2004, 2005 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 3 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, see . + */ + +#include + +#include +#include +#include +#include + +#if GNUPG_MAJOR_VERSION == 1 +#define GPG_ERR_EOF (-1) +#define GPG_ERR_BAD_BER (1) /*G10ERR_GENERAL*/ +#define GPG_ERR_INV_SEXP (45) /*G10ERR_INV_ARG*/ +typedef int gpg_error_t; +#define gpg_make_err(x,n) (n) +#else +#include +#endif + +#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 or if the object does not fit into the buffer. */ +const unsigned char * +find_tlv (const unsigned char *buffer, size_t length, + int tag, size_t *nbytes) +{ + const unsigned char *p; + + p = do_find_tlv (buffer, length, tag, nbytes, 0); + if (p && *nbytes > (length - (p-buffer))) + p = NULL; /* Object longer than buffer. */ + return p; +} + + + +/* 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_unchecked (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, + gpg_err_source_t errsource) +{ + 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_err_make (errsource, 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_err_make (errsource, GPG_ERR_EOF); + c = *buf++; length--; ++*r_nhdr; + tag |= c & 0x7f; + + } + while (c & 0x80); + } + *r_tag = tag; + + /* Get the length. */ + if (!length) + return gpg_err_make (errsource, 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_err_make (errsource, GPG_ERR_BAD_BER); + else + { + unsigned long len = 0; + int count = c & 0x7f; + + if (count > sizeof (len) || count > sizeof (size_t)) + return gpg_err_make (errsource, GPG_ERR_BAD_BER); + + for (; count; count--) + { + len <<= 8; + if (!length) + return gpg_err_make (errsource, 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; +} + + +/* FIXME: The following function should not go into this file but for + now it is easier to keep it here. */ + +/* Return the next token of an canconical encoded S-expression. BUF + is the pointer to the S-expression and BUFLEN is a pointer to the + length of this S-expression (used to validate the syntax). Both + are updated to reflect the new position. The token itself is + returned as a pointer into the orginal buffer at TOK and TOKLEN. + If a parentheses is the next token, TOK will be set to NULL. + TOKLEN is checked to be within the bounds. On error a error code + is returned and all pointers should are not guaranteed to point to + a meanigful value. DEPTH should be initialized to 0 and will + reflect on return the actual depth of the tree. To detect the end + of the S-expression it is advisable to check DEPTH after a + successful return: + + depth = 0; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth) + process_token (tok, toklen); + if (err) + handle_error (); + */ +gpg_error_t +_parse_sexp (unsigned char const **buf, size_t *buflen, + int *depth, unsigned char const **tok, size_t *toklen, + gpg_err_source_t errsource) +{ + const unsigned char *s; + size_t n, vlen; + + s = *buf; + n = *buflen; + *tok = NULL; + *toklen = 0; + if (!n) + return *depth ? gpg_err_make (errsource, GPG_ERR_INV_SEXP) : 0; + if (*s == '(') + { + s++; n--; + (*depth)++; + *buf = s; + *buflen = n; + return 0; + } + if (*s == ')') + { + if (!*depth) + return gpg_err_make (errsource, GPG_ERR_INV_SEXP); + *toklen = 1; + s++; n--; + (*depth)--; + *buf = s; + *buflen = n; + return 0; + } + for (vlen=0; n && *s && *s != ':' && (*s >= '0' && *s <= '9'); s++, n--) + vlen = vlen*10 + (*s - '0'); + if (!n || *s != ':') + return gpg_err_make (errsource, GPG_ERR_INV_SEXP); + s++; n--; + if (vlen > n) + return gpg_err_make (errsource, GPG_ERR_INV_SEXP); + *tok = s; + *toklen = vlen; + s += vlen; + n -= vlen; + *buf = s; + *buflen = n; + return 0; +} + diff --git a/common/tlv.h b/common/tlv.h new file mode 100644 index 0000000..a04af93 --- /dev/null +++ b/common/tlv.h @@ -0,0 +1,113 @@ +/* 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 3 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, see . + */ + +#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 or if the object does not fit into the buffer. */ +const unsigned char *find_tlv (const unsigned char *buffer, size_t length, + int tag, size_t *nbytes); + + +/* 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_unchecked (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, + gpg_err_source_t errsource); +#define parse_ber_header(a,b,c,d,e,f,g,h) \ + _parse_ber_header ((a),(b),(c),(d),(e),(f),(g),(h),\ + GPG_ERR_SOURCE_DEFAULT) + + +/* Return the next token of an canconical encoded S-expression. BUF + is the pointer to the S-expression and BUFLEN is a pointer to the + length of this S-expression (used to validate the syntax). Both + are updated to reflect the new position. The token itself is + returned as a pointer into the orginal buffer at TOK and TOKLEN. + If a parentheses is the next token, TOK will be set to NULL. + TOKLEN is checked to be within the bounds. On error a error code + is returned and all pointers should are not guaranteed to point to + a meanigful value. DEPTH should be initialized to 0 and will + reflect on return the actual depth of the tree. To detect the end + of the S-expression it is advisable to check DEPTH after a + successful return. */ +gpg_error_t _parse_sexp (unsigned char const **buf, size_t *buflen, + int *depth, unsigned char const **tok, size_t *toklen, + gpg_err_source_t errsource); +#define parse_sexp(a,b,c,d,e) \ + _parse_sexp ((a),(b),(c),(d),(e), GPG_ERR_SOURCE_DEFAULT) + + + +#endif /* SCD_TLV_H */ diff --git a/common/ttyio.c b/common/ttyio.c new file mode 100644 index 0000000..fc27407 --- /dev/null +++ b/common/ttyio.c @@ -0,0 +1,690 @@ +/* ttyio.c - tty i/O functions + * Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2006,2007, + * 2009 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 3 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, see . + */ + +#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 "ttyio.h" +#include "estream-printf.h" +#include "common-defs.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 + +/* Hooks set by gpgrlhelp.c if required. */ +static void (*my_rl_set_completer) (rl_completion_func_t *); +static void (*my_rl_inhibit_completion) (int); +static void (*my_rl_cleanup_after_signal) (void); +static void (*my_rl_init_stream) (FILE *); +static char *(*my_rl_readline) (const char*); +static void (*my_rl_add_history) (const char*); + + +/* 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; + /* Note that despite our checks for these macros the function is + not necessarily thread save. We mainly do this for + portability reasons, in case L_ctermid is not defined. */ +# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_TRHEADS) + char buffer[L_ctermid]; + s = ctermid (buffer); +# else + s = ctermid (NULL); +# endif + if (s) + name = strdup (s); + got_name = 1; + } +#endif /*HAVE_CTERMID*/ + /* Assume the standard 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 */ + if (my_rl_init_stream) + my_rl_init_stream (ttyfp); +#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); + } + if (my_rl_init_stream) + my_rl_init_stream (ttyfp); +#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 regular + 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( (const char *)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 ) +{ + if (!batchmode && !no_terminal && my_rl_readline && my_rl_add_history) + { + char *line; + char *buf; + + if (!initialized) + init_ttyfp(); + + last_prompt_len = 0; + + line = my_rl_readline (prompt?prompt:""); + + /* We need to copy it to memory controlled by our malloc + implementations; further we need to convert an EOF to our + convention. */ + buf = xmalloc(line? strlen(line)+1:2); + if (line) + { + strcpy (buf, line); + trim_spaces (buf); + if (strlen (buf) > 2 ) + my_rl_add_history (line); /* Note that we test BUF but add LINE. */ + free (line); + } + else + { + buf[0] = CONTROL_D; + buf[1] = 0; + } + return buf; + } + else + return do_get ( prompt, 0 ); +} + +/* Variable argument version of tty_get. The prompt is is actually a + format string with arguments. */ +char * +tty_getf (const char *promptfmt, ... ) +{ + va_list arg_ptr; + char *prompt; + char *answer; + + va_start (arg_ptr, promptfmt); + if (estream_vasprintf (&prompt, promptfmt, arg_ptr) < 0) + log_fatal ("estream_vasprintf failed: %s\n", strerror (errno)); + va_end (arg_ptr); + answer = tty_get (prompt); + xfree (prompt); + return answer; +} + + + +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; +} + + +/* Called by gnupg_rl_initialize to setup the readline support. */ +void +tty_private_set_rl_hooks (void (*init_stream) (FILE *), + void (*set_completer) (rl_completion_func_t*), + void (*inhibit_completion) (int), + void (*cleanup_after_signal) (void), + char *(*readline_fun) (const char*), + void (*add_history_fun) (const char*)) +{ + my_rl_init_stream = init_stream; + my_rl_set_completer = set_completer; + my_rl_inhibit_completion = inhibit_completion; + my_rl_cleanup_after_signal = cleanup_after_signal; + my_rl_readline = readline_fun; + my_rl_add_history = add_history_fun; +} + + +#ifdef HAVE_LIBREADLINE +void +tty_enable_completion (rl_completion_func_t *completer) +{ + if (no_terminal || !my_rl_set_completer ) + return; + + if (!initialized) + init_ttyfp(); + + my_rl_set_completer (completer); +} + +void +tty_disable_completion (void) +{ + if (no_terminal || !my_rl_inhibit_completion) + return; + + if (!initialized) + init_ttyfp(); + + my_rl_inhibit_completion (1); +} +#endif + +void +tty_cleanup_after_signal (void) +{ +#ifdef HAVE_TCGETATTR + cleanup (); +#endif +} + +void +tty_cleanup_rl_after_signal (void) +{ + if (my_rl_cleanup_after_signal) + my_rl_cleanup_after_signal (); +} diff --git a/common/ttyio.h b/common/ttyio.h new file mode 100644 index 0000000..eb2116a --- /dev/null +++ b/common/ttyio.h @@ -0,0 +1,63 @@ +/* ttyio.h + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2006, + * 2009 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 3 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, see . + */ +#ifndef GNUPG_COMMON_TTYIO_H +#define GNUPG_COMMON_TTYIO_H + +#include "util.h" /* Make sure our readline typedef is available. */ + + +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))); +char *tty_getf (const char *promptfmt, ... ) + __attribute__ ((format (printf,1,2))); +#else +void tty_printf (const char *fmt, ... ); +void tty_fprintf (FILE *fp, const char *fmt, ... ); +char *tty_getf (const char *promptfmt, ... ); +#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); + +#ifdef HAVE_LIBREADLINE +void tty_enable_completion (rl_completion_func_t *completer); +void tty_disable_completion (void); +#else +/* Use a macro to stub out these functions since a macro has no need + to typedef a "rl_completion_func_t" which would be undefined + without readline. */ +#define tty_enable_completion(x) +#define tty_disable_completion() +#endif +void tty_cleanup_after_signal (void); +void tty_cleanup_rl_after_signal (void); + + +#endif /*GNUPG_COMMON_TTYIO_H*/ diff --git a/common/util.h b/common/util.h new file mode 100644 index 0000000..cad6c8e --- /dev/null +++ b/common/util.h @@ -0,0 +1,333 @@ +/* util.h - Utility functions for GnuPG + * Copyright (C) 2001, 2002, 2003, 2004, 2009 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 3 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, see . + */ + +#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 errno. */ +#include /* We need gpg_error_t. */ + +/* Add error codes available only in newer versions of libgpg-error. */ +#ifndef GPG_ERR_NOT_ENABLED +#define GPG_ERR_NOT_ENABLED 179 +#endif +#ifndef GPG_ERR_MISSING_ISSUER_CERT +#define GPG_ERR_MISSING_ISSUER_CERT 185 +#endif + +/* Hash function used with libksba. */ +#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" +#include "../jnlib/dynload.h" + +#include "init.h" + +/* Redefine asprintf by our estream version which uses our own memory + allocator.. */ +#include "estream-printf.h" +#define asprintf estream_asprintf +#define vasprintf estream_vasprintf + +/* Due to a bug in mingw32's snprintf related to the 'l' modifier we + better use our snprintf. */ +#ifdef HAVE_W32_SYSTEM +#define snprintf estream_snprintf +#endif + + +/* GCC attributes. */ +#if __GNUC__ >= 4 +# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a))) +#else +# define GNUPG_GCC_A_SENTINEL(a) +#endif + + +/* We need this type even if we are not using libreadline and or we + did not include libreadline in the current file. */ +#ifndef GNUPG_LIBREADLINE_H_INCLUDED +typedef char **rl_completion_func_t (const char *, int, int); +#endif /*!GNUPG_LIBREADLINE_H_INCLUDED*/ + + +/* 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)) + +/* For compatibility with gpg 1.4 we also define these: */ +#define xmalloc_clear(a) gcry_xcalloc (1, (a)) +#define xmalloc_secure_clear(a) gcry_xcalloc_secure (1, (a)) + +/* Convenience function to return a gpg-error code for memory + allocation failures. This function makes sure that an error will + be returned even if accidently ERRNO is not set. */ +static inline gpg_error_t +out_of_core (void) +{ + return gpg_error_from_syserror (); +} + +/* 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]; + + +/*-- 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); +time_t isotime2epoch (const char *string); +void epoch2isotime (gnupg_isotime_t timebuf, time_t atime); +u32 add_days_to_timestamp (u32 stamp, u16 days); +const char *strtimevalue (u32 stamp); +const char *strtimestamp (u32 stamp); /* GMT */ +const char *isotimestamp (u32 stamp); /* GMT */ +const char *asctimestamp (u32 stamp); /* localized */ +gpg_error_t add_seconds_to_isotime (gnupg_isotime_t atime, int nseconds); +gpg_error_t add_days_to_isotime (gnupg_isotime_t atime, int ndays); +gpg_error_t check_isotime (const gnupg_isotime_t atime); +void dump_isotime (const gnupg_isotime_t atime); + +/* Copy one ISO date to another, this is inline so that we can do a + minimal sanity check. A null date (empty string) is allowed. */ +static inline void +gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) +{ + if (*s) + { + if ((strlen (s) != 15 || s[8] != 'T')) + BUG(); + memcpy (d, s, 15); + d[15] = 0; + } + else + *d = 0; +} + + +/*-- 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); +int answer_is_okay_cancel (const char *s, int def_answer); + +/*-- xreadline.c --*/ +ssize_t read_line (FILE *fp, + char **addr_of_buffer, size_t *length_of_buffer, + size_t *max_length); + + +/*-- b64enc.c and b64dec.c --*/ +struct b64state +{ + unsigned int flags; + int idx; + int quad_count; + FILE *fp; + char *title; + unsigned char radbuf[4]; + u32 crc; + int stop_seen:1; + int invalid_encoding:1; +}; + +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); + +gpg_error_t b64dec_start (struct b64state *state, const char *title); +gpg_error_t b64dec_proc (struct b64state *state, void *buffer, size_t length, + size_t *r_nbytes); +gpg_error_t b64dec_finish (struct b64state *state); + + + + +/*-- sexputil.c */ +gpg_error_t make_canon_sexp (gcry_sexp_t sexp, + unsigned char **r_buffer, size_t *r_buflen); +gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, + unsigned char *grip); +int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b); +unsigned char *make_simple_sexp_from_hexstr (const char *line, + size_t *nscanned); +int hash_algo_from_sigval (const unsigned char *sigval); +unsigned char *make_canon_sexp_from_rsa_pk (const void *m, size_t mlen, + const void *e, size_t elen, + size_t *r_len); +gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, + size_t keydatalen, + unsigned char const **r_n, + size_t *r_nlen, + unsigned char const **r_e, + size_t *r_elen); +gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, + size_t keydatalen, + int *r_algo); + +/*-- convert.c --*/ +int hex2bin (const char *string, void *buffer, size_t length); +int hexcolon2bin (const char *string, void *buffer, size_t length); +char *bin2hex (const void *buffer, size_t length, char *stringbuf); +char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); +const char *hex2str (const char *hexstring, + char *buffer, size_t bufsize, size_t *buflen); +char *hex2str_alloc (const char *hexstring, size_t *r_count); + +/*-- percent.c --*/ +char *percent_plus_escape (const char *string); +char *percent_plus_unescape (const char *string, int nulrepl); +char *percent_unescape (const char *string, int nulrepl); + +size_t percent_plus_unescape_inplace (char *string, int nulrepl); +size_t percent_unescape_inplace (char *string, int nulrepl); + + +/*-- homedir.c --*/ +const char *standard_homedir (void); +const char *default_homedir (void); +const char *gnupg_sysconfdir (void); +const char *gnupg_bindir (void); +const char *gnupg_libexecdir (void); +const char *gnupg_libdir (void); +const char *gnupg_datadir (void); +const char *gnupg_localedir (void); +const char *dirmngr_socket_name (void); + +/* All module names. We also include gpg and gpgsm for the sake for + gpgconf. */ +#define GNUPG_MODULE_NAME_AGENT 1 +#define GNUPG_MODULE_NAME_PINENTRY 2 +#define GNUPG_MODULE_NAME_SCDAEMON 3 +#define GNUPG_MODULE_NAME_DIRMNGR 4 +#define GNUPG_MODULE_NAME_PROTECT_TOOL 5 +#define GNUPG_MODULE_NAME_CHECK_PATTERN 6 +#define GNUPG_MODULE_NAME_GPGSM 7 +#define GNUPG_MODULE_NAME_GPG 8 +#define GNUPG_MODULE_NAME_CONNECT_AGENT 9 +#define GNUPG_MODULE_NAME_GPGCONF 10 +const char *gnupg_module_name (int which); + + + +/*-- gpgrlhelp.c --*/ +void gnupg_rl_initialize (void); + +/*-- helpfile.c --*/ +char *gnupg_get_help_string (const char *key, int only_current_locale); + +/*-- localename.c --*/ +const char *gnupg_messages_locale_name (void); + +/*-- miscellaneous.c --*/ + +/* This function is called at startup to tell libgcrypt to use our own + logging subsystem. */ +void setup_libgcrypt_logging (void); + +/* Same as estream_asprintf but die on memory failure. */ +char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); +/* This is now an alias to estream_asprintf. */ +char *xtryasprintf (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); +void print_hexstring (FILE *fp, const void *buffer, size_t length, + int reserved); +char *make_printable_string (const void *p, size_t n, int delim); + +int is_file_compressed (const char *s, int *ret_rc); + +int match_multistr (const char *multistr,const char *match); + + +/*-- Simple replacement functions. */ +#ifndef HAVE_TTYNAME +/* Systems without ttyname (W32) will merely return NULL. */ +static inline char * +ttyname (int fd) +{ + (void)fd; + return NULL; +} +#endif /* !HAVE_TTYNAME */ + + +/*-- Macros to replace ctype ones to 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)) + + +/*-- Forward declaration of the commonly used server control structure. */ +/* (We need it here as it is used by some callback prototypes.) */ +struct server_control_s; +typedef struct server_control_s *ctrl_t; + + +#endif /*GNUPG_COMMON_UTIL_H*/ diff --git a/common/xasprintf.c b/common/xasprintf.c new file mode 100644 index 0000000..9774d06 --- /dev/null +++ b/common/xasprintf.c @@ -0,0 +1,62 @@ +/* xasprintf.c + * Copyright (C) 2003, 2005 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 3 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, see . + */ + +#include +#include +#include + +#include "util.h" +#include "iobuf.h" +#include "estream-printf.h" + +#if !defined(_ESTREAM_PRINTF_MALLOC) || !defined(_ESTREAM_PRINTF_FREE) +#error Need to define ESTREAM_PRINTF_MALLOC and _FREE +#endif + +/* 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; + + va_start (ap, fmt); + if (estream_vasprintf (&buf, fmt, ap) < 0) + log_fatal ("estream_asprintf failed: %s\n", strerror (errno)); + va_end (ap); + return buf; +} + +/* Same as above but return NULL on memory failure. */ +char * +xtryasprintf (const char *fmt, ...) +{ + int rc; + va_list ap; + char *buf; + + va_start (ap, fmt); + rc = estream_vasprintf (&buf, fmt, ap); + va_end (ap); + if (rc < 0) + return NULL; + return buf; +} diff --git a/common/xreadline.c b/common/xreadline.c new file mode 100644 index 0000000..8ca72b7 --- /dev/null +++ b/common/xreadline.c @@ -0,0 +1,117 @@ +/* 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 3 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, see . + */ + +#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 by 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 starts with the 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 = 0; + if (max_length) + *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 new file mode 100644 index 0000000..a7131b7 --- /dev/null +++ b/common/yesno.c @@ -0,0 +1,141 @@ +/* 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 3 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, see . + */ + +#include +#include +#include + +#include "i18n.h" +#include "util.h" + + +/* Check the string S for a YES or NO answer and take care of + localization. If no valid string is given the value of DEF_ANSWER + is returned. Returns 1 for yes and 0 for no. */ +int +answer_is_yes_no_default (const char *s, int def_answer) +{ + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + const char *short_yes = _("yY"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + const char *short_no = _("nN"); + + /* Note: we have to use the local dependent compare here. */ + if ( match_multistr(long_yes,s) ) + return 1; + if ( *s && strchr( short_yes, *s ) && !s[1] ) + return 1; + /* Test for "no" strings to catch ambiguities for the next test. */ + if ( match_multistr(long_no,s) ) + 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 ) +{ + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + 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 a local dependent compare here. */ + if ( match_multistr(long_no,s) ) + return 0; + if ( match_multistr(long_yes,s) ) + return 1; + if ( match_multistr(long_quit,s) ) + 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; +} + +/* + Return 1 for okay, 0 for for cancel or DEF_ANSWER for default. + */ +int +answer_is_okay_cancel (const char *s, int def_answer) +{ + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_okay = _("okay|okay"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_cancel = _("cancel|cancel"); + const char *short_okay = _("oO"); + const char *short_cancel = _("cC"); + + /* Note: We have to use the locale dependent compare. */ + if ( match_multistr(long_okay,s) ) + return 1; + if ( match_multistr(long_cancel,s) ) + return 0; + if ( *s && strchr( short_okay, *s ) && !s[1] ) + return 1; + if ( *s && strchr( short_cancel, *s ) && !s[1] ) + return 0; + /* Always test for the English values (not locale here). */ + if ( !ascii_strcasecmp(s, "okay" ) ) + return 1; + if ( !ascii_strcasecmp(s, "ok" ) ) + return 1; + if ( !ascii_strcasecmp(s, "cancel" ) ) + return 0; + if ( *s && strchr( "oO", *s ) && !s[1] ) + return 1; + if ( *s && strchr( "cC", *s ) && !s[1] ) + return 0; + return def_answer; +} + diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..c10904b --- /dev/null +++ b/config.h.in @@ -0,0 +1,891 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef GNUPG_CONFIG_H_INCLUDED +#define GNUPG_CONFIG_H_INCLUDED + + +/* Define this to an absolute name of . */ +#undef ABSOLUTE_STDINT_H + +/* Defined if the host has big endian byte ordering */ +#undef BIG_ENDIAN_HOST + +/* an Apple OSXism */ +#undef BIND_8_COMPAT + +/* Define to the number of bits in type 'ptrdiff_t'. */ +#undef BITSIZEOF_PTRDIFF_T + +/* Define to the number of bits in type 'sig_atomic_t'. */ +#undef BITSIZEOF_SIG_ATOMIC_T + +/* Define to the number of bits in type 'size_t'. */ +#undef BITSIZEOF_SIZE_T + +/* Define to the number of bits in type 'wchar_t'. */ +#undef BITSIZEOF_WCHAR_T + +/* Define to the number of bits in type 'wint_t'. */ +#undef BITSIZEOF_WINT_T + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* define to disable keyserver helpers */ +#undef DISABLE_KEYSERVER_HELPERS + +/* Defined to disable exec-path for keyserver helpers */ +#undef DISABLE_KEYSERVER_PATH + +/* define to disable photo viewing */ +#undef DISABLE_PHOTO_VIEWER + +/* Define to disable regular expression support */ +#undef DISABLE_REGEX + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to enable SELinux support */ +#undef ENABLE_SELINUX_HACKS + +/* The executable file extension, if any */ +#undef EXEEXT + +/* if set, restrict photo-viewer to this */ +#undef FIXED_PHOTO_VIEWER + +/* version of the libbassuan library */ +#undef GNUPG_LIBASSUAN_VERSION + +/* Define to 1 if you have the `adns_free' function. */ +#undef HAVE_ADNS_FREE + +/* Define to 1 if you have the header file. */ +#undef HAVE_ADNS_H + +/* Define to 1 if you have `alloca' after including , a header that + may be supplied by this distribution. */ +#undef HAVE_ALLOCA + +/* Define HAVE_ALLOCA_H for backward compatibility with older code that + includes only if HAVE_ALLOCA_H is defined. */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Defined if a `byte' is typedef'd */ +#undef HAVE_BYTE_TYPEDEF + +/* Defined if the bz2 compression library is available */ +#undef HAVE_BZIP2 + +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +#undef HAVE_CFLOCALECOPYCURRENT + +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +#undef HAVE_CFPREFERENCESCOPYAPPVALUE + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the `ctermid' function. */ +#undef HAVE_CTERMID + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the declaration of `getpagesize', and to 0 if you + don't. */ +#undef HAVE_DECL_GETPAGESIZE + +/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_SIGLIST + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRECT_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) + with special properties like no file modes */ +#undef HAVE_DOSISH_SYSTEM + +/* defined if we must run on a stupid file system */ +#undef HAVE_DRIVE_LETTERS + +/* Define if you have the declaration of environ. */ +#undef HAVE_ENVIRON_DECL + +/* Define to 1 if you have the `fcntl' function. */ +#undef HAVE_FCNTL + +/* Define to 1 if you have the `flockfile' function. */ +#undef HAVE_FLOCKFILE + +/* Define to 1 if you have the `fopencookie' function. */ +#undef HAVE_FOPENCOOKIE + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the `fsync' function. */ +#undef HAVE_FSYNC + +/* Define to 1 if you have the `ftello' function. */ +#undef HAVE_FTELLO + +/* Define to 1 if you have the `ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* Define to 1 if you have the `funlockfile' function. */ +#undef HAVE_FUNLOCKFILE + +/* Define to 1 if you have the `funopen' function. */ +#undef HAVE_FUNOPEN + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `getpwnam' function. */ +#undef HAVE_GETPWNAM + +/* Define to 1 if you have the `getpwuid' function. */ +#undef HAVE_GETPWUID + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `gmtime_r' function. */ +#undef HAVE_GMTIME_R + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if the system has the type `intmax_t'. */ +#undef HAVE_INTMAX_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `isascii' function. */ +#undef HAVE_ISASCII + +/* Define if you have and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Define to 1 if you have the header file. */ +#undef HAVE_LANGINFO_H + +/* Define if you have and nl_langinfo(THOUSANDS_SEP). */ +#undef HAVE_LANGINFO_THOUSANDS_SEP + +/* Define if your file defines LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if you have the `ldap_get_option' function. */ +#undef HAVE_LDAP_GET_OPTION + +/* Define if the LDAP library supports ld_errno */ +#undef HAVE_LDAP_LD_ERRNO + +/* Define to 1 if you have the `ldap_set_option' function. */ +#undef HAVE_LDAP_SET_OPTION + +/* Define to 1 if you have the `ldap_start_tls_s' function. */ +#undef HAVE_LDAP_START_TLS_S + +/* Define to 1 if you have the `ldap_start_tls_sA' function. */ +#undef HAVE_LDAP_START_TLS_SA + +/* Define to 1 if you have a functional curl library. */ +#undef HAVE_LIBCURL + +/* Define to 1 if you have a fully functional readline library. */ +#undef HAVE_LIBREADLINE + +/* defined if libusb is available */ +#undef HAVE_LIBUSB + +/* defined if libutil is available */ +#undef HAVE_LIBUTIL + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if the system has the type `long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if the system has the type `long long int'. */ +#undef HAVE_LONG_LONG_INT + +/* Define to 1 if you have the `memicmp' function. */ +#undef HAVE_MEMICMP + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memrchr' function. */ +#undef HAVE_MEMRCHR + +/* Define to 1 if you have the `mkdtemp' function. */ +#undef HAVE_MKDTEMP + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `nl_langinfo' function. */ +#undef HAVE_NL_LANGINFO + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Defined if the GNU Pth is available */ +#undef HAVE_PTH + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#undef HAVE_PTRDIFF_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the `raise' function. */ +#undef HAVE_RAISE + +/* Define to 1 if you have the `rand' function. */ +#undef HAVE_RAND + +/* Define to 1 if you have the header file. */ +#undef HAVE_SEARCH_H + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ +#undef HAVE_SIGNED_SIG_ATOMIC_T + +/* Define to 1 if 'wchar_t' is a signed integer type. */ +#undef HAVE_SIGNED_WCHAR_T + +/* Define to 1 if 'wint_t' is a signed integer type. */ +#undef HAVE_SIGNED_WINT_T + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + +/* Define to 1 if the system has the type `sigset_t'. */ +#undef HAVE_SIGSET_T + +/* Define to 1 if you have the `stat' function. */ +#undef HAVE_STAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `stpcpy' function. */ +#undef HAVE_STPCPY + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the `stricmp' function. */ +#undef HAVE_STRICMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlwr' function. */ +#undef HAVE_STRLWR + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the `strpbrk' function. */ +#undef HAVE_STRPBRK + +/* Define to 1 if you have the `strsep' function. */ +#undef HAVE_STRSEP + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if the system has the type `struct sigaction'. */ +#undef HAVE_STRUCT_SIGACTION + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `tcgetattr' function. */ +#undef HAVE_TCGETATTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define to 1 if you have the `timegm' function. */ +#undef HAVE_TIMEGM + +/* Define to 1 if you have the `times' function. */ +#undef HAVE_TIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the `tsearch' function. */ +#undef HAVE_TSEARCH + +/* Define to 1 if you have the `ttyname' function. */ +#undef HAVE_TTYNAME + +/* Defined if a `u16' is typedef'd */ +#undef HAVE_U16_TYPEDEF + +/* Defined if a `u32' is typedef'd */ +#undef HAVE_U32_TYPEDEF + +/* Define to 1 if the system has the type `uintmax_t'. */ +#undef HAVE_UINTMAX_T + +/* Defined if a `ulong' is typedef'd */ +#undef HAVE_ULONG_TYPEDEF + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `unsetenv' function. */ +#undef HAVE_UNSETENV + +/* Define to 1 if the system has the type `unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + +/* Define to 1 if you have the `usb_create_match' function. */ +#undef HAVE_USB_CREATE_MATCH + +/* Defined if a `ushort' is typedef'd */ +#undef HAVE_USHORT_TYPEDEF + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTMP_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Defined if we run on a W32 API based system */ +#undef HAVE_W32_SYSTEM + +/* Define to 1 if you have the `wait4' function. */ +#undef HAVE_WAIT4 + +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* Define as const if the declaration of iconv() needs const. */ +#undef ICONV_CONST + +/* Defined if this is not a regular release */ +#undef IS_DEVELOPMENT_VERSION + +/* Defined if libcurl supports AsynchDNS */ +#undef LIBCURL_FEATURE_ASYNCHDNS + +/* Defined if libcurl supports IDN */ +#undef LIBCURL_FEATURE_IDN + +/* Defined if libcurl supports IPv6 */ +#undef LIBCURL_FEATURE_IPV6 + +/* Defined if libcurl supports KRB4 */ +#undef LIBCURL_FEATURE_KRB4 + +/* Defined if libcurl supports libz */ +#undef LIBCURL_FEATURE_LIBZ + +/* Defined if libcurl supports NTLM */ +#undef LIBCURL_FEATURE_NTLM + +/* Defined if libcurl supports SSL */ +#undef LIBCURL_FEATURE_SSL + +/* Defined if libcurl supports SSPI */ +#undef LIBCURL_FEATURE_SSPI + +/* Defined if libcurl supports DICT */ +#undef LIBCURL_PROTOCOL_DICT + +/* Defined if libcurl supports FILE */ +#undef LIBCURL_PROTOCOL_FILE + +/* Defined if libcurl supports FTP */ +#undef LIBCURL_PROTOCOL_FTP + +/* Defined if libcurl supports FTPS */ +#undef LIBCURL_PROTOCOL_FTPS + +/* Defined if libcurl supports HTTP */ +#undef LIBCURL_PROTOCOL_HTTP + +/* Defined if libcurl supports HTTPS */ +#undef LIBCURL_PROTOCOL_HTTPS + +/* Defined if libcurl supports LDAP */ +#undef LIBCURL_PROTOCOL_LDAP + +/* Defined if libcurl supports TELNET */ +#undef LIBCURL_PROTOCOL_TELNET + +/* Defined if libcurl supports TFTP */ +#undef LIBCURL_PROTOCOL_TFTP + +/* Defined if the host has little endian byte ordering */ +#undef LITTLE_ENDIAN_HOST + +/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */ +#undef MALLOC_0_IS_NONNULL + +/* Defined if mkdir() does not take permission flags */ +#undef MKDIR_TAKES_ONE_ARG + +/* Required version of Libksba */ +#undef NEED_KSBA_VERSION + +/* Define if the LDAP library requires including lber.h before ldap.h */ +#undef NEED_LBER_H + +/* Required version of Libgcrypt */ +#undef NEED_LIBGCRYPT_VERSION + +/* Define to disable all external program execution */ +#undef NO_EXEC + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of this package */ +#undef PACKAGE + +/* Bug report address */ +#undef PACKAGE_BUGREPORT + +/* Name of this package for gettext */ +#undef PACKAGE_GT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Size of the key and UID caches */ +#undef PK_UID_CACHE_SIZE + +/* A human readable text with the name of the OS */ +#undef PRINTABLE_OS_NAME + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'ptrdiff_t'. */ +#undef PTRDIFF_T_SUFFIX + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* defines the filename of the shred program */ +#undef SHRED + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'sig_atomic_t'. */ +#undef SIG_ATOMIC_T_SUFFIX + +/* The size of `time_t', as computed by sizeof. */ +#undef SIZEOF_TIME_T + +/* The size of `uint64_t', as computed by sizeof. */ +#undef SIZEOF_UINT64_T + +/* The size of `unsigned int', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_INT + +/* The size of `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* The size of `unsigned long long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG_LONG + +/* The size of `unsigned short', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_SHORT + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define as the maximum value of type 'size_t', if the system doesn't define + it. */ +#undef SIZE_MAX + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'size_t'. */ +#undef SIZE_T_SUFFIX + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Use ADNS as resolver library. */ +#undef USE_ADNS + +/* define to use DNS CERT */ +#undef USE_DNS_CERT + +/* define to use our experimental DNS PKA */ +#undef USE_DNS_PKA + +/* define to use DNS SRV */ +#undef USE_DNS_SRV + +/* Defined if the GNU Portable Thread Library should be used */ +#undef USE_GNU_PTH + +/* set this to limit filenames to the 8.3 format */ +#undef USE_ONLY_8DOT3 + +/* because the Unix gettext has too much overhead on MingW32 systems and these + systems lack Posix functions, we use a simplified version of gettext */ +#undef USE_SIMPLE_GETTEXT + +/* Use a standard socket for the agent by default */ +#undef USE_STANDARD_SOCKET + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Version of this package */ +#undef VERSION + +/* Define if unsetenv() returns void, not int. */ +#undef VOID_UNSETENV + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wchar_t'. */ +#undef WCHAR_T_SUFFIX + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wint_t'. */ +#undef WINT_T_SUFFIX + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define curl_free() as free() if our version of curl lacks curl_free. */ +#undef curl_free + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the widest signed integer type if and do + not define. */ +#undef intmax_t + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* type to use in place of socklen_t if not defined */ +#undef socklen_t + +/* Define to the widest unsigned integer type if and + do not define. */ +#undef uintmax_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile + + +/* 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 DIRSEP_S "\\" +#define EXTSEP_C '.' +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#define EXEEXT_S ".exe" +#else +#define DIRSEP_C '/' +#define DIRSEP_S "/" +#define EXTSEP_C '.' +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#define EXEEXT_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 '-' + +/* 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" + +/* 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 + /* FIXME: We need to use a function to determine these values depending + on the actual installation directory. */ +#define GNUPG_BINDIR "c:\\gnupg" +#define GNUPG_LIBEXECDIR "c:\\gnupg" +#define GNUPG_LIBDIR "c:\\gnupg" +#define GNUPG_DATADIR "c:\\gnupg" +#define GNUPG_SYSCONFDIR "c:\\gnupg" +#endif + +/* Derive some other constants. */ +#if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) +#define EXEC_TEMPFILE_ONLY +#endif + + +/* We didn't define endianness above, so get it from OS macros. This + is intended for making fat binary builds on OS X. */ +#if !defined(BIG_ENDIAN_HOST) && !defined(LITTLE_ENDIAN_HOST) +#if defined(__BIG_ENDIAN__) +#define BIG_ENDIAN_HOST 1 +#elif defined(__LITTLE_ENDIAN__) +#define LITTLE_ENDIAN_HOST 1 +#else +#error "No endianness found" +#endif +#endif + + +/* Hack used for W32: ldap.m4 also tests for the ASCII version of + ldap_start_tls_s because that is the actual symbol used in the + library. winldap.h redefines it to our commonly used value, + thus we define our usual macro here. */ +#ifdef HAVE_LDAP_START_TLS_SA +# ifndef HAVE_LDAP_START_TLS_S +# define HAVE_LDAP_START_TLS_S 1 +# endif +#endif + + +/* Tell libgcrypt not to use its own libgpg-error implementation. */ +#define USE_LIBGPG_ERROR 1 + +/* We use jnlib, so tell other modules about it. */ +#define HAVE_JNLIB_LOGGING 1 + +/* Our HTTP code is used in estream mode. */ +#define HTTP_USE_ESTREAM 1 + +/* Under W32 we do an explicit socket initialization, thus we need to + avoid the on-demand initialization which would also install an atexit + handler. */ +#define HTTP_NO_WSASTARTUP + +/* We always include support for the OpenPGP card. */ +#define ENABLE_CARD_SUPPORT 1 + +/* We don't want the old assuan codes anymore. */ +#define _ASSUAN_ONLY_GPG_ERRORS 1 + +/* We explicitly need to disable PTH's soft mapping as Debian + currently enables it by default for no reason. */ +#define PTH_SYSCALL_SOFT 0 + +/* We want to use the libgcrypt provided memory allocation for + asprintf. */ +#define _ESTREAM_PRINTF_MALLOC gcry_malloc +#define _ESTREAM_PRINTF_FREE gcry_free +#define _ESTREAM_PRINTF_EXTRA_INCLUDE "util.h" + +#endif /*GNUPG_CONFIG_H_INCLUDED*/ + diff --git a/configure b/configure new file mode 100755 index 0000000..829fc79 --- /dev/null +++ b/configure @@ -0,0 +1,17748 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for gnupg 2.0.19. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: http://bugs.gnupg.org about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='gnupg' +PACKAGE_TARNAME='gnupg' +PACKAGE_VERSION='2.0.19' +PACKAGE_STRING='gnupg 2.0.19' +PACKAGE_BUGREPORT='http://bugs.gnupg.org' +PACKAGE_URL='' + +ac_unique_file="sm/gpgsm.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +gt_needs= +ac_header_list= +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +RUN_GPG_TESTS_FALSE +RUN_GPG_TESTS_TRUE +BUILD_GPGTAR_FALSE +BUILD_GPGTAR_TRUE +BUILD_SYMCRYPTRUN_FALSE +BUILD_SYMCRYPTRUN_TRUE +BUILD_DOC_FALSE +BUILD_DOC_TRUE +BUILD_TOOLS_FALSE +BUILD_TOOLS_TRUE +BUILD_SCDAEMON_FALSE +BUILD_SCDAEMON_TRUE +BUILD_AGENT_FALSE +BUILD_AGENT_TRUE +BUILD_GPGSM_FALSE +BUILD_GPGSM_TRUE +BUILD_GPG_FALSE +BUILD_GPG_TRUE +GPGKEYS_KDNS +W32SOCKLIBS +NETLIBS +CROSS_COMPILING_FALSE +CROSS_COMPILING_TRUE +LIBREADLINE +ZLIBS +ENABLE_BZIP2_SUPPORT_FALSE +ENABLE_BZIP2_SUPPORT_TRUE +DISABLE_REGEX_FALSE +DISABLE_REGEX_TRUE +LIBGNU_LTLIBDEPS +LIBGNU_LIBDEPS +UNISTD_H +STDINT_H +WINT_T_SUFFIX +WCHAR_T_SUFFIX +SIZE_T_SUFFIX +SIG_ATOMIC_T_SUFFIX +PTRDIFF_T_SUFFIX +HAVE_SIGNED_WINT_T +HAVE_SIGNED_WCHAR_T +HAVE_SIGNED_SIG_ATOMIC_T +BITSIZEOF_WINT_T +BITSIZEOF_WCHAR_T +BITSIZEOF_SIZE_T +BITSIZEOF_SIG_ATOMIC_T +BITSIZEOF_PTRDIFF_T +HAVE_SYS_BITYPES_H +HAVE_SYS_INTTYPES_H +HAVE_STDINT_H +ABSOLUTE_STDINT_H +HAVE_SYS_TYPES_H +HAVE_INTTYPES_H +HAVE_WCHAR_H +HAVE_UNSIGNED_LONG_LONG_INT +HAVE_LONG_LONG_INT +LIBOBJS +ALLOCA_H +ALLOCA +GL_COND_LIBTOOL_FALSE +GL_COND_LIBTOOL_TRUE +SYS_SOCKET_H +BUILD_INCLUDED_LIBINTL +USE_INCLUDED_LIBINTL +POSUB +LTLIBINTL +LIBINTL +INTLLIBS +INTL_MACOSX_LIBS +XGETTEXT_EXTRA_OPTIONS +MSGMERGE +XGETTEXT_015 +XGETTEXT +GMSGFMT_015 +MSGFMT_015 +GMSGFMT +MSGFMT +GETTEXT_MACRO_VERSION +USE_NLS +LTLIBICONV +LIBICONV +GPGKEYS_MAILTO +SENDMAIL +GPGKEYS_CURL +FAKE_CURL_FALSE +FAKE_CURL_TRUE +LIBCURL +LIBCURL_CPPFLAGS +_libcurl_config +LDAP_CPPFLAGS +LDAPLIBS +GPGKEYS_LDAP +USE_DNS_SRV_FALSE +USE_DNS_SRV_TRUE +DNSLIBS +ADNSLIBS +PTH_LIBS +PTH_CFLAGS +PTH_CONFIG +SHRED +LIBUTIL_LIBS +DL_LIBS +LIBUSB_LIBS +KSBA_LIBS +KSBA_CFLAGS +KSBA_CONFIG +LIBASSUAN_LIBS +LIBASSUAN_CFLAGS +LIBASSUAN_CONFIG +LIBGCRYPT_LIBS +LIBGCRYPT_CFLAGS +LIBGCRYPT_CONFIG +GPG_ERROR_LIBS +GPG_ERROR_CFLAGS +GPG_ERROR_CONFIG +GPGKEYS_FINGER +GPGKEYS_HKP +HAVE_W32_SYSTEM_FALSE +HAVE_W32_SYSTEM_TRUE +USE_SIMPLE_GETTEXT_FALSE +USE_SIMPLE_GETTEXT_TRUE +HAVE_DOSISH_SYSTEM_FALSE +HAVE_DOSISH_SYSTEM_TRUE +CC_FOR_BUILD +HAVE_USTAR_FALSE +HAVE_USTAR_TRUE +TAR +WORKING_FAQPROG_FALSE +WORKING_FAQPROG_TRUE +FAQPROG +WINDRES +PERL +AR +RANLIB +LN_S +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +GNUPG_PROTECT_TOOL_PGM_FALSE +GNUPG_PROTECT_TOOL_PGM_TRUE +GNUPG_PROTECT_TOOL_PGM +GNUPG_DIRMNGR_PGM_FALSE +GNUPG_DIRMNGR_PGM_TRUE +GNUPG_DIRMNGR_PGM +GNUPG_SCDAEMON_PGM_FALSE +GNUPG_SCDAEMON_PGM_TRUE +GNUPG_SCDAEMON_PGM +GNUPG_PINENTRY_PGM_FALSE +GNUPG_PINENTRY_PGM_TRUE +GNUPG_PINENTRY_PGM +GNUPG_AGENT_PGM_FALSE +GNUPG_AGENT_PGM_TRUE +GNUPG_AGENT_PGM +PACKAGE_GT +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_gpg +enable_gpgsm +enable_agent +enable_scdaemon +enable_tools +enable_doc +enable_symcryptrun +enable_gpgtar +with_agent_pgm +with_pinentry_pgm +with_scdaemon_pgm +with_dirmngr_pgm +with_protect_tool_pgm +enable_agent_only +enable_selinux_support +enable_bzip2 +enable_exec +enable_photo_viewers +with_photo_viewer +enable_keyserver_helpers +enable_ldap +enable_hkp +enable_finger +enable_generic +enable_mailto +enable_keyserver_path +enable_key_cache +with_capabilities +enable_ccid_driver +enable_maintainer_mode +enable_largefile +with_tar +enable_standard_socket +with_gpg_error_prefix +with_libgcrypt_prefix +with_libassuan_prefix +with_ksba_prefix +with_pth_prefix +with_adns +enable_dns_srv +enable_dns_pka +enable_dns_cert +with_ldap +with_libcurl +with_mailprog +with_gnu_ld +enable_rpath +with_libiconv_prefix +enable_nls +with_libintl_prefix +enable_endian_check +enable_regex +with_regex +with_zlib +with_bzip2 +with_readline +enable_optimization +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CC_FOR_BUILD' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures gnupg 2.0.19 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/gnupg] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of gnupg 2.0.19:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-gpg do not build the gpg program + --disable-gpgsm do not build the gpgsm program + --disable-agent do not build the agent program + --disable-scdaemon do not build the scdaemon program + --disable-tools do not build the tools program + --disable-doc do not build the doc program + --enable-symcryptrun build the symcryptrun program + --enable-gpgtar build the gpgtar program + --enable-agent-only build only the gpg-agent + --enable-selinux-support + enable SELinux support + --disable-bzip2 disable the BZIP2 compression algorithm + --disable-exec disable all external program execution + --disable-photo-viewers disable photo ID viewers + --disable-keyserver-helpers disable all external keyserver support + --disable-ldap disable LDAP keyserver interface only + --disable-hkp disable HKP keyserver interface only + --disable-finger disable finger key fetching interface only + --disable-generic disable generic object key fetching interface only + --enable-mailto enable email keyserver interface only + --disable-keyserver-path + disable the exec-path option for keyserver helpers + --enable-key-cache=SIZE Set key cache to SIZE (default 4096) + --disable-ccid-driver disable the internal CCID driver + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-largefile omit support for large files + --enable-standard-socket + use a standard socket for the agent by default + --disable-dns-srv disable the use of DNS SRV in HKP and HTTP + --disable-dns-pka disable the use of PKA records in DNS + --disable-dns-cert disable the use of CERT records in DNS + --disable-rpath do not hardcode runtime library paths + --disable-nls do not use Native Language Support + --disable-endian-check disable the endian check and trust the OS provided + macros + --disable-regex do not handle regular expressions in trust + signatures + --disable-optimization disable compiler optimization + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-agent-pgm=PATH Use PATH as the default for the agent) + --with-pinentry-pgm=PATH Use PATH as the default for the pinentry) + --with-scdaemon-pgm=PATH Use PATH as the default for the scdaemon) + --with-dirmngr-pgm=PATH Use PATH as the default for the dirmngr) + --with-protect-tool-pgm=PATH Use PATH as the default for the protect-tool) + --with-photo-viewer=FIXED_VIEWER set a fixed photo ID viewer + --with-capabilities use linux capabilities default=no + --with-tar=PATH look for a tar program in PATH + --with-gpg-error-prefix=PFX + prefix where GPG Error is installed (optional) + --with-libgcrypt-prefix=PFX + prefix where LIBGCRYPT is installed (optional) + --with-libassuan-prefix=PFX + prefix where LIBASSUAN is installed (optional) + --with-ksba-prefix=PFX prefix where KSBA is installed (optional) + --with-pth-prefix=PFX prefix where GNU Pth is installed (optional) + --with-adns=DIR look for the adns library in DIR + --with-ldap=DIR look for the LDAP library in DIR + --with-libcurl=DIR look for the curl library in DIR + --with-mailprog=NAME use "NAME -t" for mail transport + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib + --without-libintl-prefix don't search for libintl in includedir and libdir + --with-regex=DIR look for regex in DIR + --with-zlib=DIR use libz in DIR + --with-bzip2=DIR look for bzip2 in DIR + --with-readline=DIR look for the readline library in DIR + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CC_FOR_BUILD + build system C compiler + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +gnupg configure 2.0.19 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------ ## +## Report this to http://bugs.gnupg.org ## +## ------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library 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_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by gnupg $as_me 2.0.19, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +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 || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +gt_needs="$gt_needs need-ngettext" +as_fn_append ac_header_list " sys/socket.h" +as_fn_append ac_header_list " sys/time.h" +as_fn_append ac_header_list " unistd.h" +as_fn_append ac_header_list " wchar.h" +as_fn_append ac_header_list " stdint.h" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# 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=no + +NEED_GPG_ERROR_VERSION=1.7 + +NEED_LIBGCRYPT_API=1 +NEED_LIBGCRYPT_VERSION=1.4.0 + +NEED_LIBASSUAN_API=2 +NEED_LIBASSUAN_VERSION=2.0.0 + +NEED_KSBA_API=1 +NEED_KSBA_VERSION=1.0.7 + + +PACKAGE=$PACKAGE_NAME +PACKAGE_GT=${PACKAGE_NAME}2 +VERSION=$PACKAGE_VERSION + +ac_aux_dir= +for ac_dir in scripts "$srcdir"/scripts; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in scripts \"$srcdir\"/scripts" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +ac_config_headers="$ac_config_headers config.h" + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=$PACKAGE + VERSION=$VERSION + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild project... ${PACKAGE_NAME:-$PACKAGE}" >&5 +$as_echo "$as_me: autobuild project... ${PACKAGE_NAME:-$PACKAGE}" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild revision... ${PACKAGE_VERSION:-$VERSION}" >&5 +$as_echo "$as_me: autobuild revision... ${PACKAGE_VERSION:-$VERSION}" >&6;} + hostname=`hostname` + if test "$hostname"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild hostname... $hostname" >&5 +$as_echo "$as_me: autobuild hostname... $hostname" >&6;} + fi + + date=`date +%Y%m%d-%H%M%S` + if test "$?" != 0; then + date=`date` + fi + if test "$date"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild timestamp... $date" >&5 +$as_echo "$as_me: autobuild timestamp... $date" >&6;} + fi + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + + +# Some status variables. +have_gpg_error=no +have_libgcrypt=no +have_libassuan=no +have_ksba=no +have_pth=no +have_libusb=no +have_adns=no + +use_bzip2=yes +use_exec=yes +disable_keyserver_path=no +use_ccid_driver=yes +use_standard_socket=no + +build_gpg=yes + + # Check whether --enable-gpg was given. +if test "${enable_gpg+set}" = set; then : + enableval=$enable_gpg; build_gpg=$enableval +else + build_gpg=yes +fi + + + case "$build_gpg" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-gpg" "$LINENO" 5 + ;; + esac + +build_gpgsm=yes + + # Check whether --enable-gpgsm was given. +if test "${enable_gpgsm+set}" = set; then : + enableval=$enable_gpgsm; build_gpgsm=$enableval +else + build_gpgsm=yes +fi + + + case "$build_gpgsm" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-gpgsm" "$LINENO" 5 + ;; + esac + +build_agent=yes + + # Check whether --enable-agent was given. +if test "${enable_agent+set}" = set; then : + enableval=$enable_agent; build_agent=$enableval +else + build_agent=yes +fi + + + case "$build_agent" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-agent" "$LINENO" 5 + ;; + esac + +build_scdaemon=yes + + # Check whether --enable-scdaemon was given. +if test "${enable_scdaemon+set}" = set; then : + enableval=$enable_scdaemon; build_scdaemon=$enableval +else + build_scdaemon=yes +fi + + + case "$build_scdaemon" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-scdaemon" "$LINENO" 5 + ;; + esac + +build_tools=yes + + # Check whether --enable-tools was given. +if test "${enable_tools+set}" = set; then : + enableval=$enable_tools; build_tools=$enableval +else + build_tools=yes +fi + + + case "$build_tools" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-tools" "$LINENO" 5 + ;; + esac + +build_doc=yes + + # Check whether --enable-doc was given. +if test "${enable_doc+set}" = set; then : + enableval=$enable_doc; build_doc=$enableval +else + build_doc=yes +fi + + + case "$build_doc" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-doc" "$LINENO" 5 + ;; + esac + +build_symcryptrun=no + + # Check whether --enable-symcryptrun was given. +if test "${enable_symcryptrun+set}" = set; then : + enableval=$enable_symcryptrun; build_symcryptrun=$enableval +else + build_symcryptrun=no +fi + + + case "$build_symcryptrun" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-symcryptrun" "$LINENO" 5 + ;; + esac + +build_gpgtar=no + + # Check whether --enable-gpgtar was given. +if test "${enable_gpgtar+set}" = set; then : + enableval=$enable_gpgtar; build_gpgtar=$enableval +else + build_gpgtar=no +fi + + + case "$build_gpgtar" in + no|yes) + ;; + *) + as_fn_error $? "only yes or no allowed for feature --enable-gpgtar" "$LINENO" 5 + ;; + esac + + + + + + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_GT "$PACKAGE_GT" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define NEED_LIBGCRYPT_VERSION "$NEED_LIBGCRYPT_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define NEED_KSBA_VERSION "$NEED_KSBA_VERSION" +_ACEOF + + + +# 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. + +# Check whether --with-agent-pgm was given. +if test "${with_agent_pgm+set}" = set; then : + withval=$with_agent_pgm; GNUPG_AGENT_PGM="$withval" +else + GNUPG_AGENT_PGM="" +fi + + + if test -n "$GNUPG_AGENT_PGM"; then + GNUPG_AGENT_PGM_TRUE= + GNUPG_AGENT_PGM_FALSE='#' +else + GNUPG_AGENT_PGM_TRUE='#' + GNUPG_AGENT_PGM_FALSE= +fi + +show_gnupg_agent_pgm="(default)" +test -n "$GNUPG_AGENT_PGM" && show_gnupg_agent_pgm="$GNUPG_AGENT_PGM" + + +# Check whether --with-pinentry-pgm was given. +if test "${with_pinentry_pgm+set}" = set; then : + withval=$with_pinentry_pgm; GNUPG_PINENTRY_PGM="$withval" +else + GNUPG_PINENTRY_PGM="" +fi + + + if test -n "$GNUPG_PINENTRY_PGM"; then + GNUPG_PINENTRY_PGM_TRUE= + GNUPG_PINENTRY_PGM_FALSE='#' +else + GNUPG_PINENTRY_PGM_TRUE='#' + GNUPG_PINENTRY_PGM_FALSE= +fi + +show_gnupg_pinentry_pgm="(default)" +test -n "$GNUPG_PINENTRY_PGM" && show_gnupg_pinentry_pgm="$GNUPG_PINENTRY_PGM" + + + +# Check whether --with-scdaemon-pgm was given. +if test "${with_scdaemon_pgm+set}" = set; then : + withval=$with_scdaemon_pgm; GNUPG_SCDAEMON_PGM="$withval" +else + GNUPG_SCDAEMON_PGM="" +fi + + + if test -n "$GNUPG_SCDAEMON_PGM"; then + GNUPG_SCDAEMON_PGM_TRUE= + GNUPG_SCDAEMON_PGM_FALSE='#' +else + GNUPG_SCDAEMON_PGM_TRUE='#' + GNUPG_SCDAEMON_PGM_FALSE= +fi + +show_gnupg_scdaemon_pgm="(default)" +test -n "$GNUPG_SCDAEMON_PGM" && show_gnupg_scdaemon_pgm="$GNUPG_SCDAEMON_PGM" + + + +# Check whether --with-dirmngr-pgm was given. +if test "${with_dirmngr_pgm+set}" = set; then : + withval=$with_dirmngr_pgm; GNUPG_DIRMNGR_PGM="$withval" +else + GNUPG_DIRMNGR_PGM="" +fi + + + if test -n "$GNUPG_DIRMNGR_PGM"; then + GNUPG_DIRMNGR_PGM_TRUE= + GNUPG_DIRMNGR_PGM_FALSE='#' +else + GNUPG_DIRMNGR_PGM_TRUE='#' + GNUPG_DIRMNGR_PGM_FALSE= +fi + +show_gnupg_dirmngr_pgm="(default)" +test -n "$GNUPG_DIRMNGR_PGM" && show_gnupg_dirmngr_pgm="$GNUPG_DIRMNGR_PGM" + + +# Check whether --with-protect-tool-pgm was given. +if test "${with_protect_tool_pgm+set}" = set; then : + withval=$with_protect_tool_pgm; GNUPG_PROTECT_TOOL_PGM="$withval" +else + GNUPG_PROTECT_TOOL_PGM="" +fi + + + if test -n "$GNUPG_PROTECT_TOOL_PGM"; then + GNUPG_PROTECT_TOOL_PGM_TRUE= + GNUPG_PROTECT_TOOL_PGM_FALSE='#' +else + GNUPG_PROTECT_TOOL_PGM_TRUE='#' + GNUPG_PROTECT_TOOL_PGM_FALSE= +fi + +show_gnupg_protect_tool_pgm="(default)" +test -n "$GNUPG_PROTECT_TOOL_PGM" \ + && show_gnupg_protect_tool_pgm="$GNUPG_PROTECT_TOOL_PGM" + + +# Some folks want to use only the agent from this packet. Make it +# easier for them by providing the configure option +# --enable-only-agent. +# Check whether --enable-agent-only was given. +if test "${enable_agent_only+set}" = set; then : + enableval=$enable_agent_only; build_agent_only=$enableval +fi + + +# SELinux support includes tracking of sensitive files to avoid +# leaking their contents through processing these files by gpg itself +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SELinux support is requested" >&5 +$as_echo_n "checking whether SELinux support is requested... " >&6; } +# Check whether --enable-selinux-support was given. +if test "${enable_selinux_support+set}" = set; then : + enableval=$enable_selinux_support; selinux_support=$enableval +else + selinux_support=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $selinux_support" >&5 +$as_echo "$selinux_support" >&6; } + +# Allow disabling of bzib2 support. +# It is defined only after we confirm the library is available later +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable the BZIP2 compression algorithm" >&5 +$as_echo_n "checking whether to enable the BZIP2 compression algorithm... " >&6; } +# Check whether --enable-bzip2 was given. +if test "${enable_bzip2+set}" = set; then : + enableval=$enable_bzip2; use_bzip2=$enableval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_bzip2" >&5 +$as_echo "$use_bzip2" >&6; } + +# Configure option to allow or disallow execution of external +# programs, like a photo viewer. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable external program execution" >&5 +$as_echo_n "checking whether to enable external program execution... " >&6; } +# Check whether --enable-exec was given. +if test "${enable_exec+set}" = set; then : + enableval=$enable_exec; use_exec=$enableval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_exec" >&5 +$as_echo "$use_exec" >&6; } +if test "$use_exec" = no ; then + +$as_echo "#define NO_EXEC 1" >>confdefs.h + +fi + +if test "$use_exec" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable photo ID viewing" >&5 +$as_echo_n "checking whether to enable photo ID viewing... " >&6; } + # Check whether --enable-photo-viewers was given. +if test "${enable_photo_viewers+set}" = set; then : + enableval=$enable_photo_viewers; if test "$enableval" = no ; then + +$as_echo "#define DISABLE_PHOTO_VIEWER 1" >>confdefs.h + + fi +else + enableval=yes +fi + + gnupg_cv_enable_photo_viewers=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } + + if test "$gnupg_cv_enable_photo_viewers" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use a fixed photo ID viewer" >&5 +$as_echo_n "checking whether to use a fixed photo ID viewer... " >&6; } + +# Check whether --with-photo-viewer was given. +if test "${with_photo_viewer+set}" = set; then : + withval=$with_photo_viewer; if test "$withval" = yes ; then + withval=no + elif test "$withval" != no ; then + +cat >>confdefs.h <<_ACEOF +#define FIXED_PHOTO_VIEWER "$withval" +_ACEOF + + fi +else + withval=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +$as_echo "$withval" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable external keyserver helpers" >&5 +$as_echo_n "checking whether to enable external keyserver helpers... " >&6; } + # Check whether --enable-keyserver-helpers was given. +if test "${enable_keyserver_helpers+set}" = set; then : + enableval=$enable_keyserver_helpers; if test "$enableval" = no ; then + +$as_echo "#define DISABLE_KEYSERVER_HELPERS 1" >>confdefs.h + + fi +else + enableval=yes +fi + + gnupg_cv_enable_keyserver_helpers=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } + + if test "$gnupg_cv_enable_keyserver_helpers" = yes ; then + # LDAP is defined only after we confirm the library is available later + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether LDAP keyserver support is requested" >&5 +$as_echo_n "checking whether LDAP keyserver support is requested... " >&6; } + # Check whether --enable-ldap was given. +if test "${enable_ldap+set}" = set; then : + enableval=$enable_ldap; try_ldap=$enableval +else + try_ldap=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_ldap" >&5 +$as_echo "$try_ldap" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether HKP keyserver support is requested" >&5 +$as_echo_n "checking whether HKP keyserver support is requested... " >&6; } + # Check whether --enable-hkp was given. +if test "${enable_hkp+set}" = set; then : + enableval=$enable_hkp; try_hkp=$enableval +else + try_hkp=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_hkp" >&5 +$as_echo "$try_hkp" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether finger key fetching support is requested" >&5 +$as_echo_n "checking whether finger key fetching support is requested... " >&6; } + # Check whether --enable-finger was given. +if test "${enable_finger+set}" = set; then : + enableval=$enable_finger; try_finger=$enableval +else + try_finger=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_finger" >&5 +$as_echo "$try_finger" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether generic object key fetching support is requested" >&5 +$as_echo_n "checking whether generic object key fetching support is requested... " >&6; } + # Check whether --enable-generic was given. +if test "${enable_generic+set}" = set; then : + enableval=$enable_generic; try_generic=$enableval +else + try_generic=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_generic" >&5 +$as_echo "$try_generic" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether email keyserver support is requested" >&5 +$as_echo_n "checking whether email keyserver support is requested... " >&6; } + # Check whether --enable-mailto was given. +if test "${enable_mailto+set}" = set; then : + enableval=$enable_mailto; try_mailto=$enableval +else + try_mailto=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_mailto" >&5 +$as_echo "$try_mailto" >&6; } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether keyserver exec-path is enabled" >&5 +$as_echo_n "checking whether keyserver exec-path is enabled... " >&6; } + # Check whether --enable-keyserver-path was given. +if test "${enable_keyserver_path+set}" = set; then : + enableval=$enable_keyserver_path; if test "$enableval" = no ; then + disable_keyserver_path=yes + fi +else + enableval=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } +fi + + +# +# Check for the key/uid cache size. This can't be zero, but can be +# pretty small on embedded systems. This is used for the gpg part. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the size of the key and uid cache" >&5 +$as_echo_n "checking for the size of the key and uid cache... " >&6; } +# Check whether --enable-key-cache was given. +if test "${enable_key_cache+set}" = set; then : + enableval=$enable_key_cache; +else + enableval=4096 +fi + +if test "$enableval" = "no"; then + enableval=5 +elif test "$enableval" = "yes" || test "$enableval" = ""; then + enableval=4096 +fi +key_cache_size=`echo "$enableval" | sed 's/[A-Za-z]//g'` +if test "$enableval" != "$key_cache_size" || test "$key_cache_size" -lt 5; then + as_fn_error $? "invalid key-cache size" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $key_cache_size" >&5 +$as_echo "$key_cache_size" >&6; } + +cat >>confdefs.h <<_ACEOF +#define PK_UID_CACHE_SIZE $key_cache_size +_ACEOF + + + + +# +# Check whether we want to use Linux capabilities +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of capabilities is requested" >&5 +$as_echo_n "checking whether use of capabilities is requested... " >&6; } + +# Check whether --with-capabilities was given. +if test "${with_capabilities+set}" = set; then : + withval=$with_capabilities; use_capabilities="$withval" +else + use_capabilities=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_capabilities" >&5 +$as_echo "$use_capabilities" >&6; } + + +# +# Allow disabling of internal CCID support. +# It is defined only after we confirm the library is available later +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable the internal CCID driver" >&5 +$as_echo_n "checking whether to enable the internal CCID driver... " >&6; } +# Check whether --enable-ccid-driver was given. +if test "${enable_ccid_driver+set}" = set; then : + enableval=$enable_ccid_driver; use_ccid_driver=$enableval +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_ccid_driver" >&5 +$as_echo "$use_ccid_driver" >&6; } + + +# +# To avoid double inclusion of config.h which might happen at some +# places, we add the usual double inclusion protection at the top of +# config.h. +# + + +# +# Stuff which goes at the bottom of config.h. +# + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +# Checks for programs. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for programs" >&5 +$as_echo "$as_me: checking for programs" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +missing_dir=`cd $ac_aux_dir && pwd` + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +if test "x$ac_cv_prog_cc_c89" = "xno" ; then + as_fn_error $? "No C-89 compiler found" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +# Extract the first word of ""perl"", so it can be a program name with args. +set dummy "perl"; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PERL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 +$as_echo "$PERL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WINDRES"; then + ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_WINDRES="${ac_tool_prefix}windres" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +WINDRES=$ac_cv_prog_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_WINDRES"; then + ac_ct_WINDRES=$WINDRES + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_WINDRES"; then + ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_WINDRES="windres" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES +if test -n "$ac_ct_WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 +$as_echo "$ac_ct_WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_WINDRES" = x; then + WINDRES=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + WINDRES=$ac_ct_WINDRES + fi +else + WINDRES="$ac_cv_prog_WINDRES" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror in -lcposix" >&5 +$as_echo_n "checking for strerror in -lcposix... " >&6; } +if ${ac_cv_lib_cposix_strerror+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcposix $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char strerror (); +int +main () +{ +return strerror (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_cposix_strerror=yes +else + ac_cv_lib_cposix_strerror=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cposix_strerror" >&5 +$as_echo "$ac_cv_lib_cposix_strerror" >&6; } +if test "x$ac_cv_lib_cposix_strerror" = xyes; then : + LIBS="$LIBS -lcposix" +fi + + + + + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for faqprog.pl" >&5 +$as_echo_n "checking for faqprog.pl... " >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $working_faqprog" >&5 +$as_echo "$working_faqprog" >&6; } + + if test "$working_faqprog" = "yes" ; then + WORKING_FAQPROG_TRUE= + WORKING_FAQPROG_FALSE='#' +else + WORKING_FAQPROG_TRUE='#' + WORKING_FAQPROG_FALSE= +fi + + + + + +# Check whether --with-tar was given. +if test "${with_tar+set}" = set; then : + withval=$with_tar; _do_tar=$withval +fi + + + if test x$_do_tar != xno ; then + + if test x$_do_tar = x ; then + # Extract the first word of ""tar"", so it can be a program name with args. +set dummy "tar"; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_TAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $TAR in + [\\/]* | ?:[\\/]*) + ac_cv_path_TAR="$TAR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +TAR=$ac_cv_path_TAR +if test -n "$TAR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5 +$as_echo "$TAR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + _mytar=$ac_cv_path_TAR + fi + + # Check if our tar is ustar format. If so, it's good. TODO: Add some + # code to check various options, etc, to try and create ustar + # format. + + if test x$_mytar != x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $_mytar speaks USTAR" >&5 +$as_echo_n "checking whether $_mytar speaks USTAR... " >&6; } + echo hithere > conftest.txt + $_mytar -cf - conftest.txt | (dd skip=257 bs=1 count=5 2>/dev/null || cat) | grep ustar > /dev/null + _tar_bad=$? + rm conftest.txt + + if test x$_tar_bad = x0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + fi + + if test x$_tar_bad = x0; then + HAVE_USTAR_TRUE= + HAVE_USTAR_FALSE='#' +else + HAVE_USTAR_TRUE='#' + HAVE_USTAR_FALSE= +fi + + + +# We need to compile and run a program on the build machine. A +# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in +# the AC archive is broken for autoconf 2.57. Given that tehre is no +# newer version of that macro, we assume that it is also broken for +# autoconf 2.61 and thus we use a simple but usually sufficient +# approach. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cc for build" >&5 +$as_echo_n "checking for cc for build... " >&6; } +if test "$cross_compiling" = "yes"; then + CC_FOR_BUILD="${CC_FOR_BUILD-cc}" +else + CC_FOR_BUILD="${CC_FOR_BUILD-$CC}" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5 +$as_echo "$CC_FOR_BUILD" >&6; } + + + + +try_gettext=yes +have_dosish_system=no +have_w32_system=no +use_simple_gettext=no +case "${host}" in + *-mingw32*) + # special stuff for Windoze NT + ac_cv_have_dev_random=no + +$as_echo "#define USE_ONLY_8DOT3 1" >>confdefs.h + + +$as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h + + +$as_echo "#define USE_SIMPLE_GETTEXT 1" >>confdefs.h + + disable_keyserver_path=yes + have_dosish_system=yes + have_w32_system=yes + try_gettext="no" + use_simple_gettext=yes + ;; + i?86-emx-os2 | i?86-*-os2*emx ) + # OS/2 with the EMX environment + ac_cv_have_dev_random=no + $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h + + have_dosish_system=yes + try_gettext="no" + ;; + + i?86-*-msdosdjgpp*) + # DOS with the DJGPP environment + ac_cv_have_dev_random=no + $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h + + 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 ptrmismatch1' 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 ptrmismatch1" + fi + ;; + m68k-atari-mint) + ;; + *) + ;; +esac + +if test "$have_dosish_system" = yes; then + +$as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h + +fi + if test "$have_dosish_system" = yes; then + HAVE_DOSISH_SYSTEM_TRUE= + HAVE_DOSISH_SYSTEM_FALSE='#' +else + HAVE_DOSISH_SYSTEM_TRUE='#' + HAVE_DOSISH_SYSTEM_FALSE= +fi + + + if test x"$use_simple_gettext" = xyes; then + USE_SIMPLE_GETTEXT_TRUE= + USE_SIMPLE_GETTEXT_FALSE='#' +else + USE_SIMPLE_GETTEXT_TRUE='#' + USE_SIMPLE_GETTEXT_FALSE= +fi + + +if test "$have_w32_system" = yes; then + +$as_echo "#define HAVE_W32_SYSTEM 1" >>confdefs.h + +fi + if test "$have_w32_system" = yes; then + HAVE_W32_SYSTEM_TRUE= + HAVE_W32_SYSTEM_FALSE='#' +else + HAVE_W32_SYSTEM_TRUE='#' + HAVE_W32_SYSTEM_FALSE= +fi + + +if test "$disable_keyserver_path" = yes; then + +$as_echo "#define DISABLE_KEYSERVER_PATH 1" >>confdefs.h + +fi + +# +# Allows enabling the use of a standard socket by default This is +# gpg-agent's option --[no-]use-standard-socket. For Windows we force +# the use of this. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use a standard socket by default" >&5 +$as_echo_n "checking whether to use a standard socket by default... " >&6; } +# Check whether --enable-standard-socket was given. +if test "${enable_standard_socket+set}" = set; then : + enableval=$enable_standard_socket; use_standard_socket=$enableval +fi + +tmp="" +if test "$use_standard_socket" != yes; then + if test "$have_w32_system" = yes; then + use_standard_socket=yes + tmp=" (forced)" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_standard_socket$tmp" >&5 +$as_echo "$use_standard_socket$tmp" >&6; } +if test "$use_standard_socket" = yes; then + +$as_echo "#define USE_STANDARD_SOCKET 1" >>confdefs.h + +fi + + +# (These need to go after AC_PROG_CC so that $EXEEXT is defined) + +cat >>confdefs.h <<_ACEOF +#define EXEEXT "$EXEEXT" +_ACEOF + + +if test x"$try_hkp" = xyes ; then + GPGKEYS_HKP="gpg2keys_hkp$EXEEXT" + +fi + +if test x"$try_finger" = xyes ; then + GPGKEYS_FINGER="gpg2keys_finger$EXEEXT" + +fi + + + +# +# Checks for libraries. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libraries" >&5 +$as_echo "$as_me: checking for libraries" >&6;} + + +# +# libgpg-error is a library with error codes shared between GnuPG +# related projects. +# + +# Check whether --with-gpg-error-prefix was given. +if test "${with_gpg_error_prefix+set}" = set; then : + withval=$with_gpg_error_prefix; gpg_error_config_prefix="$withval" +else + gpg_error_config_prefix="" +fi + + 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 + + # Extract the first word of "gpg-error-config", so it can be a program name with args. +set dummy gpg-error-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GPG_ERROR_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GPG_ERROR_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_GPG_ERROR_CONFIG="$GPG_ERROR_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GPG_ERROR_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GPG_ERROR_CONFIG" && ac_cv_path_GPG_ERROR_CONFIG="no" + ;; +esac +fi +GPG_ERROR_CONFIG=$ac_cv_path_GPG_ERROR_CONFIG +if test -n "$GPG_ERROR_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPG_ERROR_CONFIG" >&5 +$as_echo "$GPG_ERROR_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + min_gpg_error_version="$NEED_GPG_ERROR_VERSION" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GPG Error - version >= $min_gpg_error_version" >&5 +$as_echo_n "checking for GPG Error - version >= $min_gpg_error_version... " >&6; } + 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` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gpg_error_config_version)" >&5 +$as_echo "yes ($gpg_error_config_version)" >&6; } + have_gpg_error=yes + else + GPG_ERROR_CFLAGS="" + GPG_ERROR_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_gpg_error=no + fi + + + + + +# +# Libgcrypt is our generic crypto library +# + +# Check whether --with-libgcrypt-prefix was given. +if test "${with_libgcrypt_prefix+set}" = set; then : + withval=$with_libgcrypt_prefix; libgcrypt_config_prefix="$withval" +else + libgcrypt_config_prefix="" +fi + + 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 + + # Extract the first word of "libgcrypt-config", so it can be a program name with args. +set dummy libgcrypt-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LIBGCRYPT_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LIBGCRYPT_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_LIBGCRYPT_CONFIG="$LIBGCRYPT_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_LIBGCRYPT_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LIBGCRYPT_CONFIG" && ac_cv_path_LIBGCRYPT_CONFIG="no" + ;; +esac +fi +LIBGCRYPT_CONFIG=$ac_cv_path_LIBGCRYPT_CONFIG +if test -n "$LIBGCRYPT_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPT_CONFIG" >&5 +$as_echo "$LIBGCRYPT_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + tmp="$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION" + 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 + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBGCRYPT - version >= $min_libgcrypt_version" >&5 +$as_echo_n "checking for LIBGCRYPT - version >= $min_libgcrypt_version... " >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($libgcrypt_config_version)" >&5 +$as_echo "yes ($libgcrypt_config_version)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBGCRYPT API version" >&5 +$as_echo_n "checking LIBGCRYPT API version... " >&6; } + if test "$req_libgcrypt_api" -eq "$tmp" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5 +$as_echo "okay" >&6; } + else + ok=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: does not match. want=$req_libgcrypt_api got=$tmp" >&5 +$as_echo "does not match. want=$req_libgcrypt_api got=$tmp" >&6; } + fi + fi + fi + fi + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` + have_libgcrypt=yes + else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + have_libgcrypt=no + fi + + + + + +# +# libassuan is used for IPC +# + +# Check whether --with-libassuan-prefix was given. +if test "${with_libassuan_prefix+set}" = set; then : + withval=$with_libassuan_prefix; libassuan_config_prefix="$withval" +else + libassuan_config_prefix="" +fi + + 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 + # Extract the first word of "libassuan-config", so it can be a program name with args. +set dummy libassuan-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LIBASSUAN_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LIBASSUAN_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_LIBASSUAN_CONFIG="$LIBASSUAN_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_LIBASSUAN_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_LIBASSUAN_CONFIG" && ac_cv_path_LIBASSUAN_CONFIG="no" + ;; +esac +fi +LIBASSUAN_CONFIG=$ac_cv_path_LIBASSUAN_CONFIG +if test -n "$LIBASSUAN_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBASSUAN_CONFIG" >&5 +$as_echo "$LIBASSUAN_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + tmp="$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION" + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libassuan_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libassuan_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libassuan_api=0 + min_libassuan_version="$tmp" + fi + + if test "$LIBASSUAN_CONFIG" != "no" ; then + libassuan_version=`$LIBASSUAN_CONFIG --version` + fi + libassuan_version_major=`echo $libassuan_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1/'` + libassuan_version_minor=`echo $libassuan_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\2/'` + libassuan_version_micro=`echo $libassuan_version | \ + sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/'` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBASSUAN - version >= $min_libassuan_version" >&5 +$as_echo_n "checking for LIBASSUAN - version >= $min_libassuan_version... " >&6; } + 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/'` + if test "$libassuan_version_major" -gt "$req_major"; then + ok=yes + else + if test "$libassuan_version_major" -eq "$req_major"; then + if test "$libassuan_version_minor" -gt "$req_minor"; then + ok=yes + else + if test "$libassuan_version_minor" -eq "$req_minor"; then + if test "$libassuan_version_micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + + fi + + if test $ok = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($libassuan_version)" >&5 +$as_echo "yes ($libassuan_version)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + if test $ok = yes; then + if test "$req_libassuan_api" -gt 0 ; then + tmp=`$LIBASSUAN_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBASSUAN API version" >&5 +$as_echo_n "checking LIBASSUAN API version... " >&6; } + if test "$req_libassuan_api" -eq "$tmp" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5 +$as_echo "okay" >&6; } + else + ok=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: does not match. want=$req_libassuan_api got=$tmp." >&5 +$as_echo "does not match. want=$req_libassuan_api got=$tmp." >&6; } + 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` + have_libassuan=yes + else + LIBASSUAN_CFLAGS="" + LIBASSUAN_LIBS="" + have_libassuan=no + fi + + + +if test "$have_libassuan" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define GNUPG_LIBASSUAN_VERSION "$libassuan_version" +_ACEOF + +fi + + + +# +# libksba is our X.509 support library +# + +# Check whether --with-ksba-prefix was given. +if test "${with_ksba_prefix+set}" = set; then : + withval=$with_ksba_prefix; ksba_config_prefix="$withval" +else + ksba_config_prefix="" +fi + + 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 + + # Extract the first word of "ksba-config", so it can be a program name with args. +set dummy ksba-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_KSBA_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $KSBA_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_KSBA_CONFIG="$KSBA_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_KSBA_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_KSBA_CONFIG" && ac_cv_path_KSBA_CONFIG="no" + ;; +esac +fi +KSBA_CONFIG=$ac_cv_path_KSBA_CONFIG +if test -n "$KSBA_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KSBA_CONFIG" >&5 +$as_echo "$KSBA_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + tmp="$NEED_KSBA_API:$NEED_KSBA_VERSION" + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_ksba_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_ksba_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_ksba_api=0 + min_ksba_version="$tmp" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for KSBA - version >= $min_ksba_version" >&5 +$as_echo_n "checking for KSBA - version >= $min_ksba_version... " >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($ksba_config_version)" >&5 +$as_echo "yes ($ksba_config_version)" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + if test $ok = yes; then + # Even if we have a recent libksba, we should check that the + # API is compatible. + if test "$req_ksba_api" -gt 0 ; then + tmp=`$KSBA_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking KSBA API version" >&5 +$as_echo_n "checking KSBA API version... " >&6; } + if test "$req_ksba_api" -eq "$tmp" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: okay" >&5 +$as_echo "okay" >&6; } + else + ok=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: does not match. want=$req_ksba_api got=$tmp." >&5 +$as_echo "does not match. want=$req_ksba_api got=$tmp." >&6; } + 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` + have_ksba=yes + else + KSBA_CFLAGS="" + KSBA_LIBS="" + have_ksba=no + fi + + + + + +# +# libusb allows us to use the integrated CCID smartcard reader driver. +# +# FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs. +if test "$use_ccid_driver" = yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for usb_bulk_write in -lusb" >&5 +$as_echo_n "checking for usb_bulk_write in -lusb... " >&6; } +if ${ac_cv_lib_usb_usb_bulk_write+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char usb_bulk_write (); +int +main () +{ +return usb_bulk_write (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_usb_usb_bulk_write=yes +else + ac_cv_lib_usb_usb_bulk_write=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usb_usb_bulk_write" >&5 +$as_echo "$ac_cv_lib_usb_usb_bulk_write" >&6; } +if test "x$ac_cv_lib_usb_usb_bulk_write" = xyes; then : + LIBUSB_LIBS="$LIBUSB_LIBS -lusb" + +$as_echo "#define HAVE_LIBUSB 1" >>confdefs.h + + have_libusb=yes + +fi + + for ac_func in usb_create_match +do : + ac_fn_c_check_func "$LINENO" "usb_create_match" "ac_cv_func_usb_create_match" +if test "x$ac_cv_func_usb_create_match" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_USB_CREATE_MATCH 1 +_ACEOF + +fi +done + +fi + + +# +# Check wether it is necessary to link against libdl. +# +gnupg_dlopen_save_libs="$LIBS" +LIBS="" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' c dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +DL_LIBS=$LIBS + +LIBS="$gnupg_dlopen_save_libs" + +# +# Checks for symcryptrun: +# + +# libutil has openpty() and login_tty(). +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 +$as_echo_n "checking for openpty in -lutil... " >&6; } +if ${ac_cv_lib_util_openpty+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char openpty (); +int +main () +{ +return openpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_util_openpty=yes +else + ac_cv_lib_util_openpty=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 +$as_echo "$ac_cv_lib_util_openpty" >&6; } +if test "x$ac_cv_lib_util_openpty" = xyes; then : + LIBUTIL_LIBS="$LIBUTIL_LIBS -lutil" + +$as_echo "#define HAVE_LIBUTIL 1" >>confdefs.h + + +fi + + + +# shred is used to clean temporary plain text files. +# Extract the first word of "shred", so it can be a program name with args. +set dummy shred; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SHRED+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SHRED in + [\\/]* | ?:[\\/]*) + ac_cv_path_SHRED="$SHRED" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SHRED="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SHRED" && ac_cv_path_SHRED="/usr/bin/shred" + ;; +esac +fi +SHRED=$ac_cv_path_SHRED +if test -n "$SHRED"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHRED" >&5 +$as_echo "$SHRED" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +cat >>confdefs.h <<_ACEOF +#define SHRED "${SHRED}" +_ACEOF + + + + +# +# Check whether the GNU Pth library is available +# Note, that we include a Pth emulation for W32. +# + +# Check whether --with-pth-prefix was given. +if test "${with_pth_prefix+set}" = set; then : + withval=$with_pth_prefix; pth_config_prefix="$withval" +else + pth_config_prefix="" +fi + + if test x$pth_config_prefix != x ; then + PTH_CONFIG="$pth_config_prefix/bin/pth-config" + fi + # Extract the first word of "pth-config", so it can be a program name with args. +set dummy pth-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PTH_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PTH_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PTH_CONFIG="$PTH_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PTH_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PTH_CONFIG" && ac_cv_path_PTH_CONFIG="no" + ;; +esac +fi +PTH_CONFIG=$ac_cv_path_PTH_CONFIG +if test -n "$PTH_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTH_CONFIG" >&5 +$as_echo "$PTH_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + tmp=1.3.7 + if test "$PTH_CONFIG" != "no"; then + + _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print $3}'` + _req_version="$tmp" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTH - version >= $_req_version" >&5 +$as_echo_n "checking for PTH - version >= $_req_version... " >&6; } + 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 = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PTH installation is sane" >&5 +$as_echo_n "checking whether PTH installation is sane... " >&6; } + if ${gnupg_cv_pth_is_sane+:} false; then : + $as_echo_n "(cached) " >&6 +else + + _gnupg_pth_save_cflags=$CFLAGS + _gnupg_pth_save_ldflags=$LDFLAGS + _gnupg_pth_save_libs=$LIBS + CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`" + LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`" + LIBS="$LIBS `$PTH_CONFIG --libs --all`" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ + pth_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gnupg_cv_pth_is_sane=yes +else + gnupg_cv_pth_is_sane=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS=$_gnupg_pth_save_cflags + LDFLAGS=$_gnupg_pth_save_ldflags + LIBS=$_gnupg_pth_save_libs + +fi + + if test $gnupg_cv_pth_is_sane != yes; then + have_pth=no + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_pth_is_sane" >&5 +$as_echo "$gnupg_cv_pth_is_sane" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + if test $have_pth = yes; then + PTH_CFLAGS=`$PTH_CONFIG --cflags` + PTH_LIBS=`$PTH_CONFIG --ldflags` + PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`" + +$as_echo "#define HAVE_PTH 1" >>confdefs.h + + fi + fi + + + +if test "$have_pth" = "yes"; then + +$as_echo "#define USE_GNU_PTH 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** +*** 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 +***" >&5 +$as_echo "$as_me: WARNING: +*** +*** 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 +***" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for networking options" >&5 +$as_echo "$as_me: checking for networking options" >&6;} + +# +# Must check for network library requirements before doing link tests +# for ldap, for example. If ldap libs are static (or dynamic and without +# ELF runtime link paths), then link will fail and LDAP support won't +# be detected. +# +ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : + NETLIBS="-lnsl $NETLIBS" +fi + +fi + +ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" +if test "x$ac_cv_func_setsockopt" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 +$as_echo_n "checking for setsockopt in -lsocket... " >&6; } +if ${ac_cv_lib_socket_setsockopt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char setsockopt (); +int +main () +{ +return setsockopt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_setsockopt=yes +else + ac_cv_lib_socket_setsockopt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 +$as_echo "$ac_cv_lib_socket_setsockopt" >&6; } +if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : + NETLIBS="-lsocket $NETLIBS" +fi + +fi + + + +# +# Check for ADNS. +# +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" + +# Check whether --with-adns was given. +if test "${with_adns+set}" = set; then : + withval=$with_adns; if test -d "$withval"; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi +fi + +if test "$with_adns" != "no"; then + for ac_header in adns.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "adns.h" "ac_cv_header_adns_h" "$ac_includes_default" +if test "x$ac_cv_header_adns_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ADNS_H 1 +_ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for adns_init in -ladns" >&5 +$as_echo_n "checking for adns_init in -ladns... " >&6; } +if ${ac_cv_lib_adns_adns_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ladns $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char adns_init (); +int +main () +{ +return adns_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_adns_adns_init=yes +else + ac_cv_lib_adns_adns_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_adns_adns_init" >&5 +$as_echo "$ac_cv_lib_adns_adns_init" >&6; } +if test "x$ac_cv_lib_adns_adns_init" = xyes; then : + have_adns=yes +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + +done + +fi +if test "$have_adns" = "yes"; then + ADNSLIBS="-ladns" +fi + +# Newer adns versions feature a free function to be used under W32. +for ac_func in adns_free +do : + ac_fn_c_check_func "$LINENO" "adns_free" "ac_cv_func_adns_free" +if test "x$ac_cv_func_adns_free" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ADNS_FREE 1 +_ACEOF + +fi +done + + + +# +# Now try for the resolver functions so we can use DNS for SRV, PA and CERT. +# +if test x"$try_hkp" = xyes || test x"$try_http" = xyes ; then + # Check whether --enable-dns-srv was given. +if test "${enable_dns_srv+set}" = set; then : + enableval=$enable_dns_srv; use_dns_srv=$enableval +else + use_dns_srv=yes +fi + +fi + +# Check whether --enable-dns-pka was given. +if test "${enable_dns_pka+set}" = set; then : + enableval=$enable_dns_pka; use_dns_pka=$enableval +else + use_dns_pka=yes +fi + + +# Check whether --enable-dns-cert was given. +if test "${enable_dns_cert+set}" = set; then : + enableval=$enable_dns_cert; use_dns_cert=$enableval +else + use_dns_cert=yes +fi + + +if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes \ + || test x"$use_dns_cert" = xyes; then + _dns_save_libs=$LIBS + LIBS="" + # the double underscore thing is a glibc-ism? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_query" >&5 +$as_echo_n "checking for library containing res_query... " >&6; } +if ${ac_cv_search_res_query+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char res_query (); +int +main () +{ +return res_query (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_res_query=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_res_query+:} false; then : + break +fi +done +if ${ac_cv_search_res_query+:} false; then : + +else + ac_cv_search_res_query=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_query" >&5 +$as_echo "$ac_cv_search_res_query" >&6; } +ac_res=$ac_cv_search_res_query +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_query" >&5 +$as_echo_n "checking for library containing __res_query... " >&6; } +if ${ac_cv_search___res_query+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __res_query (); +int +main () +{ +return __res_query (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search___res_query=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search___res_query+:} false; then : + break +fi +done +if ${ac_cv_search___res_query+:} false; then : + +else + ac_cv_search___res_query=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_query" >&5 +$as_echo "$ac_cv_search___res_query" >&6; } +ac_res=$ac_cv_search___res_query +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + have_resolver=no +fi + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_expand" >&5 +$as_echo_n "checking for library containing dn_expand... " >&6; } +if ${ac_cv_search_dn_expand+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dn_expand (); +int +main () +{ +return dn_expand (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dn_expand=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dn_expand+:} false; then : + break +fi +done +if ${ac_cv_search_dn_expand+:} false; then : + +else + ac_cv_search_dn_expand=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dn_expand" >&5 +$as_echo "$ac_cv_search_dn_expand" >&6; } +ac_res=$ac_cv_search_dn_expand +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __dn_expand" >&5 +$as_echo_n "checking for library containing __dn_expand... " >&6; } +if ${ac_cv_search___dn_expand+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __dn_expand (); +int +main () +{ +return __dn_expand (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search___dn_expand=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search___dn_expand+:} false; then : + break +fi +done +if ${ac_cv_search___dn_expand+:} false; then : + +else + ac_cv_search___dn_expand=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___dn_expand" >&5 +$as_echo "$ac_cv_search___dn_expand" >&6; } +ac_res=$ac_cv_search___dn_expand +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + have_resolver=no +fi + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_skipname" >&5 +$as_echo_n "checking for library containing dn_skipname... " >&6; } +if ${ac_cv_search_dn_skipname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dn_skipname (); +int +main () +{ +return dn_skipname (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dn_skipname=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dn_skipname+:} false; then : + break +fi +done +if ${ac_cv_search_dn_skipname+:} false; then : + +else + ac_cv_search_dn_skipname=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dn_skipname" >&5 +$as_echo "$ac_cv_search_dn_skipname" >&6; } +ac_res=$ac_cv_search_dn_skipname +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __dn_skipname" >&5 +$as_echo_n "checking for library containing __dn_skipname... " >&6; } +if ${ac_cv_search___dn_skipname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __dn_skipname (); +int +main () +{ +return __dn_skipname (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv bind; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search___dn_skipname=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search___dn_skipname+:} false; then : + break +fi +done +if ${ac_cv_search___dn_skipname+:} false; then : + +else + ac_cv_search___dn_skipname=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___dn_skipname" >&5 +$as_echo "$ac_cv_search___dn_skipname" >&6; } +ac_res=$ac_cv_search___dn_skipname +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + have_resolver=no +fi + +fi + + + if test x"$have_resolver" != xno ; then + + # Make sure that the BIND 4 resolver interface is workable before + # enabling any code that calls it. At some point I'll rewrite the + # code to use the BIND 8 resolver API. + # We might also want to use adns instead. Problem with ADNS is that + # it does not support v6. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the resolver is usable" >&5 +$as_echo_n "checking whether the resolver is usable... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +int +main () +{ +unsigned char answer[PACKETSZ]; + res_query("foo.bar",C_IN,T_A,answer,PACKETSZ); + dn_skipname(0,0); + dn_expand(0,0,0,0,0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_resolver=yes +else + have_resolver=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_resolver" >&5 +$as_echo "$have_resolver" >&6; } + + # This is Apple-specific and somewhat bizarre as they changed the + # define in bind 8 for some reason. + + if test x"$have_resolver" != xyes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether I can make the resolver usable with BIND_8_COMPAT" >&5 +$as_echo_n "checking whether I can make the resolver usable with BIND_8_COMPAT... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define BIND_8_COMPAT +#include +#include +#include +#include +int +main () +{ +unsigned char answer[PACKETSZ]; + res_query("foo.bar",C_IN,T_A,answer,PACKETSZ); + dn_skipname(0,0); dn_expand(0,0,0,0,0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + have_resolver=yes ; need_compat=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_resolver" >&5 +$as_echo "$have_resolver" >&6; } + fi + fi + + if test x"$have_resolver" = xyes ; then + DNSLIBS=$LIBS + + if test x"$use_dns_srv" = xyes ; then + +$as_echo "#define USE_DNS_SRV 1" >>confdefs.h + + fi + + if test x"$use_dns_pka" = xyes ; then + +$as_echo "#define USE_DNS_PKA 1" >>confdefs.h + + fi + + if test x"$use_dns_cert" = xyes ; then + +$as_echo "#define USE_DNS_CERT 1" >>confdefs.h + + fi + + if test x"$need_compat" = xyes ; then + +$as_echo "#define BIND_8_COMPAT 1" >>confdefs.h + + fi + else + # If we have no resolver library but ADNS (e.g. under W32) enable the + # code parts which can be used with ADNS. + if test x"$have_adns" = xyes ; then + DNSLIBS="$ADNSLIBS" + +$as_echo "#define USE_ADNS 1" >>confdefs.h + + + if test x"$use_dns_srv" = xyes ; then + $as_echo "#define USE_DNS_SRV 1" >>confdefs.h + + fi + + if test x"$use_dns_pka" = xyes ; then + $as_echo "#define USE_DNS_PKA 1" >>confdefs.h + + fi + + if test x"$use_dns_cert" = xyes ; then + +$as_echo "#define USE_DNS_CERT 1" >>confdefs.h + + fi + else + use_dns_srv=no + use_dns_pka=no + use_dns_cert=no + fi + fi + + LIBS=$_dns_save_libs +fi + + + + if test x"$use_dns_srv" = xyes; then + USE_DNS_SRV_TRUE= + USE_DNS_SRV_FALSE='#' +else + USE_DNS_SRV_TRUE='#' + USE_DNS_SRV_FALSE= +fi + + + +# +# Check for LDAP +# +if test "$try_ldap" = yes ; then + +# Try and link a LDAP test program to weed out unusable LDAP +# libraries. -lldap [-llber [-lresolv]] is for older OpenLDAPs. +# OpenLDAP, circa 1999, was terrible with creating weird dependencies. +# If all else fails, the user can play guess-the-dependency by using +# something like ./configure LDAPLIBS="-Lfoo -lbar" + + +# Check whether --with-ldap was given. +if test "${with_ldap+set}" = set; then : + withval=$with_ldap; _ldap_with=$withval +fi + + +if test x$_ldap_with != xno ; then + + if test -d "$withval" ; then + LDAP_CPPFLAGS="-I$withval/include" + LDAP_LDFLAGS="-L$withval/lib" + fi + + _ldap_save_cppflags=$CPPFLAGS + CPPFLAGS="${LDAP_CPPFLAGS} ${CPPFLAGS}" + _ldap_save_ldflags=$LDFLAGS + LDFLAGS="${LDAP_LDFLAGS} ${LDFLAGS}" + + for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv" "-lwldap32"; do + _ldap_save_libs=$LIBS + LIBS="$MY_LDAPLIBS $NETLIBS $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether LDAP via \"$MY_LDAPLIBS\" is present and sane" >&5 +$as_echo_n "checking whether LDAP via \"$MY_LDAPLIBS\" is present and sane... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef _WIN32 +#include +#include +#else +#include +#endif + +int +main () +{ +ldap_open("foobar",1234); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gnupg_cv_func_ldap_init=yes +else + gnupg_cv_func_ldap_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_func_ldap_init" >&5 +$as_echo "$gnupg_cv_func_ldap_init" >&6; } + + if test $gnupg_cv_func_ldap_init = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether I can make LDAP be sane with lber.h" >&5 +$as_echo_n "checking whether I can make LDAP be sane with lber.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +ldap_open("foobar",1234); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gnupg_cv_func_ldaplber_init=yes +else + gnupg_cv_func_ldaplber_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_func_ldaplber_init" >&5 +$as_echo "$gnupg_cv_func_ldaplber_init" >&6; } + fi + + if test "$gnupg_cv_func_ldaplber_init" = yes ; then + +$as_echo "#define NEED_LBER_H 1" >>confdefs.h + + fi + + if test "$gnupg_cv_func_ldap_init" = yes || \ + test "$gnupg_cv_func_ldaplber_init" = yes ; then + LDAPLIBS="$LDAP_LDFLAGS $MY_LDAPLIBS" + GPGKEYS_LDAP="gpg2keys_ldap$EXEEXT" + + for ac_func in ldap_get_option ldap_set_option +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + # The extra test for ldap_start_tls_sA is for W32 because + # that is the actual function in the library. + for ac_func in ldap_start_tls_s ldap_start_tls_sA +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + if test "$ac_cv_func_ldap_get_option" != yes ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether LDAP supports ld_errno" >&5 +$as_echo_n "checking whether LDAP supports ld_errno... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +LDAP *ldap; ldap->ld_errno; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gnupg_cv_func_ldap_ld_errno=yes +else + gnupg_cv_func_ldap_ld_errno=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_func_ldap_ld_errno" >&5 +$as_echo "$gnupg_cv_func_ldap_ld_errno" >&6; } + + if test "$gnupg_cv_func_ldap_ld_errno" = yes ; then + +$as_echo "#define HAVE_LDAP_LD_ERRNO 1" >>confdefs.h + + fi + fi + fi + + LIBS=$_ldap_save_libs + + if test "$GPGKEYS_LDAP" != "" ; then break; fi + done + + + + + + CPPFLAGS=$_ldap_save_cppflags + LDFLAGS=$_ldap_save_ldflags +fi + +fi + +# +# Check for curl. We fake the curl API if libcurl isn't installed. +# We require 7.10 or later as we use curl_version_info(). +# + + + + + + + + + + + + + + + + + + + + + +# Check whether --with-libcurl was given. +if test "${with_libcurl+set}" = set; then : + withval=$with_libcurl; _libcurl_with=$withval +else + _libcurl_with=yes +fi + + + if test "$_libcurl_with" != "no" ; then + + for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[1]+256*A[2]+A[3]; print X;}'" + + _libcurl_try_link=yes + + if test -d "$_libcurl_with" ; then + LIBCURL_CPPFLAGS="-I$withval/include" + _libcurl_ldflags="-L$withval/lib" + # Extract the first word of ""$withval/bin/curl-config"", so it can be a program name with args. +set dummy "$withval/bin/curl-config"; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path__libcurl_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $_libcurl_config in + [\\/]* | ?:[\\/]*) + ac_cv_path__libcurl_config="$_libcurl_config" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path__libcurl_config="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +_libcurl_config=$ac_cv_path__libcurl_config +if test -n "$_libcurl_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_libcurl_config" >&5 +$as_echo "$_libcurl_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + # Extract the first word of "curl-config", so it can be a program name with args. +set dummy curl-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path__libcurl_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $_libcurl_config in + [\\/]* | ?:[\\/]*) + ac_cv_path__libcurl_config="$_libcurl_config" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path__libcurl_config="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +_libcurl_config=$ac_cv_path__libcurl_config +if test -n "$_libcurl_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_libcurl_config" >&5 +$as_echo "$_libcurl_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test x$_libcurl_config != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the version of libcurl" >&5 +$as_echo_n "checking for the version of libcurl... " >&6; } +if ${libcurl_cv_lib_curl_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $2}'` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libcurl_cv_lib_curl_version" >&5 +$as_echo "$libcurl_cv_lib_curl_version" >&6; } + + _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` + _libcurl_wanted=`echo 7.10 | $_libcurl_version_parse` + + if test $_libcurl_wanted -gt 0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcurl >= version 7.10" >&5 +$as_echo_n "checking for libcurl >= version 7.10... " >&6; } +if ${libcurl_cv_lib_version_ok+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test $_libcurl_version -ge $_libcurl_wanted ; then + libcurl_cv_lib_version_ok=yes + else + libcurl_cv_lib_version_ok=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libcurl_cv_lib_version_ok" >&5 +$as_echo "$libcurl_cv_lib_version_ok" >&6; } + fi + + if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then + if test x"$LIBCURL_CPPFLAGS" = "x" ; then + LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` + fi + if test x"$LIBCURL" = "x" ; then + LIBCURL=`$_libcurl_config --libs` + + # This is so silly, but Apple actually has a bug in their + # curl-config script. Fixed in Tiger, but there are still + # lots of Panther installs around. + case "${host}" in + powerpc-apple-darwin7*) + LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` + ;; + esac + fi + + # All curl-config scripts support --feature + _libcurl_features=`$_libcurl_config --feature` + + # Is it modern enough to have --protocols? (7.12.4) + if test $_libcurl_version -ge 461828 ; then + _libcurl_protocols=`$_libcurl_config --protocols` + fi + else + _libcurl_try_link=no + fi + + unset _libcurl_wanted + fi + + if test $_libcurl_try_link = yes ; then + + # we didn't find curl-config, so let's see if the user-supplied + # link line (or failing that, "-lcurl") is enough. + LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"} + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libcurl is usable" >&5 +$as_echo_n "checking whether libcurl is usable... " >&6; } +if ${libcurl_cv_lib_curl_usable+:} false; then : + $as_echo_n "(cached) " >&6 +else + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBCURL $LIBS" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + +/* Try and use a few common options to force a failure if we are + missing symbols or cannot link. */ +int x; +curl_easy_setopt(NULL,CURLOPT_URL,NULL); +x=CURL_ERROR_SIZE; +x=CURLOPT_WRITEFUNCTION; +x=CURLOPT_FILE; +x=CURLOPT_ERRORBUFFER; +x=CURLOPT_STDERR; +x=CURLOPT_VERBOSE; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libcurl_cv_lib_curl_usable=yes +else + libcurl_cv_lib_curl_usable=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libcurl_cv_lib_curl_usable" >&5 +$as_echo "$libcurl_cv_lib_curl_usable" >&6; } + + if test $libcurl_cv_lib_curl_usable = yes ; then + + # Does curl_free() exist in this version of libcurl? + # If not, fake it with free() + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + ac_fn_c_check_func "$LINENO" "curl_free" "ac_cv_func_curl_free" +if test "x$ac_cv_func_curl_free" = xyes; then : + +else + +$as_echo "#define curl_free free" >>confdefs.h + +fi + + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + + +$as_echo "#define HAVE_LIBCURL 1" >>confdefs.h + + + + + for _libcurl_feature in $_libcurl_features ; do + cat >>confdefs.h <<_ACEOF +#define `$as_echo "libcurl_feature_$_libcurl_feature" | $as_tr_cpp` 1 +_ACEOF + + eval `$as_echo "libcurl_feature_$_libcurl_feature" | $as_tr_sh`=yes + done + + if test "x$_libcurl_protocols" = "x" ; then + + # We don't have --protocols, so just assume that all + # protocols are available + _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT" + + if test x$libcurl_feature_SSL = xyes ; then + _libcurl_protocols="$_libcurl_protocols HTTPS" + + # FTPS wasn't standards-compliant until version + # 7.11.0 + if test $_libcurl_version -ge 461568; then + _libcurl_protocols="$_libcurl_protocols FTPS" + fi + fi + fi + + for _libcurl_protocol in $_libcurl_protocols ; do + cat >>confdefs.h <<_ACEOF +#define `$as_echo "libcurl_protocol_$_libcurl_protocol" | $as_tr_cpp` 1 +_ACEOF + + eval `$as_echo "libcurl_protocol_$_libcurl_protocol" | $as_tr_sh`=yes + done + else + unset LIBCURL + unset LIBCURL_CPPFLAGS + fi + fi + + unset _libcurl_try_link + unset _libcurl_version_parse + unset _libcurl_config + unset _libcurl_feature + unset _libcurl_features + unset _libcurl_protocol + unset _libcurl_protocols + unset _libcurl_version + unset _libcurl_ldflags + fi + + if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then + # This is the IF-NO path + fake_curl=yes + else + # This is the IF-YES path + : + fi + + unset _libcurl_with + + if test x"$fake_curl" = xyes; then + FAKE_CURL_TRUE= + FAKE_CURL_FALSE='#' +else + FAKE_CURL_TRUE='#' + FAKE_CURL_FALSE= +fi + + +# Generic, for us, means curl + +if test x"$try_generic" = xyes ; then + GPGKEYS_CURL="gpg2keys_curl$EXEEXT" + +fi + +# +# Check for sendmail +# +# This isn't necessarily sendmail itself, but anything that gives a +# sendmail-ish interface to the outside world. That includes Exim, +# Postfix, etc. Basically, anything that can handle "sendmail -t". +if test "$try_mailto" = yes ; then + +# Check whether --with-mailprog was given. +if test "${with_mailprog+set}" = set; then : + withval=$with_mailprog; +else + with_mailprog=yes +fi + + + if test x"$with_mailprog" = xyes ; then + # Extract the first word of "sendmail", so it can be a program name with args. +set dummy sendmail; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SENDMAIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SENDMAIL in + [\\/]* | ?:[\\/]*) + ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/sbin:/usr/libexec:/usr/lib" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SENDMAIL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +SENDMAIL=$ac_cv_path_SENDMAIL +if test -n "$SENDMAIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SENDMAIL" >&5 +$as_echo "$SENDMAIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$ac_cv_path_SENDMAIL" ; then + GPGKEYS_MAILTO="gpg2keys_mailto" + fi + elif test x"$with_mailprog" != xno ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a mail transport program" >&5 +$as_echo_n "checking for a mail transport program... " >&6; } + SENDMAIL=$with_mailprog + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_mailprog" >&5 +$as_echo "$with_mailprog" >&6; } + GPGKEYS_MAILTO="gpg2keys_mailto" + fi +fi + + + +# +# Construct a printable name of the OS +# +case "${host}" 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 + +cat >>confdefs.h <<_ACEOF +#define PRINTABLE_OS_NAME "$PRINTABLE_OS_NAME" +_ACEOF + + + +# +# Checking for iconv +# + + 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" + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# 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. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 +$as_echo_n "checking for ld used by GCC... " >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$acl_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + 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 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + acl_libdirstem=lib + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBICONV= + LTLIBICONV= + INCICONV= + LIBICONV_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + 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" + 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" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBICONV_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +else + am_cv_func_iconv_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 +$as_echo_n "checking for iconv declaration... " >&6; } + if ${am_cv_proto_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +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 + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_cv_proto_iconv_arg1="" +else + am_cv_proto_iconv_arg1="const" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + 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);" +fi + + am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- + }$am_cv_proto_iconv" >&5 +$as_echo "${ac_t:- + }$am_cv_proto_iconv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define ICONV_CONST $am_cv_proto_iconv_arg1 +_ACEOF + + fi + + + +# +# Check for gettext +# +# This is "GNU gnupg" - The project-id script from gettext +# needs this string +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext" >&5 +$as_echo "$as_me: checking for gettext" >&6;} + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; USE_NLS=$enableval +else + USE_NLS=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + + + + + GETTEXT_MACRO_VERSION=0.17 + + + + +# 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 "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGFMT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; 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 + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --statistics /dev/null >&5 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); then + ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; + *) MSGFMT_015=$MSGFMT ;; + esac + + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac + + + +# 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 "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$XGETTEXT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; 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 + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 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); then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + rm -f messages.po + + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac + + + +# 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 "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGMERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGMERGE" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; 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 + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test "$MSGMERGE" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 +$as_echo "$MSGMERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$localedir" || localedir='${datadir}/locale' + + + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + + + ac_config_commands="$ac_config_commands po-directories" + + + +if test "$try_gettext" = yes; then + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 +$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } +if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFPreferencesCopyAppValue(NULL, NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFPreferencesCopyAppValue=yes +else + gt_cv_func_CFPreferencesCopyAppValue=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 +$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + +$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 +$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } +if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFLocaleCopyCurrent(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFLocaleCopyCurrent=yes +else + gt_cv_func_CFLocaleCopyCurrent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 +$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + +$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h + + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + + + + + + + LIBINTL= + LTLIBINTL= + POSUB= + + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 +$as_echo_n "checking for GNU gettext in libc... " >&6; } +if eval \${$gt_func_gnugettext_libc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libc=yes" +else + eval "$gt_func_gnugettext_libc=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$gt_func_gnugettext_libc + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +else + am_cv_func_iconv_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libintl-prefix was given. +if test "${with_libintl_prefix+set}" = set; then : + withval=$with_libintl_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBINTL= + LTLIBINTL= + INCINTL= + LIBINTL_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='intl ' + 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" + 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" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBINTL_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" + ;; + esac + done + fi + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" + done + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 +$as_echo_n "checking for GNU gettext in libintl... " >&6; } +if eval \${$gt_func_gnugettext_libintl+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libintl=yes" +else + eval "$gt_func_gnugettext_libintl=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS" +fi +eval ac_res=\$$gt_func_gnugettext_libintl + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + fi + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + else + USE_NLS=no + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 +$as_echo_n "checking whether to use NLS... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + if test "$USE_NLS" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 +$as_echo_n "checking where the gettext function comes from... " >&6; } + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 +$as_echo "$gt_source" >&6; } + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 +$as_echo_n "checking how to link with libintl... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 +$as_echo "$LIBINTL" >&6; } + + for element in $INCINTL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + fi + + +$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h + + +$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h + + fi + + POSUB=po + fi + + + + INTLLIBS="$LIBINTL" + + + + + + + + # 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. + + for ac_func in strchr +do : + ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr" +if test "x$ac_cv_func_strchr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCHR 1 +_ACEOF + +fi +done + +else + USE_NLS=no + USE_INCLUDED_LIBINTL=no + BUILD_INCLUDED_LIBINTL=no + POSUB=po + + + + +fi + +# We use HAVE_LANGINFO_CODESET in a couple of places. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 +$as_echo_n "checking for nl_langinfo and CODESET... " >&6; } +if ${am_cv_langinfo_codeset+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char* cs = nl_langinfo(CODESET); return !cs; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_langinfo_codeset=yes +else + am_cv_langinfo_codeset=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 +$as_echo "$am_cv_langinfo_codeset" >&6; } + if test $am_cv_langinfo_codeset = yes; then + +$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h + + fi + + +# Checks required for our use locales + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 +$as_echo_n "checking for LC_MESSAGES... " >&6; } +if ${gt_cv_val_LC_MESSAGES+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +return LC_MESSAGES + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_val_LC_MESSAGES=yes +else + gt_cv_val_LC_MESSAGES=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_val_LC_MESSAGES" >&5 +$as_echo "$gt_cv_val_LC_MESSAGES" >&6; } + if test $gt_cv_val_LC_MESSAGES = yes; then + +$as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h + + fi + + + +# +# SELinux support +# +if test "$selinux_support" = yes ; then + +$as_echo "#define ENABLE_SELINUX_HACKS 1" >>confdefs.h + +fi + + +# +# Checks for header files. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for header files" >&5 +$as_echo "$as_me: checking for header files" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_header in string.h unistd.h langinfo.h termio.h locale.h getopt.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in pty.h utmp.h pwd.h inttypes.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + + + +# +# Checks for typedefs, structures, and compiler characteristics. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for system characteristics" >&5 +$as_echo "$as_me: checking for system characteristics" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if ${ac_cv_c_volatile+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_volatile=yes +else + ac_cv_c_volatile=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +$as_echo "#define volatile /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include +/* NetBSD declares sys_siglist in unistd.h. */ +#ifdef HAVE_UNISTD_H +# include +#endif + +" +if test "x$ac_cv_have_decl_sys_siglist" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_SIGLIST $ac_have_decl +_ACEOF + + + + + + + for ac_header in $ac_header_list +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + if test $ac_cv_header_sys_socket_h = yes; then + SYS_SOCKET_H='' + else + for ac_header in winsock2.h ws2tcpip.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + SYS_SOCKET_H='sys/socket.h' + fi + + + ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include + #if HAVE_SYS_SOCKET_H + # include + #elif HAVE_WS2TCPIP_H + # include + #endif +" +if test "x$ac_cv_type_socklen_t" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 +$as_echo_n "checking for socklen_t equivalent... " >&6; } + if ${gl_cv_gl_cv_socklen_t_equiv+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + gl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t "unsigned int" "long int" "unsigned long int"; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + + int getpeername (int, $arg2 *, $t *); +int +main () +{ +$t len; + getpeername (0, 0, &len); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_socklen_t_equiv="$t" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$gl_cv_socklen_t_equiv" != "" && break + done + test "$gl_cv_socklen_t_equiv" != "" && break + done + +fi + + if test "$gl_cv_socklen_t_equiv" = ""; then + as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_socklen_t_equiv" >&5 +$as_echo "$gl_cv_socklen_t_equiv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define socklen_t $gl_cv_socklen_t_equiv +_ACEOF + +fi + + +# Check whether --enable-endian-check was given. +if test "${enable_endian_check+set}" = set; then : + enableval=$enable_endian_check; endiancheck=$enableval +else + endiancheck=yes +fi + + +if test x"$endiancheck" = xyes ; then + + tmp_assumed_endian=big + if test "$cross_compiling" = yes; then + case "$host_cpu" in + i[345678]* ) + tmp_assumed_endian=little + ;; + *) + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling; assuming $tmp_assumed_endian endianess" >&5 +$as_echo "$as_me: WARNING: cross compiling; assuming $tmp_assumed_endian endianess" >&2;} + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking endianess" >&5 +$as_echo_n "checking endianess... " >&6; } + if ${gnupg_cv_c_endian+:} false; then : + $as_echo_n "(cached) " >&6 +else + gnupg_cv_c_endian=unknown + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ + + #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros + #endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ + + #if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_c_endian=big +else + gnupg_cv_c_endian=little +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test "$gnupg_cv_c_endian" = unknown; then + if test "$cross_compiling" = yes; then : + gnupg_cv_c_endian=$tmp_assumed_endian + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +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); + } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gnupg_cv_c_endian=little +else + gnupg_cv_c_endian=big +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_c_endian" >&5 +$as_echo "$gnupg_cv_c_endian" >&6; } + if test "$gnupg_cv_c_endian" = little; then + +$as_echo "#define LITTLE_ENDIAN_HOST 1" >>confdefs.h + + else + +$as_echo "#define BIG_ENDIAN_HOST 1" >>confdefs.h + + fi + +fi + +# fixme: we should get rid of the byte type + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for byte typedef" >&5 +$as_echo_n "checking for byte typedef... " >&6; } + if ${gnupg_cv_typedef_byte+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _GNU_SOURCE 1 + #include + #include +int +main () +{ + + #undef byte + int a = sizeof(byte); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_typedef_byte=yes +else + gnupg_cv_typedef_byte=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_byte" >&5 +$as_echo "$gnupg_cv_typedef_byte" >&6; } + if test "$gnupg_cv_typedef_byte" = yes; then + +$as_echo "#define HAVE_BYTE_TYPEDEF 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ushort typedef" >&5 +$as_echo_n "checking for ushort typedef... " >&6; } + if ${gnupg_cv_typedef_ushort+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _GNU_SOURCE 1 + #include + #include +int +main () +{ + + #undef ushort + int a = sizeof(ushort); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_typedef_ushort=yes +else + gnupg_cv_typedef_ushort=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_ushort" >&5 +$as_echo "$gnupg_cv_typedef_ushort" >&6; } + if test "$gnupg_cv_typedef_ushort" = yes; then + +$as_echo "#define HAVE_USHORT_TYPEDEF 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ulong typedef" >&5 +$as_echo_n "checking for ulong typedef... " >&6; } + if ${gnupg_cv_typedef_ulong+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _GNU_SOURCE 1 + #include + #include +int +main () +{ + + #undef ulong + int a = sizeof(ulong); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_typedef_ulong=yes +else + gnupg_cv_typedef_ulong=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_ulong" >&5 +$as_echo "$gnupg_cv_typedef_ulong" >&6; } + if test "$gnupg_cv_typedef_ulong" = yes; then + +$as_echo "#define HAVE_ULONG_TYPEDEF 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u16 typedef" >&5 +$as_echo_n "checking for u16 typedef... " >&6; } + if ${gnupg_cv_typedef_u16+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _GNU_SOURCE 1 + #include + #include +int +main () +{ + + #undef u16 + int a = sizeof(u16); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_typedef_u16=yes +else + gnupg_cv_typedef_u16=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_u16" >&5 +$as_echo "$gnupg_cv_typedef_u16" >&6; } + if test "$gnupg_cv_typedef_u16" = yes; then + +$as_echo "#define HAVE_U16_TYPEDEF 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u32 typedef" >&5 +$as_echo_n "checking for u32 typedef... " >&6; } + if ${gnupg_cv_typedef_u32+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _GNU_SOURCE 1 + #include + #include +int +main () +{ + + #undef u32 + int a = sizeof(u32); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_typedef_u32=yes +else + gnupg_cv_typedef_u32=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_u32" >&5 +$as_echo "$gnupg_cv_typedef_u32" >&6; } + if test "$gnupg_cv_typedef_u32" = yes; then + +$as_echo "#define HAVE_U32_TYPEDEF 1" >>confdefs.h + + fi + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5 +$as_echo_n "checking size of unsigned short... " >&6; } +if ${ac_cv_sizeof_unsigned_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5 +$as_echo "$ac_cv_sizeof_unsigned_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 +$as_echo_n "checking size of unsigned int... " >&6; } +if ${ac_cv_sizeof_unsigned_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 +$as_echo "$ac_cv_sizeof_unsigned_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 +$as_echo_n "checking size of unsigned long... " >&6; } +if ${ac_cv_sizeof_unsigned_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5 +$as_echo_n "checking size of unsigned long long... " >&6; } +if ${ac_cv_sizeof_unsigned_long_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 +$as_echo_n "checking size of time_t... " >&6; } +if ${ac_cv_sizeof_time_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" " +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +"; then : + +else + if test "$ac_cv_type_time_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (time_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_time_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 +$as_echo "$ac_cv_sizeof_time_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_TIME_T $ac_cv_sizeof_time_t +_ACEOF + + + + +# 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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UINT64_C" >&5 +$as_echo_n "checking for UINT64_C... " >&6; } +if ${gnupg_cv_uint64_c_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +uint64_t foo=UINT64_C(42); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_uint64_c_works=yes +else + gnupg_cv_uint64_c_works=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_uint64_c_works" >&5 +$as_echo "$gnupg_cv_uint64_c_works" >&6; } +if test "$gnupg_cv_uint64_c_works" = "yes" ; then + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint64_t" >&5 +$as_echo_n "checking size of uint64_t... " >&6; } +if ${ac_cv_sizeof_uint64_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint64_t))" "ac_cv_sizeof_uint64_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_uint64_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (uint64_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_uint64_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint64_t" >&5 +$as_echo "$ac_cv_sizeof_uint64_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UINT64_T $ac_cv_sizeof_uint64_t +_ACEOF + + +fi + +if test "$ac_cv_sizeof_unsigned_short" = "0" \ + || test "$ac_cv_sizeof_unsigned_int" = "0" \ + || test "$ac_cv_sizeof_unsigned_long" = "0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&5 +$as_echo "$as_me: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&2;}; +fi + + +# +# Checks for library functions. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library functions" >&5 +$as_echo "$as_me: checking for library functions" >&6;} +ac_fn_c_check_decl "$LINENO" "getpagesize" "ac_cv_have_decl_getpagesize" "$ac_includes_default" +if test "x$ac_cv_have_decl_getpagesize" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETPAGESIZE $ac_have_decl +_ACEOF + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 +$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } +if ${ac_cv_sys_largefile_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=no; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGEFILE_SOURCE 1 +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=1; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_cv_sys_largefile_source=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 +$as_echo "$ac_cv_sys_largefile_source" >&6; } +case $ac_cv_sys_largefile_source in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source +_ACEOF +;; +esac +rm -rf conftest* + +# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug +# in glibc 2.1.3, but that breaks too many other things. +# If you want fseeko and ftello with glibc, upgrade to a fixed glibc. +if test $ac_cv_sys_largefile_source != unknown; then + +$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h + +fi + +for ac_func in vprintf +do : + ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" +if test "x$ac_cv_func_vprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VPRINTF 1 +_ACEOF + +ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" +if test "x$ac_cv_func__doprnt" = xyes; then : + +$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h + +fi + +fi +done + + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include +#ifdef HAVE_VFORK_H +# include +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include , but some compilers + (e.g. gcc -O) don't grok . Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + +for ac_func in strerror strlwr tcgetattr mmap +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in strcasecmp strncasecmp ctermid times gmtime_r +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in unsetenv fcntl ftruncate +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in gettimeofday getrusage getrlimit setrlimit clock_gettime +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in atexit raise getpagesize strftime nl_langinfo setlocale +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in ttyname rand ftello fsync stat +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_fn_c_check_type "$LINENO" "struct sigaction" "ac_cv_type_struct_sigaction" "#include +" +if test "x$ac_cv_type_struct_sigaction" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SIGACTION 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "sigset_t" "ac_cv_type_sigset_t" "#include +" +if test "x$ac_cv_type_sigset_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIGSET_T 1 +_ACEOF + + +fi + + +# +# These are needed by libjnlib - fixme: we should use a jnlib.m4 +# Note: We already checked pwd.h. +for ac_func in memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in memrchr isascii timegm getrusage setrlimit stat setlocale +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +for ac_func in flockfile funlockfile fopencookie funopen getpwnam getpwuid +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# +# gnulib checks +# + + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + return find_stack_direction () < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + + for ac_header in stdlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDLIB_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 +$as_echo_n "checking for GNU libc compatible malloc... " >&6; } +if ${ac_cv_func_malloc_0_nonnull+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_malloc_0_nonnull=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_malloc_0_nonnull=yes +else + ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 +$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then : + gl_cv_func_malloc_0_nonnull=1 +else + gl_cv_func_malloc_0_nonnull=0 +fi + + +cat >>confdefs.h <<_ACEOF +#define MALLOC_0_IS_NONNULL $gl_cv_func_malloc_0_nonnull +_ACEOF + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +$as_echo_n "checking for long long int... " >&6; } +if ${ac_cv_type_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* Test preprocessor. */ + #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + error in preprocessor; + #endif + #if ! (18446744073709551615ULL <= -1ull) + error in preprocessor; + #endif + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63; +int +main () +{ +/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if test "$cross_compiling" = yes; then : + ac_cv_type_long_long_int=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #ifndef LLONG_MAX + # define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + # define LLONG_MAX (HALF - 1 + HALF) + #endif +int +main () +{ +long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_type_long_long_int=yes +else + ac_cv_type_long_long_int=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +else + ac_cv_type_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +$as_echo "$ac_cv_type_long_long_int" >&6; } + if test $ac_cv_type_long_long_int = yes; then + +$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 +$as_echo_n "checking for long double... " >&6; } +if ${gt_cv_c_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$GCC" = yes; then + gt_cv_c_long_double=yes + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* The Stardent Vistra knows sizeof(long double), but does not support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + int array [2*(sizeof(long double) >= sizeof(double)) - 1]; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_c_long_double=yes +else + gt_cv_c_long_double=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_long_double" >&5 +$as_echo "$gt_cv_c_long_double" >&6; } + if test $gt_cv_c_long_double = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5 +$as_echo_n "checking whether stat file-mode macros are broken... " >&6; } +if ${ac_cv_header_stat_broken+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +#if defined S_ISBLK && defined S_IFDIR +extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; +#endif + +#if defined S_ISBLK && defined S_IFCHR +extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; +#endif + +#if defined S_ISLNK && defined S_IFREG +extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; +#endif + +#if defined S_ISSOCK && defined S_IFREG +extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stat_broken=no +else + ac_cv_header_stat_broken=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5 +$as_echo "$ac_cv_header_stat_broken" >&6; } +if test $ac_cv_header_stat_broken = yes; then + +$as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h + +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 +$as_echo_n "checking for unsigned long long int... " >&6; } +if ${ac_cv_type_unsigned_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* Test preprocessor. */ + #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + error in preprocessor; + #endif + #if ! (18446744073709551615ULL <= -1ull) + error in preprocessor; + #endif + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63; +int +main () +{ +/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_type_unsigned_long_long_int=yes +else + ac_cv_type_unsigned_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 +$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } + if test $ac_cv_type_unsigned_long_long_int = yes; then + +$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h + + fi + + + + + + + if false; then + GL_COND_LIBTOOL_TRUE= + GL_COND_LIBTOOL_FALSE='#' +else + GL_COND_LIBTOOL_TRUE='#' + GL_COND_LIBTOOL_FALSE= +fi + + gl_cond_libtool=false + gl_libdeps= + gl_ltlibdeps= + gl_source_base='gl' + + + + + + if test $ac_cv_func_alloca_works = no; then + : + fi + + # Define an additional variable used in the Makefile substitution. + if test $ac_cv_working_alloca_h = yes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined __GNUC__ || defined _AIX || defined _MSC_VER + Need own alloca +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Need own alloca" >/dev/null 2>&1; then : + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + + ALLOCA_H=alloca.h +else + ALLOCA_H= +fi +rm -f conftest* + + else + ALLOCA_H=alloca.h + fi + + + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + + + + + + + + + + ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp" +if test "x$ac_cv_func_mkdtemp" = xyes; then : + $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" mkdtemp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS mkdtemp.$ac_objext" + ;; +esac + +fi + + + if test $ac_cv_func_mkdtemp = no; then + + + + for ac_header in time.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" +if test "x$ac_cv_header_time_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TIME_H 1 +_ACEOF + +fi + +done + + for ac_func in gettimeofday +do : + ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETTIMEOFDAY 1 +_ACEOF + +fi +done + + + fi + + + ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" +if test "x$ac_cv_func_setenv" = xyes; then : + $as_echo "#define HAVE_SETENV 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" setenv.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS setenv.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" +if test "x$ac_cv_func_unsetenv" = xyes; then : + $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" unsetenv.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext" + ;; +esac + +fi + + + if test $ac_cv_func_setenv = no; then + + + + for ac_header in search.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "search.h" "ac_cv_header_search_h" "$ac_includes_default" +if test "x$ac_cv_header_search_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SEARCH_H 1 +_ACEOF + +fi + +done + + for ac_func in tsearch +do : + ac_fn_c_check_func "$LINENO" "tsearch" "ac_cv_func_tsearch" +if test "x$ac_cv_func_tsearch" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TSEARCH 1 +_ACEOF + +fi +done + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if environ is properly declared" >&5 +$as_echo_n "checking if environ is properly declared... " >&6; } + if ${gt_cv_var_environ_declaration+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + extern struct { int foo; } environ; +int +main () +{ +environ.foo = 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_var_environ_declaration=no +else + gt_cv_var_environ_declaration=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_var_environ_declaration" >&5 +$as_echo "$gt_cv_var_environ_declaration" >&6; } + if test $gt_cv_var_environ_declaration = yes; then + +$as_echo "#define HAVE_ENVIRON_DECL 1" >>confdefs.h + + fi + + + fi + if test $ac_cv_func_unsetenv = no; then + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if environ is properly declared" >&5 +$as_echo_n "checking if environ is properly declared... " >&6; } + if ${gt_cv_var_environ_declaration+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + extern struct { int foo; } environ; +int +main () +{ +environ.foo = 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_var_environ_declaration=no +else + gt_cv_var_environ_declaration=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_var_environ_declaration" >&5 +$as_echo "$gt_cv_var_environ_declaration" >&6; } + if test $gt_cv_var_environ_declaration = yes; then + +$as_echo "#define HAVE_ENVIRON_DECL 1" >>confdefs.h + + fi + + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsetenv() return type" >&5 +$as_echo_n "checking for unsetenv() return type... " >&6; } +if ${gt_cv_func_unsetenv_ret+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +int unsetenv (const char *name); +#else +int unsetenv(); +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_func_unsetenv_ret='int' +else + gt_cv_func_unsetenv_ret='void' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_unsetenv_ret" >&5 +$as_echo "$gt_cv_func_unsetenv_ret" >&6; } + if test $gt_cv_func_unsetenv_ret = 'void'; then + +$as_echo "#define VOID_UNSETENV 1" >>confdefs.h + + fi + fi + + + for ac_header in stdint.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDINT_H 1 +_ACEOF + +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SIZE_MAX" >&5 +$as_echo_n "checking for SIZE_MAX... " >&6; } + if ${gl_cv_size_max+:} false; then : + $as_echo_n "(cached) " >&6 +else + + gl_cv_size_max= + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#if HAVE_STDINT_H +#include +#endif +#ifdef SIZE_MAX +Found it +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Found it" >/dev/null 2>&1; then : + gl_cv_size_max=yes +fi +rm -f conftest* + + if test -z "$gl_cv_size_max"; then + if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) * CHAR_BIT - 1" "size_t_bits_minus_1" "#include +#include "; then : + +else + size_t_bits_minus_1= +fi + + + if ac_fn_c_compute_int "$LINENO" "sizeof (size_t) <= sizeof (unsigned int)" "fits_in_uint" "#include "; then : + +else + fits_in_uint= +fi + + + if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then + if test $fits_in_uint = 1; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + extern size_t foo; + extern unsigned long foo; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + fits_in_uint=0 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $fits_in_uint = 1; then + gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" + else + gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" + fi + else + gl_cv_size_max='((size_t)~(size_t)0)' + fi + fi + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_size_max" >&5 +$as_echo "$gl_cv_size_max" >&6; } + if test "$gl_cv_size_max" != yes; then + +cat >>confdefs.h <<_ACEOF +#define SIZE_MAX $gl_cv_size_max +_ACEOF + + fi + + + + + if test $ac_cv_type_long_long_int = yes; then + HAVE_LONG_LONG_INT=1 + else + HAVE_LONG_LONG_INT=0 + fi + + + if test $ac_cv_type_unsigned_long_long_int = yes; then + HAVE_UNSIGNED_LONG_LONG_INT=1 + else + HAVE_UNSIGNED_LONG_LONG_INT=0 + fi + + + + if test $ac_cv_header_wchar_h = yes; then + HAVE_WCHAR_H=1 + else + HAVE_WCHAR_H=0 + fi + + + if test $ac_cv_header_inttypes_h = yes; then + HAVE_INTTYPES_H=1 + else + HAVE_INTTYPES_H=0 + fi + + + if test $ac_cv_header_sys_types_h = yes; then + HAVE_SYS_TYPES_H=1 + else + HAVE_SYS_TYPES_H=0 + fi + + + if test $ac_cv_header_stdint_h = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +$as_echo_n "checking absolute name of ... " >&6; } +if ${gl_cv_absolute_stdint_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test $ac_cv_header_stdint_h = yes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF + gl_cv_absolute_stdint_h=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | +sed -n '\#/stdint.h#{s#.*"\(.*/stdint.h\)".*#\1#;s#^/[^/]#//&#;p;q;}'` + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_absolute_stdint_h" >&5 +$as_echo "$gl_cv_absolute_stdint_h" >&6; } +cat >>confdefs.h <<_ACEOF +#define ABSOLUTE_STDINT_H "$gl_cv_absolute_stdint_h" +_ACEOF + + + ABSOLUTE_STDINT_H=\"$gl_cv_absolute_stdint_h\" + HAVE_STDINT_H=1 + else + ABSOLUTE_STDINT_H=\"no/such/file/stdint.h\" + HAVE_STDINT_H=0 + fi + + + + if test $ac_cv_header_stdint_h = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stdint.h conforms to C99" >&5 +$as_echo_n "checking whether stdint.h conforms to C99... " >&6; } +if ${gl_cv_header_working_stdint_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + gl_cv_header_working_stdint_h=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#include ABSOLUTE_STDINT_H +#ifdef INT8_MAX +int8_t a1 = INT8_MAX; +int8_t a1min = INT8_MIN; +#endif +#ifdef INT16_MAX +int16_t a2 = INT16_MAX; +int16_t a2min = INT16_MIN; +#endif +#ifdef INT32_MAX +int32_t a3 = INT32_MAX; +int32_t a3min = INT32_MIN; +#endif +#ifdef INT64_MAX +int64_t a4 = INT64_MAX; +int64_t a4min = INT64_MIN; +#endif +#ifdef UINT8_MAX +uint8_t b1 = UINT8_MAX; +#else +typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +#endif +#ifdef UINT16_MAX +uint16_t b2 = UINT16_MAX; +#endif +#ifdef UINT32_MAX +uint32_t b3 = UINT32_MAX; +#endif +#ifdef UINT64_MAX +uint64_t b4 = UINT64_MAX; +#endif +int_least8_t c1 = INT8_C (0x7f); +int_least8_t c1max = INT_LEAST8_MAX; +int_least8_t c1min = INT_LEAST8_MIN; +int_least16_t c2 = INT16_C (0x7fff); +int_least16_t c2max = INT_LEAST16_MAX; +int_least16_t c2min = INT_LEAST16_MIN; +int_least32_t c3 = INT32_C (0x7fffffff); +int_least32_t c3max = INT_LEAST32_MAX; +int_least32_t c3min = INT_LEAST32_MIN; +int_least64_t c4 = INT64_C (0x7fffffffffffffff); +int_least64_t c4max = INT_LEAST64_MAX; +int_least64_t c4min = INT_LEAST64_MIN; +uint_least8_t d1 = UINT8_C (0xff); +uint_least8_t d1max = UINT_LEAST8_MAX; +uint_least16_t d2 = UINT16_C (0xffff); +uint_least16_t d2max = UINT_LEAST16_MAX; +uint_least32_t d3 = UINT32_C (0xffffffff); +uint_least32_t d3max = UINT_LEAST32_MAX; +uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +uint_least64_t d4max = UINT_LEAST64_MAX; +int_fast8_t e1 = INT_FAST8_MAX; +int_fast8_t e1min = INT_FAST8_MIN; +int_fast16_t e2 = INT_FAST16_MAX; +int_fast16_t e2min = INT_FAST16_MIN; +int_fast32_t e3 = INT_FAST32_MAX; +int_fast32_t e3min = INT_FAST32_MIN; +int_fast64_t e4 = INT_FAST64_MAX; +int_fast64_t e4min = INT_FAST64_MIN; +uint_fast8_t f1 = UINT_FAST8_MAX; +uint_fast16_t f2 = UINT_FAST16_MAX; +uint_fast32_t f3 = UINT_FAST32_MAX; +uint_fast64_t f4 = UINT_FAST64_MAX; +#ifdef INTPTR_MAX +intptr_t g = INTPTR_MAX; +intptr_t gmin = INTPTR_MIN; +#endif +#ifdef UINTPTR_MAX +uintptr_t h = UINTPTR_MAX; +#endif +intmax_t i = INTMAX_MAX; +uintmax_t j = UINTMAX_MAX; +struct s { + int check_PTRDIFF: PTRDIFF_MIN < 0 && 0 < PTRDIFF_MAX ? 1 : -1; + int check_SIG_ATOMIC: SIG_ATOMIC_MIN <= 0 && 0 < SIG_ATOMIC_MAX ? 1 : -1; + int check_SIZE: 0 < SIZE_MAX ? 1 : -1; + int check_WCHAR: WCHAR_MIN <= 0 && 0 < WCHAR_MAX ? 1 : -1; + int check_WINT: WINT_MIN <= 0 && 0 < WINT_MAX ? 1 : -1; + + /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ + int check_UINT8_C: + (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; + int check_UINT16_C: + (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; + + /* Detect bugs in OpenBSD 3.9 stdint.h. */ +#ifdef UINT8_MAX + int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +#endif +#ifdef UINT16_MAX + int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +#endif +#ifdef UINT32_MAX + int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +#endif +#ifdef UINT64_MAX + int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +#endif + int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; + int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; + int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; + int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; + int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; + int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; + int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; + int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; + int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; + int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; + int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +}; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_header_working_stdint_h=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdint_h" >&5 +$as_echo "$gl_cv_header_working_stdint_h" >&6; } + fi + if test "$gl_cv_header_working_stdint_h" != yes; then + + for ac_header in sys/inttypes.h sys/bitypes.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + if test $ac_cv_header_sys_inttypes_h = yes; then + HAVE_SYS_INTTYPES_H=1 + else + HAVE_SYS_INTTYPES_H=0 + fi + + if test $ac_cv_header_sys_bitypes_h = yes; then + HAVE_SYS_BITYPES_H=1 + else + HAVE_SYS_BITYPES_H=0 + fi + + + + + + for gltype in ptrdiff_t sig_atomic_t size_t wchar_t wint_t ; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bit size of $gltype" >&5 +$as_echo_n "checking for bit size of $gltype... " >&6; } +if eval \${gl_cv_bitsizeof_${gltype}+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "sizeof ($gltype) * CHAR_BIT" "result" " + #include + #include + #if HAVE_WCHAR_H + /* BSD/OS 4.1 has a bug: and must be included before + . */ + # include + # include + # include + #endif + +#include "; then : + +else + result=unknown +fi + + + eval gl_cv_bitsizeof_${gltype}=\$result + +fi +eval ac_res=\$gl_cv_bitsizeof_${gltype} + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval result=\$gl_cv_bitsizeof_${gltype} + if test $result = unknown; then + result=0 + fi + GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + cat >>confdefs.h <<_ACEOF +#define BITSIZEOF_${GLTYPE} $result +_ACEOF + + eval BITSIZEOF_${GLTYPE}=\$result + done + + + + + for gltype in sig_atomic_t wchar_t wint_t ; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gltype is signed" >&5 +$as_echo_n "checking whether $gltype is signed... " >&6; } +if eval \${gl_cv_type_${gltype}_signed+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #if HAVE_WCHAR_H + /* BSD/OS 4.1 has a bug: and must be included before + . */ + # include + # include + # include + #endif + + int verify[2 * (($gltype) -1 < ($gltype) 0) - 1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + result=yes +else + result=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + eval gl_cv_type_${gltype}_signed=\$result + +fi +eval ac_res=\$gl_cv_type_${gltype}_signed + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval result=\$gl_cv_type_${gltype}_signed + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + if test "$result" = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_SIGNED_${GLTYPE} 1 +_ACEOF + + eval HAVE_SIGNED_${GLTYPE}=1 + else + eval HAVE_SIGNED_${GLTYPE}=0 + fi + done + + + gl_cv_type_ptrdiff_t_signed=yes + gl_cv_type_size_t_signed=no + + + for gltype in ptrdiff_t sig_atomic_t size_t wchar_t wint_t ; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $gltype integer literal suffix" >&5 +$as_echo_n "checking for $gltype integer literal suffix... " >&6; } +if eval \${gl_cv_type_${gltype}_suffix+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval gl_cv_type_${gltype}_suffix=no + eval result=\$gl_cv_type_${gltype}_signed + if test "$result" = yes; then + glsufu= + else + glsufu=u + fi + for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do + case $glsuf in + '') gltype1='int';; + l) gltype1='long int';; + ll) gltype1='long long int';; + i64) gltype1='__int64';; + u) gltype1='unsigned int';; + ul) gltype1='unsigned long int';; + ull) gltype1='unsigned long long int';; + ui64)gltype1='unsigned __int64';; + esac + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #if HAVE_WCHAR_H + /* BSD/OS 4.1 has a bug: and must be included before + . */ + # include + # include + # include + #endif + + extern $gltype foo; + extern $gltype1 foo; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval gl_cv_type_${gltype}_suffix=\$glsuf +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" != no && break + done +fi +eval ac_res=\$gl_cv_type_${gltype}_suffix + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" = no && result= + eval ${GLTYPE}_SUFFIX=\$result + cat >>confdefs.h <<_ACEOF +#define ${GLTYPE}_SUFFIX $result +_ACEOF + + done + + + + STDINT_H=stdint.h + fi + + + + ac_fn_c_check_func "$LINENO" "strpbrk" "ac_cv_func_strpbrk" +if test "x$ac_cv_func_strpbrk" = xyes; then : + $as_echo "#define HAVE_STRPBRK 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strpbrk.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strpbrk.$ac_objext" + ;; +esac + +fi + + + if test $ac_cv_func_strpbrk = no; then + : + fi + + + for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + + UNISTD_H='' + +else + + UNISTD_H='unistd.h' + +fi + +done + + + + + + + for ac_header in stdint.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDINT_H 1 +_ACEOF + +fi + +done + + + LIBGNU_LIBDEPS="$gl_libdeps" + + LIBGNU_LTLIBDEPS="$gl_ltlibdeps" + + + + +# +# W32 specific test +# +for ac_header in sys/stat.h unistd.h direct.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5 +$as_echo_n "checking if mkdir takes one argument... " >&6; } +if ${gnupg_cv_mkdir_takes_one_arg+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_DIRECT_H +# include +#endif +int +main () +{ +mkdir ("foo", 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gnupg_cv_mkdir_takes_one_arg=no +else + gnupg_cv_mkdir_takes_one_arg=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_mkdir_takes_one_arg" >&5 +$as_echo "$gnupg_cv_mkdir_takes_one_arg" >&6; } +if test $gnupg_cv_mkdir_takes_one_arg = yes ; then + +$as_echo "#define MKDIR_TAKES_ONE_ARG 1" >>confdefs.h + +fi + + +# +# Sanity check regex. Tests adapted from mutt. +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether regular expression support is requested" >&5 +$as_echo_n "checking whether regular expression support is requested... " >&6; } +# Check whether --enable-regex was given. +if test "${enable_regex+set}" = set; then : + enableval=$enable_regex; use_regex=$enableval +else + use_regex=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_regex" >&5 +$as_echo "$use_regex" >&6; } + +if test "$use_regex" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + +# Check whether --with-regex was given. +if test "${with_regex+set}" = set; then : + withval=$with_regex; + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + +else + withval="" +fi + + + # Does the system have regex functions at all? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing regcomp" >&5 +$as_echo_n "checking for library containing regcomp... " >&6; } +if ${ac_cv_search_regcomp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char regcomp (); +int +main () +{ +return regcomp (); + ; + return 0; +} +_ACEOF +for ac_lib in '' regex; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_regcomp=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_regcomp+:} false; then : + break +fi +done +if ${ac_cv_search_regcomp+:} false; then : + +else + ac_cv_search_regcomp=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_regcomp" >&5 +$as_echo "$ac_cv_search_regcomp" >&6; } +ac_res=$ac_cv_search_regcomp +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + ac_fn_c_check_func "$LINENO" "regcomp" "ac_cv_func_regcomp" +if test "x$ac_cv_func_regcomp" = xyes; then : + gnupg_cv_have_regex=yes +else + gnupg_cv_have_regex=no +fi + + + if test $gnupg_cv_have_regex = no; then + use_regex=no + else + if test x"$cross_compiling" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling; assuming regexp libray is not broken" >&5 +$as_echo "$as_me: WARNING: cross compiling; assuming regexp libray is not broken" >&2;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether your system's regexp library is broken" >&5 +$as_echo_n "checking whether your system's regexp library is broken... " >&6; } +if ${gnupg_cv_regex_broken+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + gnupg_cv_regex_broken=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#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); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gnupg_cv_regex_broken=no +else + gnupg_cv_regex_broken=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_regex_broken" >&5 +$as_echo "$gnupg_cv_regex_broken" >&6; } + + if test $gnupg_cv_regex_broken = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: your regex is broken - disabling regex use" >&5 +$as_echo "$as_me: WARNING: your regex is broken - disabling regex use" >&2;} + use_regex=no + fi + fi + fi + CPPFLAGS="${_cppflags}" + LDFLAGS="${_ldflags}" +fi + +if test "$use_regex" != yes ; then + +$as_echo "#define DISABLE_REGEX 1" >>confdefs.h + +fi + if test x"$use_regex" != xyes; then + DISABLE_REGEX_TRUE= + DISABLE_REGEX_FALSE='#' +else + DISABLE_REGEX_TRUE='#' + DISABLE_REGEX_FALSE= +fi + + + + +# +# Do we have zlib? Must do it here because Solaris failed +# when compiling a conftest (due to the "-lz" from LIBS). +# Note that we combine zlib and bzlib2 in ZLIBS. +# +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; + if test -d "$withval"; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + +fi + + +ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflateInit2_ in -lz" >&5 +$as_echo_n "checking for deflateInit2_ in -lz... " >&6; } +if ${ac_cv_lib_z_deflateInit2_+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char deflateInit2_ (); +int +main () +{ +return deflateInit2_ (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_deflateInit2_=yes +else + ac_cv_lib_z_deflateInit2_=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflateInit2_" >&5 +$as_echo "$ac_cv_lib_z_deflateInit2_" >&6; } +if test "x$ac_cv_lib_z_deflateInit2_" = xyes; then : + ZLIBS="-lz" +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + + + +# +# Check whether we can support bzip2 +# +if test "$use_bzip2" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + +# Check whether --with-bzip2 was given. +if test "${with_bzip2+set}" = set; then : + withval=$with_bzip2; + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + +else + withval="" +fi + + + # Checking alongside stdio.h as an early version of bzip2 (1.0) + # required stdio.h to be included before bzlib.h, and Solaris 9 is + # woefully out of date. + if test "$withval" != no ; then + ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "#include +" +if test "x$ac_cv_header_bzlib_h" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompressInit in -lbz2" >&5 +$as_echo_n "checking for BZ2_bzCompressInit in -lbz2... " >&6; } +if ${ac_cv_lib_bz2_BZ2_bzCompressInit+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzCompressInit (); +int +main () +{ +return BZ2_bzCompressInit (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bz2_BZ2_bzCompressInit=yes +else + ac_cv_lib_bz2_BZ2_bzCompressInit=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompressInit" >&5 +$as_echo "$ac_cv_lib_bz2_BZ2_bzCompressInit" >&6; } +if test "x$ac_cv_lib_bz2_BZ2_bzCompressInit" = xyes; then : + + have_bz2=yes + ZLIBS="$ZLIBS -lbz2" + +$as_echo "#define HAVE_BZIP2 1" >>confdefs.h + + +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + +else + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags} +fi + + + fi +fi + if test x"$have_bz2" = "xyes"; then + ENABLE_BZIP2_SUPPORT_TRUE= + ENABLE_BZIP2_SUPPORT_FALSE='#' +else + ENABLE_BZIP2_SUPPORT_TRUE='#' + ENABLE_BZIP2_SUPPORT_FALSE= +fi + + + + +# Check for readline support + + +# Check whether --with-readline was given. +if test "${with_readline+set}" = set; then : + withval=$with_readline; _do_readline=$withval +else + _do_readline=yes +fi + + + if test "$_do_readline" != "no" ; then + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + + for _termcap in "" "-ltermcap" "-lcurses" "-lncurses" ; do + _readline_save_libs=$LIBS + _combo="-lreadline${_termcap:+ $_termcap}" + LIBS="$LIBS $_combo" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether readline via \"$_combo\" is present and sane" >&5 +$as_echo_n "checking whether readline via \"$_combo\" is present and sane... " >&6; } + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + +int +main () +{ + +rl_completion_func_t *completer; +add_history("foobar"); +rl_catch_signals=0; +rl_inhibit_completion=0; +rl_attempted_completion_function=NULL; +rl_completion_matches(NULL,NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + _found_readline=yes +else + _found_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_found_readline" >&5 +$as_echo "$_found_readline" >&6; } + + LIBS=$_readline_save_libs + + if test $_found_readline = yes ; then + +$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h + + LIBREADLINE=$_combo + + break + fi + done + + unset _termcap + unset _readline_save_libs + unset _combo + unset _found_readline + fi + + +# +# 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 + tmp_pat='[a-zA-Z]' + if echo "$VERSION" | sed 's/-.*//' | grep "$tmp_pat" >/dev/null ; then + development_version=yes + fi +fi +if test "$development_version" = yes; then + +$as_echo "#define IS_DEVELOPMENT_VERSION 1" >>confdefs.h + +fi + + if test x$cross_compiling = xyes; then + CROSS_COMPILING_TRUE= + CROSS_COMPILING_FALSE='#' +else + CROSS_COMPILING_TRUE='#' + CROSS_COMPILING_FALSE= +fi + + + + if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then + : + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +*** +*** 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. +***" >&5 +$as_echo "$as_me: WARNING: +*** +*** 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. +***" >&2;} + fi + + +# Add some extra libs here so that previous tests don't fail for +# mysterious reasons - the final link step should bail out. +# W32SOCKLIBS is also defined so that if can be used for tools not +# requiring any network stuff but linking to code in libcommon which +# tracks in winsock stuff (e.g. init_common_subsystems. +if test "$have_w32_system" = yes; then + W32SOCKLIBS="-lws2_32" + NETLIBS="${NETLIBS} ${W32SOCKLIBS}" +fi + + + + +# +# Setup gcc specific options +# +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cc features" >&5 +$as_echo "$as_me: checking for cc features" >&6;} +if test "$GCC" = yes; then + # Note that it is okay to use CFLAGS here because this are just + # warning options and the user should have a chance of overriding + # them. + if test "$USE_MAINTAINER_MODE" = "yes"; then + CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" + CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wno-missing-field-initializers" >&5 +$as_echo_n "checking if gcc supports -Wno-missing-field-initializers... " >&6; } + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wno-missing-field-initializers" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + _gcc_wopt=yes +else + _gcc_wopt=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5 +$as_echo "$_gcc_wopt" >&6; } + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_wopt" = xyes ; then + CFLAGS="$CFLAGS -W -Wno-sign-compare -Wno-missing-field-initializers" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wdeclaration-after-statement" >&5 +$as_echo_n "checking if gcc supports -Wdeclaration-after-statement... " >&6; } + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wdeclaration-after-statement" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + _gcc_wopt=yes +else + _gcc_wopt=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5 +$as_echo "$_gcc_wopt" >&6; } + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_wopt" = xyes ; then + CFLAGS="$CFLAGS -Wdeclaration-after-statement" + fi + else + CFLAGS="$CFLAGS -Wall" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wno-pointer-sign" >&5 +$as_echo_n "checking if gcc supports -Wno-pointer-sign... " >&6; } + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wno-pointer-sign" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + _gcc_psign=yes +else + _gcc_psign=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_psign" >&5 +$as_echo "$_gcc_psign" >&6; } + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_psign" = xyes ; then + CFLAGS="$CFLAGS -Wno-pointer-sign" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wpointer-arith" >&5 +$as_echo_n "checking if gcc supports -Wpointer-arith... " >&6; } + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wpointer-arith" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + _gcc_psign=yes +else + _gcc_psign=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_psign" >&5 +$as_echo "$_gcc_psign" >&6; } + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_psign" = xyes ; then + CFLAGS="$CFLAGS -Wpointer-arith" + fi +fi + + +# +# This is handy for debugging so the compiler doesn't rearrange +# things and eliminate variables. +# +# Check whether --enable-optimization was given. +if test "${enable_optimization+set}" = set; then : + enableval=$enable_optimization; if test $enableval = no ; then + CFLAGS=`echo $CFLAGS | sed 's/-O[0-9]//'` + fi +fi + + +# +# Prepare building of estream +# + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking system features for estream-printf" >&5 +$as_echo "$as_me: checking system features for estream-printf" >&6;} + for ac_header in stdint.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDINT_H 1 +_ACEOF + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +$as_echo_n "checking for long long int... " >&6; } +if ${ac_cv_type_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* Test preprocessor. */ + #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + error in preprocessor; + #endif + #if ! (18446744073709551615ULL <= -1ull) + error in preprocessor; + #endif + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63; +int +main () +{ +/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if test "$cross_compiling" = yes; then : + ac_cv_type_long_long_int=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #ifndef LLONG_MAX + # define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + # define LLONG_MAX (HALF - 1 + HALF) + #endif +int +main () +{ +long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_type_long_long_int=yes +else + ac_cv_type_long_long_int=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +else + ac_cv_type_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +$as_echo "$ac_cv_type_long_long_int" >&6; } + if test $ac_cv_type_long_long_int = yes; then + +$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 +$as_echo_n "checking for long double... " >&6; } +if ${ac_cv_type_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$GCC" = yes; then + ac_cv_type_long_double=yes + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* The Stardent Vistra knows sizeof (long double), but does + not support it. */ + long double foo = 0.0L; +int +main () +{ +static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + sizeof (double) <= sizeof (long double))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_long_double=yes +else + ac_cv_type_long_double=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 +$as_echo "$ac_cv_type_long_double" >&6; } + if test $ac_cv_type_long_double = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + + fi + + + + ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default" +if test "x$ac_cv_type_intmax_t" = xyes; then : + +$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h + +else + test $ac_cv_type_long_long_int = yes \ + && ac_type='long long int' \ + || ac_type='long int' + +cat >>confdefs.h <<_ACEOF +#define intmax_t $ac_type +_ACEOF + +fi + + + + + ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" +if test "x$ac_cv_type_uintmax_t" = xyes; then : + +$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h + +else + test $ac_cv_type_unsigned_long_long_int = yes \ + && ac_type='unsigned long long int' \ + || ac_type='unsigned long int' + +cat >>confdefs.h <<_ACEOF +#define uintmax_t $ac_type +_ACEOF + +fi + + + ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PTRDIFF_T 1 +_ACEOF + + +fi + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5 +$as_echo_n "checking size of unsigned long... " >&6; } +if ${ac_cv_sizeof_unsigned_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +$as_echo_n "checking size of void *... " >&6; } +if ${ac_cv_sizeof_void_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_void_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +$as_echo "$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and THOUSANDS_SEP" >&5 +$as_echo_n "checking for nl_langinfo and THOUSANDS_SEP... " >&6; } +if ${estream_cv_langinfo_thousands_sep+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char* cs = nl_langinfo(THOUSANDS_SEP); return !cs; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + estream_cv_langinfo_thousands_sep=yes +else + estream_cv_langinfo_thousands_sep=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $estream_cv_langinfo_thousands_sep" >&5 +$as_echo "$estream_cv_langinfo_thousands_sep" >&6; } + if test $estream_cv_langinfo_thousands_sep = yes; then + +$as_echo "#define HAVE_LANGINFO_THOUSANDS_SEP 1" >>confdefs.h + + fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking system features for estream" >&5 +$as_echo "$as_me: checking system features for estream" >&6;} + + + + +# +# Decide what to build +# +if test "$have_adns" = "yes"; then + GPGKEYS_KDNS="gpg2keys_kdns$EXEEXT" + +fi + + +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_libusb = no; then + build_scdaemon_extra="${tmp}without internal CCID driver" + tmp=", " + fi + if test -n "$build_scdaemon_extra"; then + build_scdaemon_extra="(${build_scdaemon_extra})" + fi +fi + + +if test "$build_agent_only" = "yes" ; then + build_gpg=no + build_gpgsm=no + build_scdaemon=no + build_tools=no + build_doc=no +fi + + + if test "$build_gpg" = "yes"; then + BUILD_GPG_TRUE= + BUILD_GPG_FALSE='#' +else + BUILD_GPG_TRUE='#' + BUILD_GPG_FALSE= +fi + + if test "$build_gpgsm" = "yes"; then + BUILD_GPGSM_TRUE= + BUILD_GPGSM_FALSE='#' +else + BUILD_GPGSM_TRUE='#' + BUILD_GPGSM_FALSE= +fi + + if test "$build_agent" = "yes"; then + BUILD_AGENT_TRUE= + BUILD_AGENT_FALSE='#' +else + BUILD_AGENT_TRUE='#' + BUILD_AGENT_FALSE= +fi + + if test "$build_scdaemon" = "yes"; then + BUILD_SCDAEMON_TRUE= + BUILD_SCDAEMON_FALSE='#' +else + BUILD_SCDAEMON_TRUE='#' + BUILD_SCDAEMON_FALSE= +fi + + if test "$build_tools" = "yes"; then + BUILD_TOOLS_TRUE= + BUILD_TOOLS_FALSE='#' +else + BUILD_TOOLS_TRUE='#' + BUILD_TOOLS_FALSE= +fi + + if test "$build_doc" = "yes"; then + BUILD_DOC_TRUE= + BUILD_DOC_FALSE='#' +else + BUILD_DOC_TRUE='#' + BUILD_DOC_FALSE= +fi + + if test "$build_symcryptrun" = "yes"; then + BUILD_SYMCRYPTRUN_TRUE= + BUILD_SYMCRYPTRUN_FALSE='#' +else + BUILD_SYMCRYPTRUN_TRUE='#' + BUILD_SYMCRYPTRUN_FALSE= +fi + + if test "$build_gpgtar" = "yes"; then + BUILD_GPGTAR_TRUE= + BUILD_GPGTAR_FALSE='#' +else + BUILD_GPGTAR_TRUE='#' + BUILD_GPGTAR_FALSE= +fi + + + if test x$cross_compiling = xno -a "$build_gpg" = yes ; then + RUN_GPG_TESTS_TRUE= + RUN_GPG_TESTS_FALSE='#' +else + RUN_GPG_TESTS_TRUE='#' + RUN_GPG_TESTS_FALSE= +fi + + + +# +# 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: +*** +*** You need libgpg-error to build this program. +** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libgpg-error +*** (at least version $NEED_GPG_ERROR_VERSION is required.) +***" >&5 +$as_echo "$as_me: +*** +*** You need libgpg-error to build this program. +** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libgpg-error +*** (at least version $NEED_GPG_ERROR_VERSION is required.) +***" >&6;} +fi +if test "$have_libgcrypt" = "no"; then + die=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: +*** +*** You need libgcrypt to build this program. +** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libgcrypt/ +*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.) +***" >&5 +$as_echo "$as_me: +*** +*** You need libgcrypt to build this program. +** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libgcrypt/ +*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.) +***" >&6;} +fi +if test "$have_libassuan" = "no"; then + die=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: +*** +*** You need libassuan to build this program. +*** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libassuan/ +*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). +***" >&5 +$as_echo "$as_me: +*** +*** You need libassuan to build this program. +*** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libassuan/ +*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). +***" >&6;} +fi +if test "$have_ksba" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: +*** +*** You need libksba to build this program. +*** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libksba/ +*** (at least version $NEED_KSBA_VERSION using API $NEED_KSBA_API is required). +***" >&5 +$as_echo "$as_me: +*** +*** You need libksba to build this program. +*** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libksba/ +*** (at least version $NEED_KSBA_VERSION using API $NEED_KSBA_API is required). +***" >&6;} +fi +if test "$missing_pth" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: +*** +*** It is now required to build with support for the +*** GNU Portable Threads Library (Pth). Please install this +*** library first. 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 +*** To build GnuPG for Windows you need to use the W32PTH +*** package; available at: +*** ftp://ftp.g10code.com/g10code/w32pth/ +***" >&5 +$as_echo "$as_me: +*** +*** It is now required to build with support for the +*** GNU Portable Threads Library (Pth). Please install this +*** library first. 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 +*** To build GnuPG for Windows you need to use the W32PTH +*** package; available at: +*** ftp://ftp.g10code.com/g10code/w32pth/ +***" >&6;} + die=yes +fi + +if test "$die" = "yes"; then + as_fn_error $? " +*** +*** Required libraries not found. Please consult the above messages +*** and install them before running configure again. +***" "$LINENO" 5 +fi + + + +ac_config_files="$ac_config_files m4/Makefile Makefile po/Makefile.in gl/Makefile include/Makefile jnlib/Makefile common/Makefile kbx/Makefile g10/Makefile sm/Makefile agent/Makefile scd/Makefile keyserver/Makefile keyserver/gpg2keys_mailto keyserver/gpg2keys_test tools/gpg-zip tools/Makefile doc/Makefile tests/Makefile tests/openpgp/Makefile tests/pkits/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GNUPG_AGENT_PGM_TRUE}" && test -z "${GNUPG_AGENT_PGM_FALSE}"; then + as_fn_error $? "conditional \"GNUPG_AGENT_PGM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GNUPG_PINENTRY_PGM_TRUE}" && test -z "${GNUPG_PINENTRY_PGM_FALSE}"; then + as_fn_error $? "conditional \"GNUPG_PINENTRY_PGM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GNUPG_SCDAEMON_PGM_TRUE}" && test -z "${GNUPG_SCDAEMON_PGM_FALSE}"; then + as_fn_error $? "conditional \"GNUPG_SCDAEMON_PGM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GNUPG_DIRMNGR_PGM_TRUE}" && test -z "${GNUPG_DIRMNGR_PGM_FALSE}"; then + as_fn_error $? "conditional \"GNUPG_DIRMNGR_PGM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GNUPG_PROTECT_TOOL_PGM_TRUE}" && test -z "${GNUPG_PROTECT_TOOL_PGM_FALSE}"; then + as_fn_error $? "conditional \"GNUPG_PROTECT_TOOL_PGM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WORKING_FAQPROG_TRUE}" && test -z "${WORKING_FAQPROG_FALSE}"; then + as_fn_error $? "conditional \"WORKING_FAQPROG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_USTAR_TRUE}" && test -z "${HAVE_USTAR_FALSE}"; then + as_fn_error $? "conditional \"HAVE_USTAR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_DOSISH_SYSTEM_TRUE}" && test -z "${HAVE_DOSISH_SYSTEM_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DOSISH_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_SIMPLE_GETTEXT_TRUE}" && test -z "${USE_SIMPLE_GETTEXT_FALSE}"; then + as_fn_error $? "conditional \"USE_SIMPLE_GETTEXT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_W32_SYSTEM_TRUE}" && test -z "${HAVE_W32_SYSTEM_FALSE}"; then + as_fn_error $? "conditional \"HAVE_W32_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_DNS_SRV_TRUE}" && test -z "${USE_DNS_SRV_FALSE}"; then + as_fn_error $? "conditional \"USE_DNS_SRV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FAKE_CURL_TRUE}" && test -z "${FAKE_CURL_FALSE}"; then + as_fn_error $? "conditional \"FAKE_CURL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GL_COND_LIBTOOL_TRUE}" && test -z "${GL_COND_LIBTOOL_FALSE}"; then + as_fn_error $? "conditional \"GL_COND_LIBTOOL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DISABLE_REGEX_TRUE}" && test -z "${DISABLE_REGEX_FALSE}"; then + as_fn_error $? "conditional \"DISABLE_REGEX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_BZIP2_SUPPORT_TRUE}" && test -z "${ENABLE_BZIP2_SUPPORT_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_BZIP2_SUPPORT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then + as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_GPG_TRUE}" && test -z "${BUILD_GPG_FALSE}"; then + as_fn_error $? "conditional \"BUILD_GPG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_GPGSM_TRUE}" && test -z "${BUILD_GPGSM_FALSE}"; then + as_fn_error $? "conditional \"BUILD_GPGSM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_AGENT_TRUE}" && test -z "${BUILD_AGENT_FALSE}"; then + as_fn_error $? "conditional \"BUILD_AGENT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_SCDAEMON_TRUE}" && test -z "${BUILD_SCDAEMON_FALSE}"; then + as_fn_error $? "conditional \"BUILD_SCDAEMON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_TOOLS_TRUE}" && test -z "${BUILD_TOOLS_FALSE}"; then + as_fn_error $? "conditional \"BUILD_TOOLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_DOC_TRUE}" && test -z "${BUILD_DOC_FALSE}"; then + as_fn_error $? "conditional \"BUILD_DOC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_SYMCRYPTRUN_TRUE}" && test -z "${BUILD_SYMCRYPTRUN_FALSE}"; then + as_fn_error $? "conditional \"BUILD_SYMCRYPTRUN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_GPGTAR_TRUE}" && test -z "${BUILD_GPGTAR_FALSE}"; then + as_fn_error $? "conditional \"BUILD_GPGTAR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${RUN_GPG_TESTS_TRUE}" && test -z "${RUN_GPG_TESTS_FALSE}"; then + as_fn_error $? "conditional \"RUN_GPG_TESTS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by gnupg $as_me 2.0.19, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +gnupg config.status 2.0.19 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; + "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "gl/Makefile") CONFIG_FILES="$CONFIG_FILES gl/Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "jnlib/Makefile") CONFIG_FILES="$CONFIG_FILES jnlib/Makefile" ;; + "common/Makefile") CONFIG_FILES="$CONFIG_FILES common/Makefile" ;; + "kbx/Makefile") CONFIG_FILES="$CONFIG_FILES kbx/Makefile" ;; + "g10/Makefile") CONFIG_FILES="$CONFIG_FILES g10/Makefile" ;; + "sm/Makefile") CONFIG_FILES="$CONFIG_FILES sm/Makefile" ;; + "agent/Makefile") CONFIG_FILES="$CONFIG_FILES agent/Makefile" ;; + "scd/Makefile") CONFIG_FILES="$CONFIG_FILES scd/Makefile" ;; + "keyserver/Makefile") CONFIG_FILES="$CONFIG_FILES keyserver/Makefile" ;; + "keyserver/gpg2keys_mailto") CONFIG_FILES="$CONFIG_FILES keyserver/gpg2keys_mailto" ;; + "keyserver/gpg2keys_test") CONFIG_FILES="$CONFIG_FILES keyserver/gpg2keys_test" ;; + "tools/gpg-zip") CONFIG_FILES="$CONFIG_FILES tools/gpg-zip" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "tests/openpgp/Makefile") CONFIG_FILES="$CONFIG_FILES tests/openpgp/Makefile" ;; + "tests/pkits/Makefile") CONFIG_FILES="$CONFIG_FILES tests/pkits/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "po-directories":C) + 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 + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + 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, UPDATEPOFILES, DUMMYPOFILES, GMOFILES 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" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + 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|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|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 ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + + +echo " + GnuPG v${VERSION} has been configured as follows: + + Platform: $PRINTABLE_OS_NAME ($host) + + OpenPGP: $build_gpg + S/MIME: $build_gpgsm + Agent: $build_agent $build_agent_threaded + Smartcard: $build_scdaemon $build_scdaemon_extra + Gpgtar: $build_gpgtar + + 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 +" +if test x"$use_regex" != xyes ; then +echo " + Warning: No regular expression support available. + OpenPGP trust signatures won't work. + gpg-check-pattern will not be build. +" +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..7cc3a83 --- /dev/null +++ b/configure.ac @@ -0,0 +1,1544 @@ +# configure.ac - for GnuPG 2.0 +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, +# 2006, 2007, 2008, 2010, 2011, +# 2012 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 3 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, see . + +# Process this file with autoconf to produce a configure script. +AC_PREREQ(2.61) +min_automake_version="1.10" + +# Remember to change the version number immediately *after* a release. +# Set my_issvn to "yes" for non-released code. Remember to run an +# "svn up" and "autogen.sh" right before creating a distribution. +m4_define([my_version], [2.0.19]) +m4_define([my_issvn], [no]) + +m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ + | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) +m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \ + | awk '/^\* / {printf "%s",$3}'])) +m4_define([my_full_version], [my_version[]m4_if(my_issvn,[yes], + [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])]) + +AC_INIT([gnupg],[my_full_version],[http://bugs.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=no + +NEED_GPG_ERROR_VERSION=1.7 + +NEED_LIBGCRYPT_API=1 +NEED_LIBGCRYPT_VERSION=1.4.0 + +NEED_LIBASSUAN_API=2 +NEED_LIBASSUAN_VERSION=2.0.0 + +NEED_KSBA_API=1 +NEED_KSBA_VERSION=1.0.7 + + +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) +AM_INIT_AUTOMAKE($PACKAGE, $VERSION) +AC_CANONICAL_HOST +AB_INIT + +AC_GNU_SOURCE + +# Some status variables. +have_gpg_error=no +have_libgcrypt=no +have_libassuan=no +have_ksba=no +have_pth=no +have_libusb=no +have_adns=no + +use_bzip2=yes +use_exec=yes +disable_keyserver_path=no +use_ccid_driver=yes +use_standard_socket=no + +GNUPG_BUILD_PROGRAM(gpg, yes) +GNUPG_BUILD_PROGRAM(gpgsm, yes) +GNUPG_BUILD_PROGRAM(agent, yes) +GNUPG_BUILD_PROGRAM(scdaemon, yes) +GNUPG_BUILD_PROGRAM(tools, yes) +GNUPG_BUILD_PROGRAM(doc, yes) +GNUPG_BUILD_PROGRAM(symcryptrun, no) +GNUPG_BUILD_PROGRAM(gpgtar, no) + + +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" + + +# Some folks want to use only the agent from this packet. Make it +# easier for them by providing the configure option +# --enable-only-agent. +AC_ARG_ENABLE(agent-only, + AC_HELP_STRING([--enable-agent-only],[build only the gpg-agent]), + build_agent_only=$enableval) + +# SELinux support includes tracking of sensitive files to avoid +# leaking their contents through processing these files by gpg itself +AC_MSG_CHECKING([whether SELinux support is requested]) +AC_ARG_ENABLE(selinux-support, + AC_HELP_STRING([--enable-selinux-support], + [enable SELinux support]), + selinux_support=$enableval, selinux_support=no) +AC_MSG_RESULT($selinux_support) + +# Allow disabling of bzib2 support. +# It is defined only after we confirm the library is available later +AC_MSG_CHECKING([whether to enable the BZIP2 compression algorithm]) +AC_ARG_ENABLE(bzip2, + AC_HELP_STRING([--disable-bzip2],[disable the BZIP2 compression algorithm]), + use_bzip2=$enableval) +AC_MSG_RESULT($use_bzip2) + +# Configure option to allow or 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 + # LDAP is defined only after we confirm the library is available later + AC_MSG_CHECKING([whether LDAP keyserver support is requested]) + AC_ARG_ENABLE(ldap, + AC_HELP_STRING([--disable-ldap],[disable LDAP keyserver interface only]), + try_ldap=$enableval, try_ldap=yes) + AC_MSG_RESULT($try_ldap) + + AC_MSG_CHECKING([whether HKP keyserver support is requested]) + AC_ARG_ENABLE(hkp, + AC_HELP_STRING([--disable-hkp],[disable HKP keyserver interface only]), + try_hkp=$enableval, try_hkp=yes) + AC_MSG_RESULT($try_hkp) + + AC_MSG_CHECKING([whether finger key fetching support is requested]) + AC_ARG_ENABLE(finger, + AC_HELP_STRING([--disable-finger], + [disable finger key fetching interface only]), + try_finger=$enableval, try_finger=yes) + AC_MSG_RESULT($try_finger) + + AC_MSG_CHECKING([whether generic object key fetching support is requested]) + AC_ARG_ENABLE(generic, + AC_HELP_STRING([--disable-generic], + [disable generic object key fetching interface only]), + try_generic=$enableval, try_generic=yes) + AC_MSG_RESULT($try_generic) + + AC_MSG_CHECKING([whether email keyserver support is requested]) + AC_ARG_ENABLE(mailto, + AC_HELP_STRING([--enable-mailto], + [enable email keyserver interface only]), + try_mailto=$enableval, try_mailto=no) + AC_MSG_RESULT($try_mailto) + fi + + AC_MSG_CHECKING([whether keyserver exec-path is enabled]) + AC_ARG_ENABLE(keyserver-path, + AC_HELP_STRING([--disable-keyserver-path], + [disable the exec-path option for keyserver helpers]), + [if test "$enableval" = no ; then + disable_keyserver_path=yes + fi],enableval=yes) + AC_MSG_RESULT($enableval) +fi + + +# +# Check for the key/uid cache size. This can't be zero, but can be +# pretty small on embedded systems. This is used for the gpg part. +# +AC_MSG_CHECKING([for the size of the key and uid cache]) +AC_ARG_ENABLE(key-cache, + AC_HELP_STRING([--enable-key-cache=SIZE], + [Set key cache to SIZE (default 4096)]),,enableval=4096) +if test "$enableval" = "no"; then + enableval=5 +elif test "$enableval" = "yes" || test "$enableval" = ""; then + enableval=4096 +fi +changequote(,)dnl +key_cache_size=`echo "$enableval" | sed 's/[A-Za-z]//g'` +changequote([,])dnl +if test "$enableval" != "$key_cache_size" || test "$key_cache_size" -lt 5; then + AC_MSG_ERROR([invalid key-cache size]) +fi +AC_MSG_RESULT($key_cache_size) +AC_DEFINE_UNQUOTED(PK_UID_CACHE_SIZE,$key_cache_size, + [Size of the key and UID caches]) + + + +# +# Check whether we want to use Linux capabilities +# +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) + + +# +# Allow disabling of internal CCID support. +# It is defined only after we confirm the library is available later +# +AC_MSG_CHECKING([whether to enable the internal CCID driver]) +AC_ARG_ENABLE(ccid-driver, + AC_HELP_STRING([--disable-ccid-driver], + [disable the internal CCID driver]), + use_ccid_driver=$enableval) +AC_MSG_RESULT($use_ccid_driver) + + +# +# To avoid double inclusion of config.h which might happen at some +# places, we add the usual double inclusion protection at the top of +# config.h. +# +AH_TOP([ +#ifndef GNUPG_CONFIG_H_INCLUDED +#define GNUPG_CONFIG_H_INCLUDED +]) + +# +# Stuff which goes at the bottom of config.h. +# +AH_BOTTOM([ +/* 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 DIRSEP_S "\\" +#define EXTSEP_C '.' +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#define EXEEXT_S ".exe" +#else +#define DIRSEP_C '/' +#define DIRSEP_S "/" +#define EXTSEP_C '.' +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#define EXEEXT_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 '-' + +/* 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" + +/* 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 + /* FIXME: We need to use a function to determine these values depending + on the actual installation directory. */ +#define GNUPG_BINDIR "c:\\gnupg" +#define GNUPG_LIBEXECDIR "c:\\gnupg" +#define GNUPG_LIBDIR "c:\\gnupg" +#define GNUPG_DATADIR "c:\\gnupg" +#define GNUPG_SYSCONFDIR "c:\\gnupg" +#endif + +/* Derive some other constants. */ +#if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) +#define EXEC_TEMPFILE_ONLY +#endif + + +/* We didn't define endianness above, so get it from OS macros. This + is intended for making fat binary builds on OS X. */ +#if !defined(BIG_ENDIAN_HOST) && !defined(LITTLE_ENDIAN_HOST) +#if defined(__BIG_ENDIAN__) +#define BIG_ENDIAN_HOST 1 +#elif defined(__LITTLE_ENDIAN__) +#define LITTLE_ENDIAN_HOST 1 +#else +#error "No endianness found" +#endif +#endif + + +/* Hack used for W32: ldap.m4 also tests for the ASCII version of + ldap_start_tls_s because that is the actual symbol used in the + library. winldap.h redefines it to our commonly used value, + thus we define our usual macro here. */ +#ifdef HAVE_LDAP_START_TLS_SA +# ifndef HAVE_LDAP_START_TLS_S +# define HAVE_LDAP_START_TLS_S 1 +# endif +#endif + + +/* Tell libgcrypt not to use its own libgpg-error implementation. */ +#define USE_LIBGPG_ERROR 1 + +/* We use jnlib, so tell other modules about it. */ +#define HAVE_JNLIB_LOGGING 1 + +/* Our HTTP code is used in estream mode. */ +#define HTTP_USE_ESTREAM 1 + +/* Under W32 we do an explicit socket initialization, thus we need to + avoid the on-demand initialization which would also install an atexit + handler. */ +#define HTTP_NO_WSASTARTUP + +/* We always include support for the OpenPGP card. */ +#define ENABLE_CARD_SUPPORT 1 + +/* We don't want the old assuan codes anymore. */ +#define _ASSUAN_ONLY_GPG_ERRORS 1 + +/* We explicitly need to disable PTH's soft mapping as Debian + currently enables it by default for no reason. */ +#define PTH_SYSCALL_SOFT 0 + +/* We want to use the libgcrypt provided memory allocation for + asprintf. */ +#define _ESTREAM_PRINTF_MALLOC gcry_malloc +#define _ESTREAM_PRINTF_FREE gcry_free +#define _ESTREAM_PRINTF_EXTRA_INCLUDE "util.h" + +#endif /*GNUPG_CONFIG_H_INCLUDED*/ +]) + + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_MSG_NOTICE([checking 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 +AM_PROG_CC_C_O +if test "x$ac_cv_prog_cc_c89" = "xno" ; then + AC_MSG_ERROR([[No C-89 compiler found]]) +fi +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_RANLIB +AC_CHECK_TOOL(AR, ar, :) +AC_PATH_PROG(PERL,"perl") +AC_CHECK_TOOL(WINDRES, windres, :) +AC_ISC_POSIX +gl_EARLY +AC_SYS_LARGEFILE +GNUPG_CHECK_FAQPROG +GNUPG_CHECK_USTAR + +# We need to compile and run a program on the build machine. A +# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in +# the AC archive is broken for autoconf 2.57. Given that tehre is no +# newer version of that macro, we assume that it is also broken for +# autoconf 2.61 and thus we use a simple but usually sufficient +# approach. +AC_MSG_CHECKING(for cc for build) +if test "$cross_compiling" = "yes"; then + CC_FOR_BUILD="${CC_FOR_BUILD-cc}" +else + CC_FOR_BUILD="${CC_FOR_BUILD-$CC}" +fi +AC_MSG_RESULT($CC_FOR_BUILD) +AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) + + + +try_gettext=yes +have_dosish_system=no +have_w32_system=no +use_simple_gettext=no +case "${host}" 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]) + disable_keyserver_path=yes + have_dosish_system=yes + have_w32_system=yes + try_gettext="no" + use_simple_gettext=yes + ;; + 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 ptrmismatch1' 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 ptrmismatch1" + 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) + +AM_CONDITIONAL(USE_SIMPLE_GETTEXT, test x"$use_simple_gettext" = xyes) + +if test "$have_w32_system" = yes; then + AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) +fi +AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) + +if test "$disable_keyserver_path" = yes; then + AC_DEFINE(DISABLE_KEYSERVER_PATH,1, + [Defined to disable exec-path for keyserver helpers]) +fi + +# +# Allows enabling the use of a standard socket by default This is +# gpg-agent's option --[no-]use-standard-socket. For Windows we force +# the use of this. +# +AC_MSG_CHECKING([whether to use a standard socket by default]) +AC_ARG_ENABLE(standard-socket, + AC_HELP_STRING([--enable-standard-socket], + [use a standard socket for the agent by default]), + use_standard_socket=$enableval) +tmp="" +if test "$use_standard_socket" != yes; then + if test "$have_w32_system" = yes; then + use_standard_socket=yes + tmp=" (forced)" + fi +fi +AC_MSG_RESULT($use_standard_socket$tmp) +if test "$use_standard_socket" = yes; then + AC_DEFINE(USE_STANDARD_SOCKET,1, + [Use a standard socket for the agent by default]) +fi + + +# (These need to go after AC_PROG_CC so that $EXEEXT is defined) +AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any]) + +if test x"$try_hkp" = xyes ; then + AC_SUBST(GPGKEYS_HKP,"gpg2keys_hkp$EXEEXT") +fi + +if test x"$try_finger" = xyes ; then + AC_SUBST(GPGKEYS_FINGER,"gpg2keys_finger$EXEEXT") +fi + + + +# +# Checks for libraries. +# +AC_MSG_NOTICE([checking 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_API:$NEED_LIBASSUAN_VERSION", + have_libassuan=yes,have_libassuan=no) +if test "$have_libassuan" = "yes"; then + AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version", + [version of the libbassuan library]) +fi + + + +# +# libksba is our X.509 support library +# +AM_PATH_KSBA("$NEED_KSBA_API:$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) + + +# +# libusb allows us to use the integrated CCID smartcard reader driver. +# +# FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs. +if test "$use_ccid_driver" = yes ; then + AC_CHECK_LIB(usb, usb_bulk_write, + [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" + AC_DEFINE(HAVE_LIBUSB,1, + [defined if libusb is available]) + have_libusb=yes + ]) + AC_CHECK_FUNCS(usb_create_match) +fi +AC_SUBST(LIBUSB_LIBS) + +# +# Check wether it is necessary to link against libdl. +# +gnupg_dlopen_save_libs="$LIBS" +LIBS="" +AC_SEARCH_LIBS(dlopen, c dl,,,) +DL_LIBS=$LIBS +AC_SUBST(DL_LIBS) +LIBS="$gnupg_dlopen_save_libs" + +# +# Checks for symcryptrun: +# + +# libutil has openpty() and login_tty(). +AC_CHECK_LIB(util, openpty, + [ LIBUTIL_LIBS="$LIBUTIL_LIBS -lutil" + AC_DEFINE(HAVE_LIBUTIL,1, + [defined if libutil is available]) + ]) +AC_SUBST(LIBUTIL_LIBS) + +# shred is used to clean temporary plain text files. +AC_PATH_PROG(SHRED, shred, /usr/bin/shred) +AC_DEFINE_UNQUOTED(SHRED, + "${SHRED}", [defines the filename of the shred program]) + + + +# +# Check whether the GNU Pth library is available +# Note, that we include a Pth emulation for W32. +# +GNUPG_PATH_PTH +if test "$have_pth" = "yes"; then + AC_DEFINE(USE_GNU_PTH, 1, + [Defined if the GNU Portable Thread Library should be used]) +else + 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 +***]]) +fi + + +AC_MSG_NOTICE([checking for networking options]) + +# +# Must check for network library requirements before doing link tests +# for ldap, for example. If ldap libs are static (or dynamic and without +# ELF runtime link paths), then link will fail and LDAP support won't +# 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"])) + + +# +# Check for ADNS. +# +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" +AC_ARG_WITH(adns, + AC_HELP_STRING([--with-adns=DIR], + [look for the adns library in DIR]), + [if test -d "$withval"; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi]) +if test "$with_adns" != "no"; then + AC_CHECK_HEADERS(adns.h, + AC_CHECK_LIB(adns, adns_init, + [have_adns=yes], + [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]), + [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]) +fi +if test "$have_adns" = "yes"; then + ADNSLIBS="-ladns" +fi +AC_SUBST(ADNSLIBS) +# Newer adns versions feature a free function to be used under W32. +AC_CHECK_FUNCS(adns_free) + + +# +# Now try for the resolver functions so we can use DNS for SRV, PA and CERT. +# +if test x"$try_hkp" = xyes || test x"$try_http" = xyes ; then + AC_ARG_ENABLE(dns-srv, + AC_HELP_STRING([--disable-dns-srv], + [disable the use of DNS SRV in HKP and HTTP]), + use_dns_srv=$enableval,use_dns_srv=yes) +fi + +AC_ARG_ENABLE(dns-pka, + AC_HELP_STRING([--disable-dns-pka], + [disable the use of PKA records in DNS]), + use_dns_pka=$enableval,use_dns_pka=yes) + +AC_ARG_ENABLE(dns-cert, + AC_HELP_STRING([--disable-dns-cert], + [disable the use of CERT records in DNS]), + use_dns_cert=$enableval,use_dns_cert=yes) + +if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes \ + || test x"$use_dns_cert" = xyes; then + _dns_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,,have_resolver=no)) + AC_SEARCH_LIBS(dn_expand,resolv bind,, + AC_SEARCH_LIBS(__dn_expand,resolv bind,,have_resolver=no)) + AC_SEARCH_LIBS(dn_skipname,resolv bind,, + AC_SEARCH_LIBS(__dn_skipname,resolv bind,,have_resolver=no)) + + if test x"$have_resolver" != xno ; then + + # Make sure that the BIND 4 resolver interface is workable before + # enabling any code that calls it. At some point I'll rewrite the + # code to use the BIND 8 resolver API. + # We might also want to use adns instead. Problem with ADNS is that + # it does not support v6. + + AC_MSG_CHECKING([whether the resolver is usable]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include +#include +#include +#include ]], +[[unsigned char answer[PACKETSZ]; + res_query("foo.bar",C_IN,T_A,answer,PACKETSZ); + dn_skipname(0,0); + dn_expand(0,0,0,0,0); +]])],have_resolver=yes,have_resolver=no) + AC_MSG_RESULT($have_resolver) + + # This is Apple-specific and somewhat bizarre as they changed the + # define in bind 8 for some reason. + + if test x"$have_resolver" != xyes ; then + AC_MSG_CHECKING( + [whether I can make the resolver usable with BIND_8_COMPAT]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define BIND_8_COMPAT +#include +#include +#include +#include ]], +[[unsigned char answer[PACKETSZ]; + res_query("foo.bar",C_IN,T_A,answer,PACKETSZ); + dn_skipname(0,0); dn_expand(0,0,0,0,0); +]])],[have_resolver=yes ; need_compat=yes]) + AC_MSG_RESULT($have_resolver) + fi + fi + + if test x"$have_resolver" = xyes ; then + DNSLIBS=$LIBS + + if test x"$use_dns_srv" = xyes ; then + AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV]) + fi + + if test x"$use_dns_pka" = xyes ; then + AC_DEFINE(USE_DNS_PKA,1,[define to use our experimental DNS PKA]) + fi + + if test x"$use_dns_cert" = xyes ; then + AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT]) + fi + + if test x"$need_compat" = xyes ; then + AC_DEFINE(BIND_8_COMPAT,1,[an Apple OSXism]) + fi + else + # If we have no resolver library but ADNS (e.g. under W32) enable the + # code parts which can be used with ADNS. + if test x"$have_adns" = xyes ; then + DNSLIBS="$ADNSLIBS" + AC_DEFINE(USE_ADNS,1,[Use ADNS as resolver library.]) + + if test x"$use_dns_srv" = xyes ; then + AC_DEFINE(USE_DNS_SRV,1) + fi + + if test x"$use_dns_pka" = xyes ; then + AC_DEFINE(USE_DNS_PKA,1) + fi + + if test x"$use_dns_cert" = xyes ; then + AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT]) + fi + else + use_dns_srv=no + use_dns_pka=no + use_dns_cert=no + fi + fi + + LIBS=$_dns_save_libs +fi + +AC_SUBST(DNSLIBS) + +AM_CONDITIONAL(USE_DNS_SRV, test x"$use_dns_srv" = xyes) + + +# +# Check for LDAP +# +if test "$try_ldap" = yes ; then + GNUPG_CHECK_LDAP($NETLIBS) +fi + +# +# Check for curl. We fake the curl API if libcurl isn't installed. +# We require 7.10 or later as we use curl_version_info(). +# +LIBCURL_CHECK_CONFIG([yes],[7.10],,[fake_curl=yes]) +AM_CONDITIONAL(FAKE_CURL,test x"$fake_curl" = xyes) + +# Generic, for us, means curl + +if test x"$try_generic" = xyes ; then + AC_SUBST(GPGKEYS_CURL,"gpg2keys_curl$EXEEXT") +fi + +# +# Check for sendmail +# +# This isn't necessarily sendmail itself, but anything that gives a +# sendmail-ish interface to the outside world. That includes Exim, +# Postfix, etc. Basically, anything that can handle "sendmail -t". +if test "$try_mailto" = yes ; then + AC_ARG_WITH(mailprog, + AC_HELP_STRING([--with-mailprog=NAME], + [use "NAME -t" for mail transport]), + ,with_mailprog=yes) + + if test x"$with_mailprog" = xyes ; then + AC_PATH_PROG(SENDMAIL,sendmail,,$PATH:/usr/sbin:/usr/libexec:/usr/lib) + if test "$ac_cv_path_SENDMAIL" ; then + GPGKEYS_MAILTO="gpg2keys_mailto" + fi + elif test x"$with_mailprog" != xno ; then + AC_MSG_CHECKING([for a mail transport program]) + AC_SUBST(SENDMAIL,$with_mailprog) + AC_MSG_RESULT($with_mailprog) + GPGKEYS_MAILTO="gpg2keys_mailto" + fi +fi + +AC_SUBST(GPGKEYS_MAILTO) + +# +# Construct a printable name of the OS +# +case "${host}" 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]) + + +# +# Checking for iconv +# +AM_ICONV + + +# +# Check for gettext +# +# This is "GNU gnupg" - The project-id script from gettext +# needs this string +# +AC_MSG_NOTICE([checking for gettext]) +AM_PO_SUBDIRS +AM_GNU_GETTEXT_VERSION([0.17]) +if test "$try_gettext" = yes; then + AM_GNU_GETTEXT([external],[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 + POSUB=po + AC_SUBST(USE_NLS) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(POSUB) +fi + +# We use HAVE_LANGINFO_CODESET in a couple of places. +AM_LANGINFO_CODESET + +# Checks required for our use locales +gt_LC_MESSAGES + + +# +# SELinux support +# +if test "$selinux_support" = yes ; then + AC_DEFINE(ENABLE_SELINUX_HACKS,1,[Define to enable SELinux support]) +fi + + +# +# Checks for header files. +# +AC_MSG_NOTICE([checking for header files]) +AC_HEADER_STDC +AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h]) +AC_CHECK_HEADERS([pty.h utmp.h pwd.h inttypes.h]) +AC_HEADER_TIME + + +# +# Checks for typedefs, structures, and compiler characteristics. +# +AC_MSG_NOTICE([checking for system characteristics]) +AC_C_CONST +AC_C_INLINE +AC_C_VOLATILE +AC_TYPE_SIZE_T +AC_TYPE_MODE_T +AC_TYPE_SIGNAL +AC_DECL_SYS_SIGLIST + +gl_HEADER_SYS_SOCKET +gl_TYPE_SOCKLEN_T + +AC_ARG_ENABLE(endian-check, + AC_HELP_STRING([--disable-endian-check], + [disable the endian check and trust the OS provided macros]), + endiancheck=$enableval,endiancheck=yes) + +if test x"$endiancheck" = xyes ; then + GNUPG_CHECK_ENDIAN +fi + +# fixme: we should get rid of the byte type +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) +AC_CHECK_SIZEOF(time_t,,[[ +#include +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +]]) + + +# 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 + + +# +# Checks for library functions. +# +AC_MSG_NOTICE([checking for library functions]) +AC_CHECK_DECLS(getpagesize) +AC_FUNC_FSEEKO +AC_FUNC_VPRINTF +AC_FUNC_FORK +AC_CHECK_FUNCS([strerror strlwr tcgetattr mmap]) +AC_CHECK_FUNCS([strcasecmp strncasecmp ctermid times gmtime_r]) +AC_CHECK_FUNCS([unsetenv fcntl ftruncate]) +AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime]) +AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) +AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo]) +AC_CHECK_FUNCS([ttyname rand ftello fsync stat]) + +AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) + +# +# These are needed by libjnlib - fixme: we should use a jnlib.m4 +# Note: We already checked pwd.h. +AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol]) +AC_CHECK_FUNCS([memrchr isascii timegm getrusage setrlimit stat setlocale]) +AC_CHECK_FUNCS([flockfile funlockfile fopencookie funopen getpwnam getpwuid]) + +# +# gnulib checks +# +gl_SOURCE_BASE([gl]) +gl_M4_BASE([gl/m4]) +gl_MODULES([setenv mkdtemp xsize strpbrk]) +gl_INIT + + +# +# W32 specific test +# +GNUPG_FUNC_MKDIR_TAKES_ONE_ARG + +# +# Sanity check regex. Tests adapted from mutt. +# +AC_MSG_CHECKING([whether regular expression support is requested]) +AC_ARG_ENABLE(regex, + AC_HELP_STRING([--disable-regex], + [do not handle regular expressions in trust signatures]), + use_regex=$enableval, use_regex=yes) +AC_MSG_RESULT($use_regex) + +if test "$use_regex" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + AC_ARG_WITH(regex, + AC_HELP_STRING([--with-regex=DIR],[look for regex in DIR]), + [ + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + ],withval="") + + # Does the system have regex functions at all? + AC_SEARCH_LIBS([regcomp], [regex]) + AC_CHECK_FUNC(regcomp, gnupg_cv_have_regex=yes, gnupg_cv_have_regex=no) + + if test $gnupg_cv_have_regex = no; then + use_regex=no + else + if test x"$cross_compiling" = xyes; then + AC_MSG_WARN([cross compiling; assuming regexp libray is not broken]) + else + 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 - disabling regex use]) + use_regex=no + fi + fi + fi + CPPFLAGS="${_cppflags}" + LDFLAGS="${_ldflags}" +fi + +if test "$use_regex" != yes ; then + AC_DEFINE(DISABLE_REGEX,1, [Define to disable regular expression support]) +fi +AM_CONDITIONAL(DISABLE_REGEX, test x"$use_regex" != xyes) + + + +# +# Do we have zlib? Must do it here because Solaris failed +# when compiling a conftest (due to the "-lz" from LIBS). +# Note that we combine zlib and bzlib2 in ZLIBS. +# +_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_, + ZLIBS="-lz", + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) + +# +# Check whether we can support bzip2 +# +if test "$use_bzip2" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + AC_ARG_WITH(bzip2, + AC_HELP_STRING([--with-bzip2=DIR],[look for bzip2 in DIR]), + [ + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + ],withval="") + + # Checking alongside stdio.h as an early version of bzip2 (1.0) + # required stdio.h to be included before bzlib.h, and Solaris 9 is + # woefully out of date. + if test "$withval" != no ; then + AC_CHECK_HEADER(bzlib.h, + AC_CHECK_LIB(bz2,BZ2_bzCompressInit, + [ + have_bz2=yes + ZLIBS="$ZLIBS -lbz2" + AC_DEFINE(HAVE_BZIP2,1, + [Defined if the bz2 compression library is available]) + ], + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags},[#include ]) + fi +fi +AM_CONDITIONAL(ENABLE_BZIP2_SUPPORT,test x"$have_bz2" = "xyes") +AC_SUBST(ZLIBS) + + +# Check for readline support +GNUPG_CHECK_READLINE + +# +# 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. +# W32SOCKLIBS is also defined so that if can be used for tools not +# requiring any network stuff but linking to code in libcommon which +# tracks in winsock stuff (e.g. init_common_subsystems. +if test "$have_w32_system" = yes; then + W32SOCKLIBS="-lws2_32" + NETLIBS="${NETLIBS} ${W32SOCKLIBS}" +fi + +AC_SUBST(NETLIBS) +AC_SUBST(W32SOCKLIBS) + +# +# Setup gcc specific options +# +AC_MSG_NOTICE([checking for cc features]) +if test "$GCC" = yes; then + # Note that it is okay to use CFLAGS here because this are just + # warning options and the user should have a chance of overriding + # them. + if test "$USE_MAINTAINER_MODE" = "yes"; then + CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" + CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security" + AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers]) + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wno-missing-field-initializers" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], + [_gcc_wopt=yes],[_gcc_wopt=no]) + AC_MSG_RESULT($_gcc_wopt) + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_wopt" = xyes ; then + CFLAGS="$CFLAGS -W -Wno-sign-compare -Wno-missing-field-initializers" + fi + AC_MSG_CHECKING([if gcc supports -Wdeclaration-after-statement]) + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wdeclaration-after-statement" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], + [_gcc_wopt=yes],[_gcc_wopt=no]) + AC_MSG_RESULT($_gcc_wopt) + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_wopt" = xyes ; then + CFLAGS="$CFLAGS -Wdeclaration-after-statement" + fi + else + CFLAGS="$CFLAGS -Wall" + fi + + AC_MSG_CHECKING([if gcc supports -Wno-pointer-sign]) + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wno-pointer-sign" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],[_gcc_psign=yes],[_gcc_psign=no]) + AC_MSG_RESULT($_gcc_psign) + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_psign" = xyes ; then + CFLAGS="$CFLAGS -Wno-pointer-sign" + fi + + AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wpointer-arith" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],[_gcc_psign=yes],[_gcc_psign=no]) + AC_MSG_RESULT($_gcc_psign) + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_psign" = xyes ; then + CFLAGS="$CFLAGS -Wpointer-arith" + fi +fi + + +# +# This is handy for debugging so the compiler doesn't rearrange +# things and eliminate variables. +# +AC_ARG_ENABLE(optimization, + AC_HELP_STRING([--disable-optimization], + [disable compiler optimization]), + [if test $enableval = no ; then + CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'` + fi]) + +# +# Prepare building of estream +# +estream_INIT + + +# +# Decide what to build +# +if test "$have_adns" = "yes"; then + AC_SUBST(GPGKEYS_KDNS, "gpg2keys_kdns$EXEEXT") +fi + + +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_libusb = no; then + build_scdaemon_extra="${tmp}without internal CCID driver" + tmp=", " + fi + if test -n "$build_scdaemon_extra"; then + build_scdaemon_extra="(${build_scdaemon_extra})" + fi +fi + + +if test "$build_agent_only" = "yes" ; then + build_gpg=no + build_gpgsm=no + build_scdaemon=no + build_tools=no + build_doc=no +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") +AM_CONDITIONAL(BUILD_TOOLS, test "$build_tools" = "yes") +AM_CONDITIONAL(BUILD_DOC, test "$build_doc" = "yes") +AM_CONDITIONAL(BUILD_SYMCRYPTRUN, test "$build_symcryptrun" = "yes") +AM_CONDITIONAL(BUILD_GPGTAR, test "$build_gpgtar" = "yes") + +AM_CONDITIONAL(RUN_GPG_TESTS, + test x$cross_compiling = xno -a "$build_gpg" = 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/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/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/libassuan/ +*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). +***]]) +fi +if test "$have_ksba" = "no"; then + AC_MSG_NOTICE([[ +*** +*** You need libksba to build this program. +*** This library is for example available at +*** ftp://ftp.gnupg.org/gcrypt/libksba/ +*** (at least version $NEED_KSBA_VERSION using API $NEED_KSBA_API is required). +***]]) +fi +if test "$missing_pth" = "yes"; then + AC_MSG_NOTICE([[ +*** +*** It is now required to build with support for the +*** GNU Portable Threads Library (Pth). Please install this +*** library first. 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 +*** To build GnuPG for Windows you need to use the W32PTH +*** package; available at: +*** ftp://ftp.g10code.com/g10code/w32pth/ +***]]) + die=yes +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 +gl/Makefile +include/Makefile +jnlib/Makefile +common/Makefile +kbx/Makefile +g10/Makefile +sm/Makefile +agent/Makefile +scd/Makefile +keyserver/Makefile +keyserver/gpg2keys_mailto +keyserver/gpg2keys_test +tools/gpg-zip +tools/Makefile +doc/Makefile +tests/Makefile +tests/openpgp/Makefile +tests/pkits/Makefile +]) +AC_OUTPUT + + +echo " + GnuPG v${VERSION} has been configured as follows: + + Platform: $PRINTABLE_OS_NAME ($host) + + OpenPGP: $build_gpg + S/MIME: $build_gpgsm + Agent: $build_agent $build_agent_threaded + Smartcard: $build_scdaemon $build_scdaemon_extra + Gpgtar: $build_gpgtar + + 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 +" +if test x"$use_regex" != xyes ; then +echo " + Warning: No regular expression support available. + OpenPGP trust signatures won't work. + gpg-check-pattern will not be build. +" +fi diff --git a/doc/ChangeLog-2011 b/doc/ChangeLog-2011 new file mode 100644 index 0000000..680affa --- /dev/null +++ b/doc/ChangeLog-2011 @@ -0,0 +1,798 @@ +2011-12-02 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2011-01-13 Werner Koch + + * FAQ: Make it a static file with a pointer to the online location. + * Makefile.am (EXTRA_DIST): Remove faq.raw and faq.html. + (FAQ, faq.html): Remove these targets + +2010-03-05 Werner Koch + + * gpg.texi (GPG Configuration Options): Mention that + show-uid-validity does only work with public keys. Noted by + Daniel Kahn Gillmor. + +2009-08-24 David Shaw + + * gpg.texi: Suggested new ordering for --edit-key. + +2009-08-17 David Shaw + + * gpg.texi (OpenPGP Options): Clarify that + personal-foo-preferences overrides recipient preferences (safely). + +2009-08-14 David Shaw + + * gpg.texi (GPG Configuration Options): Document keyserver options + check-cert and ca-cert-file. + +2009-08-06 Werner Koch + + * DETAILS: Describe the new INV_SNDR and NO_SNDR.. + +2009-07-31 David Shaw + + * gpg.texi (OpenPGP Options): Don't mention + --no-sk-comment (doesn't exist any longer). + +2009-07-23 David Shaw + + * gpg.texi (GPG Configuration Options): LDAP uses DNS-SD to locate + a server before falling back to keys.{domain}. + +2009-07-23 Werner Koch + + * help.txt (gpgsm.crl-problem): New. + +2009-07-22 Werner Koch + + * scdaemon.texi, instguide.texi, gpgsm.texi, sysnotes.texi + * glossary.texi, howto-create-a-server-cert.texi, tools.texi + * gpg-agent.texi, gpg.texi, debugging.texi: Typo fixes. Reported + by Jeroen Schot. Fixes bug#1093. + + * gpg.texi (GPG Configuration Options): Tell what files to backup. + * sysnotes.texi: Remove some warning notes for W32. + +2009-07-20 Werner Koch + + * gpg.texi (Operational GPG Commands): Add a note for --send-keys. + Fixes bug#1090. + +2009-07-06 Werner Koch + + * debugging.texi (Common Problems): Add a note about corrupted + keys in --search-keys. + +2009-06-02 Werner Koch + + * tools.texi (watchgnupg): Typo fix. Fixes bug#1065. + + * gpg-agent.texi (Agent Commands): Update description of --daemon. + +2009-05-20 Werner Koch + + * gpg.texi (GPG Configuration Options): Explain new meaning of + --enable-dsa2. + +2009-03-16 David Shaw + + * gpg.texi (GPG Configuration Options): Document keyserver-options + debug. + +2009-03-04 Werner Koch + + * help.txt (gpg.keygen.size): Add a link to web page. + +2009-03-03 Werner Koch + + * gpg.texi (Operational GPG Commands): "merge-only" is an + import-option. Reported by Joseph Oreste Bruni. + +2009-03-02 Werner Koch + + * gpg-agent.texi (Invoking GPG-AGENT): Modernized instructions. + (Agent Options): Fix spelling of option --lc-ctype. + +2009-01-12 Werner Koch + + * faq.raw: Fix bug reorting address. + +2008-12-12 Werner Koch + + * gpgsm.texi (General GPGSM Commands): Fix --help, --version and + --warranty wording. + +2008-12-08 Werner Koch + + * DETAILS: Clarify the use of "trust" and "validity" as suggested + by Daniel Kahn Gillmor. Fix some typos. Remove the outdated + sections on packet headers and pipemode. Point to the libgcrypt + manual for a description of the key generation. + +2008-11-12 Werner Koch + + * gpg-agent.texi (Agent Options): Use Posix $() instead of + backticks to avoid rendering problems. + +2008-10-13 Werner Koch + + * gpgsm.texi (Certificate Management): Explain hot to delete the + secret key. + +2008-10-01 Werner Koch + + * tools.texi (Controlling gpg-connect-agent): Describe /datafile. + +2008-09-23 David Shaw + + * gpg.texi (OpenPGP Key Management): Clarify setpref a bit. + +2008-08-30 Werner Koch + + * yat2m.c (write_th): Print a note that this is generated source. + (VERSION): Bump up to 1.0. + +2008-07-30 Werner Koch + + * gpgsm.texi (GPGSM Configuration): Mention com-cert.pem. + +2008-06-25 Werner Koch + + * qualified.txt: Add new BnetzA certs 12R and 13R. + * com-certs.pem: Ditto. + * examples/trustlist.txt: Ditto. + +2008-06-19 Werner Koch + + * tools.texi (Listing options): Describe new complect gpgconf type + "alias list". + +2008-06-16 Werner Koch + + * DETAILS (group): Document %ask-passphrase. + +2008-05-26 Werner Koch + + * gpgv.texi: Minor fixes. Fixes bug#918. + + * opt-homedir.texi: Typo fixes. Fixes bug#917. + +2008-05-26 Marcus Brinkmann + + * tools.texi (Invoking gpgconf): Document --list-dirs. + +2008-05-20 Marcus Brinkmann + + * tools.texi (Invoking gpgconf): Add --dry-run and --check-options. + (Checking programs): Document --check-options. + +2008-05-15 Marcus Brinkmann + + * gpg.texi (Operational GPG Commands): Mention the way to change + the default signing key. + +2008-05-06 Werner Koch + + * Makefile.am (myman_pages): Add gpg-zip.1. + + * tools.texi (gpg-zip): Add new section. + +2008-04-08 Werner Koch + + * gpg.texi (GPG Configuration Options): Change subkeys.pgp.net to + keys.gnupg.net. Describe --auto-key-locate mechanisms local and + nodefault. + +2008-04-03 Werner Koch + + * yat2m.c (proc_texi_cmd): Remove extra apostrophe from @samp and + use open and close quote to @file and @env. + +2008-04-02 Werner Koch + + * opt-homedir.texi: Remove special case for Registry key. + + * yat2m.c (proc_texi_cmd): Use the \(aq glyph for @samp. This is + bug#898. + (proc_texi_buffer): Handle backslashs correctly. + +2008-03-27 Werner Koch + + * Makefile.am (nobase_dist_doc_DATA, dist_html_DATA): New. Move + relevant files to here. + (install-html-local): Remove. + +2008-02-27 Marcus Brinkmann + + * tools.texi (Listing options): Document new types. + +2008-02-26 Werner Koch + + * gpg.texi (GPG Configuration Options): Mention rfc4398. + +2008-02-05 David Shaw + + * gpg.texi (GPG Esoteric Options): Tweak mention of Tempest font + to add a "claimed" in there. + +2008-01-29 Justin Pryzby (wk) + + * gpg-agent.texi (Agent Options): Grammar fixes + + * qualified.txt: Spelling fixes. + +2008-01-28 Justin Pryzby (wk) + + * gpg-agent.texi, yat2m.c, scdaemon.texi, qualified.txt + * tools.texi, gpgsm.texi: Typo fixes and minor grammer fixes. + +2008-01-10 Werner Koch + + * qualified.txt: Add missing country tag to the last entries. + Reported by Marcus Brinkmann. + +2008-01-10 Marcus Brinkmann + + * tools.texi (gpgconf): Some clarifications. + +2008-01-02 Werner Koch + + * gpg.texi (GPG Esoteric Options): Mention --log-file. + +2007-12-13 Werner Koch + + * qualified.txt: Add 2 root certs from S-Trust for 2008-2012. + * examples/trustlist.txt: Ditto. + * com-certs.pem: Ditto. + + * gpgsm.texi (Esoteric Options): Document --extra-digest-algo. + +2007-12-12 Werner Koch + + * gpg.texi: Typo fixes. From Christer Andersson. + +2007-12-04 Werner Koch + + * help.txt: New online help file. + * help.be.txt, help.ca.txt, help.cs.txt, help.da.txt, help.de.txt + * help.el.txt, help.eo.txt, help.es.txt, help.et.txt, help.fi.txt + * help.fr.txt, help.gl.txt, help.hu.txt, help.id.txt, help.it.txt + * help.ja.txt, help.nb.txt, help.pl.txt, help.pt.txt + * help.pt_BR.txt, help.ro.txt, help.ru.txt, help.sk.txt + * help.sv.txt, help.tr.txt, help.zh_CN.txt, help.zh_TW.txt: New + online file, generated from teh current po files. + * Makefile.am (dist_pkgdata_DATA): Add them. + +2007-11-19 Werner Koch + + * gpg.texi (GPG Configuration Options): English Grammar fix. + Thanks to Gerg Troxel. + + * gpgsm.texi (Certificate Options): Document + --auto-issuer-key-retrieve. + +2007-11-15 Werner Koch + + * gpg.texi (GPG Configuration): Add PINENTRY_USER_DATA. + + * gpg-agent.texi (Agent Options): Add xauthority. + +2007-10-31 Marcus Brinkmann + + * gpg-agent.texi (Agent Options): Fix typos, by Bernhard Reiter. + +2007-10-27 David Shaw + + * gpg.texi: Document --rfc4880 (the new --openpgp). + +2007-10-25 David Shaw + + * gpg.texi: Clarify --force-v3-sigs, --pgp2, and --pgp6 a bit. + +2007-10-23 Werner Koch + + * tools.texi (Listing global options): New. + +2007-10-19 Werner Koch + + * tools.texi (Controlling gpg-connect-agent): Updated. + +2007-08-29 Werner Koch + + * tools.texi (Checking programs): New. + +2007-08-27 Werner Koch + + * examples/pwpattern.list: New. + +2007-08-24 Werner Koch + + * debugging.texi (Common Problems): Add "A root certifciate does + not validate." + +2007-08-14 Werner Koch + + * glossary.texi (Glossary): Add a more items. + +2007-08-13 Werner Koch + + * yat2m.c (proc_texi_cmd): Do not put @samp content between two + newlines. + + * gpg-agent.texi (Agent Configuration): Explain the CM flag for + trustlist.txt. + +2007-08-09 Werner Koch + + * gpgsm.texi (Certificate Options): Describe --validation-model. + +2007-07-23 Werner Koch + + * scdaemon.texi (Scdaemon Commands): Remove obsolete --print-atr. + +2007-07-17 Werner Koch + + * gpgsm.texi (Input and Output): Document --default-key. + +2007-07-04 Werner Koch + + * gpl.texi: Updated to GPLv3. + +2007-06-22 Werner Koch + + * gpg.texi (Operational GPG Commands): Describe the flags used by + --check-sigs. + +2007-06-21 Werner Koch + + * gpgsm.texi (Certificate Management): Changed description of + --gen-key. + +2007-06-19 Werner Koch + + * glossary.texi (Glossary): Describe PSE. + +2007-06-18 Werner Koch + + * gpg-agent.texi (Agent GETINFO): New. + +2007-06-06 Werner Koch + + * Makefile.am (yat2m): Use a plain rule to build it for the sake + of cross-compiling. + + * yat2m.c (finish_page): Init SECT to NULL. + +2007-05-11 Werner Koch + + * gpgsm.texi (--export): Enhanced description. + +2007-05-09 Werner Koch + + * examples/gpgconf.conf: Remove active example line. + + * Makefile.am (online): Distinguish between released and svn manuals. + +2007-05-08 Werner Koch + + * howtos.texi: New. + * howto-create-a-server-cert.texi: New. + * Makefile.am (gnupg_TEXINFOS): Add new files. + + * gnupg.texi: Moved the logo for HTML more to the top. + * Makefile.am (install-html-local): New. + (DVIPS): Redefine to include srcdir. + +2007-05-04 Werner Koch + + * gnupg.texi (Top): Fix typo and a grammar issue. + * Makefile.am (EXTRA_DIST): Add gnupg-logo.png. Suggested by + Bernard Leak. + +2007-04-15 David Shaw + + * gpg.texi (OpenPGP Options): Update the personal-foo-preferences + documentation a bit. + +2007-04-10 Werner Koch + + * gpg.texi (GPG Configuration Options): Document --batch, no-tty, + --yes and --no. + +2007-03-08 Werner Koch + + * gnupg-logo.png, gnupg-logo.eps, gnupg-logo.pdf: New. + * gnupg-badge-openpgp.eps, gnupg-badge-openpgp.eps + * gnupg-badge-openpgp.jpg: Removed. + * gnupg.texi: Use new logo. + +2007-03-07 Werner Koch + + * tools.texi (applygnupgdefaults): New. + +2007-03-06 Werner Koch + + * examples/gpgconf.conf: New. + +2007-03-04 David Shaw + + * gpg.texi (GPG Esoteric Options): Document + --allow-multiple-messages. + +2007-02-26 Werner Koch + + * gpg.texi (GPG Configuration): Document envvar LANGUAGE. + (GPG Configuration Options): Document show-primary-uid-only. + +2007-02-18 Werner Koch + + * gpg.texi (GPG Esoteric Options): No card reader options for gpg2. + +2007-02-14 Werner Koch + + * gpg-agent.texi (Agent Options): Doc --pinentry-touch-file. + +2007-02-05 Werner Koch + + * debugging.texi (Common Problems): Tell how to export a private + key without a certificate. + +2007-01-30 Werner Koch + + * com-certs.pem: Added the current root certifcates of D-Trust and + S-Trust. + +2007-01-18 David Shaw + + * gpg.texi, specify-user-id.texi: Only some of the mentions of + exclamation marks have an example. Give examples to the rest. + +2007-01-17 David Shaw + + * gpg.texi (GPG Configuration Options): Make http_proxy option + documentation match reality. + (BUGS): Warn about hibernate/safe-sleep/etc writing main RAM to + disk, despite locking. + +2006-12-08 Werner Koch + + * gnupg.texi (direntry): Rename gpg to gpg2. + +2006-12-04 Werner Koch + + * gpgv.texi: New. + * tools.texi: Include new file. + +2006-12-02 David Shaw + + * gpg.texi (GPG Esoteric Options): Document --passphrase-repeat. + +2006-11-14 Werner Koch + + * gpgsm.texi (GPGSM EXPORT): Document changes. + +2006-11-11 Werner Koch + + * gnupg.texi (Top): Move gpg-agent part before gpg. + +2006-11-05 David Shaw + + * gpg.texi: Reference to --s2k-count in --s2k-mode. + +2006-10-30 Werner Koch + + * faq.raw: Minor corrections. + +2006-10-12 Werner Koch + + * Makefile.am (man_MANS): Do not install gnupg.7 due to a conflict + with gpg1. + +2006-10-12 David Shaw + + * gpg.texi: Document --s2k-count. + +2006-09-25 Werner Koch + + * gpg.texi (GPG Examples): Add markup to all options. This is + required to have the double dashs printed correclty. + +2006-09-22 Werner Koch + + * instguide.texi (Installation): New. + * assuan.texi (Assuan): Removed. Use the libassuan manual instead. + * gnupg.texi: Reflect these changes. + + * gpg.texi: Make some parts depend on the "gpgone" set + command. This allows us to use the same source for gpg1 and gpg2. + + * yat2m.c (parse_file): Better parsing of @ifset and ifclear. + (main): Allow definition of "-D gpgone". + (parse_file): Allow macro definitions. + (proc_texi_cmd): Expand macros. + (proc_texi_buffer): Process commands terminated by the closing + brace of the enclosing command. + +2006-09-20 Werner Koch + + * texi.css: New. Note that the current vesion of makeinfo has a + bug while copying the @import directive. A pacth has been send to + upstream. + +2006-09-19 Werner Koch + + * gpg.texi: Some restructuring. + + * Makefile.am (online): New target. + +2006-09-18 Werner Koch + + * com-certs.pem: New. + +2006-09-13 Werner Koch + + * gpg.texi (GPG Esoteric Options): Fixed typo in + --require-cross-certification and made it the default. + +2006-09-11 Werner Koch + + * HACKING: Cleaned up. + +2006-09-08 Werner Koch + + * yat2m.c (parse_file): Ignore @node lines immediately. + (proc_texi_cmd): No special @end ifset processing anymore. + + * specify-user-id.texi: New. Factored out of gpg.texi and ../README. + +2006-09-07 Werner Koch + + * scdaemon.texi (Scdaemon Configuration): New. + + * examples/scd-event: Event handler for sdaemon. + * examples/: New directory + +2006-08-22 Werner Koch + + * yat2m.c (parse_file): Added code to skip a line after @mansect. + + * gnupg7.texi: New. + +2006-08-21 Werner Koch + + * Makefile.am: Added other doc files from gpg 1.4. + +2006-08-17 Werner Koch + + * Makefile.am: Added rules to build man pages. + + * yat2m.c: New. + +2006-02-14 Werner Koch + + * gpgsm.texi (GPGSM Configuration): New section. + +2005-11-14 Werner Koch + + * qualified.txt: Added real information. + +2005-11-13 Werner Koch + + * qualified.txt: New. + * Makefile.am (dist_pkgdata_DATA): New. + +2005-08-16 Werner Koch + + * gpg-agent.texi (Agent Options): Note default file name for + --write-env-file. + +2005-06-03 Werner Koch + + * debugging.texi (Architecture Details): New section, mostly empty. + * gnupg-card-architecture.fig: New. + * Makefile.am: Rules to build png and eps versions. + + * gpg-agent.texi (Agent UPDATESTARTUPTTY): New. + +2005-05-17 Werner Koch + + * gpg-agent.texi (Agent Options): Removed --disable-pth. + +2005-04-27 Werner Koch + + * tools.texi (symcryptrun): Added. + + * scdaemon.texi: Removed OpenSC specific options. + +2005-04-20 Werner Koch + + * gpg-agent.texi (Agent Configuration): New section. + +2005-02-24 Werner Koch + + * tools.texi (gpg-connect-agent): New. + +2005-02-14 Werner Koch + + * gpgsm.texi (Certificate Management): Document --import. + +2005-01-27 Moritz Schulte + + * gpg-agent.texi: Document ssh-agent emulation layer. + +2005-01-04 Werner Koch + + * gnupg.texi: Updated to use @copying. + +2004-12-22 Werner Koch + + * gnupg.texi: Reordered. + * contrib.texi: Updated. + +2004-12-21 Werner Koch + + * tools.texi (gpg-preset-passphrase): New section. + + * gnupg-badge-openpgp.eps, gnupg-badge-openpgp.jpg: New + * gnupg.texi: Add a logo. + * sysnotes.texi: New. + +2004-11-05 Werner Koch + + * debugging.texi (Common Problems): Curses pinentry problem. + +2004-10-22 Werner Koch + + * tools.texi (Helper Tools): Document gpgsm-gencert.sh. + +2004-10-05 Werner Koch + + * gpg-agent.texi (Invoking GPG-AGENT): Tell that GPG_TTY needs to + be set in all cases. + +2004-09-30 Werner Koch + + * gpg.texi: New. + * gnupg.texi: Include gpg.texi + + * tools.texi: Add a few @command markups. + * gpgsm.texi: Ditto. + * gpg-agent.texi: Ditto. + * scdaemon.texi: Ditto. + +2004-09-30 Marcus Brinkmann + + * tools.texi (Changing options): Add documentation for gpgconf. + + * contrib.texi (Contributors): Add two missing periods. + +2004-09-29 Werner Koch + + * gpgsm.texi (Configuration Options): Add --log-file. + + * gpg-agent.texi (Invoking GPG-AGENT): Add a few words about the + expected pinentry filename. + + Changed license of the manual stuff to GPL. + + * gnupg.texi (Top): New menu item Helper Tools. + + * tools.texi (Helper Tools): New. + * Makefile.am (gnupg_TEXINFOS): Add tools.texi. + +2004-08-05 Werner Koch + + * scdaemon.texi (Card applications): New section. + +2004-06-22 Werner Koch + + * glossary.texi: New. + +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, 2004, 2005, 2006, 2007, 2008 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/DETAILS b/doc/DETAILS new file mode 100644 index 0000000..423eea9 --- /dev/null +++ b/doc/DETAILS @@ -0,0 +1,1299 @@ + -*- text -*- +Format of colon listings +======================== +First an example: + +$ gpg --fixed-list-mode --with-colons --list-keys \ + --with-fingerprint --with-fingerprint wk@gnupg.org + +pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC: +fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013: +uid:f::::::::Werner Koch : +uid:f::::::::Werner Koch : +sub:f:1536:16:06AD222CADF6A6E1:919537416:1036177416:::::e: +fpr:::::::::CF8BCC4B18DE08FCD8A1615906AD222CADF6A6E1: +sub:r:1536:20:5CE086B5B5A18FF4:899817788:1025961788:::::esc: +fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4: + +The double --with-fingerprint prints the fingerprint for the subkeys +too. --fixed-list-mode is the modern listing way printing dates in +seconds since Epoch and does not merge the first userID with the pub +record; gpg2 does this by default and the option is a dummy. + + + 1. Field: Type of record + pub = public key + crt = X.509 certificate + crs = X.509 certificate and private key available + sub = subkey (secondary key) + sec = secret key + ssb = secret subkey (secondary key) + uid = user id (only field 10 is used). + uat = user attribute (same as user id except for field 10). + sig = signature + rev = revocation signature + fpr = fingerprint: (fingerprint is in field 10) + pkd = public key data (special field format, see below) + grp = keygrip + rvk = revocation key + tru = trust database information + spk = signature subpacket + + 2. Field: A letter describing the calculated validity. This is a single + letter, but be prepared that additional information may follow + in some future versions. (not used for secret keys) + o = Unknown (this key is new to the system) + i = The key is invalid (e.g. due to a missing self-signature) + d = The key has been disabled + (deprecated - use the 'D' in field 12 instead) + r = The key has been revoked + e = The key has expired + - = Unknown validity (i.e. no value assigned) + q = Undefined validity + '-' and 'q' may safely be treated as the same + value for most purposes + n = The key is valid + m = The key is marginal valid. + f = The key is fully valid + u = The key is ultimately valid. This often means + that the secret key is available, but any key may + be marked as ultimately valid. + + If the validity information is given for a UID or UAT + record, it describes the validity calculated based on this + user ID. If given for a key record it describes the best + validity taken from the best rated user ID. + + For X.509 certificates a 'u' is used for a trusted root + certificate (i.e. for the trust anchor) and an 'f' for all + other valid certificates. + + 3. Field: length of key in bits. + + 4. Field: Algorithm: 1 = RSA + 16 = Elgamal (encrypt only) + 17 = DSA (sometimes called DH, sign only) + 20 = Elgamal (sign and encrypt - don't use them!) + (for other id's see include/cipher.h) + + 5. Field: KeyID + + 6. Field: Creation Date (in UTC). For UID and UAT records, this is + the self-signature date. Note that the date is usally + printed in seconds since epoch, however, we are migrating + to an ISO 8601 format (e.g. "19660205T091500"). This is + currently only relevant for X.509. A simple way to detect + the new format is to scan for the 'T'. + + 7. Field: Key or user ID/user attribute expiration date or empty if none. + + 8. Field: Used for serial number in crt records (used to be the Local-ID). + For UID and UAT records, this is a hash of the user ID contents + used to represent that exact user ID. For trust signatures, + this is the trust depth seperated by the trust value by a + space. + + 9. Field: Ownertrust (primary public keys only) + This is a single letter, but be prepared that additional + information may follow in some future versions. For trust + signatures with a regular expression, this is the regular + expression value, quoted as in field 10. + +10. Field: User-ID. The value is quoted like a C string to avoid + control characters (the colon is quoted "\x3a"). + For a "pub" record this field is not used on --fixed-list-mode. + A UAT record puts the attribute subpacket count here, a + space, and then the total attribute subpacket size. + In gpgsm the issuer name comes here + An FPR record stores the fingerprint here. + The fingerprint of an revocation key is stored here. + +11. Field: Signature class as per RFC-4880. This is a 2 digit + hexnumber followed by either the letter 'x' for an + exportable signature or the letter 'l' for a local-only + signature. The class byte of an revocation key is also + given here, 'x' and 'l' is used the same way. IT is not + used for X.509. + +12. Field: Key capabilities: + e = encrypt + s = sign + c = certify + a = authentication + A key may have any combination of them in any order. In + addition to these letters, the primary key has uppercase + versions of the letters to denote the _usable_ + capabilities of the entire key, and a potential letter 'D' + to indicate a disabled key. + +13. Field: Used in FPR records for S/MIME keys to store the + fingerprint of the issuer certificate. This is useful to + build the certificate path based on certificates stored in + the local keyDB; it is only filled if the issuer + certificate is available. The root has been reached if + this is the same string as the fingerprint. The advantage + of using this value is that it is guaranteed to have been + been build by the same lookup algorithm as gpgsm uses. + For "uid" records this lists the preferences in the same + way the gpg's --edit-key menu does. + For "sig" records, this is the fingerprint of the key that + issued the signature. Note that this is only filled in if + the signature verified correctly. Note also that for + various technical reasons, this fingerprint is only + available if --no-sig-cache is used. + +14. Field Flag field used in the --edit menu output: + +15. Field Used in sec/sbb to print the serial number of a token + (internal protect mode 1002) or a '#' if that key is a + simple stub (internal protect mode 1001) + +All dates are displayed in the format yyyy-mm-dd unless you use the +option --fixed-list-mode in which case they are displayed as seconds +since Epoch. More fields may be added later, so parsers should be +prepared for this. When parsing a number the parser should stop at the +first non-number character so that additional information can later be +added. + +If field 1 has the tag "pkd", a listing looks like this: +pkd:0:1024:B665B1435F4C2 .... FF26ABB: + ! ! !-- the value + ! !------ for information number of bits in the value + !--------- index (eg. DSA goes from 0 to 3: p,q,g,y) + + +Example for a "tru" trust base record: + + tru:o:0:1166697654:1:3:1:5 + + The fields are: + + 2: Reason for staleness of trust. If this field is empty, then the + trustdb is not stale. This field may have multiple flags in it: + + o: Trustdb is old + t: Trustdb was built with a different trust model than the one we + are using now. + + 3: Trust model: + 0: Classic trust model, as used in PGP 2.x. + 1: PGP trust model, as used in PGP 6 and later. This is the same + as the classic trust model, except for the addition of trust + signatures. + + GnuPG before version 1.4 used the classic trust model by default. + GnuPG 1.4 and later uses the PGP trust model by default. + + 4: Date trustdb was created in seconds since 1970-01-01. + 5: Date trustdb will expire in seconds since 1970-01-01. + 6: Number of marginally trusted users to introduce a new key signer + (gpg's option --marginals-needed) + 7: Number of completely trusted users to introduce a new key signer. + (gpg's option --completes-needed) + 8: Maximum depth of a certification chain. + *gpg's option --max-cert-depth) + +The "spk" signature subpacket records have the fields: + + 2: Subpacket number as per RFC-4880 and later. + 3: Flags in hex. Currently the only two bits assigned are 1, to + indicate that the subpacket came from the hashed part of the + signature, and 2, to indicate the subpacket was marked critical. + 4: Length of the subpacket. Note that this is the length of the + subpacket, and not the length of field 5 below. Due to the need + for %-encoding, the length of field 5 may be up to 3x this value. + 5: The subpacket data. Printable ASCII is shown as ASCII, but other + values are rendered as %XX where XX is the hex value for the byte. + + +Format of the "--status-fd" output +================================== +Every line is prefixed with "[GNUPG:] ", followed by a keyword with +the type of the status line and a some arguments depending on the +type (maybe none); an application should always be prepared to see +more arguments in future versions. + + + NEWSIG + May be issued right before a signature verification starts. This + is useful to define a context for parsing ERROR status + messages. No arguments are currently defined. + + GOODSIG + The signature with the keyid is good. For each signature only + one of the codes GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG + or ERRSIG will be emitted. In the past they were used as a + marker for a new signature; new code should use the NEWSIG + status instead. The username is the primary one encoded in + UTF-8 and %XX escaped. The fingerprint may be used instead of + the long keyid if it is available. This is the case with CMS + and might eventually also be available for OpenPGP. + + EXPSIG + The signature with the keyid is good, but the signature is + expired. The username is the primary one encoded in UTF-8 and + %XX escaped. The fingerprint may be used instead of the long + keyid if it is available. This is the case with CMS and might + eventually also be available for OpenPGP. + + EXPKEYSIG + The signature with the keyid is good, but the signature was + made by an expired key. The username is the primary one + encoded in UTF-8 and %XX escaped. The fingerprint may be used + instead of the long keyid if it is available. This is the + case with CMS and might eventually also be available for + OpenPGP. + + REVKEYSIG + The signature with the keyid is good, but the signature was + made by a revoked key. The username is the primary one encoded + in UTF-8 and %XX escaped. The fingerprint may be used instead + of the long keyid if it is available. This is the case with + CMS and might eventually also be available for OpenPGP. + + BADSIG + The signature with the keyid has not been verified okay. The + username is the primary one encoded in UTF-8 and %XX + escaped. The fingerprint may be used instead of the long keyid + if it is available. This is the case with CMS and might + eventually also be available for OpenPGP. + + ERRSIG \ + + It was not possible to check the signature. This may be + caused by a missing public key or an unsupported algorithm. A + RC of 4 indicates unknown algorithm, a 9 indicates a missing + public key. The other fields give more information about this + signature. sig_class is a 2 byte hex-value. The fingerprint + may be used instead of the long keyid if it is available. + This is the case with CMS and might eventually also be + available for OpenPGP. + + Note, that TIMESTAMP may either be a number with seconds since + epoch or an ISO 8601 string which can be detected by the + presence of the letter 'T' inside. + + VALIDSIG + + [ ] + + The signature with the keyid is good. This is the same as + GOODSIG but has the fingerprint as the argument. Both status + lines are emitted for a good signature. All arguments here + are on one long line. sig-timestamp is the signature creation + time in seconds after the epoch. expire-timestamp is the + signature expiration time in seconds after the epoch (zero + means "does not expire"). sig-version, pubkey-algo, hash-algo, + and sig-class (a 2-byte hex value) are all straight from the + signature packet. PRIMARY-KEY-FPR is the fingerprint of the + primary key or identical to the first argument. This is + useful to get back to the primary key without running gpg + again for this purpose. + + The primary-key-fpr parameter is used for OpenPGP and not + available for CMS signatures. The sig-version as well as the + sig class is not defined for CMS and currently set to 0 and 00. + + Note, that *-TIMESTAMP may either be a number with seconds + since epoch or an ISO 8601 string which can be detected by the + presence of the letter 'T' inside. + + SIG_ID + This is emitted only for signatures of class 0 or 1 which + have been verified okay. The string is a signature id + and may be used in applications to detect replay attacks + of signed messages. Note that only DLP algorithms give + unique ids - others may yield duplicated ones when they + have been created in the same second. + + Note, that SIG-TIMESTAMP may either be a number with seconds + since epoch or an ISO 8601 string which can be detected by the + presence of the letter 'T' inside. + + ENC_TO + The message is encrypted to this LONG_KEYID. KEYTYPE is the + numerical value of the public key algorithm or 0 if it is not + known, KEYLENGTH is the length of the key or 0 if it is not + known (which is currently always the case). Gpg prints this + line always; Gpgsm only if it knows the certificate. + + NODATA + No data has been found. Codes for what are: + 1 - No armored data. + 2 - Expected a packet but did not found one. + 3 - Invalid packet found, this may indicate a non OpenPGP + message. + 4 - signature expected but not found + You may see more than one of these status lines. + + UNEXPECTED + Unexpected data has been encountered + 0 - not further specified 1 + + + TRUST_UNDEFINED + TRUST_NEVER + TRUST_MARGINAL [0 []] + TRUST_FULLY [0 []] + TRUST_ULTIMATE [0 []] + For good signatures one of these status lines are emitted to + indicate the validity of the key used to create the signature. + The error token values are currently only emitted by gpgsm. + VALIDATION_MODEL describes the algorithm used to check the + validity of the key. The defaults are the standard Web of + Trust model for gpg and the the standard X.509 model for + gpgsm. The defined values are + + "pgp" for the standard PGP WoT. + "shell" for the standard X.509 model. + "chain" for the chain model. + + Note that we use the term "TRUST_" in the status names for + historic reasons; we now speak of validity. + + PKA_TRUST_GOOD + PKA_TRUST_BAD + Depending on the outcome of the PKA check one of the above + status codes is emitted in addition to a TRUST_* status. + Without PKA info available or + + SIGEXPIRED + This is deprecated in favor of KEYEXPIRED. + + KEYEXPIRED + The key has expired. expire-timestamp is the expiration time + in seconds since Epoch. This status line is not very useful + because it will also be emitted for expired subkeys even if + this subkey is not used. To check whether a key used to sign + a message has expired, the EXPKEYSIG status line is to be + used. + + Note, that TIMESTAMP may either be a number with seconds since + epoch or an ISO 8601 string which can be detected by the + presence of the letter 'T' inside. + + KEYREVOKED + The used key has been revoked by its owner. No arguments yet. + + BADARMOR + The ASCII armor is corrupted. No arguments yet. + + RSA_OR_IDEA + The IDEA algorithms has been used in the data. A + program might want to fallback to another program to handle + the data if GnuPG failed. This status message used to be emitted + also for RSA but this has been dropped after the RSA patent expired. + However we can't change the name of the message. + + SHM_INFO + SHM_GET + SHM_GET_BOOL + SHM_GET_HIDDEN + + GET_BOOL + GET_LINE + GET_HIDDEN + GOT_IT + + NEED_PASSPHRASE + Issued whenever a passphrase is needed. + keytype is the numerical value of the public key algorithm + or 0 if this is not applicable, keylength is the length + of the key or 0 if it is not known (this is currently always the case). + + NEED_PASSPHRASE_SYM + Issued whenever a passphrase for symmetric encryption is needed. + + NEED_PASSPHRASE_PIN [] + Issued whenever a PIN is requested to unlock a card. + + MISSING_PASSPHRASE + No passphrase was supplied. An application which encounters this + message may want to stop parsing immediately because the next message + will probably be a BAD_PASSPHRASE. However, if the application + is a wrapper around the key edit menu functionality it might not + make sense to stop parsing but simply ignoring the following + BAD_PASSPHRASE. + + BAD_PASSPHRASE + The supplied passphrase was wrong or not given. In the latter case + you may have seen a MISSING_PASSPHRASE. + + GOOD_PASSPHRASE + The supplied passphrase was good and the secret key material + is therefore usable. + + DECRYPTION_FAILED + The symmetric decryption failed - one reason could be a wrong + passphrase for a symmetrical encrypted message. + + DECRYPTION_OKAY + The decryption process succeeded. This means, that either the + correct secret key has been used or the correct passphrase + for a conventional encrypted message was given. The program + itself may return an errorcode because it may not be possible to + verify a signature for some reasons. + + NO_PUBKEY + NO_SECKEY + The key is not available + + IMPORT_CHECK + This status is emitted in interactive mode right before + the "import.okay" prompt. + + IMPORTED + The keyid and name of the signature just imported + + IMPORT_OK [] + The key with the primary key's FINGERPRINT has been imported. + Reason flags: + 0 := Not actually changed + 1 := Entirely new key. + 2 := New user IDs + 4 := New signatures + 8 := New subkeys + 16 := Contains private key. + The flags may be ORed. + + IMPORT_PROBLEM [] + Issued for each import failure. Reason codes are: + 0 := "No specific reason given". + 1 := "Invalid Certificate". + 2 := "Issuer Certificate missing". + 3 := "Certificate Chain too long". + 4 := "Error storing certificate". + + IMPORT_RES + + + Final statistics on import process (this is one long line) + + FILE_START + Start processing a file . indicates the performed + operation: + 1 - verify + 2 - encrypt + 3 - decrypt + + FILE_DONE + Marks the end of a file processing which has been started + by FILE_START. + + BEGIN_DECRYPTION + END_DECRYPTION + Mark the start and end of the actual decryption process. These + are also emitted when in --list-only mode. + + BEGIN_ENCRYPTION + END_ENCRYPTION + Mark the start and end of the actual encryption process. + + BEGIN_SIGNING + Mark the start of the actual signing process. This may be used + as an indication that all requested secret keys are ready for + use. + + DELETE_PROBLEM reason_code + Deleting a key failed. Reason codes are: + 1 - No such key + 2 - Must delete secret key first + 3 - Ambigious specification + + PROGRESS what char cur total + Used by the primegen and Public key functions to indicate progress. + "char" is the character displayed with no --status-fd enabled, with + the linefeed replaced by an 'X'. "cur" is the current amount + done and "total" is amount to be done; a "total" of 0 indicates that + the total amount is not known. The condition + TOATL && CUR == TOTAL + may be used to detect the end of an operation. + Well known values for WHAT: + "pk_dsa" - DSA key generation + "pk_elg" - Elgamal key generation + "primegen" - Prime generation + "need_entropy" - Waiting for new entropy in the RNG + "file:XXX" - processing file XXX + (note that current gpg versions leave out the + "file:" prefix). + "tick" - generic tick without any special meaning - useful + for letting clients know that the server is + still working. + "starting_agent" - A gpg-agent was started because it is not + running as a daemon. + "learncard" Send by the agent and gpgsm while learing + the data of a smartcard. + "card_busy" A smartcard is still working + + SIG_CREATED + A signature has been created using these parameters. + type: 'D' = detached + 'C' = cleartext + 'S' = standard + (only the first character should be checked) + class: 2 hex digits with the signature class + + Note, that TIMESTAMP may either be a number with seconds since + epoch or an ISO 8601 string which can be detected by the + presence of the letter 'T' inside. + + KEY_CREATED [] + A key has been created + type: 'B' = primary and subkey + 'P' = primary + 'S' = subkey + The fingerprint is one of the primary key for type B and P and + the one of the subkey for S. Handle is an arbitrary + non-whitespace string used to match key parameters from batch + key creation run. + + KEY_NOT_CREATED [] + The key from batch run has not been created due to errors. + + + SESSION_KEY : + The session key used to decrypt the message. This message will + only be emitted when the special option --show-session-key + is used. The format is suitable to be passed to the option + --override-session-key + + NOTATION_NAME + NOTATION_DATA + name and string are %XX escaped; the data may be split + among several NOTATION_DATA lines. + + USERID_HINT + Give a hint about the user ID for a certain keyID. + + POLICY_URL + string is %XX escaped + + BEGIN_STREAM + END_STREAM + Issued by pipemode. + + INV_RECP + INV_SGNR + Issued for each unusable recipient/sender. The reasons codes + currently in use are: + 0 := "No specific reason given". + 1 := "Not Found" + 2 := "Ambigious specification" + 3 := "Wrong key usage" + 4 := "Key revoked" + 5 := "Key expired" + 6 := "No CRL known" + 7 := "CRL too old" + 8 := "Policy mismatch" + 9 := "Not a secret key" + 10 := "Key not trusted" + 11 := "Missing certificate" + 12 := "Missing issuer certificate" + + Note that for historical reasons the INV_RECP status is also + used for gpgsm's SIGNER command where it relates to signer's + of course. Newer GnuPG versions are using INV_SGNR; + applications should ignore the INV_RECP during the sender's + command processing once they have seen an INV_SGNR. We use + different code so that we can distinguish them while doing an + encrypt+sign. + + + NO_RECP + NO_SGNR + Issued when no recipients/senders are usable. + + ALREADY_SIGNED + Warning: This is experimental and might be removed at any time. + + TRUNCATED + The output was truncated to MAXNO items. This status code is issued + for certain external requests + + ERROR [] + + This is a generic error status message, it might be followed + by error location specific data. and + should not contain spaces. The error code is + a either a string commencing with a letter or such a string + prefixed with a numerical error code and an underscore; e.g.: + "151011327_EOF". + + SUCCESS [] + Postive confirimation that an operation succeeded. + is optional but if given should not contain spaces. + Used only with a few commands. + + + ATTRIBUTE + + This is one long line issued for each attribute subpacket when + an attribute packet is seen during key listing. is the + fingerprint of the key. is the length of the + attribute subpacket. is the attribute type + (1==image). / indicates that this is the Nth + indexed subpacket of count total subpackets in this attribute + packet. and are from the + self-signature on the attribute packet. If the attribute + packet does not have a valid self-signature, then the + timestamp is 0. are a bitwise OR of: + 0x01 = this attribute packet is a primary uid + 0x02 = this attribute packet is revoked + 0x04 = this attribute packet is expired + + CARDCTRL [] + This is used to control smartcard operations. + Defined values for WHAT are: + 1 = Request insertion of a card. Serialnumber may be given + to request a specific card. Used by gpg 1.4 w/o scdaemon. + 2 = Request removal of a card. Used by gpg 1.4 w/o scdaemon. + 3 = Card with serialnumber detected + 4 = No card available. + 5 = No card reader available + 6 = No card support available + + PLAINTEXT + This indicates the format of the plaintext that is about to be + written. The format is a 1 byte hex code that shows the + format of the plaintext: 62 ('b') is binary data, 74 ('t') is + text data with no character set specified, and 75 ('u') is + text data encoded in the UTF-8 character set. The timestamp + is in seconds since the epoch. If a filename is available it + gets printed as the third argument, percent-escaped as usual. + + PLAINTEXT_LENGTH + This indicates the length of the plaintext that is about to be + written. Note that if the plaintext packet has partial length + encoding it is not possible to know the length ahead of time. + In that case, this status tag does not appear. + + SIG_SUBPACKET + This indicates that a signature subpacket was seen. The + format is the same as the "spk" record above. + + SC_OP_FAILURE [] + An operation on a smartcard definitely failed. Currently + there is no indication of the actual error code, but + application should be prepared to later accept more arguments. + Defined values for CODE are: + 0 - unspecified error (identically to a missing CODE) + 1 - canceled + 2 - bad PIN + + SC_OP_SUCCESS + A smart card operaion succeeded. This status is only printed + for certain operation and is mostly useful to check whether a + PIN change really worked. + + BACKUP_KEY_CREATED fingerprint fname + A backup key named FNAME has been created for the key with + KEYID. + + MOUNTPOINT + NAME is a percent-plus escaped filename describing the + mountpoint for the current operation (e.g. g13 --mount). This + may either be the specified mountpoint or one randomly choosen + by g13. + + DECRYPTION_INFO + Print information about the symmetric encryption algorithm and + the MDC method. This will be emitted even if the decryption + fails. + + + +Format of the "--attribute-fd" output +===================================== + +When --attribute-fd is set, during key listings (--list-keys, +--list-secret-keys) GnuPG dumps each attribute packet to the file +descriptor specified. --attribute-fd is intended for use with +--status-fd as part of the required information is carried on the +ATTRIBUTE status tag (see above). + +The contents of the attribute data is specified by RFC 4880. For +convenience, here is the Photo ID format, as it is currently the only +attribute defined: + + Byte 0-1: The length of the image header. Due to a historical + accident (i.e. oops!) back in the NAI PGP days, this is + a little-endian number. Currently 16 (0x10 0x00). + + Byte 2: The image header version. Currently 0x01. + + Byte 3: Encoding format. 0x01 == JPEG. + + Byte 4-15: Reserved, and currently unused. + + All other data after this header is raw image (JPEG) data. + + +Format of the "--list-config" output +==================================== + +--list-config outputs information about the GnuPG configuration for +the benefit of frontends or other programs that call GnuPG. There are +several list-config items, all colon delimited like the rest of the +--with-colons output. The first field is always "cfg" to indicate +configuration information. The second field is one of (with +examples): + +version: the third field contains the version of GnuPG. + + cfg:version:1.3.5 + +pubkey: the third field contains the public key algorithmdcaiphers + this version of GnuPG supports, separated by semicolons. The + algorithm numbers are as specified in RFC-4880. Note that in + contrast to the --status-fd interface these are _not_ the + Libgcrypt identifiers. + + cfg:pubkey:1;2;3;16;17 + +cipher: the third field contains the symmetric ciphers this version of + GnuPG supports, separated by semicolons. The cipher numbers + are as specified in RFC-4880. + + cfg:cipher:2;3;4;7;8;9;10 + +digest: the third field contains the digest (hash) algorithms this + version of GnuPG supports, separated by semicolons. The + digest numbers are as specified in RFC-4880. + + cfg:digest:1;2;3;8;9;10 + +compress: the third field contains the compression algorithms this + version of GnuPG supports, separated by semicolons. The + algorithm numbers are as specified in RFC-4880. + + cfg:compress:0;1;2;3 + +group: the third field contains the name of the group, and the fourth + field contains the values that the group expands to, separated + by semicolons. + +For example, a group of: + group mynames = paige 0x12345678 joe patti + +would result in: + cfg:group:mynames:patti;joe;0x12345678;paige + + +Key generation +============== + See the Libcrypt manual. + + +Unattended key generation +========================= +This feature allows unattended generation of keys controlled by a +parameter file. To use this feature, you use --gen-key together with +--batch and feed the parameters either from stdin or from a file given +on the commandline. + +The format of this file is as 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 indicates 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 + control statement "%commit" + o Control statements: + %echo + Print . + %dry-run + Suppress actual key generation (useful for syntax checking). + %commit + Perform the key generation. An implicit commit is done + at the next "Key-Type" parameter. + %pubring + %secring + Do not write the key to the default or commandline given + keyring but to . 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). + GnuPG < 2.1: Both control statements must be given. + GnuPG >= 2.1: "%secring" is now a no-op. + %ask-passphrase + Enable a mode where the command "passphrase" is ignored and + instead the usual passphrase dialog is used. This does not + make sense for batch key generation; however the unattended + key generation feature is also used by GUIs and this feature + relinquishes the GUI from implementing its own passphrase + entry code. This is a global option. + %no-ask-passphrase + Disable the ask-passphrase mode. + %no-protection + With GnuPG 2.1 it is not anymore possible to specify a + passphrase for unattended key generation. The passphrase + command is simply ignored and %ask-passpharse is thus + implicitly enabled. Using this option allows to the creation + of keys without any passphrases. This option is mainly + intended for regression tests. + %transient-key + If given the keys are created using a faster and a somewhat + less secure random number generator. This option may be used + for keys which are only used for a short time and do not + require full cryptographic strength. It takes only effect if + used together with the option no-protection. + + 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: | + 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. It may be "default" to use the default + one; in this case don't give a Key-Usage and use "default" for + the Subkey-Type. + Key-Length: + Length of the key in bits. The default is returned by running + the command "gpg --gpgconf-list". + Key-Usage: + Space or comma delimited list of key usage, allowed values are + "encrypt", "sign", and "auth". This is used to generate the + key flags. Please make sure that the algorithm is capable of + this usage. Note that OpenPGP requires that all primary keys + are capable of certification, so no matter what usage is given + here, the "cert" flag will be on. If no Key-Usage is + specified and the key-type is not "default", all allowed + usages for that particular algorithm are used; if it is not + given but "default" is used the usage will be "sign". + Subkey-Type: | + This generates a secondary key. Currently only one subkey + can be handled. "default" is also supported. + Subkey-Length: + Length of the subkey in bits. The default is returned by running + the command "gpg --gpgconf-list". + Subkey-Usage: + Similar to Key-Usage. + Passphrase: + If you want to specify a passphrase for the secret key, + enter it here. Default is not to use any passphrase. + Name-Real: + Name-Comment: + Name-Email: + The 3 parts of a key. Remember to use UTF-8 here. + If you don't give any of them, no user ID is created. + Expire-Date: |([d|w|m|y]) + Set the expiration date for the key (and the subkey). It may + either be entered in ISO date format (2000-08-15) or as number + of days, weeks, month or years. The special notation + "seconds=N" is also allowed to directly give an Epoch + value. Without a letter days are assumed. Note that there is + no check done on the overflow of the type used by OpenPGP for + timestamps. Thus you better make sure that the given value + make sense. Although OpenPGP works with time intervals, GnuPG + uses an absolute value internally and thus the last year we + can represent is 2105. + Creation-Date: + Set the creation date of the key as stored in the key + information and which is also part of the fingerprint + calculation. Either a date like "1986-04-26" or a full + timestamp like "19860426T042640" may be used. The time is + considered to be UTC. If it is not given the current time + is used. + Preferences: + Set the cipher, hash, and compression preference values for + this key. This expects the same type of string as "setpref" + in the --edit menu. + Revoker: : [sensitive] + Add a designated revoker to the generated key. Algo is the + public key algorithm of the designated revoker (i.e. RSA=1, + DSA=17, etc.) Fpr is the fingerprint of the designated + revoker. The optional "sensitive" flag marks the designated + revoker as sensitive information. Only v4 keys may be + designated revokers. + Handle: + This is an optional parameter only used with the status lines + KEY_CREATED and KEY_NOT_CREATED. STRING may be up to 100 + characters and should not contain spaces. It is useful for + batch key generation to associate a key parameter block with a + status line. + Keyserver: + This is an optional parameter that specifies the preferred + keyserver URL for the key. + + +Here is an example on how to create a key: +$ cat >foo < +ssb 1024g/8F70E2C0 2000-03-09 + +If you want to create a key with the default algorithms you would +use these parameters: + + %echo Generating a default key + Key-Type: default + Subkey-Type: default + Name-Real: Joe Tester + Name-Comment: with stupid passphrase + Name-Email: joe@foo.bar + Expire-Date: 0 + Passphrase: abc + %pubring foo.pub + %secring foo.sec + # Do a commit here, so that we can later print "done" :-) + %commit + %echo done + + + + +Layout of the TrustDB +===================== +The TrustDB is built from fixed length records, where the first byte +describes the record type. All numeric values are stored in network +byte order. The length of each record is 40 bytes. The first record of +the DB is always of type 1 and this is the only record of this type. + +FIXME: The layout changed, document it here. + + Record type 0: + -------------- + Unused record, can be reused for any purpose. + + Record type 1: + -------------- + Version information for this TrustDB. This is always the first + record of the DB and the only one with type 1. + 1 byte value 1 + 3 bytes 'gpg' magic value + 1 byte Version of the TrustDB (2) + 1 byte marginals needed + 1 byte completes needed + 1 byte max_cert_depth + The three items are used to check whether the cached + validity value from the dir record can be used. + 1 u32 locked flags [not used] + 1 u32 timestamp of trustdb creation + 1 u32 timestamp of last modification which may affect the validity + of keys in the trustdb. This value is checked against the + validity timestamp in the dir records. + 1 u32 timestamp of last validation [currently not used] + (Used to keep track of the time, when this TrustDB was checked + against the pubring) + 1 u32 record number of keyhashtable [currently not used] + 1 u32 first free record + 1 u32 record number of shadow directory hash table [currently not used] + It does not make sense to combine this table with the key table + because the keyid is not in every case a part of the fingerprint. + 1 u32 record number of the trusthashtbale + + + Record type 2: (directory record) + -------------- + Informations about a public key certificate. + These are static values which are never changed without user interaction. + + 1 byte value 2 + 1 byte reserved + 1 u32 LID . (This is simply the record number of this record.) + 1 u32 List of key-records (the first one is the primary key) + 1 u32 List of uid-records + 1 u32 cache record + 1 byte ownertrust + 1 byte dirflag + 1 byte maximum validity of all the user ids + 1 u32 time of last validity check. + 1 u32 Must check when this time has been reached. + (0 = no check required) + + + Record type 3: (key record) + -------------- + Informations about a primary public key. + (This is mainly used to lookup a trust record) + + 1 byte value 3 + 1 byte reserved + 1 u32 LID + 1 u32 next - next key record + 7 bytes reserved + 1 byte keyflags + 1 byte pubkey algorithm + 1 byte length of the fingerprint (in bytes) + 20 bytes fingerprint of the public key + (This is the value we use to identify a key) + + Record type 4: (uid record) + -------------- + Informations about a userid + We do not store the userid but the hash value of the userid because that + is sufficient. + + 1 byte value 4 + 1 byte reserved + 1 u32 LID points to the directory record. + 1 u32 next next userid + 1 u32 pointer to preference record + 1 u32 siglist list of valid signatures + 1 byte uidflags + 1 byte validity of the key calculated over this user id + 20 bytes ripemd160 hash of the username. + + + Record type 5: (pref record) + -------------- + This record type is not anymore used. + + 1 byte value 5 + 1 byte reserved + 1 u32 LID; points to the directory record (and not to the uid record!). + (or 0 for standard preference record) + 1 u32 next + 30 byte preference data + + Record type 6 (sigrec) + ------------- + Used to keep track of key signatures. Self-signatures are not + stored. If a public key is not in the DB, the signature points to + a shadow dir record, which in turn has a list of records which + might be interested in this key (and the signature record here + is one). + + 1 byte value 6 + 1 byte reserved + 1 u32 LID points back to the dir record + 1 u32 next next sigrec of this uid or 0 to indicate the + last sigrec. + 6 times + 1 u32 Local_id of signatures dir or shadow dir record + 1 byte Flag: Bit 0 = checked: Bit 1 is valid (we have a real + directory record for this) + 1 = valid is set (but may be revoked) + + + + Record type 8: (shadow directory record) + -------------- + This record is used to reserve a LID for a public key. We + need this to create the sig records of other keys, even if we + do not yet have the public key of the signature. + This record (the record number to be more precise) will be reused + as the dir record when we import the real public key. + + 1 byte value 8 + 1 byte reserved + 1 u32 LID (This is simply the record number of this record.) + 2 u32 keyid + 1 byte pubkey algorithm + 3 byte reserved + 1 u32 hintlist A list of records which have references to + this key. This is used for fast access to + signature records which are not yet checked. + Note, that this is only a hint and the actual records + may not anymore hold signature records for that key + but that the code cares about this. + 18 byte reserved + + + + Record Type 10 (hash table) + -------------- + Due to the fact that we use fingerprints to lookup keys, we can + implement quick access by some simple hash methods, and avoid + the overhead of gdbm. A property of fingerprints is that they can be + used directly as hash values. (They can be considered as strong + random numbers.) + What we use is a dynamic multilevel architecture, which combines + hashtables, record lists, and linked lists. + + This record is a hashtable of 256 entries; a special property + is that all these records are stored consecutively to make one + big table. The hash value is simple the 1st, 2nd, ... byte of + the fingerprint (depending on the indirection level). + + When used to hash shadow directory records, a different table is used + and indexed by the keyid. + + 1 byte value 10 + 1 byte reserved + n u32 recnum; n depends on the record length: + n = (reclen-2)/4 which yields 9 for the current record length + of 40 bytes. + + the total number of such record which makes up the table is: + m = (256+n-1) / n + which is 29 for a record length of 40. + + To look up a key we use the first byte of the fingerprint to get + the recnum from this hashtable and look up the addressed record: + - If this record is another hashtable, we use 2nd byte + to index this hash table and so on. + - if this record is a hashlist, we walk all entries + until we found one a matching one. + - if this record is a key record, we compare the + fingerprint and to decide whether it is the requested key; + + + Record type 11 (hash list) + -------------- + see hash table for an explanation. + This is also used for other purposes. + + 1 byte value 11 + 1 byte reserved + 1 u32 next next hash list record + n times n = (reclen-5)/5 + 1 u32 recnum + + For the current record length of 40, n is 7 + + + + Record type 254 (free record) + --------------- + All these records form a linked list of unused records. + 1 byte value 254 + 1 byte reserved (0) + 1 u32 next_free + + + +GNU extensions to the S2K algorithm +=================================== +S2K mode 101 is used to identify these extensions. +After the hash algorithm the 3 bytes "GNU" are used to make +clear that these are extensions for GNU, the next bytes gives the +GNU protection mode - 1000. Defined modes are: + 1001 - do not store the secret part at all + 1002 - a stub to access smartcards (not used in 1.2.x) + + + +Other Notes +=========== + * For packet version 3 we calculate the keyids this way: + RSA := low 64 bits of n + ELGAMAL := build a v3 pubkey packet (with CTB 0x99) and calculate + a rmd160 hash value from it. This is used as the + fingerprint and the low 64 bits are the keyid. + + * Revocation certificates consist only of the signature packet; + "import" knows how to handle this. The rationale behind it is + to keep them small. + + +OIDs below the GnuPG arc: +========================= + + 1.3.6.1.4.1.11591.2 GnuPG + 1.3.6.1.4.1.11591.2.1 notation + 1.3.6.1.4.1.11591.2.1.1 pkaAddress + 1.3.6.1.4.1.11591.2.12242973 invalid encoded OID + + + +Keyserver Message Format +========================= + +The keyserver may be contacted by a Unix Domain socket or via TCP. + +The format of a request is: + +==== +command-tag +"Content-length:" digits +CRLF +======= + +Where command-tag is + +NOOP +GET +PUT +DELETE + + +The format of a response is: + +====== +"GNUPG/1.0" status-code status-text +"Content-length:" digits +CRLF +============ +followed by bytes of data + + +Status codes are: + + o 1xx: Informational - Request received, continuing process + + o 2xx: Success - The action was successfully received, understood, + and accepted + + o 4xx: Client Error - The request contains bad syntax or cannot be + fulfilled + + o 5xx: Server Error - The server failed to fulfill an apparently + valid request + + + +Documentation on HKP (the http keyserver protocol): + +A minimalistic HTTP server on port 11371 recognizes a GET for /pks/lookup. +The standard http URL encoded query parameters are this (always key=value): + +- op=index (like pgp -kv), op=vindex (like pgp -kvv) and op=get (like + pgp -kxa) + +- search=. This is a list of words that must occur in the key. + The words are delimited with space, points, @ and so on. The delimiters + are not searched for and the order of the words doesn't matter (but see + next option). + +- exact=on. This switch tells the hkp server to only report exact matching + keys back. In this case the order and the "delimiters" are important. + +- fingerprint=on. Also reports the fingerprints when used with 'index' or + 'vindex' + +The keyserver also recognizes http-POSTs to /pks/add. Use this to upload +keys. + + +A better way to do this would be a request like: + + /pks/lookup/?op= + +This can be implemented using Hurd's translator mechanism. +However, I think the whole key server stuff has to be re-thought; +I have some ideas and probably create a white paper. + diff --git a/doc/FAQ b/doc/FAQ new file mode 100644 index 0000000..32d0744 --- /dev/null +++ b/doc/FAQ @@ -0,0 +1,13 @@ +GnuPG Frequently Asked Questions + +A FAQ is a fast moving target and thus we don't distribute it anymore +with GnuPG. You may retrieve the current FAQ in HTML format at + + http://www.gnupg.org/faq/GnuPG-FAQ.html + +or in plain text format at the FTP server: + + ftp://ftp.gnupg.org/gcrypt/gnupg/GnuPG-FAQ.txt + + + diff --git a/doc/HACKING b/doc/HACKING new file mode 100644 index 0000000..e27bc07 --- /dev/null +++ b/doc/HACKING @@ -0,0 +1,200 @@ + A Hacker's Guide to GNUPG + ================================ + (Some notes on GNUPG internals.) + + +* No more ChangeLog files + +Do not modify any of the ChangeLog files in GnuPG. Starting on +December 1st, 2011 we put change information only in the GIT commit +log, and generate a top-level ChangeLog file from logs at "make dist" +time. As such, there are strict requirements on the form of the +commit log messages. The old ChangeLog files have all be renamed to +ChangeLog-2011 + + +* Commit log requirements + +Your commit log should always start with a one-line summary, the second +line should be blank, and the remaining lines are usually ChangeLog-style +entries for all affected files. However, it's fine -- even recommended -- +to write a few lines of prose describing the change, when the summary +and ChangeLog entries don't give enough of the big picture. Omit the +leading TABs that you're used to seeing in a "real" ChangeLog file, but +keep the maximum line length at 72 or smaller, so that the generated +ChangeLog lines, each with its leading TAB, will not exceed 80 columns. + + + +===> What follows is probably out of date <=== + + + +RFCs +==== + +1423 Privacy Enhancement for Internet Electronic Mail: + Part III: Algorithms, Modes, and Identifiers. + +1489 Registration of a Cyrillic Character Set. + +1750 Randomness Recommendations for Security. + +1991 PGP Message Exchange Formats. + +2015 MIME Security with Pretty Good Privacy (PGP). + +2144 The CAST-128 Encryption Algorithm. + +2279 UTF-8, a transformation format of ISO 10646. + +2440 OpenPGP. + + + +Directory Layout +---------------- + ./ Readme, configure + ./agent Gpg-agent and related tools + ./doc Documentation + ./doc Documentation + ./g10 Gpg program here called gpg2 + ./jnlib Utility functions + ./kbx Keybox library + ./scd Smartcard daemon + ./scripts Scripts needed by configure and others + ./sm Gpgsm program + + +Detailed Roadmap +---------------- +g10/gpg.c Main module with option parsing and all the stuff you have + to do on startup. Also has the exout handler and some + helper functions. +g10/sign.c Create signature and optionally encrypt + +g10/parse-packet.c +g10/build-packet.c +g10/free-packet.c + Parsing and creating of OpenPGP message packets. + +g10/getkey.c Key selection code +g10/pkclist.c Build a list of public keys +g10/skclist.c Build a list of secret keys +g10/ringedit.c Keyring I/O +g10/keydb.h + +g10/keyid.c Helper functions to get the keyid, fingerprint etc. + + +g10/trustdb.c +g10/trustdb.h +g10/tdbdump.c + Management of the trustdb.gpg + +g10/compress.c Filter to handle compression +g10/filter.h Declarations for all filter functions +g10/delkey.c Delete a key +g10/kbnode.c Helper for the KBNODE linked list +g10/main.h Prototypes and some constants +g10/mainproc.c Message processing +g10/armor.c Ascii armor filter +g10/mdfilter.c Filter to calculate hashs +g10/textfilter.c Filter to handle CR/LF and trailing white space +g10/cipher.c En-/Decryption filter +g10/misc.c Utlity functions +g10/options.h Structure with all the command line options + and related constants +g10/openfile.c Create/Open Files +g10/tdbio.c I/O handling for the trustdb.gpg +g10/tdbio.h +g10/hkp.h Keyserver access +g10/hkp.c +g10/packet.h Defintion of OpenPGP structures. +g10/passphrase.c Passphrase handling code +g10/pubkey-enc.c +g10/seckey-cert.c +g10/seskey.c +g10/import.c +g10/export.c +g10/comment.c +g10/status.c +g10/status.h +g10/sign.c +g10/plaintext.c +g10/encr-data.c +g10/encode.c +g10/revoke.c +g10/keylist.c +g10/sig-check.c +g10/signal.c +g10/helptext.c +g10/verify.c +g10/decrypt.c +g10/keyedit.c +g10/dearmor.c +g10/keygen.c + + + +Memory allocation +----------------- +Use only the functions: + + xmalloc + xmalloc_secure + xtrymalloc + xtrymalloc_secure + xcalloc + xcalloc_secure + xtrycalloc + xtrycalloc_secure + xrealloc + xtryrealloc + xstrdup + xtrystrdup + xfree + + +The *secure versions allocated memory in the secure memory. That is, +swapping out of this memory is avoided and is gets overwritten on +free. Use this for passphrases, session keys and other sensitive +material. This memory set aside for secure memory is linited to a few +k. In general the function don't print a memeory message and +terminate the process if there is not enough memory available. The +"try" versions of the functions return NULL instead. + + +Logging +------- + + + + + + +Option parsing +--------------- +GNUPG does not use getopt or GNU getopt but functions of it's own. See +util/argparse.c for details. The advantage of these functions is that +it is more easy to display and maintain the help texts for the options. +The same option table is also used to parse resource files. + + + +What is an IOBUF +---------------- +This is the data structure used for most I/O of gnupg. It is similar +to System V Streams but much simpler. Because OpenPGP messages are nested +in different ways; the use of such a system has big advantages. Here is +an example, how it works: If the parser sees a packet header with a partial +length, it pushes the block_filter onto the IOBUF to handle these partial +length packets: from now on you don't have to worry about this. When it sees +a compressed packet it pushes the uncompress filter and the next read byte +is one which has already been uncompressed by this filter. Same goes for +enciphered packet, plaintext packets and so on. The file g10/encode.c +might be a good staring point to see how it is used - actually this is +the other way: constructing messages using pushed filters but it may be +easier to understand. + + diff --git a/doc/KEYSERVER b/doc/KEYSERVER new file mode 100644 index 0000000..f63200a --- /dev/null +++ b/doc/KEYSERVER @@ -0,0 +1,83 @@ +Format of keyserver colon listings +================================== + +David Shaw + +The machine readable response begins with an optional information +line: + +info:: + + = this is the version of this protocol. Currently, this is + the number 1. + + = the number of keys returned in this response. Note this is + the number of keys, and not the number of lines returned. + It should match the number of "pub:" lines returned. + +If this optional line is not included, or the version information is +not supplied, the version number is assumed to be 1. + +The key listings are made up of several lines per key. The first line +is for the primary key: + +pub:::::: + + = this is either the fingerprint or the keyid of the + key. Either the 16-digit or 8-digit keyids are + acceptable, but obviously the fingerprint is best. + Since it is not possible to calculate the keyid from a + V3 key fingerprint, for V3 keys this should be either + the 16-digit or 8-digit keyid only. + + = the algorithm number from RFC-2440. (i.e. 1==RSA, 17==DSA, + etc). + + = the key length (i.e. 1024, 2048, 4096, etc.) + + = creation date of the key in standard RFC-2440 form + (i.e. number of seconds since 1/1/1970 UTC time) + + = expiration date of the key in standard RFC-2440 + form (i.e. number of seconds since 1/1/1970 UTC time) + + = letter codes to indicate details of the key, if any. Flags + may be in any order. + + r == revoked + d == disabled + e == expired + +Following the "pub" line are one or more "uid" lines to indicate user +IDs on the key: + +uid:::: + + == the user ID string, with HTTP %-escaping for + anything that isn't 7-bit safe as well as for + the ":" character. Any other characters may + be escaped, as desired. + +creationdate, expirationdate, and flags mean the same here as before. +The information is taken from the self-sig, if any, and applies to the +user ID in question, and not to the key as a whole. + +Details: + +* All characters except for the are + case-insensitive. + +* Obviously, on a keyserver without integrated crypto, many of the + items given here are not fully trustworthy until the key is + downloaded and signatures checked. For example, the information + that a key is flagged "r" for revoked should be treated as + untrustworthy information until the key is checked on the client + side. + +* Empty fields are allowed. For example, a key with no expiration + date would have the field empty. Also, a keyserver + that does not track a particular piece of information may leave that + field empty as well. I expect that the creation and expiration + dates for user IDs will be left empty in current keyservers. Colons + for empty fields on the end of each line may be left off, if + desired. diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..c8d799b --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,150 @@ +# 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 3 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, see . + +## Process this file with automake to produce Makefile.in + +examples = examples/README examples/scd-event examples/trustlist.txt \ + examples/gpgconf.conf examples/pwpattern.list + +helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt \ + help.da.txt help.de.txt help.el.txt help.eo.txt \ + help.es.txt help.et.txt help.fi.txt help.fr.txt \ + help.gl.txt help.hu.txt help.id.txt help.it.txt \ + help.ja.txt help.nb.txt help.pl.txt help.pt.txt \ + help.pt_BR.txt help.ro.txt help.ru.txt help.sk.txt \ + help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt + +EXTRA_DIST = samplekeys.asc ChangeLog-2011 \ + gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png \ + gnupg-card-architecture.eps gnupg-card-architecture.png \ + gnupg-card-architecture.pdf \ + FAQ gnupg7.texi \ + opt-homedir.texi see-also-note.texi specify-user-id.texi \ + gpgv.texi texi.css yat2m.c + +BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \ + gnupg-card-architecture.pdf + +info_TEXINFOS = gnupg.texi + +dist_pkgdata_DATA = qualified.txt com-certs.pem $(helpfiles) + +nobase_dist_doc_DATA = FAQ DETAILS HACKING TRANSLATE OpenPGP KEYSERVER \ + $(examples) + + +gnupg_TEXINFOS = \ + gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \ + tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ + sysnotes.texi gnupg-card-architecture.fig \ + howtos.texi howto-create-a-server-cert.texi + +DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips + +AM_MAKEINFOFLAGS = -I $(srcdir) --css-include=$(srcdir)/texi.css + +YAT2M_OPTIONS = -I $(srcdir) \ + --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard" + +myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \ + scdaemon.texi tools.texi +myman_pages = gpg2.1 gpgsm.1 gpg-agent.1 scdaemon.1 gpgv2.1 \ + watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \ + gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \ + gpgsm-gencert.sh.1 applygnupgdefaults.8 gpg-zip.1 + +man_MANS = $(myman_pages) +noinst_MANS = gnupg.7 + +watchgnupg_SOURCE = gnupg.texi + + +CLEANFILES = yat2m faq.txt + +DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \ + $(myman_pages) gnupg.7 + +yat2m: yat2m.c + $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c + +.fig.png: + fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.jpg: + fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.eps: + fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.pdf: + fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@ + +# Note that yatm --store has a bug in that the @ifset gpgtwoone still +# creates a dirmngr-client page from tools.texi. +yat2m-stamp: $(myman_sources) + @rm -f yat2m-stamp.tmp + @touch yat2m-stamp.tmp + for file in $(myman_sources) ; do \ + ./yat2m $(YAT2M_OPTIONS) --store \ + `test -f '$$file' || echo '$(srcdir)/'`$$file ; done + @test -f dirmngr-client.1 && rm dirmngr-client.1 + @mv -f yat2m-stamp.tmp $@ + +yat2m-stamp: yat2m + +$(myman_pages) gnupg.7 : yat2m-stamp + @if test -f $@; then :; else \ + trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \ + if mkdir yat2m-lock 2>/dev/null; then \ + rm -f yat2m-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \ + rmdir yat2m-lock; \ + else \ + while test -d yat2m-lock; do sleep 1; done; \ + test -f yat2m-stamp; exit $$?; \ + fi; \ + fi + +# Make sure that gnupg.texi is touched if any other source file has +# been modified. This is required so that the version.texi magic +# updates the release date. +gnupg.texi : $(gnupg_TEXINFOS) + touch $(srcdir)/gnupg.texi + +# Copy shared files from the master branch. We keep the texinfo files +# all in master so that we need to modify only one source. Macros are +# used to customize them for a specific version. +update-source: + @set -e; cd $(srcdir); \ + for i in $(gnupg_TEXINFOS) yat2m.c ; do \ + echo "updating from master:doc/$$i" >&2 ; \ + git show master:doc/$$i >$$i ; \ + done + +online: gnupg.html gnupg.pdf + set -e; \ + echo "Uploading current manuals to www.gnupg.org ..."; \ + cp $(srcdir)/gnupg-logo.png gnupg.html/; \ + user=werner ; dashdevel="" ; \ + if echo "@PACKAGE_VERSION@" | grep -- "-git" >/dev/null; then \ + dashdevel="-devel" ; \ + else \ + rsync -v gnupg.pdf $${user}@cvs.gnupg.org:webspace/manuals/ ; \ + fi ; \ + cd gnupg.html ; \ + rsync -vr --exclude='.svn' . \ + $${user}@cvs.gnupg.org:webspace/manuals/gnupg$${dashdevel}/ diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..cb96a30 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,1029 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# 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. + +@SET_MAKE@ + +# 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 3 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, see . + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = doc +DIST_COMMON = $(dist_pkgdata_DATA) $(gnupg_TEXINFOS) \ + $(nobase_dist_doc_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/stamp-vti \ + $(srcdir)/version.texi +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/gl/m4/absolute-header.m4 \ + $(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/allocsa.m4 \ + $(top_srcdir)/gl/m4/eealloc.m4 \ + $(top_srcdir)/gl/m4/gnulib-comp.m4 \ + $(top_srcdir)/gl/m4/gnulib-tool.m4 \ + $(top_srcdir)/gl/m4/mkdtemp.m4 $(top_srcdir)/gl/m4/setenv.m4 \ + $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/strpbrk.m4 \ + $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/estream.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gnupg-pth.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/readline.m4 $(top_srcdir)/m4/size_max.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/m4/xsize.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +INFO_DEPS = $(srcdir)/gnupg.info +TEXINFO_TEX = $(top_srcdir)/scripts/texinfo.tex +am__TEXINFO_TEX_DIR = $(top_srcdir)/scripts +DVIS = gnupg.dvi +PDFS = gnupg.pdf +PSS = gnupg.ps +HTMLS = gnupg.html +TEXINFOS = gnupg.texi +TEXI2DVI = texi2dvi +TEXI2PDF = $(TEXI2DVI) --pdf --batch +MAKEINFOHTML = $(MAKEINFO) --html +AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) +am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgdatadir)" \ + "$(DESTDIR)$(docdir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +man1dir = $(mandir)/man1 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(dist_pkgdata_DATA) $(nobase_dist_doc_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@ +ACLOCAL = @ACLOCAL@ +ADNSLIBS = @ADNSLIBS@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAQPROG = @FAQPROG@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_CURL = @GPGKEYS_CURL@ +GPGKEYS_FINGER = @GPGKEYS_FINGER@ +GPGKEYS_HKP = @GPGKEYS_HKP@ +GPGKEYS_KDNS = @GPGKEYS_KDNS@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGKEYS_MAILTO = @GPGKEYS_MAILTO@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GREP = @GREP@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +HAVE_STDINT_H = @HAVE_STDINT_H@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +PTH_CFLAGS = @PTH_CFLAGS@ +PTH_CONFIG = @PTH_CONFIG@ +PTH_LIBS = @PTH_LIBS@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +UNISTD_H = @UNISTD_H@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WINDRES = @WINDRES@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +ZLIBS = @ZLIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +examples = examples/README examples/scd-event examples/trustlist.txt \ + examples/gpgconf.conf examples/pwpattern.list + +helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt \ + help.da.txt help.de.txt help.el.txt help.eo.txt \ + help.es.txt help.et.txt help.fi.txt help.fr.txt \ + help.gl.txt help.hu.txt help.id.txt help.it.txt \ + help.ja.txt help.nb.txt help.pl.txt help.pt.txt \ + help.pt_BR.txt help.ro.txt help.ru.txt help.sk.txt \ + help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt + +EXTRA_DIST = samplekeys.asc ChangeLog-2011 \ + gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png \ + gnupg-card-architecture.eps gnupg-card-architecture.png \ + gnupg-card-architecture.pdf \ + FAQ gnupg7.texi \ + opt-homedir.texi see-also-note.texi specify-user-id.texi \ + gpgv.texi texi.css yat2m.c + +BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \ + gnupg-card-architecture.pdf + +info_TEXINFOS = gnupg.texi +dist_pkgdata_DATA = qualified.txt com-certs.pem $(helpfiles) +nobase_dist_doc_DATA = FAQ DETAILS HACKING TRANSLATE OpenPGP KEYSERVER \ + $(examples) + +gnupg_TEXINFOS = \ + gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \ + tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ + sysnotes.texi gnupg-card-architecture.fig \ + howtos.texi howto-create-a-server-cert.texi + +DVIPS = TEXINPUTS="$(srcdir)$(PATH_SEPARATOR)$$TEXINPUTS" dvips +AM_MAKEINFOFLAGS = -I $(srcdir) --css-include=$(srcdir)/texi.css +YAT2M_OPTIONS = -I $(srcdir) \ + --release "GnuPG @PACKAGE_VERSION@" --source "GNU Privacy Guard" + +myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \ + scdaemon.texi tools.texi + +myman_pages = gpg2.1 gpgsm.1 gpg-agent.1 scdaemon.1 gpgv2.1 \ + watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \ + gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 \ + gpgsm-gencert.sh.1 applygnupgdefaults.8 gpg-zip.1 + +man_MANS = $(myman_pages) +noinst_MANS = gnupg.7 +watchgnupg_SOURCE = gnupg.texi +CLEANFILES = yat2m faq.txt +DISTCLEANFILES = gnupg.tmp gnupg.ops yat2m-stamp.tmp yat2m-stamp \ + $(myman_pages) gnupg.7 + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .dvi .eps .fig .html .info .jpg .pdf .png .ps .texi +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +.texi.info: + restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + am__cwd=`pwd` && $(am__cd) $(srcdir) && \ + rm -rf $$backupdir && mkdir $$backupdir && \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ + cd "$$am__cwd"; \ + if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ $<; \ + then \ + rc=0; \ + $(am__cd) $(srcdir); \ + else \ + rc=$$?; \ + $(am__cd) $(srcdir) && \ + $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ + fi; \ + rm -rf $$backupdir; exit $$rc + +.texi.dvi: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) $< + +.texi.pdf: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) $< + +.texi.html: + rm -rf $(@:.html=.htp) + if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) $<; \ + then \ + rm -rf $@; \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ + else \ + if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ + rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ + exit 1; \ + fi +$(srcdir)/gnupg.info: gnupg.texi $(srcdir)/version.texi $(gnupg_TEXINFOS) +gnupg.dvi: gnupg.texi $(srcdir)/version.texi $(gnupg_TEXINFOS) +gnupg.pdf: gnupg.texi $(srcdir)/version.texi $(gnupg_TEXINFOS) +gnupg.html: gnupg.texi $(srcdir)/version.texi $(gnupg_TEXINFOS) +$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti +$(srcdir)/stamp-vti: gnupg.texi $(top_srcdir)/configure + @(dir=.; test -f ./gnupg.texi || dir=$(srcdir); \ + set `$(SHELL) $(top_srcdir)/scripts/mdate-sh $$dir/gnupg.texi`; \ + echo "@set UPDATED $$1 $$2 $$3"; \ + echo "@set UPDATED-MONTH $$2 $$3"; \ + echo "@set EDITION $(VERSION)"; \ + echo "@set VERSION $(VERSION)") > vti.tmp + @cmp -s vti.tmp $(srcdir)/version.texi \ + || (echo "Updating $(srcdir)/version.texi"; \ + cp vti.tmp $(srcdir)/version.texi) + -@rm -f vti.tmp + @cp $(srcdir)/version.texi $@ + +mostlyclean-vti: + -rm -f vti.tmp + +maintainer-clean-vti: +@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi +.dvi.ps: + TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) -o $@ $< + +uninstall-dvi-am: + @$(NORMAL_UNINSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ + rm -f "$(DESTDIR)$(dvidir)/$$f"; \ + done + +uninstall-html-am: + @$(NORMAL_UNINSTALL) + @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ + rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ + done + +uninstall-info-am: + @$(PRE_UNINSTALL) + @if test -d '$(DESTDIR)$(infodir)' && \ + (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ + if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ + then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ + echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +uninstall-pdf-am: + @$(NORMAL_UNINSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ + done + +uninstall-ps-am: + @$(NORMAL_UNINSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ + rm -f "$(DESTDIR)$(psdir)/$$f"; \ + done + +dist-info: $(INFO_DEPS) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + case $$base in \ + $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ + for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ + if test -f $$file; then \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f "$(distdir)/$$relfile" || \ + cp -p $$file "$(distdir)/$$relfile"; \ + else :; fi; \ + done; \ + done + +mostlyclean-aminfo: + -rm -rf gnupg.aux gnupg.cp gnupg.cps gnupg.fn gnupg.ky gnupg.log gnupg.op \ + gnupg.ops gnupg.pg gnupg.tmp gnupg.toc gnupg.tp gnupg.vr + +clean-aminfo: + -test -z "gnupg.dvi gnupg.pdf gnupg.ps gnupg.html" \ + || rm -rf gnupg.dvi gnupg.pdf gnupg.ps gnupg.html + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list=''; test -n "$(man1dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +install-dist_pkgdataDATA: $(dist_pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-dist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgdatadir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgdatadir)" && rm -f $$files +install-nobase_dist_docDATA: $(nobase_dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(docdir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(docdir)/$$dir"; }; \ + echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(docdir)/$$dir'"; \ + $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(docdir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(nobase_dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(docdir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(INFO_DEPS) $(MANS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-aminfo clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: $(DVIS) + +html: html-am + +html-am: $(HTMLS) + +info: info-am + +info-am: $(INFO_DEPS) + +install-data-am: install-dist_pkgdataDATA install-info-am install-man \ + install-nobase_dist_docDATA + +install-dvi: install-dvi-am + +install-dvi-am: $(DVIS) + @$(NORMAL_INSTALL) + test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done +install-exec-am: + +install-html: install-html-am + +install-html-am: $(HTMLS) + @$(NORMAL_INSTALL) + test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" + @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__strip_dir) \ + if test -d "$$d$$p"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + else \ + list2="$$list2 $$d$$p"; \ + fi; \ + done; \ + test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } +install-info: install-info-am + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + echo "$$ifile"; \ + else : ; fi; \ + done; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done + @$(POST_INSTALL) + @if (install-info --version && \ + install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ + install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ + done; \ + else : ; fi +install-man: install-man1 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: $(PDFS) + @$(NORMAL_INSTALL) + test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done +install-ps: install-ps-am + +install-ps-am: $(PSS) + @$(NORMAL_INSTALL) + test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-vti + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic mostlyclean-vti + +pdf: pdf-am + +pdf-am: $(PDFS) + +ps: ps-am + +ps-am: $(PSS) + +uninstall-am: uninstall-dist_pkgdataDATA uninstall-dvi-am \ + uninstall-html-am uninstall-info-am uninstall-man \ + uninstall-nobase_dist_docDATA uninstall-pdf-am uninstall-ps-am + +uninstall-man: uninstall-man1 uninstall-man8 + +.MAKE: all check install install-am install-strip + +.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ + dist-info distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dist_pkgdataDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man1 install-man8 install-nobase_dist_docDATA \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-aminfo \ + maintainer-clean-generic maintainer-clean-vti mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-vti pdf \ + pdf-am ps ps-am uninstall uninstall-am \ + uninstall-dist_pkgdataDATA uninstall-dvi-am uninstall-html-am \ + uninstall-info-am uninstall-man uninstall-man1 uninstall-man8 \ + uninstall-nobase_dist_docDATA uninstall-pdf-am uninstall-ps-am + + +yat2m: yat2m.c + $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c + +.fig.png: + fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.jpg: + fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.eps: + fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@ + +.fig.pdf: + fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@ + +# Note that yatm --store has a bug in that the @ifset gpgtwoone still +# creates a dirmngr-client page from tools.texi. +yat2m-stamp: $(myman_sources) + @rm -f yat2m-stamp.tmp + @touch yat2m-stamp.tmp + for file in $(myman_sources) ; do \ + ./yat2m $(YAT2M_OPTIONS) --store \ + `test -f '$$file' || echo '$(srcdir)/'`$$file ; done + @test -f dirmngr-client.1 && rm dirmngr-client.1 + @mv -f yat2m-stamp.tmp $@ + +yat2m-stamp: yat2m + +$(myman_pages) gnupg.7 : yat2m-stamp + @if test -f $@; then :; else \ + trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \ + if mkdir yat2m-lock 2>/dev/null; then \ + rm -f yat2m-stamp; \ + $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \ + rmdir yat2m-lock; \ + else \ + while test -d yat2m-lock; do sleep 1; done; \ + test -f yat2m-stamp; exit $$?; \ + fi; \ + fi + +# Make sure that gnupg.texi is touched if any other source file has +# been modified. This is required so that the version.texi magic +# updates the release date. +gnupg.texi : $(gnupg_TEXINFOS) + touch $(srcdir)/gnupg.texi + +# Copy shared files from the master branch. We keep the texinfo files +# all in master so that we need to modify only one source. Macros are +# used to customize them for a specific version. +update-source: + @set -e; cd $(srcdir); \ + for i in $(gnupg_TEXINFOS) yat2m.c ; do \ + echo "updating from master:doc/$$i" >&2 ; \ + git show master:doc/$$i >$$i ; \ + done + +online: gnupg.html gnupg.pdf + set -e; \ + echo "Uploading current manuals to www.gnupg.org ..."; \ + cp $(srcdir)/gnupg-logo.png gnupg.html/; \ + user=werner ; dashdevel="" ; \ + if echo "@PACKAGE_VERSION@" | grep -- "-git" >/dev/null; then \ + dashdevel="-devel" ; \ + else \ + rsync -v gnupg.pdf $${user}@cvs.gnupg.org:webspace/manuals/ ; \ + fi ; \ + cd gnupg.html ; \ + rsync -vr --exclude='.svn' . \ + $${user}@cvs.gnupg.org:webspace/manuals/gnupg$${dashdevel}/ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/doc/OpenPGP b/doc/OpenPGP new file mode 100644 index 0000000..a511ad7 --- /dev/null +++ b/doc/OpenPGP @@ -0,0 +1,108 @@ + GnuPG and OpenPGP + ================= + + See RFC2440 for a description of OpenPGP. We have an annotated version + of this RFC online: http://www.gnupg.org/rfc2440.html + + + + Compatibility Notes + =================== + GnuPG (>=1.0.3) is in compliance with RFC2440 despite these exceptions: + + * (9.2) states that IDEA SHOULD be implemented. This is not done + due to patent problems. + + + All MAY features are implemented with this exception: + + * multi-part armored messages are not supported. + MIME (rfc2015) should be used instead. + + Most of the OPTIONAL stuff is implemented. + + There are a couple of options which can be used to override some + RFC requirements. This is always mentioned with the description + of that options. + + A special format of partial packet length exists for v3 packets + which can be considered to be in compliance with RFC1991; this + format is only created if a special option is active. + + GnuPG uses a S2K mode of 101 for GNU extensions to the secret key + protection algorithms. This number is not defined in OpenPGP, but + given the fact that this number is in a range which used at many + other places in OpenPGP for private/experimenat algorithm identifiers, + this should be not a so bad choice. The 3 bytes "GNU" are used + to identify this as a GNU extension - see the file DETAILS for a + definition of the used data formats. + + + + Some Notes on OpenPGP / PGP Compatibility: + ========================================== + + * PGP 5.x does not accept V4 signatures for anything other than + key material. The GnuPG option --force-v3-sigs mimics this + behavior. + + * PGP 5.x does not recognize the "five-octet" lengths in + new-format headers or in signature subpacket lengths. + + * PGP 5.0 rejects an encrypted session key if the keylength + differs from the S2K symmetric algorithm. This is a bug in its + validation function. + + * PGP 5.0 does not handle multiple one-pass signature headers and + trailers. Signing one will compress the one-pass signed literal + and prefix a V3 signature instead of doing a nested one-pass + signature. + + * When exporting a private key, PGP 2.x generates the header + "BEGIN PGP SECRET KEY BLOCK" instead of "BEGIN PGP PRIVATE KEY + BLOCK". All previous versions ignore the implied data type, and + look directly at the packet data type. + + * In a clear-signed signature, PGP 5.0 will figure out the correct + hash algorithm if there is no "Hash:" header, but it will reject + a mismatch between the header and the actual algorithm used. The + "standard" (i.e. Zimmermann/Finney/et al.) version of PGP 2.x + rejects the "Hash:" header and assumes MD5. There are a number + of enhanced variants of PGP 2.6.x that have been modified for + SHA-1 signatures. + + * PGP 5.0 can read an RSA key in V4 format, but can only recognize + it with a V3 keyid, and can properly use only a V3 format RSA + key. + + * Neither PGP 5.x nor PGP 6.0 recognize ElGamal Encrypt and Sign + keys. They only handle ElGamal Encrypt-only keys. + + + Parts of this document are taken from: + ====================================== + + OpenPGP Message Format + draft-ietf-openpgp-formats-07.txt + + + Copyright 1998 by The Internet Society. All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph + are included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + diff --git a/doc/TRANSLATE b/doc/TRANSLATE new file mode 100644 index 0000000..8dfc183 --- /dev/null +++ b/doc/TRANSLATE @@ -0,0 +1,62 @@ +$Id$ + +Note for translators +-------------------- + +Some strings in GnuPG are for matching user input against. These +strings can accept multiple values that mean essentially the same +thing. + +For example, the string "yes" in English is "sí" in Spanish. However, +some users will type "si" (without the accent). To accomodate both +users, you can translate the string "yes" as "sí|si". You can have +any number of alternate matches seperated by the | character like +"sí|si|seguro". + +The strings that can be handled in this way are of the form "yes|yes", +(or "no|no", etc.) There should also be a comment in the .po file +directing you to this file. + + +Help files +---------- + +GnuPG provides a little help feature (entering a ? on a prompt). This +help used to be translated the usual way with gettext but it turned +out that this is too inflexible and does for example not allow to +correct little mistakes in the English text. For some newer features +we require editable help files anyway and thus the existing help +strings have neen moved to plain text files names "help.LL.txt". We +distribute these files and allow overriding them by files of that name +in /etc/gnupg. The syntax of these files is documented in +doc/help.txt. This is also the original we use to describe new +possible online help keys. The source files are located in doc/ and +need to be in encoded in UTF-8. Strings which require a translation +are disabled like this + + .#gpgsm.some.help-item + This string is not translated. + +After translation you should remove the the hash mark so that the +entry looks like. + + .gpgsm.some.help-item + This string has been translated. + +The percent sign is not a special character and if there is something +to watch out there will be a remark. + + + +Sending new or updated translations +----------------------------------- + +Please note that we do not use the TP Robot but require that +translations are to be send by mail to translations@gnupg.org. We +also strongly advise to get subscribed to i18n@gnupg.org and request +assistance if it is not clear on how to translate certain strings. A +wrongly translated string may lead to a security problem. + +A copyright disclaimer to the FSF is required by all translators. + + diff --git a/doc/com-certs.pem b/doc/com-certs.pem new file mode 100644 index 0000000..43e93b7 --- /dev/null +++ b/doc/com-certs.pem @@ -0,0 +1,484 @@ +# Common certificates for initial keybox creation. + +Issuer ...: /CN=CA Cert Signing Authority/OU=http:\x2f\x2fwww.cacert.org/O=Root CA/EMail=support@cacert.org +Serial ...: 00 +Subject ..: /CN=CA Cert Signing Authority/OU=http:\x2f\x2fwww.cacert.org/O=Root CA/EMail=support@cacert.org + +-----BEGIN CERTIFICATE----- +MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 +IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB +IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA +Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO +BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi +MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ +ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ +8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 +zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y +fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 +w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc +G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k +epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q +laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ +QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU +fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 +YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w +ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY +gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe +MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 +IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy +dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw +czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 +dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl +aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC +AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg +b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB +ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc +nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg +18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c +gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl +Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY +sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T +SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF +CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum +GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk +zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW +omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD +-----END CERTIFICATE----- + +Issuer ...: /CN=6R-Ca 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE +Serial ...: 32D18D +Subject ..: /CN=6R-Ca 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE + +-----BEGIN CERTIFICATE----- +MIICaDCCAdSgAwIBAgIDMtGNMAoGBiskAwMBAgUAMG8xCzAJBgNVBAYTAkRFMT0w +OwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21tdW5pa2F0 +aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjZSLUNhIDE6UE4w +IhgPMjAwMTAyMDEwOTUyMTdaGA8yMDA1MDYwMTA5NTIxN1owbzELMAkGA1UEBhMC +REUxPTA7BgNVBAoUNFJlZ3VsaWVydW5nc2JlaMhvcmRlIGbIdXIgVGVsZWtvbW11 +bmlrYXRpb24gdW5kIFBvc3QxITAMBgcCggYBCgcUEwExMBEGA1UEAxQKNlItQ2Eg +MTpQTjCBoTANBgkqhkiG9w0BAQEFAAOBjwAwgYsCgYEAg6KrFSTNXKqe+2GKGeW2 +wTmbVeflNkp5H/YxA9K1zmEn5XjKm0S0jH4Wfms6ipPlURVaFwTfnB1s++AnJAWf +mayaE9BP/pdIY6WtZGgW6aZc32VDMCMKPWyBNyagsJVDmzlakIA5cXBVa7Xqqd3P +ew8i2feMnQXcqHfDv02CW88CBQDAAAABoxIwEDAOBgNVHQ8BAf8EBAMCAQYwCgYG +KyQDAwECBQADgYEAOkqkUwdaTCt8wcJLA2zLuOwL5ADHMWLhv6gr5zEF+VckA6qe +IVLVf8e7fYlRmzQd+5OJcGglCQJLGT+ZplI3Mjnrd4plkoTNKV4iOzBcvJD7K4tn +XPvs9wCFcC7QU7PLvc1FDsAlr7e4wyefZRDL+wbqNfI7QZTSF1ubLd9AzeQ= +-----END CERTIFICATE----- + +Issuer ...: /CN=10R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 2A +Subject ..: /CN=10R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIDoTCCAw2gAwIBAgIBKjAKBgYrJAMDAQIFADA/MQswCQYDVQQGEwJERTEaMBgG +A1UECgwRQnVuZGVzbmV0emFnZW50dXIxFDASBgNVBAMMCzEwUi1DQSAxOlBOMB4X +DTA1MDgwMzE1MzAzNloXDTA3MTIzMTE1MDkyM1owPzELMAkGA1UEBhMCREUxGjAY +BgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMFItQ0EgMTpQTjCB +oDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAiHXC5/hw6rYNc/4cilHLjd/SqwS3 +4LaogQHZVFciyYJ0+5gAfca/kLnPEvOUuYSYNfb2ar0e/iDPxZAAEfqfVGuRT9Pa +R7hWvPiZUFpoGcNvyOVxKuM9Iyx/i1wan/wS6u12QIgGBUek5ig1+TTwuuNcanlW +kQPuodHs+BoUGHMCBEAAAIGjggGwMIIBrDAOBgNVHQ8BAf8EBAMCAgQwGAYIKwYB +BQUHAQMEDDAKMAgGBgQAjkYBATBKBggrBgEFBQcBAQQ+MDwwOgYIKwYBBQUHMAGG +Lmh0dHA6Ly9vY3NwLm5yY2EtZHMuZGU6ODA4MC9vY3NwLW9jc3ByZXNwb25kZXIw +EgYDVR0gBAswCTAHBgUrJAgBATCBsQYDVR0fBIGpMIGmMIGjoIGgoIGdhoGabGRh +cDovL2xkYXAubnJjYS1kcy5kZTozODkvQ049Q1JMLE89QnVuZGVzbmV0emFnZW50 +dXIsQz1ERSxkYz1sZGFwLGRjPW5yY2EtZHMsZGM9ZGU/Y2VydGlmaWNhdGVSZXZv +Y2F0aW9uTGlzdDtiaW5hcnk/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRp +b25Qb2ludDAbBgkrBgEEAcBtAwUEDjAMBgorBgEEAcBtAwUBMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUw8916sARU0UT/pdlYwBpUwKWuWQwHQYDVR0OBBYE +FMPPderAEVNFE/6XZWMAaVMClrlkMAoGBiskAwMBAgUAA4GBAGXK8m/O9KmfaZuA +1GzMyasIHx8Lu+V0da8NTZzAmqAl+44MtS4QNcZdtxsDvOcqHHs1Tosh9D398hSG +hXd6gjniKWxMKvjL8TQKu999QIn6YKLCowjUYpp8v4B9X8jNa9vJy2EzoPOBmdWT +l5hhXfvWpPe68kN9zaEmcDO+m60H +-----END CERTIFICATE----- + +Issuer ...: /CN=9R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE +Serial ...: 02 +Subject ..: /CN=9R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE + +-----BEGIN CERTIFICATE----- +MIIEEjCCA36gAwIBAgIBAjAKBgYrJAMDAQIFADBhMQswCQYDVQQGEwJERTE9MDsG +A1UECgw0UmVndWxpZXJ1bmdzYmVow7ZyZGUgZsO8ciBUZWxla29tbXVuaWthdGlv +biB1bmQgUG9zdDETMBEGA1UEAwwKOVItQ0EgMTpQTjAeFw0wNDExMjUxNDU5MTFa +Fw0wNzEyMzExNDU2NTlaMGExCzAJBgNVBAYTAkRFMT0wOwYDVQQKDDRSZWd1bGll +cnVuZ3NiZWjDtnJkZSBmw7xyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MRMw +EQYDVQQDDAo5Ui1DQSAxOlBOMIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBgQCN +0ECEO2KjPsHBz2cmOSePEmKEH33Q/vRUl1u8D2Uus3txZgqRvCs0F7HzAtDJKSap +C1+qj5t1R4g8jrlWwsqi+oOc3bpUuPMLo+ys9PG7ODK+xZuwFlezO6rj30mEj+y0 +HMxCaTAedim2J5CmWcqQtATGGzwqYHEVFYo0y5kuuQIEQAAAgaOCAd0wggHZMA4G +A1UdDwEB/wQEAwICBDAYBggrBgEFBQcBAwQMMAowCAYGBACORgEBMEoGCCsGAQUF +BwEBBD4wPDA6BggrBgEFBQcwAYYuaHR0cDovL29jc3AubnJjYS1kcy5kZTo4MDgw +L29jc3Atb2NzcHJlc3BvbmRlcjASBgNVHSAECzAJMAcGBSskCAEBMIHeBgNVHR8E +gdYwgdMwgdCggc2ggcqGgcdsZGFwOi8vbGRhcC5ucmNhLWRzLmRlOjM4OS9DTj1D +UkwsTz1SZWd1bGllcnVuZ3NiZWglRjZyZGUlMjBmJUZDciUyMFRlbGVrb21tdW5p +a2F0aW9uJTIwdW5kJTIwUG9zdCxDPURFLGRjPWxkYXAsZGM9bnJjYS1kcyxkYz1k +ZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeT9iYXNlP29iamVjdENs +YXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MBsGCSsGAQQBwG0DBQQOMAwGCisGAQQB +wG0DBQEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRnBgT5ZxC7e1vJLBj+ +92+P1kZrJzAdBgNVHQ4EFgQUZwYE+WcQu3tbySwY/vdvj9ZGaycwCgYGKyQDAwEC +BQADgYEACAnkgbAd47VgJqu5CY3B6AlxbGkor2guYHXO+KgBkQeXDVWt4ZvN9hY2 +blhPMc/sLv+Tmg9zjyzjqQdxhWXUDoctorBny8LQQQvMqAtc8qk6DL+X0heq1U2k +s1e8wj9AUGOfvmSL/r1BWPzLOCWay2bHQCQ1sU5QnvNbmJO21GI= +-----END CERTIFICATE----- + +Issuer ...: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 2D +Subject ..: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIDoTCCAw2gAwIBAgIBLTAKBgYrJAMDAQIFADA/MQswCQYDVQQGEwJERTEaMBgG +A1UECgwRQnVuZGVzbmV0emFnZW50dXIxFDASBgNVBAMMCzExUi1DQSAxOlBOMB4X +DTA1MDgwMzE4MDk0OVoXDTA3MTIzMTE4MDQyOFowPzELMAkGA1UEBhMCREUxGjAY +BgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMVItQ0EgMTpQTjCB +oDANBgkqhkiG9w0BAQEFAAOBjgAwgYoCgYEAkodoSFtoGjJphYloxQLsmyOe/M5h +UpURxSkop41MtGlrHeOeQsxMSRdCJInwjLKZg9Pxd92QFsB3f6AJUGTO7z6PJ/ST ++m0EBksoPtciWLYtlRXtD/RK6mUB7CG5CfqK6AUHbWtXW6mNAZLoJOd0jLsQCUi8 +XmHP92vfmW2ptSkCBEAAAIGjggGwMIIBrDAOBgNVHQ8BAf8EBAMCAgQwGAYIKwYB +BQUHAQMEDDAKMAgGBgQAjkYBATBKBggrBgEFBQcBAQQ+MDwwOgYIKwYBBQUHMAGG +Lmh0dHA6Ly9vY3NwLm5yY2EtZHMuZGU6ODA4MC9vY3NwLW9jc3ByZXNwb25kZXIw +EgYDVR0gBAswCTAHBgUrJAgBATCBsQYDVR0fBIGpMIGmMIGjoIGgoIGdhoGabGRh +cDovL2xkYXAubnJjYS1kcy5kZTozODkvQ049Q1JMLE89QnVuZGVzbmV0emFnZW50 +dXIsQz1ERSxkYz1sZGFwLGRjPW5yY2EtZHMsZGM9ZGU/Y2VydGlmaWNhdGVSZXZv +Y2F0aW9uTGlzdDtiaW5hcnk/YmFzZT9vYmplY3RDbGFzcz1jUkxEaXN0cmlidXRp +b25Qb2ludDAbBgkrBgEEAcBtAwUEDjAMBgorBgEEAcBtAwUBMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUXYAPovSdSBb8oBS7lEJmWSK6incwHQYDVR0OBBYE +FF2AD6L0nUgW/KAUu5RCZlkiuop3MAoGBiskAwMBAgUAA4GBAIxx56h5+p2lqK0v +hRVwkWAAPduspH4U9q7QsFIWbEkFe+2TcXx7MV9NAUe4kN9MsN9CEgSSeLDfpIFA +uyHndqgmDaqXmWSDl2QutHQwSj8a04bSNbY7s0FUCMqrr/465Rf6quIWi7qXhwDe +yDmXv3nzPTGVM3F+aavJCybjJ1qk +-----END CERTIFICATE----- + +Issuer ...: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 0139 +Subject ..: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIErTCCA5WgAwIBAgICATkwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx +GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMlItQ0EgMTpQ +TjAeFw0wNzA1MjUxMTAxNDRaFw0xMjA1MjUxMDU2MDdaMD8xCzAJBgNVBAYTAkRF +MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTJSLUNBIDE6 +UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCYOqYxUqr6ZdlIuVaz +1raETmld82tCCFjUnIlHGpaTbBGQ9ddW4pdkdNmK4dHDesAnGFB6tgZzFTYivjTY +Jyzv3NunMth8AjwCivQ0u2RBlunY2jg6dNSeTwGlmOlG709HgWPHvvAboqLDoV81 +knMbNbG4P7Ff/+lsTnbN/gT0X5fHUz5UO3eowyl2kD6GBZwb+noR/86U0V39yXsk +ZD/NNBXKOzKo9VXx09S1Uq027Cc+VIa62DWUeUGiUDjCXXJoaAF2wQcD/crrAJlU +zeOVZkSzRJXpjpG8kZhKgSgOpgfnpjDXAXWbkJuyDL2fqXLPxAyBq3ThgUHZT99s +QSd3AgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww +CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v +b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL +MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw +Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs +ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp +c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw +GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G +A1UdIwQYMBaAFATenX/fQ3KJumlJAfToSSjeAhlvMB0GA1UdDgQWBBQE3p1/30Ny +ibppSQH06Eko3gIZbzANBgkqhkiG9w0BAQ0FAAOCAQEADf4IOMHGmSpkPc1UP0LS +sK8Y/xXvOgdHPx4f2CpcgUKRRk+Ue9MKiZG0KCFaNK9Qpnxejuk42Iu3flC5kn8T +fPQWtxC3ZQqD8sd6EX/FDdfkHJFJ9rIYKiSG6m2PDBUcbpQZ9kwhC7qCKE1coUhb +FW3WbntkDtrQycz7ZyQ6Ip+PpRoxwToJqTsExb+8whukhOo1vsgdaMZS/6iwwVkt +rJvl7EWMJVWctm15iDQzp4sawgSOg7U5icyTb1q+FqI5KlAfd/dRbv2yvThiOl7+ +bfN9Brosoxtwi/uJO8vSGOCIUUkiGhIk7+OX+mvppTG+7R1Jn6Af6AOzGSbQz5Ks +Uw== +-----END CERTIFICATE----- + +Issuer ...: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 013C +Subject ..: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIErTCCA5WgAwIBAgICATwwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx +GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxM1ItQ0EgMTpQ +TjAeFw0wNzA1MjkxMTAyMzdaFw0xMjA1MjkxMDU1NTRaMD8xCzAJBgNVBAYTAkRF +MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTNSLUNBIDE6 +UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCaXK0TY+Vp+Hxx8B9D +lrHkc0zRdhXNuDP4Cedl9e6wPwdi90HVEjDK3FoDv7UPBtgGwMzRUQVIz/etbcQr +tnGwSQlsDI/Q5R1HAh241+/rWYodi6OqNsNeb065RRBlwHAa4uvT3b/Cj/OJI5Kp +6qRPquK0iuMaFwuxGCxfhTLOmmGVNYOE7/9UzKXA2yvthY3jfmIm18l/z08PgUYj +rjENdrez3ZRgjZ/XsXSNw3B2K3cZQ+xRP4rqfkmfPO8T6UhOeoiQFx2v1PizBWRQ +uiUtFjrCiaDeBjo3kfGgbpdPnHzqUEoEOyAlsglFLJC9xaCiLtt2ic1/1OFFlNgQ +tLJLAgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww +CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v +b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL +MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw +Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs +ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp +c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw +GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G +A1UdIwQYMBaAFAYenQPZrutto05LK939ru/TEqiNMB0GA1UdDgQWBBQGHp0D2a7r +baNOSyvd/a7v0xKojTANBgkqhkiG9w0BAQ0FAAOCAQEADrtfqJ8lnYsVyV5YK/H/ +evPf9LY1AfuuQkMkm9UP9a9BBQINoIULB+n+gF/c0dxEboF74Ikp08dhDOq0mjvj +f0lpsBPgX/eN9IOWdMBs3rKIXn7suOoUtnBuFgW6fJ32CPTLUQd5Dqv9DizTiKMf +X66oMBQD784IKya1bLaJd7x1UXtP1h2DAej1scF9DbiDDDieuid0wyibrPDgjUN1 +tbYiLH2did0zZRLlp6gDpgh4t8Efqb7XDijKzQHvWKzr4IALTpYoD42yeslMa5yV +mm15NhiRGAdX+JbvYgfP3aDIMX/yoaMB8GXEUq7CmFhAwpxfhy/oyvswX5MyE8D2 +Lw== +-----END CERTIFICATE----- + + +Issuer ...: /CN=8R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE +Serial ...: 01 +Subject ..: /CN=8R-CA 1:PN/O=Regulierungsbehörde für Telekommunikation und Post/C=DE + +-----BEGIN CERTIFICATE----- +MIIEEjCCA36gAwIBAgIBATAKBgYrJAMDAQIFADBhMQswCQYDVQQGEwJERTE9MDsG +A1UECgw0UmVndWxpZXJ1bmdzYmVow7ZyZGUgZsO8ciBUZWxla29tbXVuaWthdGlv +biB1bmQgUG9zdDETMBEGA1UEAwwKOFItQ0EgMTpQTjAeFw0wNDExMjUxNDEwMzda +Fw0wNzEyMzExNDA0MDNaMGExCzAJBgNVBAYTAkRFMT0wOwYDVQQKDDRSZWd1bGll +cnVuZ3NiZWjDtnJkZSBmw7xyIFRlbGVrb21tdW5pa2F0aW9uIHVuZCBQb3N0MRMw +EQYDVQQDDAo4Ui1DQSAxOlBOMIGgMA0GCSqGSIb3DQEBAQUAA4GOADCBigKBgQCS +DvtngJbI4K8sbCHFfCalXaDa7xgc2pdsL2oQlgZygt1EY5ZgZB93JThnDSaDzdLj +ZIPrXJLxCOLq6Kmxj63V9p9WUaF5nz/6PVRMmLzI7cvh5QDjsX4ZmEzm/it7e/YH +vC1Yiw5bTULjwVZ27vqO64mhplQM3HKVgk6FX51XnwIEQAAAgaOCAd0wggHZMA4G +A1UdDwEB/wQEAwICBDAYBggrBgEFBQcBAwQMMAowCAYGBACORgEBMEoGCCsGAQUF +BwEBBD4wPDA6BggrBgEFBQcwAYYuaHR0cDovL29jc3AubnJjYS1kcy5kZTo4MDgw +L29jc3Atb2NzcHJlc3BvbmRlcjASBgNVHSAECzAJMAcGBSskCAEBMIHeBgNVHR8E +gdYwgdMwgdCggc2ggcqGgcdsZGFwOi8vbGRhcC5ucmNhLWRzLmRlOjM4OS9DTj1D +UkwsTz1SZWd1bGllcnVuZ3NiZWglRjZyZGUlMjBmJUZDciUyMFRlbGVrb21tdW5p +a2F0aW9uJTIwdW5kJTIwUG9zdCxDPURFLGRjPWxkYXAsZGM9bnJjYS1kcyxkYz1k +ZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeT9iYXNlP29iamVjdENs +YXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MBsGCSsGAQQBwG0DBQQOMAwGCisGAQQB +wG0DBQEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTuKY5dMBMWc1wFL/fr +arlCuHKNBDAdBgNVHQ4EFgQU7imOXTATFnNcBS/362q5QrhyjQQwCgYGKyQDAwEC +BQADgYEAbDMwH4zJB/0qgmbBWvvCGJsm9lmLzLdOcB8HCm1EvlCLqaCX7TwoUuBN +voxU9OHt1wAbChNP+ueDmI/0u2KRNv6/t4cOB8d4navwsW5nmknSzdZ6UZTUfmCr +n6XIdUtl2hkiFlQpCvCIBFj/+PjQRMdovRN42EQ9XVhb5B2MGv8= +-----END CERTIFICATE----- + +Issuer ...: /CN=7R-CA 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE +Serial ...: 00C48C8D +Subject ..: /CN=7R-CA 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde fÈur Telekommunikation und Post/C=DE + +-----BEGIN CERTIFICATE----- +MIICaTCCAdWgAwIBAgIEAMSMjTAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9 +MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWth +dGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo3Ui1DQSAxOlBO +MCIYDzIwMDExMDE1MTExNTE1WhgPMjAwNjAyMTUxMTE1MTVaMG8xCzAJBgNVBAYT +AkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21t +dW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjdSLUNB +IDE6UE4wgaEwDQYJKoZIhvcNAQEBBQADgY8AMIGLAoGBAIqJA/4+pRD+BXsRd+ej +qVObXlKRhn1CoyKxVwR3O/RtE1M4FcajKDdT1p1pLULyqPBE2roMS5D/f83192gE +Mw1uGZIusehg6n8tPQIJPkSb4X22yM0ZFeLAQXKNJ+98e03xv/TU4Fa//elPiPs/ +9Y99Gm6DOvTpCxIY8QK9Pxm7AgUAwAAAAaMSMBAwDgYDVR0PAQH/BAQDAgEGMAoG +BiskAwMBAgUAA4GBADnITH+fLD0qsWcAncwPztzTAnqUw9O0+yvfmxvEU0zcJRuF +Tl8DK+/aKp4SwVhRJZlWxenHzkjWynsUXBUv878gizllRpA7265REyHQki4NnxAi +OGxEVGe/NbGeU88Pgnk7alhtdA/Ty8/WX9a3U/0G4pLaJppxGSm+ypQZ0XOY +-----END CERTIFICATE----- + + +Issuer ...: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE +Serial ...: 00B95F +Subject ..: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE + aka ..: info@d-trust.net + aka ..: (uri http://www.d-trust.net) + +-----BEGIN CERTIFICATE----- +MIIFCjCCA/KgAwIBAgIDALlfMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxLDAqBgNVBAMMI0QtVFJVU1QgUXVhbGlm +aWVkIFJvb3QgQ0EgMSAyMDA2OlBOMB4XDTA2MDQyNzEyNDA1NFoXDTExMDQyNzEy +NDA1NFowUjELMAkGA1UEBhMCREUxFTATBgNVBAoMDEQtVHJ1c3QgR21iSDEsMCoG +A1UEAwwjRC1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAxIDIwMDY6UE4wggEkMA0G +CSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQCPACqp8H/KTbDBUM8BTiRzsfCJmN5G +Uxv8x3wsYLMtZ8meq04vEun2OneNeKZ2LxJy3UchUWitYP9pLPt9M8yt0pyuOXOQ +5r2RPAM46OlfStoPbZ+lCxpZbNcQGLM+/OcQU9GoCNWWkDSctwIN8T4mUf7vSzuT +jM4n5NHW7Y8bANhH7lh2fwkfIk7PxsxFw9amptlqzDqbBPz8/SdBUFt0G8t52Niw +lcYHWDV2YH4Qs1SAxOsyG0O8hpYKiKIwRHxPu5ZD3bMgDJXA3d+9zXlrLlmL0YFC +tvlPxmvqUhmMsL4vGEj/xWivULCTVOz6KcJ9edWwK9JxyO/KmGyDLwKxAgUApBVt +/aOCAeUwggHhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJr+c6YCNnohJ6M3 +fhSzwwTq2CkWMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29j +c3AuZC10cnVzdC5uZXQwFwYDVR0gBBAwDjAMBgorBgEEAaU0Ah4BMDMGA1UdEQQs +MCqBEGluZm9AZC10cnVzdC5uZXSGFmh0dHA6Ly93d3cuZC10cnVzdC5uZXQwGAYI +KwYBBQUHAQMEDDAKMAgGBgQAjkYBATAOBgNVHQ8BAf8EBAMCAQYwggEABgNVHR8E +gfgwgfUwgfKgge+ggeyGgaVsZGFwOi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NO +PUQtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAxJTIwMjAwNiUzQVBO +LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0 +P2Jhc2U/b2JqZWN0Q2xhc3M9Y3JsRGlzdHJpYnV0aW9uUG9pbnSGQmh0dHA6Ly93 +d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfcXVhbGlmaWVkX3Jvb3RfY2FfMV8y +MDA2X3BuLmNybDANBgkqhkiG9w0BAQUFAAOCAQEABsVNHg5zVMB+A4swJ8/vW+RV +mW8KZiJb5AVytFzBeZkkF2+DXFMtursZ0sICIcRCSsNyAQcqHqzcgnDWCHASlu4o +Em3TeBsmWo8r/uGpbFVAOhjq2VOFwjjIr3TC7zmMoLE+WGBRSuZh4/5wnxQ+NNbY +8HHE52UPI6VyV7RZeE0IZfbjkejw8WpvNtRfc6NxOCxf1LYibiCUaYs+EBDD+eod +lWwpmHwPSj4GCzR9wBdbWML/GQZ6iFVOuEmApm2B11KEn4hvKtRMEp1CdHIn8Jwx +51E89XcjJOIitO0lUozimqvlUb0lEynXe1/CUOhAsiAnLvq0GbnjFN6+9GRnqg== +-----END CERTIFICATE----- + +Issuer ...: /CN=D-TRUST Qualified Root CA 2 2006:PN/O=D-Trust GmbH/C=DE +Serial ...: 00B960 +Subject ..: /CN=D-TRUST Qualified Root CA 2 2006:PN/O=D-Trust GmbH/C=DE + aka ..: info@d-trust.net + aka ..: (uri http://www.d-trust.net) + +-----BEGIN CERTIFICATE----- +MIIFBjCCA+6gAwIBAgIDALlgMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxLDAqBgNVBAMMI0QtVFJVU1QgUXVhbGlm +aWVkIFJvb3QgQ0EgMiAyMDA2OlBOMB4XDTA2MDQyNzEyNDA1NFoXDTExMDQyNzEy +NDA1NFowUjELMAkGA1UEBhMCREUxFTATBgNVBAoMDEQtVHJ1c3QgR21iSDEsMCoG +A1UEAwwjRC1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyIDIwMDY6UE4wggEkMA0G +CSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQC9p9EZM645WSti4m3Lp/m5Cu2PCeAf +DYMsN2UQab5SAD94wc0xB68rhD0QiyXT1bhqnHKGhdsmmNwVbFLWyFWVc69+5pbx +jkEa1Z5oYbftpLZlqblas/iPG1C546c/O5JUHehrpyJziTaIqvDm0hMCarEGrd4i +hdwP7XsLNLeHFVdpVMWKUIJjUud18Wyr6MVRGs85YTme2gPki8JZMjeOteTA8dnY +unohiJM1rs8YQiYgIfQJV5oBd7OWZQLSuoh5tddYnP4KDFZUCCsC1OkBD+MnVlcv +IEfrDDuWdvFgOdS8FB5l4E3D0eYPpn536EDpWeGuCnn8joQPdiMwwGL7AgUAuaHl +M6OCAeEwggHdMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFILMyG0qJl9Aqmsa +DhPJE4d+Xp/JMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29j +c3AuZC10cnVzdC5uZXQwFwYDVR0gBBAwDjAMBgorBgEEAaU0Ah4BMDMGA1UdEQQs +MCqBEGluZm9AZC10cnVzdC5uZXSGFmh0dHA6Ly93d3cuZC10cnVzdC5uZXQwGAYI +KwYBBQUHAQMEDDAKMAgGBgQAjkYBATAOBgNVHQ8BAf8EBAMCAQYwgf0GA1UdHwSB +9TCB8jCB76CB7KCB6YaBpWxkYXA6Ly9kaXJlY3RvcnkuZC10cnVzdC5uZXQvQ049 +RC1UUlVTVCUyMFF1YWxpZmllZCUyMFJvb3QlMjBDQSUyMDIlMjAyMDA2JTNBUE4s +Tz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3Q/ +YmFzZT9vYmplY3RDbGFzcz1jcmxEaXN0cmlidXRpb25Qb2ludIY/aHR0cDovL3d3 +dy5kLXRydXN0Lm5ldC9jcmwvZC10cnVzdF9xdWFsaWZpZWRfcm9vdF9jYV8yXzIw +MDYuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQB/TeSQASSUVjLVpTMB+S2bEYZWL04N +5UO5sIdV5MQFxmbmQNam4odnkOx/GjHy0uuf14Pz7lztlLh4EMvEZbvoQ8wRsrrl +vMjWBUSnhTMPhohj4gUCEJDBq50qi0057Jos9DF4iLaFgiWBER+FeSHD8uEy6WGG +UrQ9fw8wRa+CRUeZldtZ25VSR++wxBuX3bkF/hRBuSk9PzT6jZojZDWKsqhPGo0W +dK4V81hS4Zri3b3gSD/3iOAJ4EO8jdyeSVomw/u1UOapVFnWhpN7H6Nwekij66eO +4WNzbeTNgJtkdOlzW2AcsWe3mS43BE286z7l/DzDs8JK36va/TRHb29p +-----END CERTIFICATE----- + + +Issuer ...: /CN=S-TRUST Qualified Root CA 2006-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart + /ST=Baden-Wuerttemberg (BW)/C=DE +Serial ...: 00DF749F80AA51F0EDC0CB1FC183E97EE2 +Subject ..: /CN=S-TRUST Qualified Root CA 2006-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart + /ST=Baden-Wuerttemberg (BW)/C=DE + +-----BEGIN CERTIFICATE----- +MIIETDCCAzSgAwIBAgIRAN90n4CqUfDtwMsfwYPpfuIwDQYJKoZIhvcNAQEFBQAw +gZ4xCzAJBgNVBAYTAkRFMSAwHgYDVQQIExdCYWRlbi1XdWVydHRlbWJlcmcgKEJX +KTESMBAGA1UEBxMJU3R1dHRnYXJ0MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmth +c3NlbiBWZXJsYWcgR21iSDEuMCwGA1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9v +dCBDQSAyMDA2LTAwMTpQTjAeFw0wNjAxMDEwMDAwMDBaFw0xMDEyMzAyMzU5NTla +MIGeMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4tV3VlcnR0ZW1iZXJnIChC +VykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNjaGVyIFNwYXJr +YXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1QgUXVhbGlmaWVkIFJv +b3QgQ0EgMjAwNi0wMDE6UE4wggEkMA0GCSqGSIb3DQEBAQUAA4IBEQAwggEMAoIB +AQCCp5M7qIP3WgNNE9t4kxFLb2HdwE2pivcWfEjFh9AJcwZIaD781+OhuNxhMEil +C+B9N3bYgLMj7r/LbIFwRVmUf9E64kBDrY/wLAlXLpiicOiKE7rS1tcOAdD69s7I +5jaBXCz/eQo20QLsp11/btwYos9PlfptLqHjS8AUwUaMyolqmWqaxLD33ZfoQswP +FpyFFzAnRondt/5WUt244kpqgTlwP4o9J1AZamK5o/kKEXl8hDT6CulFoK51cX/J +C9lEA10mwchVfv+9cel9b2ryPXg3hPf1XFFR+l90/ZYlreaSKz5+LluI6a/ALtYl +hqJpvndXm6YZDzKKtxT3LZ1DAgUA8A8a46OBgDB+MBIGA1UdEwEB/wQIMAYBAf8C +AQEwDgYDVR0PAQH/BAQDAgEGMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwHQYD +VR0OBBYEFKhXJN3CR/Jkirm68N+VHxcd09zBMB8GA1UdIwQYMBaAFKhXJN3CR/Jk +irm68N+VHxcd09zBMA0GCSqGSIb3DQEBBQUAA4IBAQBB8UGGU179RK9v5SglLn8m +AdBrwG5B4x0nlI3Ayj+GuP9R8ALcMEBwcFgSZTav7N8ERKa8VlCRNria7Fvf3kOu ++f67smpShBvEkrHy+ThvezBUtLfSSd1HzvaPnfwu86DMVnTIOkEcl0KLrpc/ZjEt +u81iHuiHBemf6gWdTCApiJ+CN4tARi3irvWcjhz/IIcA/ZwAaCW22Z1ysDklCIPS +9OnX9ki1f73PR+kdo4G7Dfo7TbuvV5Kzeh54sZ77A5utdvKer4ZHBmn9CGmk4VeI +BWdFlE7Fispzm+jZCduF0TcazvP/tYontx71GQnHRwLfiY4xnuzXEoSNXoaHzhzO +-----END CERTIFICATE----- + +Issuer ...: /CN=S-TRUST Qualified Root CA 2007-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart + /ST=Baden-Wuerttemberg (BW)/C=DE +Serial ...: 00BC098E0402E92956B8D7DE74977E26F7 +Subject ..: /CN=S-TRUST Qualified Root CA 2007-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart + /ST=Baden-Wuerttemberg (BW)/C=DE + +-----BEGIN CERTIFICATE----- +MIIESzCCAzOgAwIBAgIRALwJjgQC6SlWuNfedJd+JvcwDQYJKoZIhvcNAQELBQAw +gZ4xCzAJBgNVBAYTAkRFMSAwHgYDVQQIExdCYWRlbi1XdWVydHRlbWJlcmcgKEJX +KTESMBAGA1UEBxMJU3R1dHRnYXJ0MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmth +c3NlbiBWZXJsYWcgR21iSDEuMCwGA1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9v +dCBDQSAyMDA3LTAwMTpQTjAeFw0wNzAxMDEwMDAwMDBaFw0xMTEyMzAyMzU5NTla +MIGeMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4tV3VlcnR0ZW1iZXJnIChC +VykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNjaGVyIFNwYXJr +YXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1QgUXVhbGlmaWVkIFJv +b3QgQ0EgMjAwNy0wMDE6UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIB +AQCnJdNNiDQLKpPIfHTC3ifleXWTf96hLfvP58q41fuywQ+rXju453yjPgr/ej5i +RgYPyJnSc498wyu/XtPLIC3gQvowfiI8WmSj/eEToHUhrLIAtx1VXSi/Rugt3E1Y +uYGkPn/gnrkk+RtPJQuBl1NRxKEVi7rg1Ch5RJvWsUTOmxgeWlr8qZnPoLkA2y6N +lhL6LP3Th+OQIH4RFFfazNYWpH4Cg6I5nzyieHaR6LrGk0L7GfDKdZG4Eqan3JvI +ilrFHzzCm7qudd+31jcRamReqZqJ0wzBmY1LNAzDyCAC3Y+YWEz8crhDW3mK/wFY +H0RHHeow06RMTEVwls+FrhWfAgRAAACBo4GAMH4wEgYDVR0TAQH/BAgwBgEB/wIB +ATAOBgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNV +HQ4EFgQUPAujGBtjPCldr0A+EM4YCZSIX1cwHwYDVR0jBBgwFoAUPAujGBtjPCld +r0A+EM4YCZSIX1cwDQYJKoZIhvcNAQELBQADggEBAJ1pVXXcVb9m0yRPjvE4Rvko +tdjIm29YnY13ILCrPqjfgtpSlId6NHPhykGLkw3ratNlWQp3rmen/8EqQJa0rsPD +CiB20ilLb1CmF8/SViJ26C+K0ayzk8s2v7S/m7/Tx9Dgd2PXWwy2XjeGG/2SkISH +5CtSjbm8U+xTh5SQMgK1MX/bDiNJebDOO0N2lxAjtcGmw7K6OTWS7KnFfjzv6fKK +L7Ed2Gpd2gBkbuJVe/wX2mDP2P4rpcCEkXrDoWbi9WWc+eP5fCgE4Nj7/VhnbPf6 +DJCvmUG571uf1oukFaoeeyzpw2q28Ly1KR8DNPw+B/3PzJUIjXYzPGyUjv3aPew= +-----END CERTIFICATE----- + + +Issuer ...: /CN=S-TRUST Qualified Root CA 2008-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE +Serial ...: 00B3963E0E6C2D65125853E970665402E5 +Subject ..: /CN=S-TRUST Qualified Root CA 2008-001:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE + +-----BEGIN CERTIFICATE----- +MIIFODCCBCCgAwIBAgIRALOWPg5sLWUSWFPpcGZUAuUwDQYJKoZIhvcNAQELBQAw +fDELMAkGA1UEBhMCREUxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1 +dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1Qg +UXVhbGlmaWVkIFJvb3QgQ0EgMjAwOC0wMDE6UE4wHhcNMDgwMTAxMDAwMDAwWhcN +MTIxMjMwMjM1OTU5WjB8MQswCQYDVQQGEwJERTESMBAGA1UEBxMJU3R1dHRnYXJ0 +MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmthc3NlbiBWZXJsYWcgR21iSDEuMCwG +A1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyMDA4LTAwMTpQTjCCASMw +DQYJKoZIhvcNAQEBBQADggEQADCCAQsCggEBAKfUBh+i0NSWzddPtWG15DdTqbPM +SJmeWw6dXutkR6UNonxC+yAm6rfZJhb83tPGB09qlAcNn7fcdR/g4SNdu3McwT+J +HKHou6hhbMZmsza72Qcj9P/AwWq/o5oJa2eI4pU7I5YjS3x3oGtvmhJkwYiehIyx +7DI+wHKcohwJV83jlZW3YrPmKgpaOZsc5lJM/+Ha4Q77MLPWHdCnxUkrbL1+Q/Ea +qY+DoMMa9wxY+UmwbKe8ANfAf2NIMfJwmb748f+7EJMLjUA8nxrQ4iAPJ1lSrfZs +d9cjzjdXZnhLvR9T2nNa2nROOHk2ARCOPAJgxk9EheRr4B6RbJ4hinuydJUCBEAA +AIGjggGyMIIBrjASBgNVHRMBAf8ECDAGAQH/AgEBMIIBLAYDVR0fBIIBIzCCAR8w +ggEboIIBF6CCAROGZWh0dHA6Ly9vbnNpdGVjcmwucy10cnVzdC5kZS9EZXV0c2No +ZXJTcGFya2Fzc2VuVmVybGFnR21iSFNUUlVTVFF1YWxpZmllZFJvb3RDQTIwMDgw +MDFQTi9MYXRlc3RDUkwuY3JshoGpbGRhcDovL2RpcmVjdG9yeS5zLXRydXN0LmRl +L0NOPVMtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAyMDA4LTAwMSUz +QVBOLE89RGV1dHNjaGVyJTIwU3Bhcmthc3NlbiUyMFZlcmxhZyUyMEdtYkgsTD1T +dHV0dGdhcnQsQz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeTAO +BgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNVHQ4E +FgQU7UBDbxBuOWcii/O2xVNRExXxPj0wHwYDVR0jBBgwFoAU7UBDbxBuOWcii/O2 +xVNRExXxPj0wDQYJKoZIhvcNAQELBQADggEBAEdeesrApdpV+0cz698ZM+fsbcmk +AYTy8U1vcnEPzcxaEAvUO57ndJlSdBK7+5yFbVuFW7CTp90TPgljoDqWDOI2hsLU +YxrHUfDCwsm/ALLDpImRKWGZ07nKxOHGAOxB4tQUaDUHwaClbw3UB3nBi9++f9d0 +FLM9oOVxbhKGco4/qo3LP+QfJU6xjL8itqaf0WHXcnN69CD/5D7e/iziwHvLWLEU +0cUXVDzdyWKEvJ3RpFIk6EUulKFHZrCctis1ixg/iQybKs2DWG/RtCo6CGhtydT8 +I1y6qAwPL2gAt+ypf+Mk4SLewnpXlw6ZVDQlLEBLGto72DAyJTxRh8f6BpY= +-----END CERTIFICATE----- + +Issuer ...: /CN=S-TRUST Qualified Root CA 2008-002:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE +Serial ...: 00C4216083F35C54F67B09A80C3C55FE7D +Subject ..: /CN=S-TRUST Qualified Root CA 2008-002:PN + /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE + +-----BEGIN CERTIFICATE----- +MIIFODCCBCCgAwIBAgIRAMQhYIPzXFT2ewmoDDxV/n0wDQYJKoZIhvcNAQELBQAw +fDELMAkGA1UEBhMCREUxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1 +dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxLjAsBgNVBAMTJVMtVFJVU1Qg +UXVhbGlmaWVkIFJvb3QgQ0EgMjAwOC0wMDI6UE4wHhcNMDgwMTAxMDAwMDAwWhcN +MTIxMjMwMjM1OTU5WjB8MQswCQYDVQQGEwJERTESMBAGA1UEBxMJU3R1dHRnYXJ0 +MSkwJwYDVQQKEyBEZXV0c2NoZXIgU3Bhcmthc3NlbiBWZXJsYWcgR21iSDEuMCwG +A1UEAxMlUy1UUlVTVCBRdWFsaWZpZWQgUm9vdCBDQSAyMDA4LTAwMjpQTjCCASMw +DQYJKoZIhvcNAQEBBQADggEQADCCAQsCggEBAJCrKgvHaZdd5LpNAlVZVf8a3CJY +lBUt4Awwlu5q9wnkObVGHyekGLG6h7wMrY9OCL4uqWn9vIz+5vGXMEvU+NniMXIn +JodZS8CbBBYUxS42PgZp7TNCd4gglEA1xOhsQH8T9iRZzdRCLyZYjysYsHiujn/x +7y0+nxQsYu2mONaPFZq7ZBsDlAk5BPdIZCrutHDHe5inKwbpDUdpnKFlM1UDZ3eS +4dl+YT/3t4QSJAVHVFz/Pzf1tevpMFYP4M7jHaktp327GMtrhYlpeoSZRc1cizHU +Vdhj6Foyj1wWkQMwvb1ChPbRxS+4V3b6R+vgelULDBqFSF0Rtj/kRUgT/q8CBEAA +AIGjggGyMIIBrjASBgNVHRMBAf8ECDAGAQH/AgEBMIIBLAYDVR0fBIIBIzCCAR8w +ggEboIIBF6CCAROGZWh0dHA6Ly9vbnNpdGVjcmwucy10cnVzdC5kZS9EZXV0c2No +ZXJTcGFya2Fzc2VuVmVybGFnR21iSFNUUlVTVFF1YWxpZmllZFJvb3RDQTIwMDgw +MDJQTi9MYXRlc3RDUkwuY3JshoGpbGRhcDovL2RpcmVjdG9yeS5zLXRydXN0LmRl +L0NOPVMtVFJVU1QlMjBRdWFsaWZpZWQlMjBSb290JTIwQ0ElMjAyMDA4LTAwMiUz +QVBOLE89RGV1dHNjaGVyJTIwU3Bhcmthc3NlbiUyMFZlcmxhZyUyMEdtYkgsTD1T +dHV0dGdhcnQsQz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeTAO +BgNVHQ8BAf8EBAMCAQYwGAYIKwYBBQUHAQMEDDAKMAgGBgQAjkYBATAdBgNVHQ4E +FgQUIQpnbAV/rAz9qSo/4q/3/TlplqwwHwYDVR0jBBgwFoAUIQpnbAV/rAz9qSo/ +4q/3/TlplqwwDQYJKoZIhvcNAQELBQADggEBAHRr6IiNPkWJYHVa8vi4tufRG9nE +Yy8t2ll8xbu4ar+LXCqbttdaQzVU/7RCX4S1aPm6wb9WFJU+/JfZHpez+gJ9uIFy +6rYJDxZ4qTxaGnIKGguZbEkpvne38/vtyjR5RuCj5AwEuP7Vy7/j5O1WZDoROMoD +rRsBHLtg90aDVou0IG+wK5+RPOixSMjfMf79uixHrsriMHrzulTEMmX+S+VfXGmO +G1RRiCiWgYaEtSIDAP0V9ehpcghfJLlmMBnxSf4n7OZvkd1whvme2rXaQxnZi2qV +d2qclY03eJ7zx6Zpq8VFuVvOxvmFZ4mMe706runhCq+rHc5x6x0/oIMhDrk= +-----END CERTIFICATE----- + diff --git a/doc/contrib.texi b/doc/contrib.texi new file mode 100644 index 0000000..bb558bd --- /dev/null +++ b/doc/contrib.texi @@ -0,0 +1,106 @@ +@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. + +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 new modularized architecture of gnupg 1.9 as well as the X.509/CMS +part has been developed as part of the Ägypten project. Direct +contributors to this project are: Bernhard Herzog, who did extensive +testing and tracked down a lot of bugs. Bernhard Reiter, who made sure +that we met the specifications and the deadlines. He did extensive +testing and came up with a lot of suggestions. Jan-Oliver Wagner made +sure that we met the specifications and the deadlines. He also did +extensive testing and came up with a lot of suggestions. Karl-Heinz +Zimmer and Marc Mutz had to struggle with all the bugs and +misconceptions while working on KDE integration. Marcus Brinkman +extended GPGME, cleaned up the Assuan code and fixed bugs all over the +place. Moritz Schulte took over Libgcrypt maintenance and developed it +into a stable an useful library. Steffen Hansen had a hard time to +write the dirmngr due to underspecified interfaces. Thomas Koester did +extensive testing and tracked down a lot of bugs. Werner Koch designed +the system and wrote most of the code. + +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 new file mode 100644 index 0000000..c83ab1e --- /dev/null +++ b/doc/debugging.texi @@ -0,0 +1,277 @@ +@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 + +Everyone 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 problems a merely configuration and user problems but +nevertheless there are the most annoying ones and responsible for many +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. +* Debugging Hints:: Various hints on debugging. +* Common Problems:: Commonly seen problems. +* Architecture Details:: How the whole thing works internally. +@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 format 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 certificates and a total of 17 keys or certificates +are flagged 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 certificates are stored +in a standard way and directly available from @command{gpgsm}. + +@noindent +To find duplicated certificates and keyblocks in a keybox file (this +should not occur but sometimes things go wrong), run it using + +@samp{kbxutil --find-dups ~/.gnupg/pubring.kbx} + + +@node Debugging Hints +@section Various hints on debugging. + +@itemize @bullet + +@item How to find the IP address of a keyserver + +If a round robin URL of is used for a keyserver +(e.g. subkeys.gnupg.org); it is not easy to see what server is actually +used. Using the keyserver debug option as in + +@smallexample + gpg --keyserver-options debug=1 -v --refresh-key 1E42B367 +@end smallexample + +is thus often helpful. Note that the actual output depends on the +backend and may change from release to release. + +@ifset gpgtwoone +@item Logging on WindowsCE + +For development, the best logging method on WindowsCE is the use of +remote debugging using a log file name of @file{tcp://:}. +The command @command{watchgnupg} may be used on the remote host to listen +on the given port. (@pxref{option watchgnupg --tcp}). For in the field +tests it is better to make use of the logging facility provided by the +@command{gpgcedev} driver (part of libassuan); this is enabled by using +a log file name of @file{GPG2:}. (@pxref{option --log-file}). +@end ifset + +@end itemize + + +@node Common Problems +@section Commonly Seen Problems + + +@itemize @bullet +@item Error code @samp{Not supported} from Dirmngr + +Most likely the option @option{enable-ocsp} is active for gpgsm +but Dirmngr's OCSP feature has not been enabled using +@option{allow-ocsp} in @file{dirmngr.conf}. + +@item The Curses based Pinentry does not work + +The far most common reason for this is that the environment variable +@code{GPG_TTY} has not been set correctly. Make sure that it has been +set to a real tty devce and not just to @samp{/dev/tty}; +i.e. @samp{GPG_TTY=tty} is plainly wrong; what you want is +@samp{GPG_TTY=`tty`} --- note the back ticks. Also make sure that +this environment variable gets exported, that is you should follow up +the setting with an @samp{export GPG_TTY} (assuming a Bourne style +shell). Even for GUI based Pinentries; you should have set +@code{GPG_TTY}. See the section on installing the @command{gpg-agent} +on how to do it. + + +@item SSH hangs while a popping up pinentry was expected + +SSH has no way to tell the gpg-agent what terminal or X display it is +running on. So when remotely logging into a box where a gpg-agent with +SSH support is running, the pinentry will get popped up on whatever +display the gpg-agent has been started. To solve this problem you may +issue the command + +@smallexample +echo UPDATESTARTUPTTY | gpg-connect-agent +@end smallexample + +and the next pinentry will pop up on your display or screen. However, +you need to kill the running pinentry first because only one pinentry +may be running at once. If you plan to use ssh on a new display you +should issue the above command before invoking ssh or any other service +making use of ssh. + + +@item Exporting a secret key without a certificate + +I may happen that you have created a certificate request using +@command{gpgsm} but not yet received and imported the certificate from +the CA. However, you want to export the secret key to another machine +right now to import the certificate over there then. You can do this +with a little trick but it requires that you know the approximate time +you created the signing request. By running the command + +@smallexample + ls -ltr ~/.gnupg/private-keys-v1.d +@end smallexample + +you get a listing of all private keys under control of @command{gpg-agent}. +Pick the key which best matches the creation time and run the command + +@smallexample + /usr/local/libexec/gpg-protect-tool --p12-export ~/.gnupg/private-keys-v1.d/@var{foo} >@var{foo}.p12 +@end smallexample + +(Please adjust the path to @command{gpg-protect-tool} to the appropriate +location). @var{foo} is the name of the key file you picked (it should +have the suffix @file{.key}). A Pinentry box will pop up and ask you +for the current passphrase of the key and a new passphrase to protect it +in the pkcs#12 file. + +To import the created file on the machine you use this command: + +@smallexample + /usr/local/libexec/gpg-protect-tool --p12-import --store @var{foo}.p12 +@end smallexample + +You will be asked for the pkcs#12 passphrase and a new passphrase to +protect the imported private key at its new location. + +Note that there is no easy way to match existing certificates with +stored private keys because some private keys are used for Secure Shell +or other purposes and don't have a corresponding certificate. + + +@item A root certificate does not verify + +A common problem is that the root certificate misses the required +basicConstraints attribute and thus @command{gpgsm} rejects this +certificate. An error message indicating ``no value'' is a sign for +such a certificate. You may use the @code{relax} flag in +@file{trustlist.txt} to accept the certificate anyway. Note that the +fingerprint and this flag may only be added manually to +@file{trustlist.txt}. + +@item Error message: ``digest algorithm N has not been enabled'' + +The signature is broken. You may try the option +@option{--extra-digest-algo SHA256} to workaround the problem. The +number N is the internal algorithm identifier; for example 8 refers to +SHA-256. + + +@item The Windows version does not work under Wine + +When running the W32 version of @command{gpg} under Wine you may get +an error messages like: + +@smallexample +gpg: fatal: WriteConsole failed: Access denied +@end smallexample + +@noindent +The solution is to use the command @command{wineconsole}. + +Some operations like gen-key really want to talk to the console directly +for increased security (for example to prevent the passphrase from +appearing on the screen). So, you should use @command{wineconsole} +instead of @command{wine}, which will launch a windows console that +implements those additional features. + + +@item Why does GPG's --search-key list weird keys? + +For performance reasons the keyservers do not check the keys the same +way @command{gpg} does. It may happen that the listing of keys +available on the keyservers shows keys with wrong user IDs or with user +Ids from other keys. If you try to import this key, the bad keys or bad +user ids won't get imported, though. This is a bit unfortunate but we +can't do anything about it without actually downloading the keys. + +@end itemize + + +@c ******************************************** +@c *** Architecture Details ***************** +@c ******************************************** +@node Architecture Details +@section How the whole thing works internally. + + +@menu +* GnuPG-1 and GnuPG-2:: Relationship between the two branches. +@end menu + +@node GnuPG-1 and GnuPG-2 +@subsection Relationship between the two branches. + +Here is a little picture showing how the components work together: + +@image{gnupg-card-architecture, 10cm} + +@noindent +Lets try to explain it: + +TO BE DONE. + + diff --git a/doc/examples/README b/doc/examples/README new file mode 100644 index 0000000..3444822 --- /dev/null +++ b/doc/examples/README @@ -0,0 +1,9 @@ +Files in this directory: + + +scd-event A handler script used with scdaemon + +trustlist.txt A list of trustworthy root certificates + (Please check yourself whether you actually trust them) + +gpgconf.conf A sample configuration file for gpgconf. diff --git a/doc/examples/gpgconf.conf b/doc/examples/gpgconf.conf new file mode 100644 index 0000000..ec8685a --- /dev/null +++ b/doc/examples/gpgconf.conf @@ -0,0 +1,63 @@ +# gpgconf.conf - configuration for gpgconf +#---------------------------------------------------------------------- +# This file is read by gpgconf(1) to setup defaults for all or +# specified users and groups. It may be used to change the hardwired +# defaults in gpgconf and to enforce certain values for the various +# GnuPG related configuration files. +# +# Empty lines and comment lines, indicated by a hash mark as first non +# white space character, are ignored. The line is separated by white +# space into fields. The first field is used to match the user or +# group and must start at the first column, the file is processes +# sequential until a matching rule is found. A rule may contain +# several lines; continuation lines are indicated by a indenting them. +# +# Syntax of a line: +# |WS