diff --git a/ABOUT-NLS b/ABOUT-NLS deleted file mode 100644 index 47d5e39f0..000000000 --- a/ABOUT-NLS +++ /dev/null @@ -1,625 +0,0 @@ -Notes on the Free Translation Project -************************************* - - Free software is going international! The Free Translation Project -is a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -Quick configuration advice -========================== - - If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - - Some packages are "localizable" when properly installed; the -programs they contain can be made to speak your own native language. -Most such packages use GNU `gettext'. Other packages have their own -ways to internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is _not_ required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will respectively bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - - As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your country by running the command -`locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -Translating Teams -================= - - For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - - Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of May 2003. -The matrix shows, in regard of each package, for which languages PO -files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files am az be bg ca cs da de el en en_GB eo es - +-------------------------------------------+ - a2ps | [] [] [] [] | - aegis | () | - anubis | | - ap-utils | | - bash | [] [] [] | - batchelor | | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] | - bluez-pin | [] [] | - clisp | | - clisp | [] [] [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - darkstat | () [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] () [] [] [] [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] [] | - flex | [] [] [] [] | - gas | [] | - gawk | [] [] [] [] | - gcal | [] | - gcc | [] [] | - gettext | [] [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] [] [] [] [] | - gliv | | - glunarclock | [] [] [] | - gnucash | () [] | - gnucash-glossary | [] () [] | - gnupg | [] () [] [] [] [] | - gpe-calendar | [] | - gpe-conf | [] | - gpe-contacts | [] | - gpe-edit | | - gpe-login | [] | - gpe-ownerinfo | [] | - gpe-sketchbook | [] | - gpe-timesheet | | - gpe-today | [] | - gpe-todo | [] | - gphoto2 | [] [] [] [] | - gprof | [] [] | - gpsdrive | () () () | - grep | [] [] [] [] [] | - gretl | [] | - hello | [] [] [] [] [] [] | - id-utils | [] [] | - indent | [] [] [] [] | - jpilot | [] [] [] [] | - jwhois | [] | - kbd | [] [] [] [] [] | - ld | [] [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] | - libiconv | [] [] [] [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lingoteach_lessons | () () | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] | - man-db | [] () [] [] () | - mysecretdiary | [] [] [] | - nano | [] () [] [] [] | - nano_1_0 | [] () [] [] [] | - opcodes | [] [] | - parted | [] [] [] [] [] | - ptx | [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] [] [] [] | - screem | | - sed | [] [] [] [] [] | - sh-utils | [] [] [] | - sharutils | [] [] [] [] [] [] | - sketch | [] () [] | - soundtracker | [] [] [] | - sp | [] | - tar | [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] | - tin | () () | - util-linux | [] [] [] [] [] | - vorbis-tools | [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] [] [] [] [] [] | - xchat | [] [] [] | - xpad | | - +-------------------------------------------+ - am az be bg ca cs da de el en en_GB eo es - 0 1 4 2 31 17 54 60 14 1 4 12 56 - - et fa fi fr ga gl he hr hu id it ja ko - +----------------------------------------+ - a2ps | [] [] [] () () | - aegis | | - anubis | [] | - ap-utils | [] | - bash | [] [] | - batchelor | [] | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] [] | - bluez-pin | [] [] [] [] | - clisp | | - clisp | [] | - coreutils | [] [] [] [] | - cpio | [] [] [] [] | - darkstat | () [] [] [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] | - findutils | [] [] [] [] [] [] [] [] [] [] [] | - flex | [] [] | - gas | [] | - gawk | [] [] | - gcal | [] | - gcc | [] | - gettext | [] [] [] | - gettext-runtime | [] [] [] [] | - gettext-tools | [] | - gimp-print | [] [] | - gliv | () | - glunarclock | [] [] [] [] | - gnucash | [] | - gnucash-glossary | [] | - gnupg | [] [] [] [] [] [] [] | - gpe-calendar | [] | - gpe-conf | | - gpe-contacts | [] | - gpe-edit | [] [] | - gpe-login | [] | - gpe-ownerinfo | [] [] [] | - gpe-sketchbook | [] | - gpe-timesheet | [] [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] | - gprof | [] [] | - gpsdrive | () [] () () | - grep | [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] | - indent | [] [] [] [] [] [] [] [] | - jpilot | [] () | - jwhois | [] [] [] [] | - kbd | [] | - ld | [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] [] | - libiconv | [] [] [] [] [] [] [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] | - lingoteach_lessons | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] [] [] [] [] | - man-db | [] () () | - mysecretdiary | [] [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] [] [] [] | - screem | | - sed | [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] | - sharutils | [] [] [] [] [] | - sketch | [] | - soundtracker | [] [] [] | - sp | [] () | - tar | [] [] [] [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] [] | - tin | [] () | - util-linux | [] [] [] [] () [] | - vorbis-tools | [] | - wastesedge | () | - wdiff | [] [] [] [] [] | - wget | [] [] [] [] [] [] [] [] | - xchat | [] [] [] | - xpad | | - +----------------------------------------+ - et fa fi fr ga gl he hr hu id it ja ko - 20 1 15 73 14 24 8 10 30 31 19 31 9 - - lg lt lv ms nb nl nn no pl pt pt_BR ro - +----------------------------------------+ - a2ps | [] [] () () () [] [] | - aegis | () | - anubis | [] [] | - ap-utils | () | - bash | [] | - batchelor | | - bfd | | - binutils | | - bison | [] [] [] [] | - bluez-pin | [] | - clisp | | - clisp | [] | - coreutils | [] | - cpio | [] [] [] | - darkstat | [] [] [] [] | - diffutils | [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] | - fetchmail | () () | - fileutils | [] | - findutils | [] [] [] [] | - flex | [] | - gas | | - gawk | [] | - gcal | | - gcc | | - gettext | [] | - gettext-runtime | [] | - gettext-tools | | - gimp-print | [] | - gliv | [] | - glunarclock | [] | - gnucash | | - gnucash-glossary | [] [] | - gnupg | | - gpe-calendar | [] [] | - gpe-conf | [] [] | - gpe-contacts | [] | - gpe-edit | [] [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-sketchbook | [] [] | - gpe-timesheet | [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | | - gprof | [] | - gpsdrive | () () () | - grep | [] [] [] [] | - gretl | | - hello | [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] | - indent | [] [] [] | - jpilot | () () | - jwhois | [] [] [] | - kbd | | - ld | | - libc | [] [] [] [] | - libgpewidget | [] [] | - libiconv | [] [] | - lifelines | | - lilypond | [] | - lingoteach | | - lingoteach_lessons | | - lynx | [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] | - man-db | [] | - mysecretdiary | [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] [] [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | | - recode | [] [] [] | - screem | | - sed | [] [] | - sh-utils | [] | - sharutils | [] | - sketch | [] | - soundtracker | | - sp | | - tar | [] [] [] [] [] [] | - texinfo | [] | - textutils | [] | - tin | | - util-linux | [] [] | - vorbis-tools | [] [] | - wastesedge | | - wdiff | [] [] [] [] | - wget | [] [] [] | - xchat | [] [] | - xpad | [] | - +----------------------------------------+ - lg lt lv ms nb nl nn no pl pt pt_BR ro - 0 0 2 11 7 26 3 4 18 15 34 34 - - ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW - +-------------------------------------------+ - a2ps | [] [] [] [] [] | 16 - aegis | () | 0 - anubis | [] [] | 5 - ap-utils | () | 1 - bash | [] | 7 - batchelor | | 1 - bfd | [] [] [] | 7 - binutils | [] [] [] | 7 - bison | [] [] | 13 - bluez-pin | | 7 - clisp | | 0 - clisp | | 5 - coreutils | [] [] [] [] [] | 14 - cpio | [] [] [] | 13 - darkstat | [] () () | 9 - diffutils | [] [] [] [] | 21 - e2fsprogs | [] | 3 - enscript | [] [] [] | 11 - error | [] [] [] | 14 - fetchmail | [] | 7 - fileutils | [] [] [] [] [] [] | 15 - findutils | [] [] [] [] [] [] | 27 - flex | [] [] [] | 10 - gas | [] | 3 - gawk | [] [] | 9 - gcal | [] [] | 4 - gcc | [] | 4 - gettext | [] [] [] [] [] [] | 15 - gettext-runtime | [] [] [] [] [] [] | 16 - gettext-tools | [] [] | 5 - gimp-print | [] [] | 10 - gliv | | 1 - glunarclock | [] [] [] | 11 - gnucash | [] [] | 4 - gnucash-glossary | [] [] [] | 8 - gnupg | [] [] [] [] | 16 - gpe-calendar | [] | 5 - gpe-conf | | 3 - gpe-contacts | [] | 4 - gpe-edit | [] | 5 - gpe-login | [] | 5 - gpe-ownerinfo | [] | 7 - gpe-sketchbook | [] | 5 - gpe-timesheet | [] | 6 - gpe-today | [] | 6 - gpe-todo | [] | 6 - gphoto2 | [] [] | 9 - gprof | [] [] | 7 - gpsdrive | [] [] | 3 - grep | [] [] [] [] | 24 - gretl | | 2 - hello | [] [] [] [] [] | 33 - id-utils | [] [] [] | 11 - indent | [] [] [] [] | 19 - jpilot | [] [] [] [] [] | 10 - jwhois | () () [] [] | 10 - kbd | [] [] | 8 - ld | [] [] | 5 - libc | [] [] [] [] | 20 - libgpewidget | | 6 - libiconv | [] [] [] [] [] [] | 21 - lifelines | [] | 2 - lilypond | [] | 4 - lingoteach | | 2 - lingoteach_lessons | () | 0 - lynx | [] [] [] [] | 14 - m4 | [] [] [] | 15 - mailutils | | 2 - make | [] [] [] [] | 15 - man-db | [] | 6 - mysecretdiary | [] [] | 8 - nano | [] [] [] | 15 - nano_1_0 | [] [] [] | 15 - opcodes | [] [] | 9 - parted | [] [] | 13 - ptx | [] [] [] | 22 - python | | 0 - radius | | 0 - recode | [] [] [] [] | 19 - screem | [] | 1 - sed | [] [] [] [] [] | 20 - sh-utils | [] [] [] | 13 - sharutils | [] [] [] [] | 16 - sketch | [] | 5 - soundtracker | [] | 7 - sp | [] | 3 - tar | [] [] [] [] [] | 24 - texinfo | [] [] [] [] | 13 - textutils | [] [] [] [] [] | 15 - tin | | 1 - util-linux | [] [] | 14 - vorbis-tools | [] | 7 - wastesedge | | 0 - wdiff | [] [] [] [] | 17 - wget | [] [] [] [] [] [] [] | 25 - xchat | [] [] [] | 11 - xpad | | 1 - +-------------------------------------------+ - 50 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW - 97 domains 32 19 16 0 56 0 48 10 1 1 12 23 913 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If May 2003 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -Using `gettext' in new packages -=============================== - - If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index e69de29bb..000000000 diff --git a/COPYING b/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index f71334c9e..000000000 --- a/ChangeLog +++ /dev/null @@ -1,452 +0,0 @@ -2004-06-08 Werner Koch - - Released 1.9.9. - -2004-06-06 Werner Koch - - * configure.ac: Require libksba 0.9.7. - -2004-04-29 Werner Koch - - Released 1.9.8. - -2004-04-20 Werner Koch - - * configure.ac: Remove the fopencookie test. We don't need the - dummy function because we conditionally use fopencookie, - fpencookie or a replacement at place. - -2004-04-02 Thomas Schwinge - - * autogen.sh: Added ACLOCAL_FLAGS. - -2004-04-06 Werner Koch - - Released 1.9.7. - - * configure.ac: Require libgcrypt 1.1.94. - Introduce PACKAGE_GT and set it to gnupg2. - -2004-03-23 Werner Koch - - * configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT. - -2004-03-09 Werner Koch - - * configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7. - -2004-03-06 Werner Koch - - Released 1.9.6. - - * configure.ac: Check the Libgcrypt API. - -2004-02-25 Werner Koch - - * configure.ac: New option --disable-threads to inhibit - unintentional builds without Pth. - -2004-02-21 Werner Koch - - Released 1.9.5. - -2004-02-20 Werner Koch - - * configure.ac: Fixed URLs in the notice messages. - -2004-02-18 Werner Koch - - * acinclude.m4: Removed macros to detect gpg-error, libgcrypt, - libassuan and ksba as they are now distributed in m4/. - -2004-02-13 Werner Koch - - * configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92. - -2004-02-12 Werner Koch - - * autogen.sh: Removed cruft from debugging. - - * am/cmacros.am: New. - -2004-02-11 Werner Koch - - * configure.ac: Removed the need for g10defs.h. Reworked the - --with-foo-pgm stuff. - - * autogen.sh (check_version): Removed bashism and simplified. - * acinclude.m4 (AM_PATH_OPENSC): Kludge to avoid error output for - a bad opensc-config. - -2004-01-30 Werner Koch - - Released 1.9.4. - - * configure.ac: Require libksba 0.9.3 due to another bug fix there. - -2004-01-29 Werner Koch - - * README: Updated. - - * configure.ac: Require libksba 0.9.2 due to bug fixes. - -2004-01-24 Werner Koch - - * configure.ac: Now requires libassuan 0.6.3. - -2003-12-23 Werner Koch - - Released 1.9.3. - - * README-alpha: Removed. - * configure.ac, Makefile.am: Add the tests and tools directories. - -2003-12-19 Werner Koch - - * configure.ac: Now require libgcrypt 1.1.91 to help testing the - latest libgcrypt changes. Requires libksab 0.9.1. - -2003-12-17 Werner Koch - - * configure.ac: Requires now libassuan 0.6.2. - (CFLAGS): Add --Wformat-noliteral in gcc mode. - -2003-12-16 Werner Koch - - * configure.ac: Check for funopen and fopencookie as part of the - jnlib checks. - -2003-12-09 Werner Koch - - * configure.ac: Add a min_automake_version. - * README.CVS: New. - * autogen.sh: Revamped except for the --build-w32 hack. - * Makefile.am: Add README.CVS - -2003-11-17 Werner Koch - - Release 1.9.2. - - * configure.ac: Requires now libassuan 0.6.1. - -2003-10-31 Werner Koch - - * configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed - time interface. - -2003-10-21 Werner Koch - - * configure.ac (PRINTABLE_OS_NAME): Remove special case for The - Hurd; Robert Millan reported that the uname test is now - sufficient. - -2003-10-01 Werner Koch - - * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. - -2003-09-23 Werner Koch - - Merged most of David Shaw's changes in 1.3 since 2003-06-03. - - * configure.ac: Drop all TIGER/192 support. - (uint64_t): Check for UINT64_C to go along with uint64_t. - (getaddrinfo): Check for it. - (sigset_t): Check for sigset_t and struct sigaction. This is for - Forte c89 on Solaris which seems to define only the function call - half of the two pairs by default. - (W32LIBS): Include wsock32 in W32LIBS. This is different from - NETLIBS so we don't need to force other platforms to pull in the - netlibs when they aren't actually needed. - -2003-09-06 Werner Koch - - Released 1.9.1. - - * configure.ac: Require newer versions of some libraries. - -2003-09-02 Werner Koch - - * configure.ac (HAVE_LIBUSB): Added a simple test for libusb. - -2003-08-19 Marcus Brinkmann - - * configure.ac (AM_PATH_GPG_ERROR): Add missing comma in - invocation. - -2003-08-06 Werner Koch - - * configure.ac: Check for libgpg-error. Print infos about missing - libraries more nicely. - * acinclude.m4 (AM_PATH_GPG_ERROR): Added. - -2003-08-05 Werner Koch - - Released 1.9.0. - - * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg. - -2003-07-31 Werner Koch - - * Makefile.am (DISTCLEANFILES): Add g10defs.h - -2003-06-18 Werner Koch - - * configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to - .gnupg2 to avoid accidential use with production keys. - -2003-06-11 Werner Koch - - * configure.ac: Merged all stuff from current 1.3 version in. - * acinclude.m4: Merged required macros from current 1.2 version in. - -2003-06-04 Werner Koch - - * configure.ac, Makefile.am: Enable building of gpg. - -2003-04-29 Werner Koch - - * configure.ac: Build a limited version of scdaemon if libopensc - is not available. - - * configure.ac (ALL_LINUGAS): Removed. - - * Makefile.am (ACLOCAL_AMFLAGS): New. - * configure.ac (AM_GNU_GETTEXT_VERSION): New. Set to 0.11.5. - -2003-04-29 gettextize - - * Makefile.am (SUBDIRS): Add m4. - (ACLOCAL_AMFLAGS): New variable. - (EXTRA_DIST): Add scripts/config.rpath. - * configure.ac (AC_CONFIG_FILES): Add m4/Makefile. - -2003-04-29 Werner Koch - - * assuan/ : Removed. We now use libassuan. - * Makefile.am (SUBDIRS): Removed assuan - - * configure.ac: Check for libassuan. - -2003-01-09 Werner Koch - - * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. - (NEED_KSBA_VERSION): Does now require 0.4.6. - - * README: Noted where to find gpg-protect-tool. - -2002-10-31 Neal H. Walfield - - * configure.ac: Check for flockfile and funlockfile. Check for - isascii and putc_unlocked replacing them if not found. - - * configure.ac (PTH_LIBS): If pth is found, add the output of - `$PTH_CONFIG --ldflags`, not just `$PTH_CONFIG --libs`. - -2002-10-19 Werner Koch - - * configure.ac: Bumped version number to 1.9.0-cvs. - - NewPG (Aegypten project) to GnuPG merge. - -2002-09-20 Werner Koch - - Released 0.9.2. - -2002-09-05 Neal H. Walfield - - * configure.ac: Check for makeinfo. - -2002-09-03 Neal H. Walfield - - * autogen.sh (have_version): New function. Generalize and - simplify logic for finding and determining the versions of GNU - programs. Use it. - -2002-08-23 Werner Koch - - Released 0.9.1. - - * acinclude.m4 (AM_PATH_LIBGCRYPT): Updated from Libgcrypt. - (AM_PATH_OPENSC): Strip non-digits from the micro version. - -2002-08-21 Werner Koch - - Released 0.9.0. - - * configure.ac: Changed the default homedir to .gnupg. - * README-alpha: Removed. - -2002-08-19 Werner Koch - - * acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug. - -2002-08-13 Werner Koch - - * acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New. - * configure.ac: Use them. - -2002-08-10 Werner Koch - - Released 0.3.10. - - * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support - for gettext. - -2002-07-22 Werner Koch - - * configure.ac: Check for ftello and provide a replacement. - -2002-07-01 Werner Koch - - Released 0.3.9. - - * README: Short note on how to export in pkcs-12 format. - -2002-06-29 Werner Koch - - * configure.ac: Define --with options to set the default location - of the agent, scdaemon, pinentry and dirmngr. - -2002-06-27 Werner Koch - - * README: Short blurb on how to import a PKCS-12 file. - - * configure.ac (AH_BOTTOM): New to define some constants. - -2002-06-25 Werner Koch - - Released 0.3.8. - - * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8. - -2002-06-12 Werner Koch - - * configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now. - -2002-06-04 Werner Koch - - Released 0.3.7. - -2002-05-21 Werner Koch - - * configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2. - -2002-05-14 Werner Koch - - * doc/: New - * configure.ac, Makefile.am: Added doc/ - -2002-05-03 Werner Koch - - Released 0.3.6. - -2002-04-25 Werner Koch - - * configure.ac: Check for setlocale. - -2002-04-24 Marcus Brinkmann - - * configure.ac: Check for locale.h. - -2002-04-15 Werner Koch - - Released 0.3.5. - - * NEWS: Started to describe release notes. - - * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined - -2002-04-01 Werner Koch - - Released 0.3.4. - -2002-03-18 Werner Koch - - Released 0.3.3. - -2002-03-08 Werner Koch - - * README: Add some explanation on how to specify a user ID. - -2002-03-06 Werner Koch - - Released 0.3.2. - -2002-03-04 Werner Koch - - Released 0.3.1. - - * README: Explained some options and files. - -2002-02-14 Werner Koch - - * configure.ac: Fixed status messages related to presence of Pth. - -2002-02-13 Werner Koch - - * acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New. - * configure.ac: use it. - -2002-02-12 Werner Koch - - * configure.ac: Check for PTH. Provide replacement fucntions for - apsrintf and fopencookie. - - * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. - -2002-02-07 Werner Koch - - Released 0.3.0. - - * configure.ac: Require libgcrypt 1.1.6. - -2002-02-01 Marcus Brinkmann - - * configure.ac (KSBA_CONFIG): Remove superfluous x in front of - variable. - -2002-01-26 Werner Koch - - * configure.ac: Add options to disable the build of some programs - and print a configure status at the end. - * acinclude.m4 (GNUPG_BUILD_PROGRAM): New. - - * scd/ : New. Added to Makefile and configure. - * configure.ac: Check for libopensc - * Makefile.am: Build scd only when libopensc is available - -2002-01-23 Werner Koch - - * configure.ac (mkdtemp): See whether we have to provide a - replacement. - -2001-12-18 Werner Koch - - Released 0.0.0. - -2001-12-17 Werner Koch - - * acinclude.m4: Add AM_PATH_LIBGCRYPT macro. - * configure.ac: and use it here. Figure out the location of libksba - -2001-12-15 Werner Koch - - * configure.ac (missing_dir): Bail out if asprintf and fopencookie - are not available. - -2001-12-04 Werner Koch - - * configure.ac (HAVE_JNLIB_LOGGING): always define it. - - - Copyright 2001, 2002, 2004 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 54caf7c19..000000000 --- a/INSTALL +++ /dev/null @@ -1,229 +0,0 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 8f7d1771c..000000000 --- a/Makefile.am +++ /dev/null @@ -1,64 +0,0 @@ -# Makefile.am - main makefile for NewPG/GnuPG -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -ACLOCAL_AMFLAGS = -I m4 - -EXTRA_DIST = scripts/config.rpath autogen.sh README.CVS -DISTCLEANFILES = g10defs.h - -if BUILD_GPG -gpg = g10 -else -gpg = -endif -if BUILD_GPGSM -sm = sm -else -sm = -endif -if BUILD_AGENT -agent = agent -else -agent = -endif -if BUILD_SCDAEMON -scd = scd -else -scd = -endif - -SUBDIRS = m4 intl jnlib common kbx \ - ${gpg} ${sm} ${agent} ${scd} tools po doc tests - -dist-hook: - @set -e; \ - for file in `cd $(top_srcdir); \ - find scripts include -type f -name distfiles`; do \ - dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \ - for i in distfiles `cat $(top_srcdir)/$$file` ; do \ - ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \ - || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \ - done ; \ - done - echo "$(VERSION)" > $(distdir)/VERSION - - - diff --git a/NEWS b/NEWS deleted file mode 100644 index 3d9b4ca34..000000000 --- a/NEWS +++ /dev/null @@ -1,171 +0,0 @@ -Noteworthy changes in version 1.9.10 ------------------------------------------------- - - -Noteworthy changes in version 1.9.9 (2004-06-08) ------------------------------------------------- - - * [gpg-agent] The new option --allow-mark-trusted is now required to - allow gpg-agent to add a key to the trustlist.txt after user - confirmation. - - * Creating PKCS#10 requests does now honor the key usage. - - -Noteworthy changes in version 1.9.8 (2004-04-29) ------------------------------------------------- - - * [scdaemon] Overhauled the internal CCID driver. - - * [scdaemon] Status files named ~/.gnupg/reader_.status are now - written when using the internal CCID driver. - - * [gpgsm] New commands --dump-{,secret,external}-keys to show a very - detailed view of the certificates. - - * The keybox gets now compressed after 3 hours and ephemeral - stored certificates are deleted after about a day. - - * [gpg] Usability fixes for --card-edit. Note, that this has already - been ported back to gnupg-1.3 - - -Noteworthy changes in version 1.9.7 (2004-04-06) ------------------------------------------------- - - * Instrumented the modules for gpgconf. - - * Added support for DINSIG card applications. - - * Include the smimeCapabilities attribute with signed messages. - - * Now uses the gettext domain "gnupg2" to avoid conflicts with gnupg - versions < 1.9. - - -Noteworthy changes in version 1.9.6 (2004-03-06) ------------------------------------------------- - - * Code cleanups and bug fixes. - - -Noteworthy changes in version 1.9.5 (2004-02-21) ------------------------------------------------- - - * gpg-protect-tool gets now installed into libexec as it ought to be. - Cleaned up the build system to better comply with the coding - standards. - - * [gpgsm] The --import command is now able to autodetect pkcs#12 - files and import secret and private keys from this file format. - A new command --export-secret-key-p12 is provided to allow - exporting of secret keys in PKCS\#12 format. - - * [gpgsm] The pinentry will now present a description of the key for - whom the passphrase is requested. - - * [gpgsm] New option --with-validation to check the validity of key - while listing it. - - * New option --debug-level={none,basic,advanced,expert,guru} to map - the debug flags to sensitive levels on a per program base. - - -Noteworthy changes in version 1.9.4 (2004-01-30) ------------------------------------------------- - - * Added support for the Telesec NKS 2.0 card application. - - * Added simple tool addgnupghome to create .gnupg directories from - /etc/skel/.gnupg. - - * Various minor bug fixes and cleanups; mainly gpgsm and gpg-agent - related. - - -Noteworthy changes in version 1.9.3 (2003-12-23) ------------------------------------------------- - - * New gpgsm options --{enable,disable}-ocsp to validate keys using - OCSP. This option requires a not yet released DirMngr version. - Default is disabled. - - * The --log-file option may now be used to print logs to a socket. - Prefix the socket name with "socket://" to enable this. This does - not work on all systems and falls back to stderr if there is a - problem with the socket. - - * The options --encrypt-to and --no-encrypt-to now work the same in - gpgsm as in gpg. Note, they are also used in server mode. - - * Duplicated recipients are now silently removed in gpgsm. - - -Noteworthy changes in version 1.9.2 (2003-11-17) ------------------------------------------------- - - * On card key generation is no longer done using the --gen-key - command but from the menu provided by the new --card-edit command. - - * PINs are now properly cached and there are only 2 PINs visible. - The 3rd PIN (CHV2) is internally syncronized with the regular PIN. - - * All kind of other internal stuff. - - -Noteworthy changes in version 1.9.1 (2003-09-06) ------------------------------------------------- - - * Support for OpenSC is back. scdaemon supports a --disable-opensc to - disable OpenSC use at runtime, so that PC/SC or ct-API can still be - used directly. - - * Rudimentary support for the SCR335 smartcard reader using an - internal driver. Requires current libusb from CVS. - - * Bug fixes. - - -Noteworthy changes in version 1.9.0 (2003-08-05) ------------------------------------------------- - - ====== PLEASE SEE README-alpha ======= - - * gpg has been renamed to gpg2 and gpgv to gpgv2. This is a - temporary change to allow co-existing with stable gpg versions. - - * ~/.gnupg/gpg.conf-1.9.0 is fist tried as config file before the - usual gpg.conf. - - * Removed the -k, -kv and -kvv commands. -k is now an alias to - --list-keys. New command -K as alias for --list-secret-keys. - - * Removed --run-as-shm-coprocess feature. - - * gpg does now also use libgcrypt, libgpg-error is required. - - * New gpgsm commands --call-dirmngr and --call-protect-tool. - - * Changing a passphrase is now possible using "gpgsm --passwd" - - * The content-type attribute is now recognized and created. - - * The agent does now reread certain options on receiving a HUP. - - * The pinentry is now forked for each request so that clients with - different environments are supported. When running in daemon mode - and --keep-display is not used the DISPLAY variable is ignored. - - * Merged stuff from the newpg branch and started this new - development branch. - - - Copyright 2002, 2003 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/README b/README deleted file mode 100644 index 5b4a69027..000000000 --- a/README +++ /dev/null @@ -1,511 +0,0 @@ - The GNU Privacy Guard 2 - ========================= - Version 1.9.x - - -GnuPG 1.9 is the future version of GnuPG; it is based on the gnupg-1.3 -code and the previous newpg package. It will eventually lead to a -GnuPG 2.0 release. Note that GnuPG 1.3 and 1.9 are not always in sync -and thus features and bug fixes done in 1.3 are not necessary -available in 1.9. - - -BUILD INSTRUCTIONS -================== - -GnuPG 1.9 depends on the following packages: - - libgpg-error (ftp://ftp.gnupg.org/gcrypt/alpha/libgpg-error/) - libgcrypt (ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/) - libassuan (ftp://ftp.gnupg.org/gcrypt/alpha/libassuan/) - libksba (ftp://ftp.gnupg.org/gcrypt/alpha/libksba/) - -You also need the pinentry package for most function of GnupG; however -it is not a build requirement. pinentry is available at -ftp://ftp.gnupg.org/gcrypt/pinentry/ . - -You should get the latest versions of course, the GnuPG configure -script complains if a version is not sufficient. - -After building and installing the above packages in the order as given -above, you may now continue with GnupG installation (you may also just -try to build GnuPG to see whether your already installed versions are -sufficient). - -As with all packages, you just have to do - - ./configure - make - make install - -(Before doing install you might need to become root.) - -If everything succeeds, you have a working GnuPG with support for -S/MIME and smartcards. Note that there is no binary gpg but a gpg2 so -that this package won't confict with a GnuPG 1.2 or1.3 -installation. gpg2 behaves just like gpg and it is possible to symlink -oto gpg if you want to use gpg 1.9. - -In case of problem please ask on gpa-dev@gnupg.org for advise. Note -that this release is only expected to build on GNU and *BSD systems. - -A texinfo manual named `gnupg.info' will get installed. Some commands -and options given below. See also the section `SMARTCARD INTRO'. - - -COMMANDS -======== - -gpgsm: ------- - ---learn-card - - Read information about the private keys from the smartcard and - import the certificates from there. - ---export - - Export all certificates stored in the Keybox or those specified on - the command line. When using --armor a few informational lines are - prepended before each block. - - -gpg2: ------ - ---card-status - - Show information pertaining smartcards implementing the OpenPGP - application. - ---change-pin - - Offers a menu to change the PIN of OpenPGP smartcards and to reset - the retry counters. - ---card-edit - - Offers a menu to change any data object on the card and to generate - the keys. - - -OPTIONS -======= - -gpgsm: ------- - ---include-certs - - Using N of -2 includes all certificate except for the Root cert, - -1 includes all certs, 0 does not include any certs, 1 includes only - the signers cert (this is the default) and all other positives - values include up to N certs starting with the signer cert. - ---policy-file - - Chnage the deault name of the policy file - ---enable-policy-checks ---disable-policy-checks - - By default policy checks are enabled. These options may be used to - change it. - ---enable-crl-checks ---disable-crl-checks - - By default the CRL checks are enabled and the DirMngr is used to - check for revoked certificates. The disable option is most useful - with a off-line connection to suppres this check. - ---agent-program - - Specify an agent program to be used for secret key operations. The - default value is "../agent/gpg-agent". This is only used as a - fallback when the envrionment varaibale GPG_AGENT_INFO is not set or - a running agent can't be connected. - ---dirmngr-program - - Specify a dirmngr program to be used for CRL checks. The default - value is "/usr/sbin/dirmngr". This is only used as a fallback when - the environment varaibale DIRMNGR_INFO is not set or a running - dirmngr can't be connected. - ---no-secmem-warning - - Don't print the warning "no secure memory" - ---armor - - Create PEM ecoded output. Default is binary output. - ---base64 - - Create Base-64 encoded output; i.e. PEM without the header lines. - ---assume-armor - - Assume the input data is PEM encoded. Default is to autodetect the - encoding but this is may fail. - ---assume-base64 - - Assume the input data is plain base-64 encoded. - ---assume-binary - - Assume the input data is binary encoded. - ---server - - Run in server mode. This is used by GPGME to control gpgsm. See - the assuan specification regarding gpgsm about the used protocol. - Some options are ignored in server mode. - ---local-user - - Set the user to be used for signing. The default is the first - secret key found in the database. - ---with-key-data - - Displays extra information with the --list-keys commands. Especially - a line tagged "grp" is printed which tells you the keygrip of a - key. This is string is for example used as the filename of the - secret key. - - - -gpg-agent: ---------- - ---pinentry-program - - Specify the PINentry program. The default value is - "/bin/pinentry" so you most likely want to specify it. - ---no-grab - - Tell the pinentry not to grab keybourd and mouse. You most likely - want to give this option during testing and development to avoid - lockups in case of bugs. - - -scdaemon: --------- - ---ctapi-driver - - The default for Scdaemon is to use the PC/SC API currently provided - by libpcsclite.so. As an alternative the ctAPI can be used by - specify this option with the appropriate driver name - (e.g. libtowitoko.so). - ---reader-port - - This specifies the port of the chipcard reader. For PC/SC this is - currently ignored and the first PC/SC reader is used. For the - ctAPI, a number must be specified (the default is 32768 for the - first USB port). - ---disable-ccid - - Disable the integrated support for CCID compliant readers. This - allows to fall back to one of the other drivers even if the internal - CCID driver can handle the reader. Note, that CCID support is only - available if libusb was available at build time. - - -FILES -===== - -The default home directory is ~/.gnupg. It can be changed by -either the --homedir option or by seting the environment variable -GNUPGHOME. This is a list of files usually found in this directory: - -gpgsm.conf - - Options for gpgsm. Options are the same as the command line - options but don't enter the leading dashes and give arguments - without an equal sign. Blank lines and lines starting with a - hash mark as the first non whitye space character are ignored. - -gpg-agent.conf - - Options for gpg-agent - -scdaemon.conf - - Options for scdaemon. - -dirmngr.conf - - Options for the DirMngr which is not part of this package and - the option file wilol most likely be moved to /etc - -gpg.conf - - Options for gpg. Note that old versions of gpg use the - filename `options' instead of `gpg.conf'. - -gpg.conf-1.9.x - - Options for gpg; tried before gpg.conf - - -policies.txt - - A list of allowed CA policies. This file should give the - object identifiers of the policies line by line. Empty lines - and lines startung with a hash mark are ignored. - - ++++++++++ - 2.289.9.9 - ++++++++++ - -trustlist.txt - - A list of trusted certificates usually maintained by - gpg-agent. It can however be edited manually. The file will - be created automagically with some explaining comments. - -random_seed - - Used internally for keeping the state of the RNG over - invocations. - -pubring.kbx - - The database file with the certificates. - -pubring.gpg - - The database file with the OpenPGP public keys. This will - eventually be merged with pubring.kbx - -secring.gpg - - The database file with the OpenPGP secret keys. This will be - removed when gpg is changed to make use of the gpg-agent. - - -private-keys-v1.d/ - - Directory holding the private keys maintained by gpg-agent. - For detailed info see agent/keyformat.txt. Note that there is - a helper tool gpg-protect-tool which may be used to protect or - unprotect keys. This is however nothing a user should care - about. - - -SOURCE FILES -============ - -Here is a list of directories with source files: - -jnlib/ utility functions -kbx/ keybox library -g10/ the gpg program here called gpg2 -sm/ the gpgsm program -agent/ the gpg-agent -scd/ the smartcard daemon -doc/ documentation - - - -HOW TO SPECIFY A USER ID -======================== - -Due to the way X.509 certificates are made up we need a few new ways -to specify a certificate (aka key in OpenPGP). In addition to the -ways a user ID can be specified with gpg, I have implemented 3 new -modes for gpgsm, here is the entire list of ways to specify a key: - - * By keyID. - - This format is deducded from the length of the string and its - content or "0x" prefix. For use with OpenPGP a exclamation mark may - be appended to force use of the specified (sub)key. - - As with v34 OpenPGP keys, the keyID of an X509 certificate are the - low 64 bits of the SHA-1 fingerprint. The use of keyIDs is just a - shortcut, for all automated processing the fingerprint should be - used. - - Examples: - - 234567C4 - 0F34E556E - 01347A56A - 0xAB123456 - - 234AABBCC34567C4 - 0F323456784E56EAB - 01AB3FED1347A5612 - 0x234AABBCC34567C4 - - * By fingerprint - - This is format is deduced from the length of the string and its - content or "0x" prefix. Note, that only the 20 byte fingerprint is - used with GPGSM (SHA-1 hash of the certificate). For use with - OpenPGP a exclamation mark may be appended to force use of the - specified (sub)key. - - Examples: - - 1234343434343434C434343434343434 - 123434343434343C3434343434343734349A3434 - 0E12343434343434343434EAB3484343434343434 - 0xE12343434343434343434EAB3484343434343434 - - * Exact match on OpenPGP user ID - - This is denoted by a leading equal sign. It does not make much - sense for X.509. - - Example: - - =Heinrich Heine - - * Exact match on an email address. - - This is indicated by enclosing the email address in the usual way - with left and right angles - - Example: - - - - * Word match - - All words must match exactly (not case sensitive) but can appear in - any order in the user ID or a subjects name. Words are any - sequences of letters, digits, the underscore and all characters - with bit 7 set. - - Example: - - +Heinrich Heine duesseldorf - - * [NEW] Exact match by subject's DN - - This is indicated by a leading slash, directly followed by the - rfc2253 encoded DN of the subject. Note that you can't use the - string printed by "gpgsm --list-keys" because that one as been - reordered and modified for better readability; use --with-colons to - print the raw (but standard escaped) rfc2253 string - - Example: - - /CN=Heinrich Heine,O=Poets,L=Paris,C=FR - - * [NEW] Excact match by issuer's DN - - This is indicated by a leading hash mark, directly followed by a - slash and then directly followed by the rfc2253 encoded DN of the - issuer. This should return the Root cert of the issuer. See note - above. - - Example: - - #/CN=Root Cert,O=Poets,L=Paris,C=FR - - * [NEW] Exact match by serial number and subject's DN - - This is indicated by a hash mark, followed by the hexadecmal - representation of the serial number, the followed by a slahs and - the RFC2253 encoded DN of the issuer. See note above. - - Example: - - #4F03/CN=Root Cert,O=Poets,L=Paris,C=FR - - * Substring match - - By case insensitive substring matching. This is the default mode - but applications may want to explicitly indicate this by putting - the asterisk in front. - - Example: - - Heine - *Heine - - -Please note that we have reused the hash mark indentifier which was -used in old GnuPG versions to indicate the so called local-id. It is -not anymore used and there should be no conflict when used with X.509 -stuff. - -Using the rfc2253 format of DNs has the drawback that it is not -possible to map them back to the original encoding, however we don't -have to do this, because our key database stores this encoding as meta -data. - -Some of the search modes are not yet implemented ;-) - - -HOW TO IMPORT A PRIVATE KEY -=========================== -There is some limited support to import a private key from a PKCS-12 -file. - - gpgsm --import foo.p12 - -This require that the gpg-agent is running. - - -HOW TO EXPORT A PRIVATE KEY -=========================== -There is also limited support to export a private key in PKCS-12 -format. However the certificate is not stored and there is no MAC applied. - - gpgsm --call-protect-tool --p12-export foo.key >foo.p12 - - -SMARTCARD INTRO -=============== - -GPG, the OpenPGP part of GnuPG, supports the OpenPGP smartcard -(surprise!); see http://g10code.com/p-card.html. - -[Fixme: We need to explain this further] - - -GPGSM, the CMS (S/MIME) part of GnuPG, supports two kinds of -smartcards. The most flexible way is to use PKCS#15 compliant cards, -however you must have build GnuPG with support for the OpenSC library. -The build process automagically detects the presence of this library -and will include support for these cards. - -The other card we currently support is the Telesec NetKey card with -the NKS 2.0 card application. - -Before GPGSM can make use of a new card it must gather some -information, like the card's serial number, the public keys and the -certificates stored on the card. Thus for a new card you need to run -the command - - gpgsm --learn-card - -once. This is also a good test to see whether your card reader is -properly installed. See below in case of error. Once this has been -done you may use the keys stored on the card in the same way you use -keys stored on the disk. gpgsm automagically knows whether a card is -required and will pop up the pinentry to ask you to insert the -correct card. - -For selecting the driver, see the options of scdaemon. A useful -debugging flag is "--debug 2048" showing the communication between -scdaemon and the reader. - -[fixme: write more stuff] - - - - - diff --git a/README.CVS b/README.CVS deleted file mode 100644 index ae17923bd..000000000 --- a/README.CVS +++ /dev/null @@ -1,51 +0,0 @@ -If you are building from CVS, run the script - -./autogen.sh - -first, to make sure that you have all the necessary maintainer tools -are installed and to build the actual configuration files. Then run - -./configure --enable-maintainer-mode - -followed by the usual make. - -If autogen.sh complains about insufficient versions of the required -tools, or the tools are not installed, you may use environment -variables to override the default tool names: - - AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake - package. For example - AUTOMAKE_SUFFIX="-1.7" ./autogen.sh - uses "automake-1.7" and "aclocal-1.7. - AUTOMAKE_PREFIX is used as a prefix for all tools from the automake - page and may be combined with AUTOMAKE_SUFFIX. e.g.: - AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh - uses "automake" and "aclocal" in the /usr/foo/bin - directory. - AUTOCONF_SUFFIX is used as a suffix for all tools from the automake - package - AUTOCONF_PREFIX is used as a prefix for all tools from the automake - package - GETTEXT_SUFFIX is used as a suffix for all tools from the gettext - package - GETTEXT_PREFIX is used as a prefix for all tools from the gettext - package - -It is also possible to use the variable name AUTOMAKE, AUTOCONF, -ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name -of the programs to run. It is however better to use the suffix and -prefix forms as described above because that does not require -knowledge about the actual tools used by autgen.sh. - - -Please don't use autopoint, libtoolize or autoreconf unless you are -the current maintainer and want to update the standard configuration -files. All those files should be in the CVS and only updated manually -if the maintainer decides that newer versions are required. The -maintainer should also make sure that the required version of automake -et al. are properly indicated at the top of configure.ac and take care -to copy the files and not merely use symlinks. - - - - diff --git a/THANKS b/THANKS deleted file mode 100644 index 3f56e29d3..000000000 --- a/THANKS +++ /dev/null @@ -1,5 +0,0 @@ - - -Richard Lefebvre rick at CERCA.UMontreal.CA -Andrew J. Schorr aschorr at telemetry-investments.com -Michael Nottebrock michaelnottebrock at gmx.net diff --git a/TODO b/TODO deleted file mode 100644 index f22a19b41..000000000 --- a/TODO +++ /dev/null @@ -1,78 +0,0 @@ - -*- outline -*- - -* src/base64 -** Make parsing more robust -Currently we don't cope with overlong lines in the best way. - -* sm/call-agent.c -** The protocol uses an incomplete S-expression -We should always use valid S-Exp and not just parts. -** Some code should go into import.c -** When we allow concurrent service request in gpgsm, we -might want to have an agent context for each service request -(i.e. Assuan context). - -* sm/certreqgen.c -** Improve error reporting -** Do some basic checks on the supplied DNs - -* sm/certchain.c -** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent. -** figure out how to auto retrieve a key by serialno+issuer. - Dirmngr is currently not able to parse more than the CN. - -* sm/decrypt.c -** replace leading zero in integer hack by a cleaner solution - -* sm/gpgsm.c -** Support --output for all commands -** mark all unimplemented commands and options. -** Print a hint when MD2 is the cause for a problem. -** Implement --default-key -** Using --export-secret-key-p12 with a non-pth agent - This leads to a lockup because gpgsm is still accessing the agent - while gpg-protect-tool wants to pop up the pinentry. Solution is - to release the connection. This is not trivial, thus we are going - to do that while changing gpgsm to allow concurrent operations. - -* sm/keydb.c -** Check file permissions -** Check that all error code mapping is done. -** Remove the inter-module dependencies between gpgsm and keybox -** Add an source_of_key field - -* agent/gpg-agent.c -** A SIGHUP should also restart the scdaemon - But do this only after all connections terminated. - As of now we only send a RESET. - -* agent/command.c -** Make sure that secure memory is used where appropriate - -* agent/pkdecrypt.c, agent/pksign.c -** Don't use stdio to return results. - -* agent/divert-scd.c - Remove the agent_reset_scd kludge. - -* Move pkcs-1 encoding into libgcrypt. - -* Use a MAC to protect some files. - -* sm/export.c -** Return an error code or a status info per user ID. - -* Where is http.c, regcomp.c, srv.c, w32reg.c ? - -* scd/sc-investigate -** Enhance with card compatibility check - -* tests -** Makefile.am - We use printf(1) to setup the library path, this is not portable. - Furthermore LD_LIBRARY_PATH is not used on all systems. It doesn't - matter for now, because we use some GNU/*BSDish features anyway. - -** Add a test to check the extkeyusage. - - diff --git a/acinclude.m4 b/acinclude.m4 deleted file mode 100644 index f6bbae78e..000000000 --- a/acinclude.m4 +++ /dev/null @@ -1,436 +0,0 @@ -dnl macros to configure gnupg -dnl Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. -dnl -dnl This file is part of GnuPG. -dnl -dnl GnuPG is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl GnuPG is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME) -dnl Check whether a typedef exists and create a #define $2 if it exists -dnl -AC_DEFUN(GNUPG_CHECK_TYPEDEF, - [ AC_MSG_CHECKING(for $1 typedef) - AC_CACHE_VAL(gnupg_cv_typedef_$1, - [AC_TRY_COMPILE([#define _GNU_SOURCE 1 - #include - #include ], [ - #undef $1 - int a = sizeof($1); - ], gnupg_cv_typedef_$1=yes, gnupg_cv_typedef_$1=no )]) - AC_MSG_RESULT($gnupg_cv_typedef_$1) - if test "$gnupg_cv_typedef_$1" = yes; then - AC_DEFINE($2,1,[Defined if a `]$1[' is typedef'd]) - fi - ]) - - -dnl GNUPG_CHECK_GNUMAKE -dnl -AC_DEFUN(GNUPG_CHECK_GNUMAKE, - [ - if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then - : - else - AC_MSG_WARN([[ -*** -*** It seems that you are not using GNU make. Some make tools have serious -*** flaws and you may not be able to build this software at all. Before you -*** complain, please try GNU make: GNU make is easy to build and available -*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make. -***]]) - fi - ]) - -dnl GNUPG_CHECK_FAQPROG -dnl -AC_DEFUN(GNUPG_CHECK_FAQPROG, - [ AC_MSG_CHECKING(for faqprog.pl) - if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then - working_faqprog=yes - FAQPROG="faqprog.pl" - else - working_faqprog=no - FAQPROG=": " - fi - AC_MSG_RESULT($working_faqprog) - AC_SUBST(FAQPROG) - AM_CONDITIONAL(WORKING_FAQPROG, test "$working_faqprog" = "yes" ) - -dnl if test $working_faqprog = no; then -dnl AC_MSG_WARN([[ -dnl *** -dnl *** It seems that the faqprog.pl program is not installed; -dnl *** however it is only needed if you want to change the FAQ. -dnl *** (faqprog.pl should be available at: -dnl *** ftp://ftp.gnupg.org/gcrypt/contrib/faqprog.pl ) -dnl *** No need to worry about this warning. -dnl ***]]) -dnl fi - ]) - -dnl GNUPG_CHECK_DOCBOOK_TO_TEXI -dnl -AC_DEFUN(GNUPG_CHECK_DOCBOOK_TO_TEXI, - [ - AC_CHECK_PROG(DOCBOOK_TO_TEXI, docbook2texi, yes, no) - AC_MSG_CHECKING(for sgml to texi tools) - working_sgmltotexi=no - if test "$ac_cv_prog_DOCBOOK_TO_TEXI" = yes; then - if sgml2xml -v /dev/null 2>&1 | grep 'SP version' >/dev/null 2>&1 ; then - working_sgmltotexi=yes - fi - fi - AC_MSG_RESULT($working_sgmltotexi) - AM_CONDITIONAL(HAVE_DOCBOOK_TO_TEXI, test "$working_sgmltotexi" = "yes" ) - ]) - - - -dnl GNUPG_CHECK_ENDIAN -dnl define either LITTLE_ENDIAN_HOST or BIG_ENDIAN_HOST -dnl -define(GNUPG_CHECK_ENDIAN, - [ - tmp_assumed_endian=big - if test "$cross_compiling" = yes; then - case "$host_cpu" in - i@<:@345678@:>@* ) - tmp_assumed_endian=little - ;; - *) - ;; - esac - AC_MSG_WARN(cross compiling; assuming $tmp_assumed_endian endianess) - fi - AC_MSG_CHECKING(endianess) - AC_CACHE_VAL(gnupg_cv_c_endian, - [ gnupg_cv_c_endian=unknown - # See if sys/param.h defines the BYTE_ORDER macro. - AC_TRY_COMPILE([#include - #include ], [ - #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros - #endif], [# It does; now see whether it defined to BIG_ENDIAN or not. - AC_TRY_COMPILE([#include - #include ], [ - #if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif], gnupg_cv_c_endian=big, gnupg_cv_c_endian=little)]) - if test "$gnupg_cv_c_endian" = unknown; then - AC_TRY_RUN([main () { - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long l; - char c[sizeof (long)]; - } u; - u.l = 1; - exit (u.c[sizeof (long) - 1] == 1); - }], - gnupg_cv_c_endian=little, - gnupg_cv_c_endian=big, - gnupg_cv_c_endian=$tmp_assumed_endian - ) - fi - ]) - AC_MSG_RESULT([$gnupg_cv_c_endian]) - if test "$gnupg_cv_c_endian" = little; then - AC_DEFINE(LITTLE_ENDIAN_HOST,1, - [Defined if the host has little endian byte ordering]) - else - AC_DEFINE(BIG_ENDIAN_HOST,1, - [Defined if the host has big endian byte ordering]) - fi - ]) - - - -# Check for the getsockopt SO_PEERCRED -AC_DEFUN(GNUPG_SYS_SO_PEERCRED, - [ AC_MSG_CHECKING(for SO_PEERCRED) - AC_CACHE_VAL(gnupg_cv_sys_so_peercred, - [AC_TRY_COMPILE([#include ], - [struct ucred cr; - int cl = sizeof cr; - getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);], - gnupg_cv_sys_so_peercred=yes, - gnupg_cv_sys_so_peercred=no) - ]) - AC_MSG_RESULT($gnupg_cv_sys_so_peercred) - if test $gnupg_cv_sys_so_peercred = yes; then - AC_DEFINE(HAVE_SO_PEERCRED, 1, - [Defined if SO_PEERCRED is supported (Linux)]) - fi - ]) - - - -# GNUPG_BUILD_PROGRAM(NAME,DEFAULT) -# Add a --enable-NAME option to configure an set the -# shell variable build_NAME either to "yes" or "no". DEFAULT must -# either be "yes" or "no" and decided on the default value for -# build_NAME and whether --enable-NAME or --disable-NAME is shown with -# ./configure --help -AC_DEFUN(GNUPG_BUILD_PROGRAM, - [build_$1=$2 - m4_if([$2],[yes],[ - AC_ARG_ENABLE([$1], AC_HELP_STRING([--disable-$1], - [do not build the $1 program]), - build_$1=$enableval, build_$1=$2) - ],[ - AC_ARG_ENABLE([$1], AC_HELP_STRING([--enable-$1], - [build the $1 program]), - build_$1=$enableval, build_$1=$2) - ]) - case "$build_$1" in - no|yes) - ;; - *) - AC_MSG_ERROR([only yes or no allowed for feature --enable-$1]) - ;; - esac - ]) - - - -# GNUPG_PTH_VERSION_CHECK(REQUIRED) -# -# If the version is sufficient, HAVE_PTH will be set to yes. -# -# Taken form the m4 macros which come with Pth -AC_DEFUN(GNUPG_PTH_VERSION_CHECK, - [ - _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'` - _req_version="ifelse([$1],,1.2.0,$1)" - for _var in _pth_version _req_version; do - eval "_val=\"\$${_var}\"" - _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'` - _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'` - _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'` - _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'` - case $_rtype in - "a" ) _rtype=0 ;; - "b" ) _rtype=1 ;; - "." ) _rtype=2 ;; - esac - _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \ - "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"` - eval "${_var}_hex=\"\$_hex\"" - done - have_pth=no - if test ".$_pth_version_hex" != .; then - if test ".$_req_version_hex" != .; then - if test $_pth_version_hex -ge $_req_version_hex; then - have_pth=yes - fi - fi - fi - if test $have_pth = no; then - AC_MSG_WARN([[ -*** -*** Found Pth version $_pth_version, but require at least -*** version $_req_version. Please upgrade Pth first. -***]]) - fi - ]) - - -# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock -# is not called from uid 0 (not tested whether uid 0 works) -# For DECs Tru64 we have also to check whether mlock is in librt -# mlock is there a macro using memlk() -dnl GNUPG_CHECK_MLOCK -dnl -define(GNUPG_CHECK_MLOCK, - [ AC_CHECK_FUNCS(mlock) - if test "$ac_cv_func_mlock" = "no"; then - AC_CHECK_HEADERS(sys/mman.h) - if test "$ac_cv_header_sys_mman_h" = "yes"; then - # Add librt to LIBS: - AC_CHECK_LIB(rt, memlk) - AC_CACHE_CHECK([whether mlock is in sys/mman.h], - gnupg_cv_mlock_is_in_sys_mman, - [AC_TRY_LINK([ - #include - #ifdef HAVE_SYS_MMAN_H - #include - #endif - ], [ - int i; - - /* glibc defines this for functions which it implements - * to always fail with ENOSYS. Some functions are actually - * named something starting with __ and the normal name - * is an alias. */ - #if defined (__stub_mlock) || defined (__stub___mlock) - choke me - #else - mlock(&i, 4); - #endif - ; return 0; - ], - gnupg_cv_mlock_is_in_sys_mman=yes, - gnupg_cv_mlock_is_in_sys_mman=no)]) - if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then - AC_DEFINE(HAVE_MLOCK,1, - [Defined if the system supports an mlock() call]) - fi - fi - fi - if test "$ac_cv_func_mlock" = "yes"; then - AC_MSG_CHECKING(whether mlock is broken) - AC_CACHE_VAL(gnupg_cv_have_broken_mlock, - AC_TRY_RUN([ - #include - #include - #include - #include - #include - #include - - int main() - { - char *pool; - int err; - long int pgsize = getpagesize(); - - pool = malloc( 4096 + pgsize ); - if( !pool ) - return 2; - pool += (pgsize - ((long int)pool % pgsize)); - - err = mlock( pool, 4096 ); - if( !err || errno == EPERM ) - return 0; /* okay */ - - return 1; /* hmmm */ - } - - ], - gnupg_cv_have_broken_mlock="no", - gnupg_cv_have_broken_mlock="yes", - gnupg_cv_have_broken_mlock="assume-no" - ) - ) - if test "$gnupg_cv_have_broken_mlock" = "yes"; then - AC_DEFINE(HAVE_BROKEN_MLOCK,1, - [Defined if the mlock() call does not work]) - AC_MSG_RESULT(yes) - AC_CHECK_FUNCS(plock) - else - if test "$gnupg_cv_have_broken_mlock" = "no"; then - AC_MSG_RESULT(no) - else - AC_MSG_RESULT(assuming no) - fi - fi - fi - ]) - - -dnl Stolen from gcc -dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead -dnl of the usual 2. -AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG, -[AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h) -AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg, -[AC_TRY_COMPILE([ -#include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_DIRECT_H -# include -#endif], [mkdir ("foo", 0);], - gnupg_cv_mkdir_takes_one_arg=no, gnupg_cv_mkdir_takes_one_arg=yes)]) -if test $gnupg_cv_mkdir_takes_one_arg = yes ; then - AC_DEFINE(MKDIR_TAKES_ONE_ARG,1, - [Defined if mkdir() does not take permission flags]) -fi -]) - - - - -dnl AM_PATH_OPENSC([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for OpenSC and define OPENSC_CFLAGS and OPENSC_LIBS -dnl -AC_DEFUN(AM_PATH_OPENSC, -[ AC_ARG_WITH(opensc-prefix, - AC_HELP_STRING([--with-opensc-prefix=PFX], - [prefix where OpenSC is installed (optional)]), - opensc_config_prefix="$withval", opensc_config_prefix="") - if test x$opensc_config_prefix != x ; then - opensc_config_args="$opensc_config_args --prefix=$opensc_config_prefix" - if test x${OPENSC_CONFIG+set} != xset ; then - OPENSC_CONFIG=$opensc_config_prefix/bin/opensc-config - fi - fi - - AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) - min_opensc_version=ifelse([$1], ,0.7.0,$1) - AC_MSG_CHECKING(for OpenSC - version >= $min_opensc_version) - ok=no - if test "$OPENSC_CONFIG" != "no" ; then - req_major=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_opensc_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - opensc_config_version=`$OPENSC_CONFIG $opensc_config_args --version 2>/dev/null || echo 0.0.0` - major=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $opensc_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - OPENSC_CFLAGS=`$OPENSC_CONFIG $opensc_config_args --cflags` - OPENSC_LIBS=`$OPENSC_CONFIG $opensc_config_args --libs` - OPENSC_LIBS="$OPENSC_LIBS -lpcsclite -lpthread" - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - OPENSC_CFLAGS="" - OPENSC_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(OPENSC_CFLAGS) - AC_SUBST(OPENSC_LIBS) -]) - - diff --git a/am/cmacros.am b/am/cmacros.am deleted file mode 100644 index 0f7a09fe0..000000000 --- a/am/cmacros.am +++ /dev/null @@ -1,45 +0,0 @@ -# cmacros.am - C macro definitions -# Copyright (C) 2004 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -localedir = $(datadir)/locale - -AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\" - -if ! HAVE_DOSISH_SYSTEM -AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \ - -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ - -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ - -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" -endif - -if GNUPG_AGENT_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" -endif -if GNUPG_PINENTRY_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" -endif -if GNUPG_SCDAEMON_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" -endif -if GNUPG_DIRMNGR_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" -endif -if GNUPG_PROTECT_TOOL_PGM -AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" -endif diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index a607d63da..000000000 --- a/autogen.sh +++ /dev/null @@ -1,161 +0,0 @@ -#! /bin/sh -# Run this to generate all the initial makefiles, etc. -# -# Copyright (C) 2003 g10 Code GmbH -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -configure_ac="configure.ac" - -cvtver () { - awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}' -} - -check_version () { - if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then - return 0 - fi - echo "**Error**: "\`$1\'" not installed or too old." >&2 - echo ' Version '$3' or newer is required.' >&2 - [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2 - DIE="yes" - return 1 -} - -# Allow to override the default tool names -AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} -AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} - -AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} -ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} - -GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} -MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} - -DIE=no - -if [ "$1" = "--build-w32" ]; then - shift - target=i386--mingw32 - if [ ! -f ./config.guess ]; then - echo "./config.guess not found" >&2 - exit 1 - fi - host=`./config.guess` - - if ! mingw32 --version >/dev/null; then - echo "We need at least version 0.3 of MingW32/CPD" >&2 - exit 1 - fi - - if [ -f config.h ]; then - if grep HAVE_DOSISH_SYSTEM config.h | grep undef >/dev/null; then - echo "Pease run a 'make distclean' first" >&2 - exit 1 - fi - fi - - crossinstalldir=`mingw32 --install-dir` - crossbindir=`mingw32 --get-bindir 2>/dev/null` \ - || crossbindir="$crossinstalldir/bin" - crossdatadir=`mingw32 --get-datadir 2>/dev/null` \ - || crossdatadir="$crossinstalldir/share" - crosslibdir=`mingw32 --get-libdir 2>/dev/null` \ - || crosslibdir="$crossinstalldir/i386--mingw32/lib" - crossincdir=`mingw32 --get-includedir 2>/dev/null` \ - || crossincdir="$crossinstalldir/i386--mingw32/include" - CC=`mingw32 --get-path gcc` - CPP=`mingw32 --get-path cpp` - AR=`mingw32 --get-path ar` - RANLIB=`mingw32 --get-path ranlib` - export CC CPP AR RANLIB - - disable_foo_tests="" - if [ -n "$lib_config_files" ]; then - for i in $lib_config_files; do - j=`echo $i | tr '[a-z-]' '[A-Z_]'` - eval "$j=${crossbindir}/$i" - export $j - disable_foo_tests="$disable_foo_tests --disable-`echo $i| \ - sed 's,-config$,,'`-test" - if [ ! -f "${crossbindir}/$i" ]; then - echo "$i not installed for MingW32" >&2 - DIE=yes - fi - done - fi - [ $DIE = yes ] && exit 1 - - ./configure --host=${host} --target=${target} ${disable_foo_tests} \ - --bindir=${crossbindir} --libdir=${crosslibdir} \ - --datadir=${crossdatadir} --includedir=${crossincdir} \ - --enable-maintainer-mode $* - exit $? -fi - - - -# Grep the required versions from configure.ac -autoconf_vers=`sed -n '/^AC_PREREQ(/ { -s/^.*(\(.*\))/\1/p -q -}' ${configure_ac}` -autoconf_vers_num=`echo "$autoconf_vers" | cvtver` - -automake_vers=`sed -n '/^min_automake_version=/ { -s/^.*="\(.*\)"/\1/p -q -}' ${configure_ac}` -automake_vers_num=`echo "$automake_vers" | cvtver` - -gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ { -s/^.*(\(.*\))/\1/p -q -}' ${configure_ac}` -gettext_vers_num=`echo "$gettext_vers" | cvtver` - - -if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ] -then - echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2 - exit 1 -fi - - -if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then - check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf -fi -if check_version $AUTOMAKE $automake_vers_num $automake_vers; then - check_version $ACLOCAL $automake_vers_num $autoconf_vers automake -fi -if check_version $GETTEXT $gettext_vers_num $gettext_vers; then - check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext -fi - -if test "$DIE" = "yes"; then - cat < - - * xreadline.c: New. Based on the iobuf_read_line function. - -2004-05-12 Werner Koch - - * util.h (xtrycalloc_secure,xtrymalloc_secure): New. - -2004-05-11 Werner Koch - - * sysutils.c (disable_core_dumps): Only set the current limit. - (enable_core_dumps): New. - -2004-04-13 Werner Koch - - * simple-pwquery.c (copy_and_escape): Relaxed quoting. - -2004-04-05 Werner Koch - - * errors.h (STATUS_NEWSIG): New. - -2004-03-11 Werner Koch - - * dynload.h [__MINGW32__]: Define RTLD_LAZY. - -2004-03-09 Werner Koch - - * maperror.c (map_assuan_err): Map the Locale_Problem item. - -2004-03-03 Werner Koch - - * asshelp.c, asshelp.h: New. - (send_pinentry_environment): New. Code taken from ../sm/call-agent.c. - -2004-02-19 Werner Koch - - * simple-pwquery.c (agent_open): Don't mangle INFOSTR. - -2004-02-17 Werner Koch - - * simple-pwquery.c (agent_open): Ignore an empty GPG_AGENT_INFO. - - * errors.h: Added STATUS_IMPORT_OK. - -2004-02-10 Werner Koch - - * b64enc.c: New. Based on code from ../sm/base64.c. - -2004-01-30 Marcus Brinkmann - - * Makefile.am (libcommon_a_SOURCES): Add xasprintf.c. - * miscellaneous.c (xasprintf): Moved to ... - * xasprintf (xasprintf): ... here. New file. - This allows to use xasprintf without sucking in gpg-error. - -2004-01-27 Werner Koch - - * sexp-parse.h: New; moved from../agent. - - * util.h (xtoi_4): New. - -2003-12-23 Werner Koch - - * maperror.c (map_assuan_err): Prepared for a new error code. - -2003-12-17 Werner Koch - - * gettime.c (asctimestamp): Add a note on a non-avoidable gcc warning. - - * util.h [!HAVE_VASPRINTF]: Add printf format attribute to the - replacement function. - - * miscellaneous.c (xasprintf): New. - -2003-11-14 Werner Koch - - * mkdtemp.c (mkdtemp): Use gcry_create_nonce. - - * cryptmiss.c: Removed. - -2003-11-13 Werner Koch - - * util.h (vasprintf): Also fixed the prototype. - - * vasprintf.c (vasprintf): ARGS should not be a pointer. Fixed - segv on Solaris. Reported by Andrew J. Schorr. - -2003-11-12 Werner Koch - - * maperror.c (map_ksba_err, map_gcry_err, map_kbx_err): Removed. - -2003-10-31 Werner Koch - - * util.h (gnupg_isotime_t): New. - (gnupg_copy_time): New. - - * gettime.c (gnupg_get_isotime): New. - -2003-09-23 Werner Koch - - * iobuf.c (check_special_filename): Replaced is isdigit by digitp - to avoid passing negative values and potential locale problems. - Problem noted by Christian Biere. - - * util.h (ascii_isspace): New. - -2003-09-18 Werner Koch - - * ttyio.c (tty_fprintf): New. - (tty_print_string, tty_print_utf8_string2) - (tty_print_utf8_string): Made P argument const byte*. - -2003-08-20 Marcus Brinkmann - - * maperror.c (map_ksba_err): Map -1. Use gpg_err_make to set - the error source. - -2003-08-14 Timo Schulz - - * dynload.h. New. W32 wrapper around the dynload mechanism. - -2003-07-15 Werner Koch - - * simple-pwquery.c, simple-pwquery.h: New; moved from ../agent. - * Makefile.am (libsimple_pwquery_a_LIBADD): New. - -2003-06-25 Werner Koch - - * maperror.c (map_to_assuan_status): Directly map 0 to 0. - -2003-06-17 Werner Koch - - * gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue) - (strtimestamp,asctimestamp): New. Code taken from gnupg 1.3.2 - mischelp.c. - - * yesno.c: New. Code taken from gnupg 1.3.2 mischelp.c - - * miscellaneous.c: New. - - * util.h: Include utf8conf.h - -2003-06-16 Werner Koch - - * gettime.c (make_timestamp): New. - - * ttyio.c: New. Taken from gnupg 1.2. - * ttyio.h: Move from ../include. - -2003-06-13 Werner Koch - - * util.h (seterr): Removed macro. - (xmalloc_secure,xcalloc_secure): New. - -2003-06-11 Werner Koch - - * iobuf.c (iobuf_writebyte,iobuf_write): Return error code from - iobuf_flush. - (iobuf_writestr): Ditto. - -2003-06-10 Werner Koch - - * iobuf.c, iobuf.h: New. Taken from current gnupg 1.3 CVS. Run - indent on it and adjusted error handling to libgpg-error style. - Replaced IOBUF by iobuf_t. Renamed malloc functions. - -2003-06-04 Werner Koch - - * errors.h: Removed all error codes. We keep the status codes for - now. - * Makefile.am: Do not create errors.c anymore; remove it from the - sources. - - * maperror.c: Don't include error.h. Change all error codes to - libgpg-error style. - (map_assuan_err): Changed to new Assuan error code convention. - (map_to_assuan_status): Likewise. - (map_gcry_err,map_kbx_err): Not needed. For now dummy functions. - - * membuf.c, membuf.h: New. Code taken from ../sm/call-agent.h. - * Makefile.am: Added above. - -2003-04-29 Werner Koch - - * util.h (fopencokokie): Removed prototype and struct. - - * fopencookie.c: Removed. - - * maperror.c: Use system assuan.h - -2002-10-31 Neal H. Walfield - - * isascii.c: New file. - * putc_unlocked.c: Likewise. - -2002-10-28 Neal H. Walfield - - * signal.c (caught_fatal_sig): Remove superfluous zero - initializer. - (caught_sigusr1): Likewise. - -2002-09-04 Neal H. Walfield - - * vasprintf.c (vasprintf) [va_copy]: Use va_copy. - [!va_copy && __va_copy]: Use __va_copy. - [!va_copy && !__va_copy]: Only now fall back to using memcpy. - -2002-08-21 Werner Koch - - * errors.h: Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch - - * vasprintf.c: Hack to handle NULL for %s. - -2002-08-09 Werner Koch - - * signal.c: New. Taken from GnuPG 1.1.91. - -2002-07-23 Werner Koch - - * util.h (_IO_cookie_io_functions_t): Fixed typo. Noted by - Richard Lefebvre. - -2002-07-22 Werner Koch - - * fseeko.c, ftello.c: New. - -2002-06-28 Werner Koch - - * maperror.c (map_to_assuan_status): Map more errorcodes to Bad - Certificate. - -2002-06-26 Werner Koch - - * maperror.c (map_to_assuan_status): Map EOF to No_Data_Available. - -2002-06-10 Werner Koch - - * errors.h (gnupg_error_token): Add new prototype. - (STATUS_ERROR): New. - - * mkerrtok: New. - * Makefile.am: Use it to create the new error token function. - -2002-06-04 Werner Koch - - * maperror.c (map_to_assuan_status): Map Bad_CA_Certificate. - -2002-05-23 Werner Koch - - * no-pth.c, Makefile.am: Removed. - -2002-05-22 Werner Koch - - * mkdtemp.c: Replaced byte by unsigned char because it is no longer - defined in gcrypt.h. - -2002-05-21 Werner Koch - - * maperror.c (map_gcry_err): Add libgcrypt's new S-expression errors. - (map_ksba_err): Add a few mappings. - -2002-05-14 Werner Koch - - * gettime.c: New. - -2002-05-03 Werner Koch - - * errors.h: Added STARUS_EXPSIG and STATUS_EXPKEYSIG. - -2002-04-15 Werner Koch - - * cryptmiss.c: New. - -2002-02-14 Werner Koch - - * maperror.c: Add more assuan<->gnupg mappings. - -2002-02-12 Werner Koch - - * fopencookie.c: Dummy function. - - * vasprintf.c: New. Taken from binutils-2.9.1 and dropped all non - ANSI-C stuff. Merged with asprintf version. - - * no-pth.c: New. - -2002-01-23 Werner Koch - - * mkdtemp.c: Copied from gnupg-1.0.6c and changed to use libgcrypt. - -2002-01-19 Werner Koch - - * sysutils.c: New. This is the misc.c file from gnupg 1.0.6 with - the OpenPGP stuff removed. - * sysutils.h: New. - -2002-01-15 Werner Koch - - * maperror.c: Add mapping for Not_Trusted. - -2002-01-11 Werner Koch - - * maperror.c (map_assuan_err): Codes for CRL - -2002-01-08 Werner Koch - - * util.h (spacep): New. - -2002-01-02 Werner Koch - - * maperror.c (map_to_assuan_status): New. Merged from ../agent - and ../sm. - -2001-12-20 Werner Koch - - * maperror.c (map_gcry_err): Add some mappings. - -2001-12-18 Werner Koch - - * Makefile.am (AM_CPPFLAGS): Include flags for gcrypt and ksba - -2001-12-14 Werner Koch - - * util.h (digitp, hexdigitp): New ctype like macros. - (atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New. - - - Copyright 2001, 2002 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - diff --git a/common/Makefile.am b/common/Makefile.am deleted file mode 100644 index 64b565cd2..000000000 --- a/common/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -# Makefile for common gnupg modules -# Copyright (C) 2001, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = mkerrors mkerrtok - -noinst_LIBRARIES = libcommon.a libsimple-pwquery.a - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) - -libcommon_a_SOURCES = \ - util.h i18n.h \ - errors.h \ - sexp-parse.h \ - maperror.c \ - sysutils.c sysutils.h \ - gettime.c \ - yesno.c \ - b64enc.c \ - miscellaneous.c \ - xasprintf.c \ - xreadline.c \ - membuf.c membuf.h \ - iobuf.c iobuf.h \ - ttyio.c ttyio.h \ - asshelp.c asshelp.h \ - signal.c \ - dynload.h - - -libcommon_a_LIBADD = @LIBOBJS@ - -libsimple_pwquery_a_SOURCES = \ - simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h - -libsimple_pwquery_a_LIBADD = @LIBOBJS@ - - - - - - - - - diff --git a/common/README b/common/README deleted file mode 100644 index a90224bab..000000000 --- a/common/README +++ /dev/null @@ -1,11 +0,0 @@ -Stuff used by several modules of GnuPG. - -These directories use it: - -gpg -sm -agent - -These directories don't use it: - -kbx \ No newline at end of file diff --git a/common/asshelp.c b/common/asshelp.c deleted file mode 100644 index 23feca507..000000000 --- a/common/asshelp.c +++ /dev/null @@ -1,166 +0,0 @@ -/* asshelp.c - Helper functions for Assuan - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#include "util.h" - -#include "asshelp.h" - -/* Send the assuan command pertaining to the pinenry environment. The - OPT_* arguments are optional and may be used to overide the - defaults taken from the current locale. */ -gpg_error_t -send_pinentry_environment (assuan_context_t ctx, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, - const char *opt_lc_ctype, - const char *opt_lc_messages) -{ - int rc = 0; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - - dft_display = getenv ("DISPLAY"); - if (opt_display || dft_display) - { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt_display ? opt_display : dft_display) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt_ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt_ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt_ttyname ? opt_ttyname : dft_ttyname) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - dft_ttytype = getenv ("TERM"); - if (opt_ttytype || (dft_ttyname && dft_ttytype)) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt_ttyname ? opt_ttytype : dft_ttytype) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt_lc_ctype || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt_lc_ctype ? opt_lc_ctype : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - free (old_lc); - } -#endif - if (rc) - return rc; -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt_lc_messages || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt_lc_messages ? opt_lc_messages : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - free (old_lc); - } -#endif - - return rc; -} - diff --git a/common/asshelp.h b/common/asshelp.h deleted file mode 100644 index 993594882..000000000 --- a/common/asshelp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* asshelp.h - Helper functions for Assuan - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_ASSHELP_H -#define GNUPG_COMMON_ASSHELP_H - -#include -#include - -gpg_error_t -send_pinentry_environment (assuan_context_t ctx, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, - const char *opt_lc_ctype, - const char *opt_lc_messages); - - -#endif /*GNUPG_COMMON_ASSHELP_H*/ diff --git a/common/b64enc.c b/common/b64enc.c deleted file mode 100644 index edcf6e3ad..000000000 --- a/common/b64enc.c +++ /dev/null @@ -1,211 +0,0 @@ -/* b64enc.c - Simple Base64 encoder. - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include - -#include "i18n.h" -#include "util.h" - -#define B64ENC_DID_HEADER 1 -#define B64ENC_DID_TRAILER 2 -#define B64ENC_NO_LINEFEEDS 16 - - -/* The base-64 character list */ -static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL - and not an empty string, this string will be used as the title for - the armor lines, with TITLE being an empty string, we don't write - the header lines and furthermore even don't write any linefeeds. - With TITLE beeing NULL, we merely don't write header but make sure - that lines are not too long. Note, that we don't write any output - unless at least one byte get written using b64enc_write. */ -gpg_error_t -b64enc_start (struct b64state *state, FILE *fp, const char *title) -{ - memset (state, 0, sizeof *state); - state->fp = fp; - if (title && !*title) - state->flags |= B64ENC_NO_LINEFEEDS; - else if (title) - { - state->title = xtrystrdup (title); - if (!state->title) - return gpg_error_from_errno (errno); - } - return 0; -} - - -/* Write NBYTES from BUFFER to the Base 64 stream identified by - STATE. With BUFFER and NBYTES being 0, merely do a fflush on the - stream. */ -gpg_error_t -b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) -{ - unsigned char radbuf[4]; - int idx, quad_count; - const unsigned char *p; - FILE *fp = state->fp; - - - if (!nbytes) - { - if (buffer && fflush (fp)) - goto write_error; - return 0; - } - - if (!(state->flags & B64ENC_DID_HEADER)) - { - if (state->title) - { - if ( fputs ("-----BEGIN ", fp) == EOF - || fputs (state->title, fp) == EOF - || fputs ("-----\n", fp) == EOF) - goto write_error; - } - state->flags |= B64ENC_DID_HEADER; - } - - idx = state->idx; - quad_count = state->quad_count; - assert (idx < 4); - memcpy (radbuf, state->radbuf, idx); - - for (p=buffer; nbytes; p++, nbytes--) - { - radbuf[idx++] = *p; - if (idx > 2) - { - char tmp[4]; - - tmp[0] = bintoasc[(*radbuf >> 2) & 077]; - tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - tmp[3] = bintoasc[radbuf[2]&077]; - for (idx=0; idx < 4; idx++) - putc (tmp[idx], fp); - idx = 0; - if (ferror (fp)) - goto write_error; - if (++quad_count >= (64/4)) - { - quad_count = 0; - if (!(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - } - } - } - memcpy (state->radbuf, radbuf, idx); - state->idx = idx; - state->quad_count = quad_count; - return 0; - - write_error: - return gpg_error_from_errno (errno); -} - -gpg_error_t -b64enc_finish (struct b64state *state) -{ - gpg_error_t err = 0; - unsigned char radbuf[4]; - int idx, quad_count; - FILE *fp; - - if (!(state->flags & B64ENC_DID_HEADER)) - goto cleanup; - - /* Flush the base64 encoding */ - fp = state->fp; - idx = state->idx; - quad_count = state->quad_count; - assert (idx < 4); - memcpy (radbuf, state->radbuf, idx); - - if (idx) - { - char tmp[4]; - - tmp[0] = bintoasc[(*radbuf>>2)&077]; - if (idx == 1) - { - tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077]; - tmp[2] = '='; - tmp[3] = '='; - } - else - { - tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077]; - tmp[3] = '='; - } - for (idx=0; idx < 4; idx++) - putc (tmp[idx], fp); - idx = 0; - if (ferror (fp)) - goto write_error; - - if (++quad_count >= (64/4)) - { - quad_count = 0; - if (!(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - } - } - - /* Finish the last line and write the trailer. */ - if (quad_count - && !(state->flags & B64ENC_NO_LINEFEEDS) - && fputs ("\n", fp) == EOF) - goto write_error; - - if (state->title) - { - if ( fputs ("-----END ", fp) == EOF - || fputs (state->title, fp) == EOF - || fputs ("-----\n", fp) == EOF) - goto write_error; - } - - goto cleanup; - - write_error: - err = gpg_error_from_errno (errno); - - cleanup: - if (state->title) - { - xfree (state->title); - state->title = NULL; - } - state->fp = NULL; - return err; -} - diff --git a/common/dynload.h b/common/dynload.h deleted file mode 100644 index 3c4652091..000000000 --- a/common/dynload.h +++ /dev/null @@ -1,71 +0,0 @@ -/* dlfcn.h - W32 functions for run-time dynamic loading - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_DYNLOAD_H -#define GNUPG_DYNLOAD_H -#ifndef __MINGW32__ -#include -#else -#include - -#define RTLD_LAZY 0 - -static __inline__ void * -dlopen (const char * name, int flag) -{ - void * hd = LoadLibrary (name); - return hd; -} - -static __inline__ void * -dlsym (void *hd, const char *sym) -{ - if (hd && sym) - { - void * fnc = GetProcAddress (hd, sym); - if (!fnc) - return NULL; - return fnc; - } - return NULL; -} - - -static __inline__ const char * -dlerror (void) -{ - static char buf[32]; - sprintf (buf, "ec=%lu", GetLastError ()); - return buf; -} - - -static __inline__ int -dlclose (void * hd) -{ - if (hd) - { - CloseHandle (hd); - return 0; - } - return -1; -} -#endif /*__MINGW32__*/ -#endif /*GNUPG_DYNLOAD_H*/ diff --git a/common/errors.h b/common/errors.h deleted file mode 100644 index f34f3ba79..000000000 --- a/common/errors.h +++ /dev/null @@ -1,112 +0,0 @@ -/* errors.h - Globally used error codes - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_ERRORS_H -#define GNUPG_COMMON_ERRORS_H - -#include "util.h" - -/* Status codes - fixme: should go into another file */ -enum { - STATUS_ENTER, - STATUS_LEAVE, - STATUS_ABORT, - STATUS_GOODSIG, - STATUS_BADSIG, - STATUS_ERRSIG, - STATUS_BADARMOR, - STATUS_RSA_OR_IDEA, - STATUS_SIGEXPIRED, - STATUS_KEYREVOKED, - STATUS_TRUST_UNDEFINED, - STATUS_TRUST_NEVER, - STATUS_TRUST_MARGINAL, - STATUS_TRUST_FULLY, - STATUS_TRUST_ULTIMATE, - - STATUS_SHM_INFO, - STATUS_SHM_GET, - STATUS_SHM_GET_BOOL, - STATUS_SHM_GET_HIDDEN, - - STATUS_NEED_PASSPHRASE, - STATUS_VALIDSIG, - STATUS_SIG_ID, - STATUS_ENC_TO, - STATUS_NODATA, - STATUS_BAD_PASSPHRASE, - STATUS_NO_PUBKEY, - STATUS_NO_SECKEY, - STATUS_NEED_PASSPHRASE_SYM, - STATUS_DECRYPTION_FAILED, - STATUS_DECRYPTION_OKAY, - STATUS_MISSING_PASSPHRASE, - STATUS_GOOD_PASSPHRASE, - STATUS_GOODMDC, - STATUS_BADMDC, - STATUS_ERRMDC, - STATUS_IMPORTED, - STATUS_IMPORT_OK, - STATUS_IMPORT_PROBLEM, - STATUS_IMPORT_RES, - STATUS_FILE_START, - STATUS_FILE_DONE, - STATUS_FILE_ERROR, - - STATUS_BEGIN_DECRYPTION, - STATUS_END_DECRYPTION, - STATUS_BEGIN_ENCRYPTION, - STATUS_END_ENCRYPTION, - - STATUS_DELETE_PROBLEM, - STATUS_GET_BOOL, - STATUS_GET_LINE, - STATUS_GET_HIDDEN, - STATUS_GOT_IT, - STATUS_PROGRESS, - STATUS_SIG_CREATED, - STATUS_SESSION_KEY, - STATUS_NOTATION_NAME, - STATUS_NOTATION_DATA, - STATUS_POLICY_URL, - STATUS_BEGIN_STREAM, - STATUS_END_STREAM, - STATUS_KEY_CREATED, - STATUS_USERID_HIN, - STATUS_UNEXPECTED, - STATUS_INV_RECP, - STATUS_NO_RECP, - STATUS_ALREADY_SIGNED, - - STATUS_EXPSIG, - STATUS_EXPKEYSIG, - - STATUS_TRUNCATED, - STATUS_ERROR, - STATUS_NEWSIG -}; - - -/*-- errors.c (build by mkerror and mkerrtok) --*/ -const char *gnupg_strerror (int err); -const char *gnupg_error_token (int err); - - -#endif /*GNUPG_COMMON_ERRORS_H*/ diff --git a/common/fseeko.c b/common/fseeko.c deleted file mode 100644 index f151b09ec..000000000 --- a/common/fseeko.c +++ /dev/null @@ -1,40 +0,0 @@ -/* fseeko.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -int -fseeko (FILE *stream, off_t off, int whence) -{ - return fseek (stream, off, whence); -} - - - - - - - - - - diff --git a/common/ftello.c b/common/ftello.c deleted file mode 100644 index e3141900d..000000000 --- a/common/ftello.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ftello.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -off_t -ftello (FILE *stream) -{ - long int off; - - off = ftell (stream); - if (off == -1) - return (off_t)-1; - return off; -} - - - - - - - - - - diff --git a/common/gettime.c b/common/gettime.c deleted file mode 100644 index 93e4ba113..000000000 --- a/common/gettime.c +++ /dev/null @@ -1,278 +0,0 @@ -/* gettime.c - Wrapper for time functions - * Copyright (C) 1998, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#ifdef HAVE_LANGINFO_H -#include -#endif - -#include "util.h" - -static unsigned long timewarp; -static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode; - -/* Wrapper for the time(3). We use this here so we can fake the time - for tests */ -time_t -gnupg_get_time () -{ - time_t current = time (NULL); - if (timemode == NORMAL) - return current; - else if (timemode == FROZEN) - return timewarp; - else if (timemode == FUTURE) - return current + timewarp; - else - return current - timewarp; -} - - -/* Return the current time (possibly faked) in ISO format. */ -void -gnupg_get_isotime (gnupg_isotime_t timebuf) -{ - time_t atime = gnupg_get_time (); - - if (atime < 0) - *timebuf = 0; - else - { - struct tm *tp; -#ifdef HAVE_GMTIME_R - struct tm tmbuf; - - tp = gmtime_r (&atime, &tmbuf); -#else - tp = gmtime (&atime); -#endif - sprintf (timebuf,"%04d%02d%02dT%02d%02d%02d", - 1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - } -} - - -/* set the time to NEWTIME so that gnupg_get_time returns a time - starting with this one. With FREEZE set to 1 the returned time - will never change. Just for completeness, a value of (time_t)-1 - for NEWTIME gets you back to rality. Note that this is obviously - not thread-safe but this is not required. */ -void -gnupg_set_time (time_t newtime, int freeze) -{ - time_t current = time (NULL); - - if ( newtime == (time_t)-1 || current == newtime) - { - timemode = NORMAL; - timewarp = 0; - } - else if (freeze) - { - timemode = FROZEN; - timewarp = current; - } - else if (newtime > current) - { - timemode = FUTURE; - timewarp = newtime - current; - } - else - { - timemode = PAST; - timewarp = current - newtime; - } -} - -/* Returns true when we are in timewarp mode */ -int -gnupg_faked_time_p (void) -{ - return timemode; -} - - -/* This function is used by gpg because OpenPGP defines the timestamp - as an unsigned 32 bit value. */ -u32 -make_timestamp (void) -{ - time_t t = gnupg_get_time (); - - if (t == (time_t)-1) - log_fatal ("gnupg_get_time() failed\n"); - return (u32)t; -} - - - -/**************** - * Scan a date string and return a timestamp. - * The only supported format is "yyyy-mm-dd" - * Returns 0 for an invalid date. - */ -u32 -scan_isodatestr( const char *string ) -{ - int year, month, day; - struct tm tmbuf; - time_t stamp; - int i; - - if( strlen(string) != 10 || string[4] != '-' || string[7] != '-' ) - return 0; - for( i=0; i < 4; i++ ) - if( !digitp (string+i) ) - return 0; - if( !digitp (string+5) || !digitp(string+6) ) - return 0; - if( !digitp(string+8) || !digitp(string+9) ) - return 0; - year = atoi(string); - month = atoi(string+5); - day = atoi(string+8); - /* some basic checks */ - if( year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ) - return 0; - memset( &tmbuf, 0, sizeof tmbuf ); - tmbuf.tm_mday = day; - tmbuf.tm_mon = month-1; - tmbuf.tm_year = year - 1900; - tmbuf.tm_isdst = -1; - stamp = mktime( &tmbuf ); - if( stamp == (time_t)-1 ) - return 0; - return stamp; -} - - -u32 -add_days_to_timestamp( u32 stamp, u16 days ) -{ - return stamp + days*86400L; -} - - -/**************** - * Return a string with a time value in the form: x Y, n D, n H - */ - -const char * -strtimevalue( u32 value ) -{ - static char buffer[30]; - unsigned int years, days, hours, minutes; - - value /= 60; - minutes = value % 60; - value /= 60; - hours = value % 24; - value /= 24; - days = value % 365; - value /= 365; - years = value; - - sprintf(buffer,"%uy%ud%uh%um", years, days, hours, minutes ); - if( years ) - return buffer; - if( days ) - return strchr( buffer, 'y' ) + 1; - return strchr( buffer, 'd' ) + 1; -} - - -/**************** - * Note: this function returns GMT - */ -const char * -strtimestamp( u32 stamp ) -{ - static char buffer[11+5]; - struct tm *tp; - time_t atime = stamp; - - if (atime < 0) { - strcpy (buffer, "????" "-??" "-??"); - } - else { - tp = gmtime( &atime ); - sprintf(buffer,"%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); - } - return buffer; -} - -/**************** - * Note: this function returns local time - */ -const char * -asctimestamp( u32 stamp ) -{ - static char buffer[50]; -#if defined (HAVE_STRFTIME) && defined (HAVE_NL_LANGINFO) - static char fmt[50]; -#endif - struct tm *tp; - time_t atime = stamp; - - if (atime < 0) { - strcpy (buffer, "????" "-??" "-??"); - return buffer; - } - - tp = localtime( &atime ); -#ifdef HAVE_STRFTIME -#if defined(HAVE_NL_LANGINFO) - mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 ); - if( strstr( fmt, "%Z" ) == NULL ) - strcat( fmt, " %Z"); - /* NOTE: gcc -Wformat-noliteral will complain here. I have - found no way to suppress this warning .*/ - strftime (buffer, DIM(buffer)-1, fmt, tp); -#else - /* FIXME: we should check whether the locale appends a " %Z" - * These locales from glibc don't put the " %Z": - * fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN - */ - strftime( buffer, DIM(buffer)-1, "%c %Z", tp ); -#endif - buffer[DIM(buffer)-1] = 0; -#else - mem2str( buffer, asctime(tp), DIM(buffer) ); -#endif - return buffer; -} - - - - - - - - - - - - - - diff --git a/common/i18n.h b/common/i18n.h deleted file mode 100644 index 0e13dca4d..000000000 --- a/common/i18n.h +++ /dev/null @@ -1,47 +0,0 @@ -/* i18n.h - * Copyright (C) 1998, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_I18N_H -#define GNUPG_COMMON_I18N_H - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); -# define _(a) gettext (a) -# define N_(a) (a) -#else -# ifdef HAVE_LOCALE_H -# include -# endif -# ifdef ENABLE_NLS -# include -# define _(a) gettext (a) -# ifdef gettext_noop -# define N_(a) gettext_noop (a) -# else -# define N_(a) (a) -# endif -# else -# define _(a) (a) -# define N_(a) (a) -# endif -#endif /*!USE_SIMPLE_GETTEXT*/ - -#endif /*GNUPG_COMMON_I18N_H*/ diff --git a/common/iobuf.c b/common/iobuf.c deleted file mode 100644 index 4d735397e..000000000 --- a/common/iobuf.c +++ /dev/null @@ -1,2415 +0,0 @@ -/* iobuf.c - file handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_DOSISH_SYSTEM -#include -#endif -#ifdef __riscos__ -#include -#include -#endif /* __riscos__ */ - -#include "memory.h" -#include "util.h" -#include "iobuf.h" - -#undef FILE_FILTER_USES_STDIO - -#ifdef HAVE_DOSISH_SYSTEM -#define USE_SETMODE 1 -#endif - -#ifdef FILE_FILTER_USES_STDIO -#define my_fileno(a) fileno ((a)) -#define my_fopen_ro(a,b) fopen ((a),(b)) -#define my_fopen(a,b) fopen ((a),(b)) -typedef FILE *FILEP_OR_FD; -#define INVALID_FP NULL -#define FILEP_OR_FD_FOR_STDIN (stdin) -#define FILEP_OR_FD_FOR_STDOUT (stdout) -typedef struct -{ - FILE *fp; /* open file handle */ - int keep_open; - int no_cache; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; -#else -#define my_fileno(a) (a) -#define my_fopen_ro(a,b) fd_cache_open ((a),(b)) -#define my_fopen(a,b) direct_open ((a),(b)) -#ifdef HAVE_DOSISH_SYSTEM -typedef HANDLE FILEP_OR_FD; -#define INVALID_FP ((HANDLE)-1) -#define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) -#define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) -#undef USE_SETMODE -#else -typedef int FILEP_OR_FD; -#define INVALID_FP (-1) -#define FILEP_OR_FD_FOR_STDIN (0) -#define FILEP_OR_FD_FOR_STDOUT (1) -#endif -typedef struct -{ - FILEP_OR_FD fp; /* open file handle */ - int keep_open; - int no_cache; - int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; - -struct close_cache_s -{ - struct close_cache_s *next; - FILEP_OR_FD fp; - char fname[1]; -}; -typedef struct close_cache_s *CLOSE_CACHE; -static CLOSE_CACHE close_cache; -#endif - -#ifdef _WIN32 -typedef struct -{ - int sock; - int keep_open; - int no_cache; - int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -sock_filter_ctx_t; -#endif /*_WIN32*/ - -/* The first partial length header block must be of size 512 - * to make it easier (and efficienter) we use a min. block size of 512 - * for all chunks (but the last one) */ -#define OP_MIN_PARTIAL_CHUNK 512 -#define OP_MIN_PARTIAL_CHUNK_2POW 9 - -typedef struct -{ - int use; - size_t size; - size_t count; - int partial; /* 1 = partial header, 2 in last partial packet */ - char *buffer; /* used for partial header */ - size_t buflen; /* used size of buffer */ - int first_c; /* of partial header (which is > 0) */ - int eof; -} -block_filter_ctx_t; - -static int special_names_enabled; - -static int underflow (iobuf_t a); -static int translate_file_handle (int fd, int for_write); - -#ifndef FILE_FILTER_USES_STDIO - -/* - * Invalidate (i.e. close) a cached iobuf - */ -static void -fd_cache_invalidate (const char *fname) -{ - CLOSE_CACHE cc; - - assert (fname); - if (DBG_IOBUF) - log_debug ("fd_cache_invalidate (%s)\n", fname); - - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) - { - if (DBG_IOBUF) - log_debug (" did (%s)\n", cc->fname); -#ifdef HAVE_DOSISH_SYSTEM - CloseHandle (cc->fp); -#else - close (cc->fp); -#endif - cc->fp = INVALID_FP; - } - } -} - - - -static FILEP_OR_FD -direct_open (const char *fname, const char *mode) -{ -#ifdef HAVE_DOSISH_SYSTEM - unsigned long da, cd, sm; - HANDLE hfile; - - /* Note, that we do not handle all mode combinations */ - - /* According to the ReactOS source it seems that open() of the - * standard MSW32 crt does open the file in share mode which is - * something new for MS applications ;-) - */ - if (strchr (mode, '+')) - { - fd_cache_invalidate (fname); - da = GENERIC_READ | GENERIC_WRITE; - cd = OPEN_EXISTING; - sm = FILE_SHARE_READ | FILE_SHARE_WRITE; - } - else if (strchr (mode, 'w')) - { - fd_cache_invalidate (fname); - da = GENERIC_WRITE; - cd = CREATE_ALWAYS; - sm = FILE_SHARE_WRITE; - } - else - { - da = GENERIC_READ; - cd = OPEN_EXISTING; - sm = FILE_SHARE_READ; - } - - hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); - return hfile; -#else - int oflag; - int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - - /* Note, that we do not handle all mode combinations */ - if (strchr (mode, '+')) - { - fd_cache_invalidate (fname); - oflag = O_RDWR; - } - else if (strchr (mode, 'w')) - { - fd_cache_invalidate (fname); - oflag = O_WRONLY | O_CREAT | O_TRUNC; - } - else - { - oflag = O_RDONLY; - } -#ifdef O_BINARY - if (strchr (mode, 'b')) - oflag |= O_BINARY; -#endif -#ifndef __riscos__ - return open (fname, oflag, cflag); -#else - { - struct stat buf; - int rc = stat (fname, &buf); - - /* Don't allow iobufs on directories */ - if (!rc && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode)) - return __set_errno (EISDIR); - else - return open (fname, oflag, cflag); - } -#endif -#endif -} - - -/* - * Instead of closing an FD we keep it open and cache it for later reuse - * Note that this caching strategy only works if the process does not chdir. - */ -static void -fd_cache_close (const char *fname, FILEP_OR_FD fp) -{ - CLOSE_CACHE cc; - - assert (fp); - if (!fname || !*fname) - { -#ifdef HAVE_DOSISH_SYSTEM - CloseHandle (fp); -#else - close (fp); -#endif - if (DBG_IOBUF) - log_debug ("fd_cache_close (%p) real\n", (void *) fp); - return; - } - /* try to reuse a slot */ - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp == INVALID_FP && !strcmp (cc->fname, fname)) - { - cc->fp = fp; - if (DBG_IOBUF) - log_debug ("fd_cache_close (%s) used existing slot\n", fname); - return; - } - } - /* add a new one */ - if (DBG_IOBUF) - log_debug ("fd_cache_close (%s) new slot created\n", fname); - cc = xcalloc (1, sizeof *cc + strlen (fname)); - strcpy (cc->fname, fname); - cc->fp = fp; - cc->next = close_cache; - close_cache = cc; -} - -/* - * Do an direct_open on FNAME but first try to reuse one from the fd_cache - */ -static FILEP_OR_FD -fd_cache_open (const char *fname, const char *mode) -{ - CLOSE_CACHE cc; - - assert (fname); - for (cc = close_cache; cc; cc = cc->next) - { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) - { - FILEP_OR_FD fp = cc->fp; - cc->fp = INVALID_FP; - if (DBG_IOBUF) - log_debug ("fd_cache_open (%s) using cached fp\n", fname); -#ifdef HAVE_DOSISH_SYSTEM - if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) - { - log_error ("rewind file failed on handle %p: ec=%d\n", - fp, (int) GetLastError ()); - fp = INVALID_FP; - } -#else - if (lseek (fp, 0, SEEK_SET) == (off_t) - 1) - { - log_error ("can't rewind fd %d: %s\n", fp, strerror (errno)); - fp = INVALID_FP; - } -#endif - return fp; - } - } - if (DBG_IOBUF) - log_debug ("fd_cache_open (%s) not cached\n", fname); - return direct_open (fname, mode); -} - - -#endif /*FILE_FILTER_USES_STDIO */ - - -/**************** - * Read data from a file into buf which has an allocated length of *LEN. - * return the number of read bytes in *LEN. OPAQUE is the FILE * of - * the stream. A is not used. - * control may be: - * IOBUFCTRL_INIT: called just before the function is linked into the - * list of function. This can be used to prepare internal - * data structures of the function. - * IOBUFCTRL_FREE: called just before the function is removed from the - * list of functions and can be used to release internal - * data structures or close a file etc. - * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer - * with new stuff. *RET_LEN is the available size of the - * buffer, and should be set to the number of bytes - * which were put into the buffer. The function - * returns 0 to indicate success, -1 on EOF and - * GPG_ERR_xxxxx for other errors. - * - * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff. - * *RET_LAN is the number of bytes in BUF. - * - * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The - * filter may take appropriate action on this message. - */ -static int -file_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - file_filter_ctx_t *a = opaque; - FILEP_OR_FD f = a->fp; - size_t size = *ret_len; - size_t nbytes = 0; - int rc = 0; - -#ifdef FILE_FILTER_USES_STDIO - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (feof (f)) - { /* On terminals you could easiely read as many EOFs as you call */ - rc = -1; /* fread() or fgetc() repeatly. Every call will block until you press */ - *ret_len = 0; /* CTRL-D. So we catch this case before we call fread() again. */ - } - else - { - clearerr (f); - nbytes = fread (buf, 1, size, f); - if (feof (f) && !nbytes) - { - rc = -1; /* okay: we can return EOF now. */ - } - else if (ferror (f) && errno != EPIPE) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: read error: %s\n", a->fname, strerror (errno)); - } - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { - clearerr (f); - nbytes = fwrite (buf, 1, size, f); - if (ferror (f)) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: write error: %s\n", a->fname, strerror (errno)); - } - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->keep_open = a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "file_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (f != stdin && f != stdout) - { - if (DBG_IOBUF) - log_debug ("%s: close fd %d\n", a->fname, fileno (f)); - if (!a->keep_open) - fclose (f); - } - f = NULL; - xfree (a); /* we can free our context now */ - } -#else /* !stdio implementation */ - - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (a->eof_seen) - { - rc = -1; - *ret_len = 0; - } - else - { -#ifdef HAVE_DOSISH_SYSTEM - unsigned long nread; - - nbytes = 0; - if (!ReadFile (f, buf, size, &nread, NULL)) - { - int ec = (int) GetLastError (); - if (ec != ERROR_BROKEN_PIPE) - { - rc = gpg_error_from_errno (ec); - log_error ("%s: read error: ec=%d\n", a->fname, ec); - } - } - else if (!nread) - { - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = nread; - } - -#else - - int n; - - nbytes = 0; - do - { - n = read (f, buf, size); - } - while (n == -1 && errno == EINTR); - if (n == -1) - { /* error */ - if (errno != EPIPE) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: read error: %s\n", - a->fname, strerror (errno)); - } - } - else if (!n) - { /* eof */ - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = n; - } -#endif - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { -#ifdef HAVE_DOSISH_SYSTEM - byte *p = buf; - unsigned long n; - - nbytes = size; - do - { - if (size && !WriteFile (f, p, nbytes, &n, NULL)) - { - int ec = (int) GetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("%s: write error: ec=%d\n", a->fname, ec); - break; - } - p += n; - nbytes -= n; - } - while (nbytes); - nbytes = p - buf; -#else - byte *p = buf; - int n; - - nbytes = size; - do - { - do - { - n = write (f, p, nbytes); - } - while (n == -1 && errno == EINTR); - if (n > 0) - { - p += n; - nbytes -= n; - } - } - while (n != -1 && nbytes); - if (n == -1) - { - rc = gpg_error_from_errno (errno); - log_error ("%s: write error: %s\n", a->fname, strerror (errno)); - } - nbytes = p - buf; -#endif - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->eof_seen = 0; - a->keep_open = 0; - a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "file_filter(fd)"; - } - else if (control == IOBUFCTRL_FREE) - { -#ifdef HAVE_DOSISH_SYSTEM - if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT) - { - if (DBG_IOBUF) - log_debug ("%s: close handle %p\n", a->fname, f); - if (!a->keep_open) - fd_cache_close (a->no_cache ? NULL : a->fname, f); - } -#else - if ((int) f != 0 && (int) f != 1) - { - if (DBG_IOBUF) - log_debug ("%s: close fd %d\n", a->fname, f); - if (!a->keep_open) - fd_cache_close (a->no_cache ? NULL : a->fname, f); - } - f = INVALID_FP; -#endif - xfree (a); /* we can free our context now */ - } -#endif /* !stdio implementation */ - return rc; -} - -#ifdef _WIN32 -/* Becuase sockets are an special object under Lose32 we have to - * use a special filter */ -static int -sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - sock_filter_ctx_t *a = opaque; - size_t size = *ret_len; - size_t nbytes = 0; - int rc = 0; - - if (control == IOBUFCTRL_UNDERFLOW) - { - assert (size); /* need a buffer */ - if (a->eof_seen) - { - rc = -1; - *ret_len = 0; - } - else - { - int nread; - - nread = recv (a->sock, buf, size, 0); - if (nread == SOCKET_ERROR) - { - int ec = (int) WSAGetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("socket read error: ec=%d\n", ec); - } - else if (!nread) - { - a->eof_seen = 1; - rc = -1; - } - else - { - nbytes = nread; - } - *ret_len = nbytes; - } - } - else if (control == IOBUFCTRL_FLUSH) - { - if (size) - { - byte *p = buf; - int n; - - nbytes = size; - do - { - n = send (a->sock, p, nbytes, 0); - if (n == SOCKET_ERROR) - { - int ec = (int) WSAGetLastError (); - rc = gpg_error_from_errno (ec); - log_error ("socket write error: ec=%d\n", ec); - break; - } - p += n; - nbytes -= n; - } - while (nbytes); - nbytes = p - buf; - } - *ret_len = nbytes; - } - else if (control == IOBUFCTRL_INIT) - { - a->eof_seen = 0; - a->keep_open = 0; - a->no_cache = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "sock_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (!a->keep_open) - closesocket (a->sock); - xfree (a); /* we can free our context now */ - } - return rc; -} -#endif /*_WIN32*/ - -/**************** - * This is used to implement the block write mode. - * Block reading is done on a byte by byte basis in readbyte(), - * without a filter - */ -static int -block_filter (void *opaque, int control, iobuf_t chain, byte * buf, - size_t * ret_len) -{ - block_filter_ctx_t *a = opaque; - size_t size = *ret_len; - int c, needed, rc = 0; - char *p; - - if (control == IOBUFCTRL_UNDERFLOW) - { - size_t n = 0; - - p = buf; - assert (size); /* need a buffer */ - if (a->eof) /* don't read any further */ - rc = -1; - while (!rc && size) - { - if (!a->size) - { /* get the length bytes */ - if (a->partial == 2) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - else if (a->partial) - { - /* These OpenPGP introduced huffman like encoded length - * bytes are really a mess :-( */ - if (a->first_c) - { - c = a->first_c; - a->first_c = 0; - } - else if ((c = iobuf_get (chain)) == -1) - { - log_error ("block_filter: 1st length byte missing\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - if (c < 192) - { - a->size = c; - a->partial = 2; - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - else if (c < 224) - { - a->size = (c - 192) * 256; - if ((c = iobuf_get (chain)) == -1) - { - log_error - ("block_filter: 2nd length byte missing\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - a->size += c + 192; - a->partial = 2; - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - else if (c == 255) - { - a->size = iobuf_get (chain) << 24; - a->size |= iobuf_get (chain) << 16; - a->size |= iobuf_get (chain) << 8; - if ((c = iobuf_get (chain)) == -1) - { - log_error ("block_filter: invalid 4 byte length\n"); - rc = GPG_ERR_BAD_DATA; - break; - } - a->size |= c; - } - else - { /* next partial body length */ - a->size = 1 << (c & 0x1f); - } - /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */ - } - else - { /* the gnupg partial length scheme - much better :-) */ - c = iobuf_get (chain); - a->size = c << 8; - c = iobuf_get (chain); - a->size |= c; - if (c == -1) - { - log_error ("block_filter: error reading length info\n"); - rc = GPG_ERR_BAD_DATA; - } - if (!a->size) - { - a->eof = 1; - if (!n) - rc = -1; - break; - } - } - } - - while (!rc && size && a->size) - { - needed = size < a->size ? size : a->size; - c = iobuf_read (chain, p, needed); - if (c < needed) - { - if (c == -1) - c = 0; - log_error - ("block_filter %p: read error (size=%lu,a->size=%lu)\n", - a, (ulong) size + c, (ulong) a->size + c); - rc = GPG_ERR_BAD_DATA; - } - else - { - size -= c; - a->size -= c; - p += c; - n += c; - } - } - } - *ret_len = n; - } - else if (control == IOBUFCTRL_FLUSH) - { - if (a->partial) - { /* the complicated openpgp scheme */ - size_t blen, n, nbytes = size + a->buflen; - - assert (a->buflen <= OP_MIN_PARTIAL_CHUNK); - if (nbytes < OP_MIN_PARTIAL_CHUNK) - { - /* not enough to write a partial block out; so we store it */ - if (!a->buffer) - a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK); - memcpy (a->buffer + a->buflen, buf, size); - a->buflen += size; - } - else - { /* okay, we can write out something */ - /* do this in a loop to use the most efficient block lengths */ - p = buf; - do - { - /* find the best matching block length - this is limited - * by the size of the internal buffering */ - for (blen = OP_MIN_PARTIAL_CHUNK * 2, - c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes; - blen *= 2, c++) - ; - blen /= 2; - c--; - /* write the partial length header */ - assert (c <= 0x1f); /*;-) */ - c |= 0xe0; - iobuf_put (chain, c); - if ((n = a->buflen)) - { /* write stuff from the buffer */ - assert (n == OP_MIN_PARTIAL_CHUNK); - if (iobuf_write (chain, a->buffer, n)) - rc = gpg_error_from_errno (errno); - a->buflen = 0; - nbytes -= n; - } - if ((n = nbytes) > blen) - n = blen; - if (n && iobuf_write (chain, p, n)) - rc = gpg_error_from_errno (errno); - p += n; - nbytes -= n; - } - while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK); - /* store the rest in the buffer */ - if (!rc && nbytes) - { - assert (!a->buflen); - assert (nbytes < OP_MIN_PARTIAL_CHUNK); - if (!a->buffer) - a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK); - memcpy (a->buffer, p, nbytes); - a->buflen = nbytes; - } - } - } - else - { /* the gnupg scheme (which is not openpgp compliant) */ - size_t avail, n; - - for (p = buf; !rc && size;) - { - n = size; - avail = a->size - a->count; - if (!avail) - { - if (n > a->size) - { - iobuf_put (chain, (a->size >> 8) & 0xff); - iobuf_put (chain, a->size & 0xff); - avail = a->size; - a->count = 0; - } - else - { - iobuf_put (chain, (n >> 8) & 0xff); - iobuf_put (chain, n & 0xff); - avail = n; - a->count = a->size - n; - } - } - if (n > avail) - n = avail; - if (iobuf_write (chain, p, n)) - rc = gpg_error_from_errno (errno); - a->count += n; - p += n; - size -= n; - } - } - } - else if (control == IOBUFCTRL_INIT) - { - if (DBG_IOBUF) - log_debug ("init block_filter %p\n", a); - if (a->partial) - a->count = 0; - else if (a->use == 1) - a->count = a->size = 0; - else - a->count = a->size; /* force first length bytes */ - a->eof = 0; - a->buffer = NULL; - a->buflen = 0; - } - else if (control == IOBUFCTRL_DESC) - { - *(char **) buf = "block_filter"; - } - else if (control == IOBUFCTRL_FREE) - { - if (a->use == 2) - { /* write the end markers */ - if (a->partial) - { - u32 len; - /* write out the remaining bytes without a partial header - * the length of this header may be 0 - but if it is - * the first block we are not allowed to use a partial header - * and frankly we can't do so, because this length must be - * a power of 2. This is _really_ complicated because we - * have to check the possible length of a packet prior - * to it's creation: a chain of filters becomes complicated - * and we need a lot of code to handle compressed packets etc. - * :-((((((( - */ - /* construct header */ - len = a->buflen; - /*log_debug("partial: remaining length=%u\n", len ); */ - if (len < 192) - rc = iobuf_put (chain, len); - else if (len < 8384) - { - if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192))) - rc = iobuf_put (chain, ((len - 192) % 256)); - } - else - { /* use a 4 byte header */ - if (!(rc = iobuf_put (chain, 0xff))) - if (!(rc = iobuf_put (chain, (len >> 24) & 0xff))) - if (!(rc = iobuf_put (chain, (len >> 16) & 0xff))) - if (!(rc = iobuf_put (chain, (len >> 8) & 0xff))) - rc = iobuf_put (chain, len & 0xff); - } - if (!rc && len) - rc = iobuf_write (chain, a->buffer, len); - if (rc) - { - log_error ("block_filter: write error: %s\n", - strerror (errno)); - rc = gpg_error_from_errno (errno); - } - xfree (a->buffer); - a->buffer = NULL; - a->buflen = 0; - } - else - { - iobuf_writebyte (chain, 0); - iobuf_writebyte (chain, 0); - } - } - else if (a->size) - { - log_error ("block_filter: pending bytes!\n"); - } - if (DBG_IOBUF) - log_debug ("free block_filter %p\n", a); - xfree (a); /* we can free our context now */ - } - - return rc; -} - - -static void -print_chain (iobuf_t a) -{ - if (!DBG_IOBUF) - return; - for (; a; a = a->chain) - { - size_t dummy_len = 0; - const char *desc = "[none]"; - - if (a->filter) - a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, - (byte *) & desc, &dummy_len); - - log_debug ("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n", - a->no, a->subno, desc, a->filter_eof, - (int) a->d.start, (int) a->d.len); - } -} - -int -iobuf_print_chain (iobuf_t a) -{ - print_chain (a); - return 0; -} - -/**************** - * Allocate a new io buffer, with no function assigned. - * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer - * BUFSIZE is a suggested buffer size. - */ -iobuf_t -iobuf_alloc (int use, size_t bufsize) -{ - iobuf_t a; - static int number = 0; - - a = xcalloc (1, sizeof *a); - a->use = use; - a->d.buf = xmalloc (bufsize); - a->d.size = bufsize; - a->no = ++number; - a->subno = 0; - a->opaque = NULL; - a->real_fname = NULL; - return a; -} - -int -iobuf_close (iobuf_t a) -{ - iobuf_t a2; - size_t dummy_len = 0; - int rc = 0; - - if (a && a->directfp) - { - fclose (a->directfp); - xfree (a->real_fname); - if (DBG_IOBUF) - log_debug ("iobuf_close -> %p\n", a->directfp); - return 0; - } - - for (; a && !rc; a = a2) - { - a2 = a->chain; - if (a->use == 2 && (rc = iobuf_flush (a))) - log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc)); - - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc); - if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, - a->chain, NULL, &dummy_len))) - log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc)); - xfree (a->real_fname); - if (a->d.buf) - { - memset (a->d.buf, 0, a->d.size); /* erase the buffer */ - xfree (a->d.buf); - } - xfree (a); - } - return rc; -} - -int -iobuf_cancel (iobuf_t a) -{ - const char *s; - iobuf_t a2; - int rc; -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - char *remove_name = NULL; -#endif - - if (a && a->use == 2) - { - s = iobuf_get_real_fname (a); - if (s && *s) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove_name = m_strdup (s); -#else - remove (s); -#endif - } - } - - /* send a cancel message to all filters */ - for (a2 = a; a2; a2 = a2->chain) - { - size_t dummy; - if (a2->filter) - a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy); - } - - rc = iobuf_close (a); -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - if (remove_name) - { - /* Argg, MSDOS does not allow to remove open files. So - * we have to do it here */ - remove (remove_name); - xfree (remove_name); - } -#endif - return rc; -} - - -/**************** - * create a temporary iobuf, which can be used to collect stuff - * in an iobuf and later be written by iobuf_write_temp() to another - * iobuf. - */ -iobuf_t -iobuf_temp () -{ - iobuf_t a; - - a = iobuf_alloc (3, 8192); - - return a; -} - -iobuf_t -iobuf_temp_with_content (const char *buffer, size_t length) -{ - iobuf_t a; - - a = iobuf_alloc (3, length); - memcpy (a->d.buf, buffer, length); - a->d.len = length; - - return a; -} - -void -iobuf_enable_special_filenames (int yes) -{ - special_names_enabled = yes; -} - -/* - * see whether the filename has the for "-&nnnn", where n is a - * non-zero number. - * Returns this number or -1 if it is not the case. - */ -static int -check_special_filename (const char *fname) -{ - if (special_names_enabled && fname && *fname == '-' && fname[1] == '&') - { - int i; - - fname += 2; - for (i = 0; digitp (fname+i); i++) - ; - if (!fname[i]) - return atoi (fname); - } - return -1; -} - -/**************** - * Create a head iobuf for reading from a file - * returns: NULL if an error occures and sets errno - */ -iobuf_t -iobuf_open (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - int print_only = 0; - int fd; - - if (!fname || (*fname == '-' && !fname[1])) - { - fp = FILEP_OR_FD_FOR_STDIN; -#ifdef USE_SETMODE - setmode (my_fileno (fp), O_BINARY); -#endif - fname = "[stdin]"; - print_only = 1; - } - else if ((fd = check_special_filename (fname)) != -1) - return iobuf_fdopen (translate_file_handle (fd, 0), "rb"); - else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP) - return NULL; - a = iobuf_alloc (1, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - fcx->print_only_name = print_only; - strcpy (fcx->fname, fname); - if (!print_only) - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: open `%s' fd=%d\n", - a->no, a->subno, fname, (int) my_fileno (fcx->fp)); - - return a; -} - -/**************** - * Create a head iobuf for reading from a file - * returns: NULL if an error occures and sets errno - */ -iobuf_t -iobuf_fdopen (int fd, const char *mode) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - -#ifdef FILE_FILTER_USES_STDIO - if (!(fp = fdopen (fd, mode))) - return NULL; -#else - fp = (FILEP_OR_FD) fd; -#endif - a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); - fcx = xmalloc (sizeof *fcx + 20); - fcx->fp = fp; - fcx->print_only_name = 1; - sprintf (fcx->fname, "[fd %d]", fd); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname); - iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */ - return a; -} - - -iobuf_t -iobuf_sockopen (int fd, const char *mode) -{ - iobuf_t a; -#ifdef _WIN32 - sock_filter_ctx_t *scx; - size_t len; - - a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); - scx = m_alloc (sizeof *scx + 25); - scx->sock = fd; - scx->print_only_name = 1; - sprintf (scx->fname, "[sock %d]", fd); - a->filter = sock_filter; - a->filter_ov = scx; - sock_filter (scx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname); - iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */ -#else - a = iobuf_fdopen (fd, mode); -#endif - return a; -} - -/**************** - * create an iobuf for writing to a file; the file will be created. - */ -iobuf_t -iobuf_create (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - int print_only = 0; - int fd; - - if (!fname || (*fname == '-' && !fname[1])) - { - fp = FILEP_OR_FD_FOR_STDOUT; -#ifdef USE_SETMODE - setmode (my_fileno (fp), O_BINARY); -#endif - fname = "[stdout]"; - print_only = 1; - } - else if ((fd = check_special_filename (fname)) != -1) - return iobuf_fdopen (translate_file_handle (fd, 1), "wb"); - else if ((fp = my_fopen (fname, "wb")) == INVALID_FP) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - fcx->print_only_name = print_only; - strcpy (fcx->fname, fname); - if (!print_only) - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc); - - return a; -} - -/**************** - * append to an iobuf; if the file does not exist, create it. - * cannot be used for stdout. - * Note: This is not used. - */ -#if 0 /* not used */ -iobuf_t -iobuf_append (const char *fname) -{ - iobuf_t a; - FILE *fp; - file_filter_ctx_t *fcx; - size_t len; - - if (!fname) - return NULL; - else if (!(fp = my_fopen (fname, "ab"))) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = m_alloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - strcpy (fcx->fname, fname); - a->real_fname = m_strdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc); - - return a; -} -#endif - -iobuf_t -iobuf_openrw (const char *fname) -{ - iobuf_t a; - FILEP_OR_FD fp; - file_filter_ctx_t *fcx; - size_t len; - - if (!fname) - return NULL; - else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP) - return NULL; - a = iobuf_alloc (2, 8192); - fcx = xmalloc (sizeof *fcx + strlen (fname)); - fcx->fp = fp; - strcpy (fcx->fname, fname); - a->real_fname = xstrdup (fname); - a->filter = file_filter; - a->filter_ov = fcx; - file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); - file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc); - - return a; -} - - -int -iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval) -{ - if (cmd == 1) - { /* keep system filepointer/descriptor open */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n", - a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?", - intval); - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - b->keep_open = intval; - return 0; - } -#ifdef _WIN32 - else if (!a->chain && a->filter == sock_filter) - { - sock_filter_ctx_t *b = a->filter_ov; - b->keep_open = intval; - return 0; - } -#endif - } - else if (cmd == 2) - { /* invalidate cache */ - if (DBG_IOBUF) - log_debug ("iobuf-*.*: ioctl `%s' invalidate\n", - ptrval ? (char *) ptrval : "?"); - if (!a && !intval && ptrval) - { -#ifndef FILE_FILTER_USES_STDIO - fd_cache_invalidate (ptrval); -#endif - return 0; - } - } - else if (cmd == 3) - { /* disallow/allow caching */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n", - a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?", - intval); - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - b->no_cache = intval; - return 0; - } -#ifdef _WIN32 - else if (!a->chain && a->filter == sock_filter) - { - sock_filter_ctx_t *b = a->filter_ov; - b->no_cache = intval; - return 0; - } -#endif - } - - return -1; -} - - -/**************** - * Register an i/o filter. - */ -int -iobuf_push_filter (iobuf_t a, - int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov) -{ - return iobuf_push_filter2 (a, f, ov, 0); -} - -int -iobuf_push_filter2 (iobuf_t a, - int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov, int rel_ov) -{ - iobuf_t b; - size_t dummy_len = 0; - int rc = 0; - - if (a->directfp) - BUG (); - - if (a->use == 2 && (rc = iobuf_flush (a))) - return rc; - /* make a copy of the current stream, so that - * A is the new stream and B the original one. - * The contents of the buffers are transferred to the - * new stream. - */ - b = xmalloc (sizeof *b); - memcpy (b, a, sizeof *b); - /* fixme: it is stupid to keep a copy of the name at every level - * but we need the name somewhere because the name known by file_filter - * may have been released when we need the name of the file */ - b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL; - /* remove the filter stuff from the new stream */ - a->filter = NULL; - a->filter_ov = NULL; - a->filter_ov_owner = 0; - a->filter_eof = 0; - if (a->use == 3) - a->use = 2; /* make a write stream from a temp stream */ - - if (a->use == 2) - { /* allocate a fresh buffer for the - original stream */ - b->d.buf = xmalloc (a->d.size); - b->d.len = 0; - b->d.start = 0; - } - else - { /* allocate a fresh buffer for the new - stream */ - a->d.buf = xmalloc (a->d.size); - a->d.len = 0; - a->d.start = 0; - } - /* disable nlimit for the new stream */ - a->ntotal = b->ntotal + b->nbytes; - a->nlimit = a->nbytes = 0; - a->nofast &= ~1; - /* make a link from the new stream to the original stream */ - a->chain = b; - a->opaque = b->opaque; - - /* setup the function on the new stream */ - a->filter = f; - a->filter_ov = ov; - a->filter_ov_owner = rel_ov; - - a->subno = b->subno + 1; - f (ov, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &dummy_len); - - if (DBG_IOBUF) - { - log_debug ("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc); - print_chain (a); - } - - /* now we can initialize the new function if we have one */ - if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain, - NULL, &dummy_len))) - log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc)); - return rc; -} - -/**************** - * Remove an i/o filter. - */ -int -pop_filter (iobuf_t a, int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len), - void *ov) -{ - iobuf_t b; - size_t dummy_len = 0; - int rc = 0; - - if (a->directfp) - BUG (); - - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc); - if (!a->filter) - { /* this is simple */ - b = a->chain; - assert (b); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - return 0; - } - for (b = a; b; b = b->chain) - if (b->filter == f && (!ov || b->filter_ov == ov)) - break; - if (!b) - log_bug ("pop_filter(): filter function not found\n"); - - /* flush this stream if it is an output stream */ - if (a->use == 2 && (rc = iobuf_flush (b))) - { - log_error ("iobuf_flush failed in pop_filter: %s\n", gpg_strerror (rc)); - return rc; - } - /* and tell the filter to free it self */ - if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain, - NULL, &dummy_len))) - { - log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (b->filter_ov && b->filter_ov_owner) - { - xfree (b->filter_ov); - b->filter_ov = NULL; - } - - - /* and see how to remove it */ - if (a == b && !b->chain) - log_bug ("can't remove the last filter from the chain\n"); - else if (a == b) - { /* remove the first iobuf from the chain */ - /* everything from b is copied to a. This is save because - * a flush has been done on the to be removed entry - */ - b = a->chain; - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno); - } - else if (!b->chain) - { /* remove the last iobuf from the chain */ - log_bug ("Ohh jeee, trying to remove a head filter\n"); - } - else - { /* remove an intermediate iobuf from the chain */ - log_bug ("Ohh jeee, trying to remove an intermediate filter\n"); - } - - return rc; -} - - -/**************** - * read underflow: read more bytes into the buffer and return - * the first byte or -1 on EOF. - */ -static int -underflow (iobuf_t a) -{ - size_t len; - int rc; - - assert (a->d.start == a->d.len); - if (a->use == 3) - return -1; /* EOF because a temp buffer can't do an underflow */ - - if (a->filter_eof) - { - if (a->chain) - { - iobuf_t b = a->chain; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s' in underflow\n", - a->no, a->subno, a->desc); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - print_chain (a); - } - else - a->filter_eof = 0; /* for the top level filter */ - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof (due to filter eof)\n", - a->no, a->subno); - return -1; /* return one(!) EOF */ - } - if (a->error) - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: error\n", a->no, a->subno); - return -1; - } - - if (a->directfp) - { - FILE *fp = a->directfp; - - len = fread (a->d.buf, 1, a->d.size, fp); - if (len < a->d.size) - { - if (ferror (fp)) - a->error = gpg_error_from_errno (errno); - } - a->d.len = len; - a->d.start = 0; - return len ? a->d.buf[a->d.start++] : -1; - } - - - if (a->filter) - { - len = a->d.size; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: req=%lu\n", - a->no, a->subno, (ulong) len); - rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain, - a->d.buf, &len); - if (DBG_IOBUF) - { - log_debug ("iobuf-%d.%d: underflow: got=%lu rc=%d\n", - a->no, a->subno, (ulong) len, rc); -/* if( a->no == 1 ) */ -/* log_hexdump (" data:", a->d.buf, len); */ - } - if (a->use == 1 && rc == -1) - { /* EOF: we can remove the filter */ - size_t dummy_len = 0; - - /* and tell the filter to free itself */ - if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain, - NULL, &dummy_len))) - log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc)); - if (a->filter_ov && a->filter_ov_owner) - { - xfree (a->filter_ov); - a->filter_ov = NULL; - } - a->filter = NULL; - a->desc = NULL; - a->filter_ov = NULL; - a->filter_eof = 1; - if (!len && a->chain) - { - iobuf_t b = a->chain; - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: pop `%s' in underflow (!len)\n", - a->no, a->subno, a->desc); - xfree (a->d.buf); - xfree (a->real_fname); - memcpy (a, b, sizeof *a); - xfree (b); - print_chain (a); - } - } - else if (rc) - a->error = rc; - - if (!len) - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof\n", a->no, a->subno); - return -1; - } - a->d.len = len; - a->d.start = 0; - return a->d.buf[a->d.start++]; - } - else - { - if (DBG_IOBUF) - log_debug ("iobuf-%d.%d: underflow: eof (no filter)\n", - a->no, a->subno); - return -1; /* no filter; return EOF */ - } -} - - -int -iobuf_flush (iobuf_t a) -{ - size_t len; - int rc; - - if (a->directfp) - return 0; - - if (a->use == 3) - { /* increase the temp buffer */ - char *newbuf; - size_t newsize = a->d.size + 8192; - - if (DBG_IOBUF) - log_debug ("increasing temp iobuf from %lu to %lu\n", - (ulong) a->d.size, (ulong) newsize); - newbuf = xmalloc (newsize); - memcpy (newbuf, a->d.buf, a->d.len); - xfree (a->d.buf); - a->d.buf = newbuf; - a->d.size = newsize; - return 0; - } - else if (a->use != 2) - log_bug ("flush on non-output iobuf\n"); - else if (!a->filter) - log_bug ("iobuf_flush: no filter\n"); - len = a->d.len; - rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len); - if (!rc && len != a->d.len) - { - log_info ("iobuf_flush did not write all!\n"); - rc = GPG_ERR_INTERNAL; - } - else if (rc) - a->error = rc; - a->d.len = 0; - - return rc; -} - - -/**************** - * Read a byte from the iobuf; returns -1 on EOF - */ -int -iobuf_readbyte (iobuf_t a) -{ - int c; - - /* nlimit does not work together with unget */ - /* nbytes is also not valid! */ - if (a->unget.buf) - { - if (a->unget.start < a->unget.len) - return a->unget.buf[a->unget.start++]; - xfree (a->unget.buf); - a->unget.buf = NULL; - a->nofast &= ~2; - } - - if (a->nlimit && a->nbytes >= a->nlimit) - return -1; /* forced EOF */ - - if (a->d.start < a->d.len) - { - c = a->d.buf[a->d.start++]; - } - else if ((c = underflow (a)) == -1) - return -1; /* EOF */ - - a->nbytes++; - return c; -} - - -int -iobuf_read (iobuf_t a, byte * buf, unsigned buflen) -{ - int c, n; - - if (a->unget.buf || a->nlimit) - { - /* handle special cases */ - for (n = 0; n < buflen; n++) - { - if ((c = iobuf_readbyte (a)) == -1) - { - if (!n) - return -1; /* eof */ - break; - } - else if (buf) - *buf = c; - if (buf) - buf++; - } - return n; - } - - n = 0; - do - { - if (n < buflen && a->d.start < a->d.len) - { - unsigned size = a->d.len - a->d.start; - if (size > buflen - n) - size = buflen - n; - if (buf) - memcpy (buf, a->d.buf + a->d.start, size); - n += size; - a->d.start += size; - if (buf) - buf += size; - } - if (n < buflen) - { - if ((c = underflow (a)) == -1) - { - a->nbytes += n; - return n ? n : -1 /*EOF*/; - } - if (buf) - *buf++ = c; - n++; - } - } - while (n < buflen); - a->nbytes += n; - return n; -} - - -/**************** - * Have a look at the iobuf. - * NOTE: This only works in special cases. - */ -int -iobuf_peek (iobuf_t a, byte * buf, unsigned buflen) -{ - int n = 0; - - if (a->filter_eof) - return -1; - - if (!(a->d.start < a->d.len)) - { - if (underflow (a) == -1) - return -1; - /* and unget this character */ - assert (a->d.start == 1); - a->d.start = 0; - } - - for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++) - *buf = a->d.buf[n]; - return n; -} - - - - -int -iobuf_writebyte (iobuf_t a, unsigned c) -{ - int rc; - - if (a->directfp) - BUG (); - - if (a->d.len == a->d.size) - if ((rc=iobuf_flush (a))) - return rc; - - assert (a->d.len < a->d.size); - a->d.buf[a->d.len++] = c; - return 0; -} - - -int -iobuf_write (iobuf_t a, byte * buf, unsigned buflen) -{ - int rc; - - if (a->directfp) - BUG (); - - do - { - if (buflen && a->d.len < a->d.size) - { - unsigned size = a->d.size - a->d.len; - if (size > buflen) - size = buflen; - memcpy (a->d.buf + a->d.len, buf, size); - buflen -= size; - buf += size; - a->d.len += size; - } - if (buflen) - { - rc = iobuf_flush (a); - if (rc) - return rc; - } - } - while (buflen); - return 0; -} - - -int -iobuf_writestr (iobuf_t a, const char *buf) -{ - int rc; - - for (; *buf; buf++) - if ((rc=iobuf_writebyte (a, *buf))) - return rc; - return 0; -} - - - -/**************** - * copy the contents of TEMP to A. - */ -int -iobuf_write_temp (iobuf_t a, iobuf_t temp) -{ - while (temp->chain) - pop_filter (temp, temp->filter, NULL); - return iobuf_write (a, temp->d.buf, temp->d.len); -} - -/**************** - * copy the contents of the temp io stream to BUFFER. - */ -size_t -iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen) -{ - size_t n = a->d.len; - - if (n > buflen) - n = buflen; - memcpy (buffer, a->d.buf, n); - return n; -} - - -/**************** - * Call this function to terminate processing of the temp stream - * without closing it. This removes all filters from the stream - * makes sure that iobuf_get_temp_{buffer,length}() returns correct - * values. - */ -void -iobuf_flush_temp (iobuf_t temp) -{ - while (temp->chain) - pop_filter (temp, temp->filter, NULL); -} - - -/**************** - * Set a limit on how many bytes may be read from the input stream A. - * Setting the limit to 0 disables this feature. - */ -void -iobuf_set_limit (iobuf_t a, off_t nlimit) -{ - if (nlimit) - a->nofast |= 1; - else - a->nofast &= ~1; - a->nlimit = nlimit; - a->ntotal += a->nbytes; - a->nbytes = 0; -} - - - -/**************** - * Return the length of an open file - */ -off_t -iobuf_get_filelength (iobuf_t a) -{ - struct stat st; - - if (a->directfp) - { - FILE *fp = a->directfp; - - if (!fstat (fileno (fp), &st)) - return st.st_size; - log_error ("fstat() failed: %s\n", strerror (errno)); - return 0; - } - - /* Hmmm: file_filter may have already been removed */ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; - -#if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) - ulong size; - - if ((size = GetFileSize (fp, NULL)) != 0xffffffff) - return size; - log_error ("GetFileSize for handle %p failed: ec=%d\n", - fp, (int) GetLastError ()); -#else - if (!fstat (my_fileno (fp), &st)) - return st.st_size; - log_error ("fstat() failed: %s\n", strerror (errno)); -#endif - break; - } - - return 0; -} - -/**************** - * Tell the file position, where the next read will take place - */ -off_t -iobuf_tell (iobuf_t a) -{ - return a->ntotal + a->nbytes; -} - - -#if !defined(HAVE_FSEEKO) && !defined(fseeko) - -#ifdef HAVE_LIMITS_H -# include -#endif -#ifndef LONG_MAX -# define LONG_MAX ((long) ((unsigned long) -1 >> 1)) -#endif -#ifndef LONG_MIN -# define LONG_MIN (-1 - LONG_MAX) -#endif - -/**************** - * A substitute for fseeko, for hosts that don't have it. - */ -static int -fseeko (FILE * stream, off_t newpos, int whence) -{ - while (newpos != (long) newpos) - { - long pos = newpos < 0 ? LONG_MIN : LONG_MAX; - if (fseek (stream, pos, whence) != 0) - return -1; - newpos -= pos; - whence = SEEK_CUR; - } - return fseek (stream, (long) newpos, whence); -} -#endif - -/**************** - * This is a very limited implementation. It simply discards all internal - * buffering and removes all filters but the first one. - */ -int -iobuf_seek (iobuf_t a, off_t newpos) -{ - file_filter_ctx_t *b = NULL; - - if (a->directfp) - { - FILE *fp = a->directfp; - if (fseeko (fp, newpos, SEEK_SET)) - { - log_error ("can't seek: %s\n", strerror (errno)); - return -1; - } - clearerr (fp); - } - else - { - for (; a; a = a->chain) - { - if (!a->chain && a->filter == file_filter) - { - b = a->filter_ov; - break; - } - } - if (!a) - return -1; -#ifdef FILE_FILTER_USES_STDIO - if (fseeko (b->fp, newpos, SEEK_SET)) - { - log_error ("can't fseek: %s\n", strerror (errno)); - return -1; - } -#else -#ifdef HAVE_DOSISH_SYSTEM - if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff) - { - log_error ("SetFilePointer failed on handle %p: ec=%d\n", - b->fp, (int) GetLastError ()); - return -1; - } -#else - if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1) - { - log_error ("can't lseek: %s\n", strerror (errno)); - return -1; - } -#endif -#endif - } - a->d.len = 0; /* discard buffer */ - a->d.start = 0; - a->nbytes = 0; - a->nlimit = 0; - a->nofast &= ~1; - a->ntotal = newpos; - a->error = 0; - /* remove filters, but the last */ - if (a->chain) - log_debug ("pop_filter called in iobuf_seek - please report\n"); - while (a->chain) - pop_filter (a, a->filter, NULL); - - return 0; -} - - - - - - -/**************** - * Retrieve the real filename - */ -const char * -iobuf_get_real_fname (iobuf_t a) -{ - if (a->real_fname) - return a->real_fname; - - /* the old solution */ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - return b->print_only_name ? NULL : b->fname; - } - - return NULL; -} - - -/**************** - * Retrieve the filename - */ -const char * -iobuf_get_fname (iobuf_t a) -{ - for (; a; a = a->chain) - if (!a->chain && a->filter == file_filter) - { - file_filter_ctx_t *b = a->filter_ov; - return b->fname; - } - - return NULL; -} - -/**************** - * Start the block write mode, see rfc1991.new for details. - * A value of 0 for N stops this mode (flushes and writes - * the end marker) - */ -void -iobuf_set_block_mode (iobuf_t a, size_t n) -{ - block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx); - - assert (a->use == 1 || a->use == 2); - ctx->use = a->use; - if (!n) - { - if (a->use == 1) - log_debug ("pop_filter called in set_block_mode - please report\n"); - pop_filter (a, block_filter, NULL); - } - else - { - ctx->size = n; /* only needed for use 2 */ - iobuf_push_filter (a, block_filter, ctx); - } -} - -/**************** - * enable partial block mode as described in the OpenPGP draft. - * LEN is the first length byte on read, but ignored on writes. - */ -void -iobuf_set_partial_block_mode (iobuf_t a, size_t len) -{ - block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx); - - assert (a->use == 1 || a->use == 2); - ctx->use = a->use; - if (!len) - { - if (a->use == 1) - log_debug ("pop_filter called in set_partial_block_mode" - " - please report\n"); - pop_filter (a, block_filter, NULL); - } - else - { - ctx->partial = 1; - ctx->size = 0; - ctx->first_c = len; - iobuf_push_filter (a, block_filter, ctx); - } -} - - -/**************** - * Checks whether the stream is in block mode - * Note: This does not work if other filters are pushed on the stream. - */ -int -iobuf_in_block_mode (iobuf_t a) -{ - if (a && a->filter == block_filter) - return 1; /* yes */ - return 0; /* no */ -} - - -/**************** - * Same as fgets() but if the buffer is too short a larger one will - * be allocated up to some limit *max_length. - * A line is considered a byte stream ending in a LF. - * Returns the length of the line. EOF is indicated by a line of - * length zero. The last LF may be missing due to an EOF. - * is max_length is zero on return, the line has been truncated. - * - * Note: The buffer is allocated with enough space to append a CR,LF,EOL - */ -unsigned int -iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, - unsigned *length_of_buffer, unsigned *max_length) -{ - int c; - char *buffer = *addr_of_buffer; - unsigned length = *length_of_buffer; - unsigned nbytes = 0; - unsigned maxlen = *max_length; - char *p; - - if (!buffer) - { /* must allocate a new buffer */ - length = 256; - buffer = xmalloc (length); - *addr_of_buffer = buffer; - *length_of_buffer = length; - } - - length -= 3; /* reserve 3 bytes (cr,lf,eol) */ - p = buffer; - while ((c = iobuf_get (a)) != -1) - { - if (nbytes == length) - { /* increase the buffer */ - if (length > maxlen) - { /* this is out limit */ - /* skip the rest of the line */ - while (c != '\n' && (c = iobuf_get (a)) != -1) - ; - *p++ = '\n'; /* always append a LF (we have reserved space) */ - nbytes++; - *max_length = 0; /* indicate truncation */ - break; - } - length += 3; /* correct for the reserved byte */ - length += length < 1024 ? 256 : 1024; - buffer = xrealloc (buffer, length); - *addr_of_buffer = buffer; - *length_of_buffer = length; - length -= 3; /* and reserve again */ - p = buffer + nbytes; - } - *p++ = c; - nbytes++; - if (c == '\n') - break; - } - *p = 0; /* make sure the line is a string */ - - return nbytes; -} - -/* This is the non iobuf specific function */ -int -iobuf_translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 - { - int x; - - if (fd <= 2) - return fd; /* do not do this for error, stdin, stdout, stderr */ - - x = _open_osfhandle (fd, for_write ? 1 : 0); - if (x == -1) - log_error ("failed to translate osfhandle %p\n", (void *) fd); - else - { - /*log_info ("_open_osfhandle %p yields %d%s\n", - (void*)fd, x, for_write? " for writing":"" ); */ - fd = x; - } - } -#endif - return fd; -} - -static int -translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 -#ifdef FILE_FILTER_USES_STDIO - fd = iobuf_translate_file_handle (fd, for_write); -#else - { - int x; - - if (fd == 0) - x = (int) GetStdHandle (STD_INPUT_HANDLE); - else if (fd == 1) - x = (int) GetStdHandle (STD_OUTPUT_HANDLE); - else if (fd == 2) - x = (int) GetStdHandle (STD_ERROR_HANDLE); - else - x = fd; - - if (x == -1) - log_debug ("GetStdHandle(%d) failed: ec=%d\n", - fd, (int) GetLastError ()); - - fd = x; - } -#endif -#endif - return fd; -} diff --git a/common/iobuf.h b/common/iobuf.h deleted file mode 100644 index 0af94e22d..000000000 --- a/common/iobuf.h +++ /dev/null @@ -1,170 +0,0 @@ -/* iobuf.h - I/O buffer - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_IOBUF_H -#define GNUPG_COMMON_IOBUF_H - -#include "../include/types.h" /* fixme: should be moved elsewhere. */ - - -#define DBG_IOBUF iobuf_debug_mode - - -#define IOBUFCTRL_INIT 1 -#define IOBUFCTRL_FREE 2 -#define IOBUFCTRL_UNDERFLOW 3 -#define IOBUFCTRL_FLUSH 4 -#define IOBUFCTRL_DESC 5 -#define IOBUFCTRL_CANCEL 6 -#define IOBUFCTRL_USER 16 - -typedef struct iobuf_struct *iobuf_t; - -/* fixme: we should hide most of this stuff */ -struct iobuf_struct -{ - int use; /* 1 input , 2 output, 3 temp */ - off_t nlimit; - off_t nbytes; /* used together with nlimit */ - off_t ntotal; /* total bytes read (position of stream) */ - int nofast; /* used by the iobuf_get() */ - void *directfp; - struct - { - size_t size; /* allocated size */ - size_t start; /* number of invalid bytes at the begin of the buffer */ - size_t len; /* currently filled to this size */ - byte *buf; - } - d; - int filter_eof; - int error; - int (*filter) (void *opaque, int control, - iobuf_t chain, byte * buf, size_t * len); - void *filter_ov; /* value for opaque */ - int filter_ov_owner; - char *real_fname; - iobuf_t chain; /* next iobuf used for i/o if any - (passed to filter) */ - int no, subno; - const char *desc; - void *opaque; /* can be used to hold any information - this value is copied to all - instances */ - struct - { - size_t size; /* allocated size */ - size_t start; /* number of invalid bytes at the - begin of the buffer */ - size_t len; /* currently filled to this size */ - byte *buf; - } - unget; -}; - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int iobuf_debug_mode; - -void iobuf_enable_special_filenames (int yes); -iobuf_t iobuf_alloc (int use, size_t bufsize); -iobuf_t iobuf_temp (void); -iobuf_t iobuf_temp_with_content (const char *buffer, size_t length); -iobuf_t iobuf_open (const char *fname); -iobuf_t iobuf_fdopen (int fd, const char *mode); -iobuf_t iobuf_sockopen (int fd, const char *mode); -iobuf_t iobuf_create (const char *fname); -iobuf_t iobuf_append (const char *fname); -iobuf_t iobuf_openrw (const char *fname); -int iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval); -int iobuf_close (iobuf_t iobuf); -int iobuf_cancel (iobuf_t iobuf); - -int iobuf_push_filter (iobuf_t a, int (*f) (void *opaque, int control, - iobuf_t chain, byte * buf, - size_t * len), void *ov); -int iobuf_push_filter2 (iobuf_t a, - int (*f) (void *opaque, int control, iobuf_t chain, - byte * buf, size_t * len), void *ov, - int rel_ov); -int iobuf_flush (iobuf_t a); -void iobuf_clear_eof (iobuf_t a); -#define iobuf_set_error(a) do { (a)->error = 1; } while(0) -#define iobuf_error(a) ((a)->error) - -void iobuf_set_limit (iobuf_t a, off_t nlimit); - -off_t iobuf_tell (iobuf_t a); -int iobuf_seek (iobuf_t a, off_t newpos); - -int iobuf_readbyte (iobuf_t a); -int iobuf_read (iobuf_t a, byte * buf, unsigned buflen); -unsigned iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, - unsigned *length_of_buffer, unsigned *max_length); -int iobuf_peek (iobuf_t a, byte * buf, unsigned buflen); -int iobuf_writebyte (iobuf_t a, unsigned c); -int iobuf_write (iobuf_t a, byte * buf, unsigned buflen); -int iobuf_writestr (iobuf_t a, const char *buf); - -void iobuf_flush_temp (iobuf_t temp); -int iobuf_write_temp (iobuf_t a, iobuf_t temp); -size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen); -void iobuf_unget_and_close_temp (iobuf_t a, iobuf_t temp); - -off_t iobuf_get_filelength (iobuf_t a); -#define IOBUF_FILELENGTH_LIMIT 0xffffffff -const char *iobuf_get_real_fname (iobuf_t a); -const char *iobuf_get_fname (iobuf_t a); - -void iobuf_set_block_mode (iobuf_t a, size_t n); -void iobuf_set_partial_block_mode (iobuf_t a, size_t len); -int iobuf_in_block_mode (iobuf_t a); - -int iobuf_translate_file_handle (int fd, int for_write); - - -/* get a byte form the iobuf; must check for eof prior to this function - * this function returns values in the range 0 .. 255 or -1 to indicate EOF - * iobuf_get_noeof() does not return -1 to indicate EOF, but masks the - * returned value to be in the range 0 ..255. - */ -#define iobuf_get(a) \ - ( ((a)->nofast || (a)->d.start >= (a)->d.len )? \ - iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) ) -#define iobuf_get_noeof(a) (iobuf_get((a))&0xff) - -/* write a byte to the iobuf and return true on write error - * This macro does only write the low order byte - */ -#define iobuf_put(a,c) iobuf_writebyte(a,c) - -#define iobuf_where(a) "[don't know]" -#define iobuf_id(a) ((a)->no) - -#define iobuf_get_temp_buffer(a) ( (a)->d.buf ) -#define iobuf_get_temp_length(a) ( (a)->d.len ) -#define iobuf_is_temp(a) ( (a)->use == 3 ) - -#endif /*GNUPG_COMMON_IOBUF_H*/ diff --git a/common/isascii.c b/common/isascii.c deleted file mode 100644 index 565c71664..000000000 --- a/common/isascii.c +++ /dev/null @@ -1,29 +0,0 @@ -/* isascii.c - Replacement for isascii. - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -int -isascii (int c) -{ - return (((c) & ~0x7f) == 0); -} diff --git a/common/maperror.c b/common/maperror.c deleted file mode 100644 index 2f6f1b159..000000000 --- a/common/maperror.c +++ /dev/null @@ -1,105 +0,0 @@ -/* maperror.c - Error mapping - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "util.h" -#include "errors.h" - - -/* Map Assuan error code ERR to an GPG_ERR_ code. We need to - distinguish between genuine (and legacy) Assuan error codes and - application error codes shared with all GnuPG modules. The rule is - simple: All errors with a gpg_err_source of UNKNOWN are genuine - Assuan codes all others are passed verbatim through. */ -gpg_error_t -map_assuan_err (int err) -{ - gpg_err_code_t ec; - - if (gpg_err_source (err)) - return err; - - switch (err) - { - case -1: ec = GPG_ERR_EOF; break; - case 0: ec = 0; break; - - case ASSUAN_Canceled: ec = GPG_ERR_CANCELED; break; - case ASSUAN_Invalid_Index: ec = GPG_ERR_INV_INDEX; break; - - case ASSUAN_Not_Implemented: ec = GPG_ERR_NOT_IMPLEMENTED; break; - case ASSUAN_Server_Fault: ec = GPG_ERR_ASSUAN_SERVER_FAULT; break; - case ASSUAN_No_Public_Key: ec = GPG_ERR_NO_PUBKEY; break; - case ASSUAN_No_Secret_Key: ec = GPG_ERR_NO_SECKEY; break; - - case ASSUAN_Cert_Revoked: ec = GPG_ERR_CERT_REVOKED; break; - case ASSUAN_No_CRL_For_Cert: ec = GPG_ERR_NO_CRL_KNOWN; break; - case ASSUAN_CRL_Too_Old: ec = GPG_ERR_CRL_TOO_OLD; break; - - case ASSUAN_Not_Trusted: ec = GPG_ERR_NOT_TRUSTED; break; - - case ASSUAN_Card_Error: ec = GPG_ERR_CARD; break; - case ASSUAN_Invalid_Card: ec = GPG_ERR_INV_CARD; break; - case ASSUAN_No_PKCS15_App: ec = GPG_ERR_NO_PKCS15_APP; break; - case ASSUAN_Card_Not_Present: ec= GPG_ERR_CARD_NOT_PRESENT; break; - case ASSUAN_Not_Confirmed: ec = GPG_ERR_NOT_CONFIRMED; break; - case ASSUAN_Invalid_Id: ec = GPG_ERR_INV_ID; break; - - case ASSUAN_Locale_Problem: ec = GPG_ERR_LOCALE_PROBLEM; break; - - default: - ec = err < 100? GPG_ERR_ASSUAN_SERVER_FAULT : GPG_ERR_ASSUAN; - break; - } - return gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, ec); -} - -/* Map GPG_xERR_xx error codes to Assuan status codes */ -int -map_to_assuan_status (int rc) -{ - gpg_err_code_t ec = gpg_err_code (rc); - gpg_err_source_t es = gpg_err_source (rc); - - if (!rc) - return 0; - if (!es) - { - es = GPG_ERR_SOURCE_USER_4; /* This should not happen, but we - need to make sure to pass a new - Assuan errorcode along. */ - log_debug ("map_to_assuan_status called with no error source\n"); - } - - if (ec == -1) - ec = GPG_ERR_NO_DATA; /* That used to be ASSUAN_No_Data_Available. */ - - return gpg_err_make (es, ec); -} diff --git a/common/membuf.c b/common/membuf.c deleted file mode 100644 index 69e4ab908..000000000 --- a/common/membuf.c +++ /dev/null @@ -1,89 +0,0 @@ -/* membuf.c - A simple implementation of a dynamic buffer - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "membuf.h" - -#include "util.h" - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -void -init_membuf (membuf_t *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = errno; -} - - -void -put_membuf (membuf_t *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = errno; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - - -void * -get_membuf (membuf_t *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */ - return p; -} diff --git a/common/membuf.h b/common/membuf.h deleted file mode 100644 index c199363cc..000000000 --- a/common/membuf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* membuf.h - A simple implementation of a dynamic buffer - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_MEMBUF_H -#define GNUPG_COMMON_MEMBUF_H - -/* The definition of the structure is private, we only need it here, - so it can be allocated on the stack. */ -struct private_membuf_s { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - -typedef struct private_membuf_s membuf_t; - - -void init_membuf (membuf_t *mb, int initiallen); -void put_membuf (membuf_t *mb, const void *buf, size_t len); -void *get_membuf (membuf_t *mb, size_t *len); - - -#endif /*GNUPG_COMMON_MEMBUF_H*/ diff --git a/common/miscellaneous.c b/common/miscellaneous.c deleted file mode 100644 index 86b0fcb3a..000000000 --- a/common/miscellaneous.c +++ /dev/null @@ -1,127 +0,0 @@ -/* miscellaneous.c - Stuff not fitting elsewhere - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "util.h" -#include "iobuf.h" - - -/* Decide whether the filename is stdout or a real filename and return - * an appropriate string. */ -const char * -print_fname_stdout (const char *s) -{ - if( !s || (*s == '-' && !s[1]) ) - return "[stdout]"; - return s; -} - - -/* Decide whether the filename is stdin or a real filename and return - * an appropriate string. */ -const char * -print_fname_stdin (const char *s) -{ - if( !s || (*s == '-' && !s[1]) ) - return "[stdin]"; - return s; -} - -void -print_string( FILE *fp, const byte *p, size_t n, int delim ) -{ - print_sanitized_buffer (fp, p, n, delim); -} - -void -print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim ) -{ - print_sanitized_utf8_buffer (fp, p, n, delim); -} - -void -print_utf8_string( FILE *fp, const byte *p, size_t n ) -{ - print_utf8_string2 (fp, p, n, 0); -} - -char * -make_printable_string( const byte *p, size_t n, int delim ) -{ - return sanitize_buffer (p, n, delim); -} - - -/* - * Check if the file is compressed. - */ -int -is_file_compressed (const char *s, int *ret_rc) -{ - iobuf_t a; - byte buf[4]; - int i, rc = 0; - - struct magic_compress_s { - size_t len; - byte magic[4]; - } magic[] = { - { 3, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ - { 3, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ - { 4, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ - }; - - if ( !s || (*s == '-' && !s[1]) || !ret_rc ) - return 0; /* We can't check stdin or no file was given */ - - a = iobuf_open( s ); - if ( a == NULL ) { - *ret_rc = gpg_error_from_errno (errno); - return 0; - } - - if ( iobuf_get_filelength( a ) < 4 ) { - *ret_rc = 0; - goto leave; - } - - if ( iobuf_read( a, buf, 4 ) == -1 ) { - *ret_rc = a->error; - goto leave; - } - - for ( i = 0; i < DIM( magic ); i++ ) { - if ( !memcmp( buf, magic[i].magic, magic[i].len ) ) { - *ret_rc = 0; - rc = 1; - break; - } - } - -leave: - iobuf_close( a ); - return rc; -} - - - diff --git a/common/mkdtemp.c b/common/mkdtemp.c deleted file mode 100644 index abe731e0a..000000000 --- a/common/mkdtemp.c +++ /dev/null @@ -1,96 +0,0 @@ -/* mkdtemp.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a replacement function for mkdtemp in case the platform - we're building on (like mine!) doesn't have it. */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MKDIR_TAKES_ONE_ARG -# undef mkdir -# define mkdir(a,b) mkdir(a) -#endif - -char *mkdtemp(char *template) -{ - int attempts,idx,count=0; - unsigned char *ch; - - idx=strlen(template); - - /* Walk backwards to count all the Xes */ - while(idx>0 && template[idx-1]=='X') - { - count++; - idx--; - } - - if(count==0) - { - errno=EINVAL; - return NULL; - } - - ch=&template[idx]; - - /* Try 4 times to make the temp directory */ - for(attempts=0;attempts<4;attempts++) - { - int remaining=count; - char *marker=ch; - unsigned char *randombits; - - idx=0; - - randombits = gcry_xmalloc (4*remaining); - gcry_create_nonce (randombits, 4*remaining); - - while(remaining>1) - { - sprintf(marker,"%02X",randombits[idx++]); - marker+=2; - remaining-=2; - } - - /* Any leftover Xes? get_random_bits rounds up to full bytes, - so this is safe. */ - if(remaining>0) - sprintf(marker,"%X",randombits[idx]&0xF); - - gcry_free (randombits); - - if(mkdir(template,0700)==0) - break; - } - - if(attempts==4) - return NULL; /* keeps the errno from mkdir, whatever it is */ - - return template; -} - - diff --git a/common/mkerrors b/common/mkerrors deleted file mode 100755 index 5a1ef33da..000000000 --- a/common/mkerrors +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from errors.h -# and create C source for gnupg_strerror -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -cat < -#include -#include "errors.h" - -/** - * gnupg_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -gnupg_strerror (int err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/GNUPG_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/GNUPG_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,7)); -} -' - -cat < -#endif - -#include - -int -putc_unlocked (int c, FILE *stream) -{ - return putc (c, stream); -} diff --git a/common/sexp-parse.h b/common/sexp-parse.h deleted file mode 100644 index 89aa7210f..000000000 --- a/common/sexp-parse.h +++ /dev/null @@ -1,99 +0,0 @@ -/* sexp-parse.h - S-Exp helper functions - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SEXP_PARSE_H -#define SEXP_PARSE_H - -#include - -/* Return the length of the next S-Exp part and update the pointer to - the first data byte. 0 is returned on error */ -static inline size_t -snext (unsigned char const **buf) -{ - const unsigned char *s; - int n; - - s = *buf; - for (n=0; *s && *s != ':' && (*s >= '0' && *s <= '9'); s++) - n = n*10 + (*s - '0'); - if (!n || *s != ':') - return 0; /* we don't allow empty lengths */ - *buf = s+1; - return n; -} - -/* Skip over the S-Expression BUF points to and update BUF to point to - the chacter right behind. DEPTH gives the initial number of open - lists and may be passed as a positive number to skip over the - remainder of an S-Expression if the current position is somewhere - in an S-Expression. The function may return an error code if it - encounters an impossible conditions */ -static inline gpg_error_t -sskip (unsigned char const **buf, int *depth) -{ - const unsigned char *s = *buf; - size_t n; - int d = *depth; - - while (d > 0) - { - if (*s == '(') - { - d++; - s++; - } - else if (*s == ')') - { - d--; - s++; - } - else - { - if (!d) - return gpg_error (GPG_ERR_INV_SEXP); - n = snext (&s); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); - s += n; - } - } - *buf = s; - *depth = d; - return 0; -} - - -/* Check whether the the string at the address BUF points to matches - the token. Return true on match and update BUF to point behind the - token. Return false and dont update tha buffer if it does not - match. */ -static inline int -smatch (unsigned char const **buf, size_t buflen, const char *token) -{ - size_t toklen = strlen (token); - - if (buflen != toklen || memcmp (*buf, token, toklen)) - return 0; - *buf += toklen; - return 1; -} - -#endif /*SEXP_PARSE_H*/ diff --git a/common/signal.c b/common/signal.c deleted file mode 100644 index dc026c10f..000000000 --- a/common/signal.c +++ /dev/null @@ -1,226 +0,0 @@ -/* signal.c - signal handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util.h" - - -static volatile int caught_fatal_sig; -static volatile int caught_sigusr1; -static void (*cleanup_fnc)(void); - - -static void -init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_SIGACTION - struct sigaction oact, nact; - - if (check_ign) - { - /* we don't want to change an IGN handler */ - sigaction (sig, NULL, &oact ); - if (oact.sa_handler == SIG_IGN ) - return; - } - - nact.sa_handler = handler; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - sigaction ( sig, &nact, NULL); -# else - RETSIGTYPE (*ohandler)(int); - - ohandler = signal (sig, handler); - if (check_ign && ohandler == SIG_IGN) - { - /* Change it back if it was already set to IGN */ - signal (sig, SIG_IGN); - } -# endif -#endif /*!HAVE_DOSISH_SYSTEM*/ -} - -static const char * -get_signal_name( int signum ) -{ -#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG) - return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?"; -#else - return "some signal"; -#endif -} - -static RETSIGTYPE -got_fatal_signal (int sig) -{ - const char *s; - - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - if (cleanup_fnc) - cleanup_fnc (); - /* better don't translate these messages */ - write (2, "\n", 1 ); - s = log_get_prefix (NULL); - if (s) - write(2, s, strlen (s)); - write (2, ": ", 2 ); - s = get_signal_name(sig); - write (2, s, strlen(s) ); - write (2, " caught ... exiting\n", 20); - - /* reset action to default action and raise signal again */ - init_one_signal (sig, SIG_DFL, 0); - /* fixme: remove_lockfiles ();*/ -#ifdef __riscos__ - close_fds (); -#endif /* __riscos__ */ - raise( sig ); -} - - -static RETSIGTYPE -got_usr_signal (int sig) -{ - caught_sigusr1 = 1; -} - - -void -gnupg_init_signals (int mode, void (*fast_cleanup)(void)) -{ - assert (!mode); - - cleanup_fnc = fast_cleanup; -#ifndef HAVE_DOSISH_SYSTEM - init_one_signal (SIGINT, got_fatal_signal, 1 ); - init_one_signal (SIGHUP, got_fatal_signal, 1 ); - init_one_signal (SIGTERM, got_fatal_signal, 1 ); - init_one_signal (SIGQUIT, got_fatal_signal, 1 ); - init_one_signal (SIGSEGV, got_fatal_signal, 1 ); - init_one_signal (SIGUSR1, got_usr_signal, 0 ); - init_one_signal (SIGPIPE, SIG_IGN, 0 ); -#endif -} - -void -gnupg_pause_on_sigusr (int which) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_SIGPROCMASK - sigset_t mask, oldmask; - - assert (which == 1); - sigemptyset( &mask ); - sigaddset( &mask, SIGUSR1 ); - - sigprocmask( SIG_BLOCK, &mask, &oldmask ); - while (!caught_sigusr1) - sigsuspend (&oldmask); - caught_sigusr1 = 0; - sigprocmask (SIG_UNBLOCK, &mask, NULL); -# else - assert (which == 1); - sighold (SIGUSR1); - while (!caught_sigusr1) - sigpause(SIGUSR1); - caught_sigusr1 = 0; - sigrelease(SIGUSR1); -# endif /*!HAVE_SIGPROCMASK*/ -#endif -} - - -static void -do_block( int block ) -{ -#ifndef HAVE_DOSISH_SYSTEM - static int is_blocked; -#ifdef HAVE_SIGPROCMASK - static sigset_t oldmask; - - if (block) - { - sigset_t newmask; - - if (is_blocked) - log_bug ("signals are already blocked\n"); - sigfillset( &newmask ); - sigprocmask( SIG_BLOCK, &newmask, &oldmask ); - is_blocked = 1; - } - else - { - if (!is_blocked) - log_bug("signals are not blocked\n"); - sigprocmask (SIG_SETMASK, &oldmask, NULL); - is_blocked = 0; - } -#else /*!HAVE_SIGPROCMASK*/ - static void (*disposition[MAXSIG])(); - int sig; - - if (block) - { - if (is_blocked) - log_bug("signals are already blocked\n"); - for (sig=1; sig < MAXSIG; sig++) - { - disposition[sig] = sigset (sig, SIG_HOLD); - } - is_blocked = 1; - } - else - { - if (!is_blocked) - log_bug ("signals are not blocked\n"); - for (sig=1; sig < MAXSIG; sig++) { - sigset (sig, disposition[sig]); - } - is_blocked = 0; - } -#endif /*!HAVE_SIGPROCMASK*/ -#endif /*HAVE_DOSISH_SYSTEM*/ -} - - -void -gnupg_block_all_signals () -{ - do_block(1); -} - -void -gnupg_unblock_all_signals () -{ - do_block(0); -} diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c deleted file mode 100644 index 36244b120..000000000 --- a/common/simple-pwquery.c +++ /dev/null @@ -1,493 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This module is intended as a standalone client implementation to - gpg-agent's GET_PASSPHRASE command. In particular it does not use - the Assuan library and can only cope with an already running - gpg-agent. Some stuff is configurable in the header file. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#define SIMPLE_PWQUERY_IMPLEMENTATION 1 -#include "simple-pwquery.h" - -#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING) -# undef SPWQ_USE_LOGGING -#endif - -#ifndef _ -#define _(a) (a) -#endif - -#if !defined (hexdigitp) && !defined (xtoi_2) -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#endif - - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { - nwritten = write( fd, buf, nleft ); - if (nwritten < 0) - { - if (errno == EINTR) - nwritten = 0; - else { -#ifdef SPWQ_USE_LOGGING - log_error ("write failed: %s\n", strerror (errno)); -#endif - return SPWQ_IO_ERROR; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - - return 0; -} - - -/* Read an entire line and return number of bytes read. */ -static int -readline (int fd, char *buf, size_t buflen) -{ - size_t nleft = buflen; - char *p; - int nread = 0; - - while (nleft > 0) - { - int n = read (fd, buf, nleft); - if (n < 0) - { - if (errno == EINTR) - continue; - return -(SPWQ_IO_ERROR); - } - else if (!n) - { - return -(SPWQ_PROTOCOL_ERROR); /* incomplete line */ - } - p = buf; - nleft -= n; - buf += n; - nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - break; /* at least one full line available - that's enough. - This function is just a simple implementation, so - it is okay to forget about pending bytes */ - } - } - - return nread; -} - - -/* Send an option to the agent */ -static int -agent_send_option (int fd, const char *name, const char *value) -{ - char buf[200]; - int nread; - char *line; - int i; - - line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2); - if (!line) - return SPWQ_OUT_OF_CORE; - strcpy (stpcpy (stpcpy (stpcpy ( - stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - spwq_free (line); - if (i) - return i; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 0) - return -nread; - if (nread < 3) - return SPWQ_PROTOCOL_ERROR; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ - - return SPWQ_ERR_RESPONSE; -} - - -/* Send all available options to the agent. */ -static int -agent_send_all_options (int fd) -{ - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - int rc = 0; - - dft_display = getenv ("DISPLAY"); - if (dft_display) - { - if ((rc = agent_send_option (fd, "display", dft_display))) - return rc; - } - - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - if (dft_ttyname && *dft_ttyname) - { - if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) - return rc; - } - - dft_ttytype = getenv ("TERM"); - if (dft_ttyname && dft_ttytype) - { - if ((rc = agent_send_option (fd, "ttytype", dft_ttytype))) - return rc; - } - -#if defined(HAVE_SETLOCALE) - { - char *old_lc = NULL; - char *dft_lc = NULL; - -#if defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_CTYPE, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-ctype", dft_lc); - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - -#if defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_MESSAGES, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-messages", dft_lc); - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - } -#endif /*HAVE_SETLOCALE*/ - - return 0; -} - - - -/* Try to open a connection to the agent, send all options and return - the file descriptor for the connection. Return -1 in case of - error. */ -static int -agent_open (int *rfd) -{ - int rc; - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - int prot; - char line[200]; - int nread; - - *rfd = -1; - infostr = getenv ( "GPG_AGENT_INFO" ); - if ( !infostr || !*infostr ) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent is not available in this session\n")); -#endif - return SPWQ_NO_AGENT; - } - p = spwq_malloc (strlen (infostr)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, infostr); - infostr = p; - - if ( !(p = strchr ( infostr, ':')) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("malformed GPG_AGENT_INFO environment variable\n")); -#endif - return SPWQ_NO_AGENT; - } - *p++ = 0; - - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if ( prot != 1) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent protocol version %d is not supported\n"),prot); -#endif - return SPWQ_PROTOCOL_ERROR; - } - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) - { -#ifdef SPWQ_USE_LOGGING - log_error ("can't create socket: %s\n", strerror(errno) ); -#endif - return SPWQ_SYS_ERROR; - } - - memset (&client_addr, 0, sizeof client_addr); - client_addr.sun_family = AF_UNIX; - strcpy (client_addr.sun_path, infostr); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(client_addr.sun_path) + 1); - - if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno)); -#endif - close (fd ); - return SPWQ_IO_ERROR; - } - - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("communication problem with gpg-agent\n")); -#endif - close (fd ); - return SPWQ_PROTOCOL_ERROR; - } - - rc = agent_send_all_options (fd); - if (rc) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem setting the gpg-agent options\n")); -#endif - close (fd); - return rc; - } - - *rfd = fd; - return 0; -} - - -/* Copy text to BUFFER and escape as required. Return a pointer to - the end of the new buffer. NOte that BUFFER must be large enough - to keep the entire text; allocataing it 3 times the size of TEXT - is sufficient. */ -static char * -copy_and_escape (char *buffer, const char *text) -{ - int i; - const unsigned char *s = text; - char *p = buffer; - - - for (i=0; s[i]; i++) - { - if (s[i] < ' ' || s[i] == '+') - { - sprintf (p, "%%%02X", s[i]); - p += 3; - } - else if (s[i] == ' ') - *p++ = '+'; - else - *p++ = s[i]; - } - return p; -} - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; thsi errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char * -simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode) -{ - int fd = -1; - int nread; - char *result = NULL; - char *pw = NULL; - char *p; - int rc, i; - - rc = agent_open (&fd); - if (rc) - goto leave; - - if (!cacheid) - cacheid = "X"; - if (!tryagain) - tryagain = "X"; - if (!prompt) - prompt = "X"; - if (!description) - description = "X"; - - { - char *line; - /* We allocate 3 times the needed space so that there is enough - space for escaping. */ - line = spwq_malloc (15 - + 3*strlen (cacheid) + 1 - + 3*strlen (tryagain) + 1 - + 3*strlen (prompt) + 1 - + 3*strlen (description) + 1 - + 2); - if (!line) - { - rc = SPWQ_OUT_OF_CORE; - goto leave; - } - strcpy (line, "GET_PASSPHRASE "); - p = line+15; - p = copy_and_escape (p, cacheid); - *p++ = ' '; - p = copy_and_escape (p, tryagain); - *p++ = ' '; - p = copy_and_escape (p, prompt); - *p++ = ' '; - p = copy_and_escape (p, description); - *p++ = '\n'; - rc = writen (fd, line, p - line); - spwq_free (line); - if (rc) - goto leave; - } - - /* get response */ - pw = spwq_secure_malloc (500); - nread = readline (fd, pw, 499); - if (nread < 0) - { - rc = -nread; - goto leave; - } - if (nread < 3) - { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } - - if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') - { /* we got a passphrase - convert it back from hex */ - size_t pwlen = 0; - - for (i=3; i < nread && hexdigitp (pw+i); i+=2) - pw[pwlen++] = xtoi_2 (pw+i); - pw[pwlen] = 0; /* make a C String */ - result = pw; - pw = NULL; - } - else if (nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - { -#ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); -#endif - *errorcode = 0; /* canceled */ - } - else - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent\n")); -#endif - rc = SPWQ_ERR_RESPONSE; - } - - leave: - if (errorcode) - *errorcode = rc; - if (fd != -1) - close (fd); - if (pw) - spwq_free (pw); - return result; -} diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h deleted file mode 100644 index 5947c42b5..000000000 --- a/common/simple-pwquery.h +++ /dev/null @@ -1,69 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SIMPLE_PWQUERY_H -#define SIMPLE_PWQUERY_H - -#ifdef SIMPLE_PWQUERY_IMPLEMENTATION /* Begin configuration stuff. */ - -/* Include whatever files you need. */ -#include -#include "../jnlib/logging.h" - -/* Try to write error message using the standard log mechanism. The - current implementation requires that the HAVE_JNLIB_LOGGING is also - defined. */ -#define SPWQ_USE_LOGGING 1 - -/* Memory allocation functions used by the implementation. Note, that - the returned value is expected to be freed with - spwq_secure_free. */ -#define spwq_malloc(a) gcry_malloc (a) -#define spwq_free(a) gcry_free (a) -#define spwq_secure_malloc(a) gcry_malloc_secure (a) -#define spwq_secure_free(a) gcry_free (a) - - -#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */ - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; this errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char *simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode); - - -#define SPWQ_OUT_OF_CORE 1 -#define SPWQ_IO_ERROR 2 -#define SPWQ_PROTOCOL_ERROR 3 -#define SPWQ_ERR_RESPONSE 4 -#define SPWQ_NO_AGENT 5 -#define SPWQ_SYS_ERROR 6 -#define SPWQ_GENERAL_ERROR 7 - -#endif /*SIMPLE_PWQUERY_H*/ diff --git a/common/sysutils.c b/common/sysutils.c deleted file mode 100644 index 97fa23d95..000000000 --- a/common/sysutils.c +++ /dev/null @@ -1,230 +0,0 @@ -/* sysutils.c - system helpers - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_STAT -#include -#endif -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 - #include - #include -#endif -#ifdef HAVE_SETRLIMIT - #include - #include - #include -#endif -#include "util.h" -#include "i18n.h" - -#include "sysutils.h" - -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -#warning using trap_unaligned -static int -setsysinfo(unsigned long op, void *buffer, unsigned long size, - int *start, void *arg, unsigned long flag) -{ - return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); -} - -void -trap_unaligned(void) -{ - unsigned int buf[2]; - - buf[0] = SSIN_UACPROC; - buf[1] = UAC_SIGBUS | UAC_NOPRINT; - setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); -} -#else -void -trap_unaligned(void) -{ /* dummy */ -} -#endif - - -int -disable_core_dumps (void) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -# ifdef HAVE_SETRLIMIT - struct rlimit limit; - - /* We only set the current limit unless we were not able to - retrieve the old value. */ - if (getrlimit (RLIMIT_CORE, &limit)) - limit.rlim_max = 0; - limit.rlim_cur = 0; - if( !setrlimit (RLIMIT_CORE, &limit) ) - return 0; - if( errno != EINVAL && errno != ENOSYS ) - log_fatal (_("can't disable core dumps: %s\n"), strerror(errno) ); -#endif - return 1; -#endif -} - -int -enable_core_dumps (void) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -# ifdef HAVE_SETRLIMIT - struct rlimit limit; - - if (getrlimit (RLIMIT_CORE, &limit)) - return 1; - limit.rlim_cur = limit.rlim_max; - setrlimit (RLIMIT_CORE, &limit); - return 1; /* We always return true because trhis function is - merely a debugging aid. */ -#endif - return 1; -#endif -} - - - -/* Return a string which is used as a kind of process ID */ -const byte * -get_session_marker( size_t *rlen ) -{ - static byte marker[SIZEOF_UNSIGNED_LONG*2]; - static int initialized; - - if ( !initialized ) { - volatile ulong aa, bb; /* we really want the uninitialized value */ - ulong a, b; - - initialized = 1; - /* also this marker is guessable it is not easy to use this - * for a faked control packet because an attacker does not - * have enough control about the time the verification does - * take place. Of course, we can add just more random but - * than we need the random generator even for verification - * tasks - which does not make sense. */ - a = aa ^ (ulong)getpid(); - b = bb ^ (ulong)time(NULL); - memcpy( marker, &a, SIZEOF_UNSIGNED_LONG ); - memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG ); - } - *rlen = sizeof(marker); - return marker; -} - - -#if 0 /* not yet needed - Note that this will require inclusion of - cmacros.am in Makefile.am */ -int -check_permissions(const char *path,int extension,int checkonly) -{ -#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - char *tmppath; - struct stat statbuf; - int ret=1; - int isdir=0; - - if(opt.no_perm_warn) - return 0; - - if(extension && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=m_strdup(path); - - /* It's okay if the file doesn't exist */ - if(stat(tmppath,&statbuf)!=0) - { - ret=0; - goto end; - } - - isdir=S_ISDIR(statbuf.st_mode); - - /* Per-user files must be owned by the user. Extensions must be - owned by the user or root. */ - if((!extension && statbuf.st_uid != getuid()) || - (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid())) - { - if(!checkonly) - log_info(_("Warning: unsafe ownership on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - /* This works for both directories and files - basically, we don't - care what the owner permissions are, so long as the group and - other permissions are 0 for per-user files, and non-writable for - extensions. */ - if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) || - (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0)) - { - char *dir; - - /* However, if the directory the directory/file is in is owned - by the user and is 700, then this is not a problem. - Theoretically, we could walk this test up to the root - directory /, but for the sake of sanity, I'm stopping at one - level down. */ - - dir= make_dirname (tmppath); - if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() && - S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - { - xfree (dir); - ret=0; - goto end; - } - - m_free(dir); - - if(!checkonly) - log_info(_("Warning: unsafe permissions on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - ret=0; - - end: - m_free(tmppath); - - return ret; - -#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ - - return 0; -} -#endif diff --git a/common/sysutils.h b/common/sysutils.h deleted file mode 100644 index 66f714acd..000000000 --- a/common/sysutils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* sysutils.h - System utility functions for Gnupg - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_SYSUTILS_H -#define GNUPG_COMMON_SYSUTILS_H - -void trap_unaligned (void); -int disable_core_dumps (void); -int enable_core_dumps (void); -const unsigned char *get_session_marker (size_t *rlen); -int check_permissions (const char *path,int extension,int checkonly); - - -#endif /*GNUPG_COMMON_SYSUTILS_H*/ diff --git a/common/ttyio.c b/common/ttyio.c deleted file mode 100644 index eab805e20..000000000 --- a/common/ttyio.c +++ /dev/null @@ -1,555 +0,0 @@ -/* ttyio.c - tty i/O functions - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_TCGETATTR -#include -#else -#ifdef HAVE_TERMIO_H -/* simulate termios with termio */ -#include -#define termios termio -#define tcsetattr ioctl -#define TCSAFLUSH TCSETAF -#define tcgetattr(A,B) ioctl(A,TCGETA,B) -#define HAVE_TCGETATTR -#endif -#endif -#ifdef _WIN32 /* use the odd Win32 functions */ -#include -#ifdef HAVE_TCGETATTR -#error mingw32 and termios -#endif -#endif -#include -#include -#include "util.h" -#include "memory.h" -#include "ttyio.h" - -#define CONTROL_D ('D' - 'A' + 1) - -#ifdef _WIN32 /* use the odd Win32 functions */ -static struct { - HANDLE in, out; -} con; -#define DEF_INPMODE (ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT \ - |ENABLE_PROCESSED_INPUT ) -#define HID_INPMODE (ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT ) -#define DEF_OUTMODE (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT) - -#else /* yeah, we have a real OS */ -static FILE *ttyfp = NULL; -#endif - -static int initialized; -static int last_prompt_len; -static int batchmode; -static int no_terminal; - -#ifdef HAVE_TCGETATTR - static struct termios termsave; - static int restore_termios; -#endif - - - -/* This is a wrapper around ttyname so that we can use it even when - the standard streams are redirected. It figures the name out the - first time and returns it in a statically allocated buffer. */ -const char * -tty_get_ttyname (void) -{ - static char *name; - - /* On a GNU system ctermid() always return /dev/tty, so this does - not make much sense - however if it is ever changed we do the - Right Thing now. */ -#ifdef HAVE_CTERMID - static int got_name; - - if (!got_name) - { - const char *s; - s = ctermid (NULL); - if (s) - name = strdup (s); - got_name = 1; - } -#endif - /* Assume the staandrd tty on memory error or when tehre is no - certmid. */ - return name? name : "/dev/tty"; -} - - - -#ifdef HAVE_TCGETATTR -static void -cleanup(void) -{ - if( restore_termios ) { - restore_termios = 0; /* do it prios in case it is interrupted again */ - if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) ) - log_error("tcsetattr() failed: %s\n", strerror(errno) ); - } -} -#endif - -static void -init_ttyfp(void) -{ - if( initialized ) - return; - -#if defined(_WIN32) - { - SECURITY_ATTRIBUTES sa; - - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - con.out = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - &sa, OPEN_EXISTING, 0, 0 ); - if( con.out == INVALID_HANDLE_VALUE ) - log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() ); - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - &sa, OPEN_EXISTING, 0, 0 ); - if( con.in == INVALID_HANDLE_VALUE ) - log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() ); - } - SetConsoleMode(con.in, DEF_INPMODE ); - SetConsoleMode(con.out, DEF_OUTMODE ); - -#elif defined(__EMX__) - ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */ -#else - ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+"); - if( !ttyfp ) { - log_error("cannot open `%s': %s\n", tty_get_ttyname (), - strerror(errno) ); - exit(2); - } -#endif -#ifdef HAVE_TCGETATTR - atexit( cleanup ); -#endif - initialized = 1; -} - - -int -tty_batchmode( int onoff ) -{ - int old = batchmode; - if( onoff != -1 ) - batchmode = onoff; - return old; -} - -int -tty_no_terminal(int onoff) -{ - int old = no_terminal; - no_terminal = onoff ? 1 : 0; - return old; -} - -void -tty_printf( const char *fmt, ... ) -{ - va_list arg_ptr; - - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - - va_start( arg_ptr, fmt ) ; -#ifdef _WIN32 - { - char *buf = NULL; - int n; - DWORD nwritten; - - n = vasprintf(&buf, fmt, arg_ptr); - if( !buf ) - log_bug("vasprintf() failed\n"); - - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); - last_prompt_len += n; - xfree (buf); - } -#else - last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; - fflush(ttyfp); -#endif - va_end(arg_ptr); -} - - -/* Same as tty_printf but if FP is not NULL, behave like a regualr - fprintf. */ -void -tty_fprintf (FILE *fp, const char *fmt, ... ) -{ - va_list arg_ptr; - - if (fp) - { - va_start (arg_ptr, fmt) ; - vfprintf (fp, fmt, arg_ptr ); - va_end (arg_ptr); - return; - } - - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - - va_start( arg_ptr, fmt ) ; -#ifdef _WIN32 - { - char *buf = NULL; - int n; - DWORD nwritten; - - n = vasprintf(&buf, fmt, arg_ptr); - if( !buf ) - log_bug("vasprintf() failed\n"); - - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); - last_prompt_len += n; - xfree (buf); - } -#else - last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; - fflush(ttyfp); -#endif - va_end(arg_ptr); -} - - -/**************** - * Print a string, but filter all control characters out. - */ -void -tty_print_string ( const byte *p, size_t n ) -{ - if (no_terminal) - return; - - if( !initialized ) - init_ttyfp(); - -#ifdef _WIN32 - /* not so effective, change it if you want */ - for( ; n; n--, p++ ) - if( iscntrl( *p ) ) { - if( *p == '\n' ) - tty_printf("\\n"); - else if( !*p ) - tty_printf("\\0"); - else - tty_printf("\\x%02x", *p); - } - else - tty_printf("%c", *p); -#else - for( ; n; n--, p++ ) - if( iscntrl( *p ) ) { - putc('\\', ttyfp); - if( *p == '\n' ) - putc('n', ttyfp); - else if( !*p ) - putc('0', ttyfp); - else - fprintf(ttyfp, "x%02x", *p ); - } - else - putc(*p, ttyfp); -#endif -} - -void -tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) -{ - size_t i; - char *buf; - - if (no_terminal) - return; - - /* we can handle plain ascii simpler, so check for it first */ - for(i=0; i < n; i++ ) { - if( p[i] & 0x80 ) - break; - } - if( i < n ) { - buf = utf8_to_native( p, n, 0 ); - if( max_n && (strlen( buf ) > max_n )) { - buf[max_n] = 0; - } - /*(utf8 conversion already does the control character quoting)*/ - tty_printf("%s", buf ); - xfree( buf ); - } - else { - if( max_n && (n > max_n) ) { - n = max_n; - } - tty_print_string( p, n ); - } -} - -void -tty_print_utf8_string( const byte *p, size_t n ) -{ - tty_print_utf8_string2( p, n, 0 ); -} - - -static char * -do_get( const char *prompt, int hidden ) -{ - char *buf; -#ifndef __riscos__ - byte cbuf[1]; -#endif - int c, n, i; - - if( batchmode ) { - log_error("Sorry, we are in batchmode - can't get input\n"); - exit(2); - } - - if (no_terminal) { - log_error("Sorry, no terminal at all requested - can't get input\n"); - exit(2); - } - - if( !initialized ) - init_ttyfp(); - - last_prompt_len = 0; - tty_printf( "%s", prompt ); - buf = xmalloc((n=50)); - i = 0; - -#ifdef _WIN32 /* windoze version */ - if( hidden ) - SetConsoleMode(con.in, HID_INPMODE ); - - for(;;) { - DWORD nread; - - if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) ) - log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() ); - if( !nread ) - continue; - if( *cbuf == '\n' ) - break; - - if( !hidden ) - last_prompt_len++; - c = *cbuf; - if( c == '\t' ) - c = ' '; - else if( c > 0xa0 ) - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - else if( iscntrl(c) ) - continue; - if( !(i < n-1) ) { - n += 50; - buf = xrealloc (buf, n); - } - buf[i++] = c; - } - - if( hidden ) - SetConsoleMode(con.in, DEF_INPMODE ); - -#elif defined(__riscos__) - do { - c = riscos_getchar(); - if (c == 0xa || c == 0xd) { /* Return || Enter */ - c = (int) '\n'; - } else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */ - if (i>0) { - i--; - if (!hidden) { - last_prompt_len--; - fputc(8, ttyfp); - fputc(32, ttyfp); - fputc(8, ttyfp); - fflush(ttyfp); - } - } else { - fputc(7, ttyfp); - fflush(ttyfp); - } - continue; - } else if (c == (int) '\t') { /* Tab */ - c = ' '; - } else if (c > 0xa0) { - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - } else if (iscntrl(c)) { - continue; - } - if(!(i < n-1)) { - n += 50; - buf = xrealloc (buf, n); - } - buf[i++] = c; - if (!hidden) { - last_prompt_len++; - fputc(c, ttyfp); - fflush(ttyfp); - } - } while (c != '\n'); - i = (i>0) ? i-1 : 0; -#else /* unix version */ - if( hidden ) { -#ifdef HAVE_TCGETATTR - struct termios term; - - if( tcgetattr(fileno(ttyfp), &termsave) ) - log_fatal("tcgetattr() failed: %s\n", strerror(errno) ); - restore_termios = 1; - term = termsave; - term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - if( tcsetattr( fileno(ttyfp), TCSAFLUSH, &term ) ) - log_fatal("tcsetattr() failed: %s\n", strerror(errno) ); -#endif - } - - /* fixme: How can we avoid that the \n is echoed w/o disabling - * canonical mode - w/o this kill_prompt can't work */ - while( read(fileno(ttyfp), cbuf, 1) == 1 && *cbuf != '\n' ) { - if( !hidden ) - last_prompt_len++; - c = *cbuf; - if( c == CONTROL_D ) - log_info("control d found\n"); - if( c == '\t' ) - c = ' '; - else if( c > 0xa0 ) - ; /* we don't allow 0xa0, as this is a protected blank which may - * confuse the user */ - else if( iscntrl(c) ) - continue; - if( !(i < n-1) ) { - n += 50; - buf = xrealloc (buf, n ); - } - buf[i++] = c; - } - if( *cbuf != '\n' ) { - buf[0] = CONTROL_D; - i = 1; - } - - - if( hidden ) { -#ifdef HAVE_TCGETATTR - if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) ) - log_error("tcsetattr() failed: %s\n", strerror(errno) ); - restore_termios = 0; -#endif - } -#endif /* end unix version */ - buf[i] = 0; - return buf; -} - - -char * -tty_get( const char *prompt ) -{ - return do_get( prompt, 0 ); -} - -char * -tty_get_hidden( const char *prompt ) -{ - return do_get( prompt, 1 ); -} - - -void -tty_kill_prompt() -{ - if ( no_terminal ) - return; - - if( !initialized ) - init_ttyfp(); - - if( batchmode ) - last_prompt_len = 0; - if( !last_prompt_len ) - return; -#ifdef _WIN32 - tty_printf("\r%*s\r", last_prompt_len, ""); -#else - { - int i; - putc('\r', ttyfp); - for(i=0; i < last_prompt_len; i ++ ) - putc(' ', ttyfp); - putc('\r', ttyfp); - fflush(ttyfp); - } -#endif - last_prompt_len = 0; -} - - -int -tty_get_answer_is_yes( const char *prompt ) -{ - int yes; - char *p = tty_get( prompt ); - tty_kill_prompt(); - yes = answer_is_yes(p); - xfree(p); - return yes; -} diff --git a/common/ttyio.h b/common/ttyio.h deleted file mode 100644 index 6fa7400a9..000000000 --- a/common/ttyio.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ttyio.h - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_COMMON_TTYIO_H -#define GNUPG_COMMON_TTYIO_H - -const char *tty_get_ttyname (void); -int tty_batchmode (int onoff); -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -void tty_printf (const char *fmt, ... ) - __attribute__ ((format (printf,1,2))); -void tty_fprintf (FILE *fp, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); -#else -void tty_printf (const char *fmt, ... ); -void tty_fprintf (FILE *fp, const char *fmt, ... ); -#endif -void tty_print_string (const unsigned char *p, size_t n); -void tty_print_utf8_string (const unsigned char *p, size_t n); -void tty_print_utf8_string2 (const unsigned char *p, size_t n, size_t max_n); -char *tty_get (const char *prompt); -char *tty_get_hidden (const char *prompt); -void tty_kill_prompt (void); -int tty_get_answer_is_yes (const char *prompt); -int tty_no_terminal (int onoff); - - -#endif /*GNUPG_COMMON_TTYIO_H*/ diff --git a/common/util.h b/common/util.h deleted file mode 100644 index b9ffe6562..000000000 --- a/common/util.h +++ /dev/null @@ -1,171 +0,0 @@ -/* util.h - Utility functions for GnuPG - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_COMMON_UTIL_H -#define GNUPG_COMMON_UTIL_H - -#include /* We need this for the memory function protos. */ -#include /* We need time_t. */ -#include /* we need gpg-error_t. */ - -/* to pass hash functions to libksba we need to cast it */ -#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) - -/* get all the stuff from jnlib */ -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../jnlib/mischelp.h" -#include "../jnlib/strlist.h" -#include "../jnlib/dotlock.h" -#include "../jnlib/utf8conv.h" - -/* Handy malloc macros - please use only them. */ -#define xtrymalloc(a) gcry_malloc ((a)) -#define xtrymalloc_secure(a) gcry_malloc_secure ((a)) -#define xtrycalloc(a,b) gcry_calloc ((a),(b)) -#define xtrycalloc_secure(a,b) gcry_calloc_secure ((a),(b)) -#define xtryrealloc(a,b) gcry_realloc ((a),(b)) -#define xtrystrdup(a) gcry_strdup ((a)) -#define xfree(a) gcry_free ((a)) - -#define xmalloc(a) gcry_xmalloc ((a)) -#define xmalloc_secure(a) gcry_xmalloc_secure ((a)) -#define xcalloc(a,b) gcry_xcalloc ((a),(b)) -#define xcalloc_secure(a,b) gcry_xcalloc_secure ((a),(b)) -#define xrealloc(a,b) gcry_xrealloc ((a),(b)) -#define xstrdup(a) gcry_xstrdup ((a)) - - -/* A type to hold the ISO time. Note that this this is the same as - the the KSBA type ksba_isotime_t. */ -typedef char gnupg_isotime_t[16]; - - -/*-- maperror.c --*/ -int map_kbx_err (int err); -gpg_error_t map_assuan_err (int err); -int map_to_assuan_status (int rc); - -/*-- gettime.c --*/ -time_t gnupg_get_time (void); -void gnupg_get_isotime (gnupg_isotime_t timebuf); -void gnupg_set_time (time_t newtime, int freeze); -int gnupg_faked_time_p (void); -u32 make_timestamp (void); -u32 scan_isodatestr (const char *string); -u32 add_days_to_timestamp (u32 stamp, u16 days); -const char *strtimevalue (u32 stamp); -const char *strtimestamp (u32 stamp); /* GMT */ -const char *asctimestamp (u32 stamp); /* localized */ - - -/* Copy one iso ddate to another, this is inline so that we can do a - sanity check. */ -static inline void -gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) -{ - if (*s && (strlen (s) != 15 || s[8] != 'T')) - BUG(); - strcpy (d, s); -} - - -/*-- signal.c --*/ -void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); -void gnupg_pause_on_sigusr (int which); -void gnupg_block_all_signals (void); -void gnupg_unblock_all_signals (void); - -/*-- yesno.c --*/ -int answer_is_yes (const char *s); -int answer_is_yes_no_default (const char *s, int def_answer); -int answer_is_yes_no_quit (const char *s); - -/*-- xreadline.c --*/ -ssize_t read_line (FILE *fp, - char **addr_of_buffer, size_t *length_of_buffer, - size_t *max_length); - - -/*-- b64enc.c --*/ -struct b64state -{ - unsigned int flags; - int idx; - int quad_count; - FILE *fp; - char *title; - unsigned char radbuf[4]; -}; -gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); -gpg_error_t b64enc_write (struct b64state *state, - const void *buffer, size_t nbytes); -gpg_error_t b64enc_finish (struct b64state *state); - - -/*-- miscellaneous.c --*/ - -/* Same as asprintf but return an allocated buffer suitable to be - freed using xfree. This function simply dies on memory failure, - thus no extra check is required. */ -char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); - -const char *print_fname_stdout (const char *s); -const char *print_fname_stdin (const char *s); -void print_string (FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string (FILE *fp, const byte *p, size_t n); -char *make_printable_string (const byte *p, size_t n, int delim); - -int is_file_compressed (const char *s, int *ret_rc); - - -/*-- replacement functions from funcname.c --*/ -#if !HAVE_VASPRINTF -#include -int vasprintf (char **result, const char *format, va_list args); -int asprintf (char **result, const char *format, ...) JNLIB_GCC_A_PRINTF(2,3); -#endif - - - -/*-- some macros to replace ctype ones and avoid locale problems --*/ -#define spacep(p) (*(p) == ' ' || *(p) == '\t') -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) - /* Note this isn't identical to a C locale isspace() without \f and - \v, but works for the purposes used here. */ -#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') - -/* The atoi macros assume that the buffer has only valid digits. */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2)) - - - -#endif /*GNUPG_COMMON_UTIL_H*/ diff --git a/common/vasprintf.c b/common/vasprintf.c deleted file mode 100644 index 9efea33f2..000000000 --- a/common/vasprintf.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Like vsprintf but provides a pointer to malloc'd storage, which must - be freed by the caller. - Copyright (C) 1994, 2002 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#ifdef TEST -int global_total_width; -#endif - -int -vasprintf (char **result, const char *format, va_list args) -{ - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - -#ifdef va_copy - va_copy (ap, args); -#else -#ifdef __va_copy - __va_copy (ap, args); -#else - memcpy (&ap, args, sizeof (va_list)); -#endif /* __va_copy */ -#endif /* va_copy */ - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s - and floats. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - { - char *tmp = va_arg (ap, char *); - if (tmp) - total_width += strlen (tmp); - else /* in case the vsprintf does prints a text */ - total_width += 25; /* e.g. "(null pointer reference)" */ - } - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - } - } -#ifdef TEST - global_total_width = total_width; -#endif - *result = malloc (total_width); - if (*result != NULL) - return vsprintf (*result, format, args); - else - return 0; -} - - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (buf, fmt, ap); - va_end (ap); - return status; -} - - -#ifdef TEST -void -checkit (const char* format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - vasprintf (&result, format, args); - if (strlen (result) < global_total_width) - printf ("PASS: "); - else - printf ("FAIL: "); - printf ("%d %s\n", global_total_width, result); -} - -int -main (void) -{ - checkit ("%d", 0x12345678); - checkit ("%200d", 5); - checkit ("%.300d", 6); - checkit ("%100.150d", 7); - checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ -777777777777777777333333333333366666666666622222222222777777777777733333"); - checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); -} -#endif /* TEST */ diff --git a/common/xasprintf.c b/common/xasprintf.c deleted file mode 100644 index 2c8fafc06..000000000 --- a/common/xasprintf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* xasprintf.c - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "util.h" -#include "iobuf.h" - -/* Same as asprintf but return an allocated buffer suitable to be - freed using xfree. This function simply dies on memory failure, - thus no extra check is required. */ -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *buf, *p; - - va_start (ap, fmt); - if (vasprintf (&buf, fmt, ap) < 0) - log_fatal ("asprintf failed: %s\n", strerror (errno)); - va_end (ap); - p = xstrdup (buf); - free (buf); - return p; -} diff --git a/common/xreadline.c b/common/xreadline.c deleted file mode 100644 index 85f0af02e..000000000 --- a/common/xreadline.c +++ /dev/null @@ -1,116 +0,0 @@ -/* xreadline.c - fgets replacement function - * Copyright (C) 1999, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include - -#include "util.h" - - -/* Same as fgets() but if the provided buffer is too short a larger - one will be allocated. This is similar to getline. A line is - considered a byte stream ending in a LF. - - If MAX_LENGTH is not NULL, it shall point to a value with the - maximum allowed allocation. - - Returns the length of the line. EOF is indicated by a line of - length zero. A truncated line is indicated my setting the value at - MAX_LENGTH to 0. If the returned value is less then 0 not enough - memory was enable and ERRNO is set accordingly. - - If a line has been truncated, the file pointer is moved forward to - the end of the line so that the next read start with tghe next - line. Note that MAX_LENGTH must be re-initialzied in this case.. - - Note: The returned buffer is allocated with enough extra space to - append a CR,LF,Nul - */ -ssize_t -read_line (FILE *fp, - char **addr_of_buffer, size_t *length_of_buffer, - size_t *max_length) -{ - int c; - char *buffer = *addr_of_buffer; - size_t length = *length_of_buffer; - size_t nbytes = 0; - size_t maxlen = max_length? *max_length : 0; - char *p; - - if (!buffer) - { /* No buffer given - allocate a new one. */ - length = 256; - buffer = xtrymalloc (length); - *addr_of_buffer = buffer; - if (!buffer) - { - *length_of_buffer = 0; - if (max_length) - *max_length = 0; - return -1; - } - *length_of_buffer = length; - } - - length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */ - p = buffer; - while ((c = getc (fp)) != EOF) - { - if (nbytes == length) - { /* Enlarge the buffer. */ - if (maxlen && length > maxlen) /* But not beyond our limit. */ - { - /* Skip the rest of the line. */ - while (c != '\n' && (c=getc (fp)) != EOF) - ; - *p++ = '\n'; /* Always append a LF (we reserved some space). */ - nbytes++; - if (max_length) - *max_length = 0; /* Indicate truncation. */ - break; /* the while loop. */ - } - length += 3; /* Adjust for the reserved bytes. */ - length += length < 1024? 256 : 1024; - *addr_of_buffer = xtryrealloc (buffer, length); - if (!*addr_of_buffer) - { - int save_errno = errno; - xfree (buffer); - *length_of_buffer = *max_length = 0; - errno = save_errno; - return -1; - } - buffer = *addr_of_buffer; - *length_of_buffer = length; - length -= 3; - p = buffer + nbytes; - } - *p++ = c; - nbytes++; - if (c == '\n') - break; - } - *p = 0; /* Make sure the line is a string. */ - - return nbytes; -} diff --git a/common/yesno.c b/common/yesno.c deleted file mode 100644 index 2a96b4e5d..000000000 --- a/common/yesno.c +++ /dev/null @@ -1,96 +0,0 @@ -/* yesno.c - Yes/No questions - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include - -#include "i18n.h" -#include "util.h" - -int -answer_is_yes_no_default( const char *s, int def_answer ) -{ - const char *long_yes = _("yes"); - const char *short_yes = _("yY"); - const char *long_no = _("no"); - const char *short_no = _("nN"); - - /* Note: we have to use the local dependent strcasecmp here */ - if( !strcasecmp(s, long_yes ) ) - return 1; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - /* test for no strings to catch ambiguities for the next test */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - /* test for the english version (for those who are used to type yes) */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - return def_answer; -} - -int -answer_is_yes( const char *s ) -{ - return answer_is_yes_no_default(s,0); -} - -/**************** - * Return 1 for yes, -1 for quit, or 0 for no - */ -int -answer_is_yes_no_quit( const char *s ) -{ - const char *long_yes = _("yes"); - const char *long_no = _("no"); - const char *long_quit = _("quit"); - const char *short_yes = _("yY"); - const char *short_no = _("nN"); - const char *short_quit = _("qQ"); - - /* Note: We have to use the locale dependent strcasecmp */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( !strcasecmp(s, long_yes ) ) - return 1; - if( !strcasecmp(s, long_quit ) ) - return -1; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - if( *s && strchr( short_quit, *s ) && !s[1] ) - return -1; - /* but not here */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( !ascii_strcasecmp(s, "quit" ) ) - return -1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - if( *s && strchr( "qQ", *s ) && !s[1] ) - return -1; - return 0; -} diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 4e611651e..000000000 --- a/configure.ac +++ /dev/null @@ -1,1123 +0,0 @@ -# configure.ac - for GnuPG 1.9 -# Copyright (C) 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -# Process this file with autoconf to produce a configure script. -AC_PREREQ(2.52) -min_automake_version="1.7.6" - -# Version number: Remember to change it immediately *after* a release. -# Add a "-cvs" prefix for non-released code. -AC_INIT(gnupg, 1.9.10-cvs, gnupg-devel@gnupg.org) -# Set development_version to yes if the minor number is odd or you -# feel that the default check for a development version is not -# sufficient. -development_version=yes -NEED_GPG_ERROR_VERSION=0.7 - -NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.1.94 - -NEED_LIBASSUAN_VERSION=0.6.6 - -NEED_KSBA_VERSION=0.9.7 - -NEED_OPENSC_VERSION=0.8.0 - - - -PACKAGE=$PACKAGE_NAME -PACKAGE_GT=${PACKAGE_NAME}2 -VERSION=$PACKAGE_VERSION - -AC_CONFIG_AUX_DIR(scripts) -AC_CONFIG_SRCDIR(sm/gpgsm.c) -AM_CONFIG_HEADER(config.h) -AC_CANONICAL_TARGET() -AM_INIT_AUTOMAKE($PACKAGE, $VERSION) - -AC_GNU_SOURCE - -# Some status variables to give feedback at the end of a configure run -have_gpg_error=no -have_libgcrypt=no -have_libassuan=no -have_ksba=no -have_opensc=no -have_pth=no - -GNUPG_BUILD_PROGRAM(gpg, yes) -GNUPG_BUILD_PROGRAM(gpgsm, yes) -GNUPG_BUILD_PROGRAM(agent, yes) -GNUPG_BUILD_PROGRAM(scdaemon, yes) - - -AC_SUBST(PACKAGE) -AC_SUBST(PACKAGE_GT) -AC_SUBST(VERSION) -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) -AC_DEFINE_UNQUOTED(PACKAGE_GT, "$PACKAGE_GT", - [Name of this package for gettext]) -AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) -AC_DEFINE_UNQUOTED(PACKAGE_BUGREPORT, "$PACKAGE_BUGREPORT", - [Bug report address]) -AC_DEFINE_UNQUOTED(NEED_LIBGCRYPT_VERSION, "$NEED_LIBGCRYPT_VERSION", - [Required version of Libgcrypt]) -AC_DEFINE_UNQUOTED(NEED_KSBA_VERSION, "$NEED_KSBA_VERSION", - [Required version of Libksba]) - - - -# The default is to use the modules from this package and the few -# other packages in a standard place; i.e where this package gets -# installed. With these options it is possible to override these -# ${prefix} depended values with fixed paths, which can't be replaced -# at make time. See also am/cmacros.am and the defaults in AH_BOTTOM. -AC_ARG_WITH(agent-pgm, - [ --with-agent-pgm=PATH Use PATH as the default for the agent)], - GNUPG_AGENT_PGM="$withval", GNUPG_AGENT_PGM="" ) -AC_SUBST(GNUPG_AGENT_PGM) -AM_CONDITIONAL(GNUPG_AGENT_PGM, test -n "$GNUPG_AGENT_PGM") -show_gnupg_agent_pgm="(default)" -test -n "$GNUPG_AGENT_PGM" && show_gnupg_agent_pgm="$GNUPG_AGENT_PGM" - -AC_ARG_WITH(pinentry-pgm, - [ --with-pinentry-pgm=PATH Use PATH as the default for the pinentry)], - GNUPG_PINENTRY_PGM="$withval", GNUPG_PINENTRY_PGM="" ) -AC_SUBST(GNUPG_PINENTRY_PGM) -AM_CONDITIONAL(GNUPG_PINENTRY_PGM, test -n "$GNUPG_PINENTRY_PGM") -show_gnupg_pinentry_pgm="(default)" -test -n "$GNUPG_PINENTRY_PGM" && show_gnupg_pinentry_pgm="$GNUPG_PINENTRY_PGM" - - -AC_ARG_WITH(scdaemon-pgm, - [ --with-scdaemon-pgm=PATH Use PATH as the default for the scdaemon)], - GNUPG_SCDAEMON_PGM="$withval", GNUPG_SCDAEMON_PGM="" ) -AC_SUBST(GNUPG_SCDAEMON_PGM) -AM_CONDITIONAL(GNUPG_SCDAEMON_PGM, test -n "$GNUPG_SCDAEMON_PGM") -show_gnupg_scdaemon_pgm="(default)" -test -n "$GNUPG_SCDAEMON_PGM" && show_gnupg_scdaemon_pgm="$GNUPG_SCDAEMON_PGM" - - -AC_ARG_WITH(dirmngr-pgm, - [ --with-dirmngr-pgm=PATH Use PATH as the default for the dirmngr)], - GNUPG_DIRMNGR_PGM="$withval", GNUPG_DIRMNGR_PGM="" ) -AC_SUBST(GNUPG_DIRMNGR_PGM) -AM_CONDITIONAL(GNUPG_DIRMNGR_PGM, test -n "$GNUPG_DIRMNGR_PGM") -show_gnupg_dirmngr_pgm="(default)" -test -n "$GNUPG_DIRMNGR_PGM" && show_gnupg_dirmngr_pgm="$GNUPG_DIRMNGR_PGM" - -AC_ARG_WITH(protect-tool-pgm, - [ --with-protect-tool-pgm=PATH Use PATH as the default for the protect-tool)], - GNUPG_PROTECT_TOOL_PGM="$withval", GNUPG_PROTECT_TOOL_PGM="" ) -AC_SUBST(GNUPG_PROTECT_TOOL_PGM) -AM_CONDITIONAL(GNUPG_PROTECT_TOOL_PGM, test -n "$GNUPG_PROTECT_TOOL_PGM") -show_gnupg_protect_tool_pgm="(default)" -test -n "$GNUPG_PROTECT_TOOL_PGM" \ - && show_gnupg_protect_tool_pgm="$GNUPG_PROTECT_TOOL_PGM" - - - -# Configure option to allow ot disallow execution of external -# programs, like a photo viewer. -AC_MSG_CHECKING([whether to enable external program execution]) -AC_ARG_ENABLE(exec, - AC_HELP_STRING([--disable-exec],[disable all external program execution]), - use_exec=$enableval) -AC_MSG_RESULT($use_exec) -if test "$use_exec" = no ; then - AC_DEFINE(NO_EXEC,1,[Define to disable all external program execution]) -fi - -if test "$use_exec" = yes ; then - AC_MSG_CHECKING([whether to enable photo ID viewing]) - AC_ARG_ENABLE(photo-viewers, - [ --disable-photo-viewers disable photo ID viewers], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_PHOTO_VIEWER,1,[define to disable photo viewing]) - fi],enableval=yes) - gnupg_cv_enable_photo_viewers=$enableval - AC_MSG_RESULT($enableval) - - if test "$gnupg_cv_enable_photo_viewers" = yes ; then - AC_MSG_CHECKING([whether to use a fixed photo ID viewer]) - AC_ARG_WITH(photo-viewer, - [ --with-photo-viewer=FIXED_VIEWER set a fixed photo ID viewer], - [if test "$withval" = yes ; then - withval=no - elif test "$withval" != no ; then - AC_DEFINE_UNQUOTED(FIXED_PHOTO_VIEWER,"$withval", - [if set, restrict photo-viewer to this]) - fi],withval=no) - AC_MSG_RESULT($withval) - fi - - AC_MSG_CHECKING([whether to enable external keyserver helpers]) - AC_ARG_ENABLE(keyserver-helpers, - [ --disable-keyserver-helpers disable all external keyserver support], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_KEYSERVER_HELPERS,1, - [define to disable keyserver helpers]) - fi],enableval=yes) - gnupg_cv_enable_keyserver_helpers=$enableval - AC_MSG_RESULT($enableval) - - if test "$gnupg_cv_enable_keyserver_helpers" = yes ; then - AC_MSG_CHECKING([whether LDAP keyserver support is requested]) - AC_ARG_ENABLE(ldap, - [ --disable-ldap disable LDAP keyserver interface], - try_ldap=$enableval, try_ldap=yes) - AC_MSG_RESULT($try_ldap) - - AC_MSG_CHECKING([whether HKP keyserver support is requested]) - AC_ARG_ENABLE(hkp, - [ --disable-hkp disable HKP keyserver interface], - try_hkp=$enableval, try_hkp=yes) - AC_MSG_RESULT($try_hkp) - - if test "$try_hkp" = yes ; then - AC_SUBST(GPGKEYS_HKP,"gpgkeys_hkp$EXEEXT") - fi - - AC_MSG_CHECKING([whether email keyserver support is requested]) - AC_ARG_ENABLE(mailto, - [ --disable-mailto disable email keyserver interface], - try_mailto=$enableval, try_mailto=yes) - AC_MSG_RESULT($try_mailto) - fi - - AC_MSG_CHECKING([whether keyserver exec-path is enabled]) - AC_ARG_ENABLE(keyserver-path, - [ --disable-keyserver-path disable the exec-path option for keyserver helpers], - [if test "$enableval" = no ; then - AC_DEFINE(DISABLE_KEYSERVER_PATH,1,[define to disable exec-path for keyserver helpers]) - fi],enableval=yes) - AC_MSG_RESULT($enableval) - fi - -AC_MSG_CHECKING([whether the included zlib is requested]) -AC_ARG_WITH(included-zlib, - [ --with-included-zlib use the zlib code included here], -[g10_force_zlib=yes], [g10_force_zlib=no] ) -AC_MSG_RESULT($g10_force_zlib) - -dnl -dnl Check whether we want to use Linux capabilities -dnl -AC_MSG_CHECKING([whether use of capabilities is requested]) -AC_ARG_WITH(capabilities, - [ --with-capabilities use linux capabilities [default=no]], -[use_capabilities="$withval"],[use_capabilities=no]) -AC_MSG_RESULT($use_capabilities) - - -AH_BOTTOM([ -/* Some global constants. */ -#ifdef HAVE_DRIVE_LETTERS -#define GNUPG_DEFAULT_HOMEDIR "c:/gnupg" -#elif defined(__VMS) -#define GNUPG_DEFAULT_HOMEDIR "/SYS\$LOGIN/gnupg" -#else -#define GNUPG_DEFAULT_HOMEDIR "~/.gnupg" -#endif -#define GNUPG_PRIVATE_KEYS_DIR "private-keys-v1.d" - -/* Tell libgcrypt not to use its own libgpg-error implementation. */ -#define USE_LIBGPG_ERROR 1 - -/* This is the major version number of GnuPG so that - source included files can test for this. Note, that\ - we use 2 here even for GnuPG 1.9.x. */ -#define GNUPG_MAJOR_VERSION 2 - -/* Now to separate file name parts. - Please note that the string version must not contain more - than one character because the code assumes strlen()==1 */ -#ifdef HAVE_DOSISH_SYSTEM -#define DIRSEP_C '\\' -#define EXTSEP_C '.' -#define DIRSEP_S "\\" -#define EXTSEP_S "." -#else -#define DIRSEP_C '/' -#define EXTSEP_C '.' -#define DIRSEP_S "/" -#define EXTSEP_S "." -#endif - -/* This is the same as VERSION, but should be overridden if the - platform cannot handle things like dots '.' in filenames. Set - SAFE_VERSION_DOT and SAFE_VERSION_DASH to whatever SAFE_VERSION - uses for dots and dashes. */ -#define SAFE_VERSION VERSION -#define SAFE_VERSION_DOT '.' -#define SAFE_VERSION_DASH '-' - -/* For some systems (DOS currently), we hardcode the path here. For - POSIX systems the values are constructed by the Makefiles, so that - the values may be overridden by the make invocations; this is to - comply with the GNU coding standards. */ -#ifdef HAVE_DRIVE_LETTERS -#define GNUPG_BINDIR "c:\\gnupg" -#define GNUPG_LIBEXECDIR "c:\\lib\\gnupg" -#define GNUPG_LIBDIR "c:\\lib\\gnupg" -#define GNUPG_DATADIR "c:\\lib\\gnupg" -#endif - -/* Setup the hardwired names of modules. */ -#ifndef GNUPG_DEFAULT_AGENT -#define GNUPG_DEFAULT_AGENT ( GNUPG_BINDIR DIRSEP_S "gpg-agent" ) -#endif -#ifndef GNUPG_DEFAULT_PINENTRY -#define GNUPG_DEFAULT_PINENTRY ( GNUPG_BINDIR DIRSEP_S "pinentry" ) -#endif -#ifndef GNUPG_DEFAULT_SCDAEMON -#define GNUPG_DEFAULT_SCDAEMON ( GNUPG_BINDIR DIRSEP_S "scdaemon" ) -#endif -#ifndef GNUPG_DEFAULT_DIRMNGR -#define GNUPG_DEFAULT_DIRMNGR ( GNUPG_BINDIR DIRSEP_S "dirmngr" ) -#endif -#ifndef GNUPG_DEFAULT_PROTECT_TOOL -#define GNUPG_DEFAULT_PROTECT_TOOL \ - ( GNUPG_LIBEXECDIR DIRSEP_S "gpg-protect-tool" ) -#endif - - -/* Derive some other constants. */ -#if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) -#define EXEC_TEMPFILE_ONLY -#endif - -]) - -AM_MAINTAINER_MODE - -# Checks for programs. -AC_PROG_MAKE_SET -AM_SANITY_CHECK -missing_dir=`cd $ac_aux_dir && pwd` -AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) -AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) -AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) -AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) -AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) -AC_PROG_AWK -AC_PROG_CC -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_RANLIB -AC_CHECK_TOOL(AR, ar, :) -AC_PATH_PROG(PERL,"perl") -AC_ISC_POSIX -AC_SYS_LARGEFILE -AC_CHECK_PROG(DOCBOOK_TO_MAN, docbook-to-man, yes, no) -AM_CONDITIONAL(HAVE_DOCBOOK_TO_MAN, test "$ac_cv_prog_DOCBOOK_TO_MAN" = yes) -GNUPG_CHECK_FAQPROG -GNUPG_CHECK_DOCBOOK_TO_TEXI - - -try_gettext=yes -have_dosish_system=no -case "${target}" in - *-*-mingw32*) - # special stuff for Windoze NT - ac_cv_have_dev_random=no - AC_DEFINE(USE_ONLY_8DOT3,1, - [set this to limit filenames to the 8.3 format]) - AC_DEFINE(HAVE_DRIVE_LETTERS,1, - [defined if we must run on a stupid file system]) - AC_DEFINE(USE_SIMPLE_GETTEXT,1, - [because the Unix gettext has too much overhead on - MingW32 systems and these systems lack Posix functions, - we use a simplified version of gettext]) - have_dosish_system=yes - try_gettext="no" - ;; - i?86-emx-os2 | i?86-*-os2*emx ) - # OS/2 with the EMX environment - ac_cv_have_dev_random=no - AC_DEFINE(HAVE_DRIVE_LETTERS) - have_dosish_system=yes - try_gettext="no" - ;; - - i?86-*-msdosdjgpp*) - # DOS with the DJGPP environment - ac_cv_have_dev_random=no - AC_DEFINE(HAVE_DRIVE_LETTERS) - have_dosish_system=yes - try_gettext="no" - ;; - - *-*-freebsd*) - # FreeBSD - CPPFLAGS="$CPPFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - ;; - - *-*-hpux*) - if test -z "$GCC" ; then - CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE" - fi - ;; - *-dec-osf4*) - if test -z "$GCC" ; then - # Suppress all warnings - # to get rid of the unsigned/signed char mismatch warnings. - CFLAGS="$CFLAGS -w" - fi - ;; - *-dec-osf5*) - if test -z "$GCC" ; then - # Use the newer compiler `-msg_disable ptrmismatch' to - # get rid of the unsigned/signed char mismatch warnings. - # Using this may hide other pointer mismatch warnings, but - # it at least lets other warning classes through - CFLAGS="$CFLAGS -msg_disable ptrmismatch" - fi - ;; - m68k-atari-mint) - ;; - *) - ;; -esac - -if test "$have_dosish_system" = yes; then - AC_DEFINE(HAVE_DOSISH_SYSTEM,1, - [defined if we run on some of the PCDOS like systems - (DOS, Windoze. OS/2) with special properties like - no file modes]) -fi -AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes) - - -# -# Checks for libraries. -# - - -# -# libgpg-error is a library with error codes shared between GnuPG -# related projects. -# -AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", - have_gpg_error=yes,have_gpg_error=no) - - -# -# Libgcrypt is our generic crypto library -# -AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", - have_libgcrypt=yes,have_libgcrypt=no) - - -# -# libassuan is used for IPC -# -AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION", - have_libassuan=yes,have_libassuan=no) - - -# -# libksba is our X.509 support library -# -AM_PATH_KSBA("$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) - -# -# libusb allows us to use the integrated CCID smartcard reader driver. -# -# Note, that we need the CVS version. FIXME: libusb should have a -# regular check as the other libraries do. -# -AC_CHECK_LIB(usb, usb_find_device, - [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" - AC_DEFINE(HAVE_LIBUSB,1, - [defined if libusb is available]) - ]) -AC_SUBST(LIBUSB_LIBS) - - -# -# OpenSC is needed by the SCdaemon - if it is not availbale we can only -# build a limited SCdaemon -# -AM_PATH_OPENSC("$NEED_OPENSC_VERSION",have_opensc=yes,have_opensc=no) -if test $have_opensc = yes; then - AC_DEFINE(HAVE_OPENSC,1, - [defined if the OpenSC library is available]) -fi - -# -# Check whether the (highly desirable) GNU Pth library is available -# -AC_ARG_WITH(pth-prefix, - AC_HELP_STRING([--with-pth-prefix=PFX], - [prefix where GNU Pth is installed (optional)]), - pth_config_prefix="$withval", pth_config_prefix="") -if test x$pth_config_prefix != x ; then - PTH_CONFIG="$pth_config_prefix/bin/pth-config" -fi -AC_PATH_PROG(PTH_CONFIG, pth-config, no) -if test "$PTH_CONFIG" = "no"; then - AC_MSG_WARN([[ -*** -*** To support concurrent access to the gpg-agent and the SCdaemon -*** we need the support of the GNU Portable Threads Library. -*** Download it from ftp://ftp.gnu.org/gnu/pth/ -*** On a Debian GNU/Linux system you might want to try -*** apt-get install libpth-dev -***]]) -else - GNUPG_PTH_VERSION_CHECK(1.3.7) - if test $have_pth = yes; then - PTH_CFLAGS=`$PTH_CONFIG --cflags` - PTH_LIBS=`$PTH_CONFIG --ldflags` - PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs`" - AC_DEFINE(USE_GNU_PTH, 1, - [Defined if the GNU Portable Thread Library should be used]) - fi -fi -AC_SUBST(PTH_CFLAGS) -AC_SUBST(PTH_LIBS) - -AC_ARG_ENABLE(threads, - AC_HELP_STRING([--disable-threads],[allow building without Pth support]); - -) - - -dnl Must check for network library requirements before doing link tests -dnl for ldap, for example. If ldap libs are static (or dynamic and without -dnl ELF runtime link paths), then link will fail and LDAP support won't -dnl be detected. - -AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname, - [NETLIBS="-lnsl $NETLIBS"])) -AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt, - [NETLIBS="-lsocket $NETLIBS"])) - -dnl Now try for the resolver functions so we can use DNS SRV - -AC_ARG_ENABLE(dns-srv, - AC_HELP_STRING([--disable-dns-srv],[disable the use of DNS SRV in HKP]), - use_dns_srv=$enableval,use_dns_srv=yes) - -if test x"$try_hkp" = xyes && test x"$use_dns_srv" = xyes ; then - _srv_save_libs=$LIBS - LIBS="" - # the double underscore thing is a glibc-ism? - AC_SEARCH_LIBS(res_query,resolv bind,, - AC_SEARCH_LIBS(__res_query,resolv bind,,use_dns_srv=no)) - AC_SEARCH_LIBS(dn_expand,resolv bind,, - AC_SEARCH_LIBS(__dn_expand,resolv bind,,use_dns_srv=no)) - AC_SEARCH_LIBS(dn_skipname,resolv bind,, - AC_SEARCH_LIBS(__dn_skipname,resolv bind,,use_dns_srv=no)) - - if test x"$use_dns_srv" = xyes ; then - AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV]) - SRVLIBS=$LIBS - else - AC_MSG_WARN([Resolver functions not found. Disabling DNS SRV.]) - fi - LIBS=$_srv_save_libs -fi - -AC_SUBST(SRVLIBS) - -# Try and link a LDAP test program to weed out unusable LDAP -# libraries. -lldap [-llber [-lresolv]] is for OpenLDAP. OpenLDAP in -# general is terrible with creating weird dependencies. If all else -# fails, the user can play guess-the-dependency by using something -# like ./configure LDAPLIBS="-Lfoo -lbar" - -if test "$try_ldap" = yes ; then - for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv"; do - _ldap_save_libs=$LIBS - LIBS="$MY_LDAPLIBS $NETLIBS $LIBS" - - AC_MSG_CHECKING([whether LDAP via \"$MY_LDAPLIBS\" is present and sane]) - AC_TRY_LINK([#include ],[ldap_open("foobar",1234);], - [gnupg_cv_func_ldap_init=yes],[gnupg_cv_func_ldap_init=no]) - AC_MSG_RESULT([$gnupg_cv_func_ldap_init]) - - if test $gnupg_cv_func_ldap_init = no; then - AC_MSG_CHECKING([whether I can make LDAP be sane with lber.h]) - AC_TRY_LINK([#include -#include ],[ldap_open("foobar",1234);], - [gnupg_cv_func_ldaplber_init=yes],[gnupg_cv_func_ldaplber_init=no]) - AC_MSG_RESULT([$gnupg_cv_func_ldaplber_init]) - fi - - if test "$gnupg_cv_func_ldaplber_init" = yes ; then - AC_DEFINE(NEED_LBER_H,1,[Define if the LDAP library requires including lber.h before ldap.h]) - fi - - if test "$gnupg_cv_func_ldap_init" = yes || \ - test "$gnupg_cv_func_ldaplber_init" = yes ; then - LDAPLIBS=$MY_LDAPLIBS - GPGKEYS_LDAP="gpgkeys_ldap$EXEEXT" - - AC_MSG_CHECKING([whether LDAP supports ldap_get_option]) - - if test "$gnupg_cv_func_ldap_init" = yes ; then - AC_TRY_LINK([#include ], - [ldap_get_option((void *)0,0,(void *)0);], - [gnupg_cv_func_ldap_get_option=yes], - [gnupg_cv_func_ldap_get_option=no]) - else - AC_TRY_LINK([#include -#include ],[ldap_get_option((void *)0,0,(void *)0);], - [gnupg_cv_func_ldap_get_option=yes], - [gnupg_cv_func_ldap_get_option=no]) - fi - - AC_MSG_RESULT([$gnupg_cv_func_ldap_get_option]) - - if test "$gnupg_cv_func_ldap_get_option" = yes ; then - AC_DEFINE(HAVE_LDAP_GET_OPTION,1,[Define if the LDAP library has ldap_get_option]) - else - AC_MSG_CHECKING([whether LDAP supports ld_errno]) - - if test "$gnupg_cv_func_ldap_init" = yes ; then - AC_TRY_COMPILE([#include ], - [LDAP *ldap; ldap->ld_errno;], - [gnupg_cv_func_ldap_ld_errno=yes], - [gnupg_cv_func_ldap_ld_errno=no]) - else - AC_TRY_LINK([#include -#include ],[LDAP *ldap; ldap->ld_errno;], - [gnupg_cv_func_ldap_ld_errno=yes], - [gnupg_cv_func_ldap_ld_errno=no]) - fi - - AC_MSG_RESULT([$gnupg_cv_func_ldap_ld_errno]) - - if test "$gnupg_cv_func_ldap_ld_errno" = yes ; then - AC_DEFINE(HAVE_LDAP_LD_ERRNO,1,[Define if the LDAP library supports ld_errno]) - fi - fi - fi - - LIBS=$_ldap_save_libs - - if test "$GPGKEYS_LDAP" != "" ; then break; fi - done -fi - -AC_SUBST(GPGKEYS_LDAP) -AC_SUBST(LDAPLIBS) - -dnl This isn't necessarily sendmail itself, but anything that gives a -dnl sendmail-ish interface to the outside world. That includes qmail, -dnl postfix, etc. Basically, anything that can handle "sendmail -t". - -if test "$try_mailto" = yes ; then - AC_ARG_WITH(mailprog,[ --with-mailprog=NAME use "NAME -t" for mail transport],,with_mailprog=yes) - - if test "$with_mailprog" = yes ; then - AC_PATH_PROG(SENDMAIL,sendmail,,$PATH:/usr/sbin:/usr/libexec:/usr/lib) - if test "$ac_cv_path_SENDMAIL" ; then - GPGKEYS_MAILTO="gpgkeys_mailto" - fi - elif test "$with_mailprog" != no ; then - AC_MSG_CHECKING([for a mail transport program]) - AC_SUBST(SENDMAIL,$with_mailprog) - AC_MSG_RESULT($with_mailprog) - GPGKEYS_MAILTO="gpgkeys_mailto" - fi -fi - -AC_SUBST(GPGKEYS_MAILTO) - -case "${target}" in - *-*-mingw32*) - PRINTABLE_OS_NAME="MingW32" - ;; - *-*-cygwin*) - PRINTABLE_OS_NAME="Cygwin" - ;; - i?86-emx-os2 | i?86-*-os2*emx ) - PRINTABLE_OS_NAME="OS/2" - ;; - i?86-*-msdosdjgpp*) - PRINTABLE_OS_NAME="MSDOS/DJGPP" - try_dynload=no - ;; - *-linux*) - PRINTABLE_OS_NAME="GNU/Linux" - ;; - *) - PRINTABLE_OS_NAME=`uname -s || echo "Unknown"` - ;; -esac -AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME", - [A human readable text with the name of the OS]) - - -AM_GNU_GETTEXT_VERSION(0.12.1) -if test "$try_gettext" = yes; then - AM_GNU_GETTEXT(,[need-ngettext]) - - # gettext requires some extra checks. These really should be part of - # the basic AM_GNU_GETTEXT macro. TODO: move other gettext-specific - # function checks to here. - - AC_CHECK_FUNCS(strchr) -else - USE_NLS=no - USE_INCLUDED_LIBINTL=no - BUILD_INCLUDED_LIBINTL=no - AC_SUBST(USE_NLS) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(BUILD_INCLUDED_LIBINTL) -fi - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_C_INLINE -AC_TYPE_SIZE_T -AC_TYPE_SIGNAL -AC_DECL_SYS_SIGLIST - -GNUPG_CHECK_ENDIAN - -GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF) -GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF) -GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF) -GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF) -GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF) - -AC_CHECK_SIZEOF(unsigned short) -AC_CHECK_SIZEOF(unsigned int) -AC_CHECK_SIZEOF(unsigned long) -AC_CHECK_SIZEOF(unsigned long long) -# Ensure that we have UINT64_C before we bother to check for uint64_t -# fixme: really needed in gnupg? I think it is only useful in libcgrypt. -AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works], - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include -uint64_t foo=UINT64_C(42);]),gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no)) -if test "$gnupg_cv_uint64_c_works" = "yes" ; then - AC_CHECK_SIZEOF(uint64_t) -fi - - - - -if test "$ac_cv_sizeof_unsigned_short" = "0" \ - || test "$ac_cv_sizeof_unsigned_int" = "0" \ - || test "$ac_cv_sizeof_unsigned_long" = "0"; then - AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]); -fi - -dnl Do we have any 64-bit data types? -if test "$ac_cv_sizeof_unsigned_int" != "8" \ - && test "$ac_cv_sizeof_unsigned_long" != "8" \ - && test "$ac_cv_sizeof_unsigned_long_long" != "8" \ - && test "$ac_cv_sizeof_uint64_t" != "8"; then - AC_MSG_WARN([No 64-bit types. Disabling SHA-384, and SHA-512]) -else - if test x"$use_sha512" = xyes ; then - AC_SUBST(SHA512_O,sha512.o) - AC_DEFINE(USE_SHA512,1,[Define to include the SHA-384 and SHA-512 digests]) - fi -fi - -GNUPG_SYS_SO_PEERCRED - -# Checks for library functions. -AC_FUNC_FSEEKO -AC_FUNC_VPRINTF -AC_FUNC_FORK -AC_CHECK_FUNCS(strerror stpcpy strsep strlwr tcgetattr strtoul mmap) -AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times gmtime_r) -AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime) -AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale) -AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo) - -AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) - -# These are needed by libjnlib - fixme: we should have macros for them -AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp strtol) -AC_CHECK_FUNCS(getrusage setrlimit stat setlocale) -AC_CHECK_FUNCS(flockfile funlockfile fopencookie funopen) - -AC_REPLACE_FUNCS(vasprintf) -AC_REPLACE_FUNCS(mkdtemp) -AC_REPLACE_FUNCS(fseeko ftello) -AC_REPLACE_FUNCS(isascii) -AC_REPLACE_FUNCS(putc_unlocked) - - - - -# -# check for gethrtime and run a testprogram to see whether -# it is broken. It has been reported that some Solaris and HP UX systems -# raise an SIGILL -# -AC_CACHE_CHECK([for gethrtime], - [gnupg_cv_func_gethrtime], - [AC_TRY_LINK([#include ],[ - hrtime_t tv; - tv = gethrtime(); - ], - [gnupg_cv_func_gethrtime=yes], - [gnupg_cv_func_gethrtime=no]) - ]) -if test $gnupg_cv_func_gethrtime = yes; then - AC_DEFINE([HAVE_GETHRTIME], 1, - [Define if you have the `gethrtime(2)' function.]) - AC_CACHE_CHECK([whether gethrtime is broken], - [gnupg_cv_func_broken_gethrtime], - [AC_TRY_RUN([ - #include - int main () { - hrtime_t tv; - tv = gethrtime(); - } - ], - [gnupg_cv_func_broken_gethrtime=no], - [gnupg_cv_func_broken_gethrtime=yes], - [gnupg_cv_func_broken_gethrtime=assume-no]) - ]) - if test $gnupg_cv_func_broken_gethrtime = yes; then - AC_DEFINE([HAVE_BROKEN_GETHRTIME], 1, - [Define if `gethrtime(2)' does not work correctly i.e. issues a SIGILL.]) - fi -fi - - -GNUPG_CHECK_MLOCK -GNUPG_FUNC_MKDIR_TAKES_ONE_ARG - -dnl -dnl Check whether we can use Linux capabilities as requested -dnl -if test "$use_capabilities" = "yes" ; then -use_capabilities=no -AC_CHECK_HEADERS(sys/capability.h) -if test "$ac_cv_header_sys_capability_h" = "yes" ; then - AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1) - if test "$ac_cv_lib_cap_cap_init" = "yes"; then - AC_DEFINE(USE_CAPABILITIES,1, - [define if capabilities should be used]) - AC_SUBST(CAPLIBS,"-lcap") - use_capabilities=yes - fi -fi -if test "$use_capabilities" = "no" ; then - AC_MSG_WARN([[ -*** -*** The use of capabilities on this system is not possible. -*** You need a recent Linux kernel and some patches: -*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9) -*** fcap-module-990613.tar.gz (kernel module) -*** libcap-1.92.tar.gz (user mode library and utilities) -*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN -*** set (filesystems menu). Be warned: This code is *really* ALPHA. -***]]) -fi -fi - - -# Sanity check regex. Tests adapted from mutt. - -AC_MSG_CHECKING([whether regular expression support is requested]) -AC_ARG_ENABLE(regex, -[ --disable-regex do not handle regular expressions in trust sigs], - use_regex=$enableval, use_regex=yes) -AC_MSG_RESULT($use_regex) - -if test "$use_regex" = yes ; then - AC_MSG_CHECKING([whether the included regex lib is requested]) - AC_ARG_WITH(included-regex, - [ --with-included-regex use the included GNU regex library], - [gnupg_cv_included_regex=yes],[gnupg_cv_included_regex=no]) - AC_MSG_RESULT($gnupg_cv_included_regex) - - if test $gnupg_cv_included_regex = no ; then - # Does the system have regex functions at all? - AC_CHECK_FUNC(regcomp,gnupg_cv_included_regex=no, - gnupg_cv_included_regex=yes) - fi - - if test $gnupg_cv_included_regex = no ; then - AC_CACHE_CHECK([whether your system's regexp library is broken], - [gnupg_cv_regex_broken], - AC_TRY_RUN([ -#include -#include -main() { regex_t blah ; regmatch_t p; p.rm_eo = p.rm_eo; return regcomp(&blah, "foo.*bar", REG_NOSUB) || regexec (&blah, "foobar", 0, NULL, 0); }], - gnupg_cv_regex_broken=no, gnupg_cv_regex_broken=yes, gnupg_cv_regex_broken=yes)) - - if test $gnupg_cv_regex_broken = yes ; then - AC_MSG_WARN(your regex is broken - using the included GNU regex instead.) - gnupg_cv_included_regex=yes - fi - fi - - if test $gnupg_cv_included_regex = yes; then - AC_DEFINE(USE_GNU_REGEX,1,[ Define if you want to use the included regex lib ]) - AC_SUBST(REGEX_O,regex.o) - fi -else - - AC_DEFINE(DISABLE_REGEX,1,[ Define to disable regular expression support ]) -fi - -dnl Do we have zlib? Must do it here because Solaris failed -dnl when compiling a conftest (due to the "-lz" from LIBS). -use_local_zlib=yes -if test "$g10_force_zlib" = "yes"; then - : -else - _cppflags="${CPPFLAGS}" - _ldflags="${LDFLAGS}" - - AC_ARG_WITH(zlib, - [ --with-zlib=DIR use libz in DIR],[ - if test -d "$withval"; then - CPPFLAGS="${CPPFLAGS} -I$withval/include" - LDFLAGS="${LDFLAGS} -L$withval/lib" - fi - ]) - - AC_CHECK_HEADER(zlib.h, - AC_CHECK_LIB(z, deflateInit2_, - use_local_zlib=no - LIBS="$LIBS -lz", - CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), - CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) -fi - -if test "$use_local_zlib" = yes ; then - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) - AC_CONFIG_LINKS(zlib.h:zlib/zlib.h zconf.h:zlib/zconf.h ) - ZLIBS="../zlib/libzlib.a" -else - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) - ZLIBS= -fi -AC_SUBST(ZLIBS) - -# Allow users to append something to the version string without -# flagging it as development version. The user version parts is -# considered everything after a dash. -if test "$development_version" != yes; then - changequote(,)dnl - tmp_pat='[a-zA-Z]' - changequote([,])dnl - if echo "$VERSION" | sed 's/-.*//' | grep "$tmp_pat" >/dev/null ; then - development_version=yes - fi -fi -if test "$development_version" = yes; then - AC_DEFINE(IS_DEVELOPMENT_VERSION,1, - [Defined if this is not a regular release]) -fi - -AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes) - -GNUPG_CHECK_GNUMAKE - -# add some extra libs here so that previous tests don't fail for -# mysterious reasons - the final link step should bail out. -case "${target}" in - *-*-mingw32*) - W32LIBS="-lwsock32" - ;; - *) - ;; -esac - - -if test "$GCC" = yes; then - if test "$USE_MAINTAINER_MODE" = "yes"; then - CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" - CFLAGS="$CFLAGS -Wformat-nonliteral" - else - CFLAGS="$CFLAGS -Wall" - fi -fi - -AC_SUBST(NETLIBS) -AC_SUBST(W32LIBS) - - -# We use jnlib, so tell other modules about it -AC_DEFINE(HAVE_JNLIB_LOGGING, 1, - [Defined if jnlib style logging fucntions are available]) - - - -# -# Decide what to build -# -missing_pth=no -if test $have_ksba = no; then - build_gpgsm=no - build_scdaemon=no -fi - -build_agent_threaded="" -if test "$build_agent" = "yes"; then - if test $have_pth = no; then - build_agent_threaded="(not multi-threaded)" - missing_pth=yes - fi -fi - -build_scdaemon_extra="" -if test "$build_scdaemon" = "yes"; then - tmp="" - if test $have_pth = no; then - build_scdaemon_extra="not multi-threaded" - tmp=", " - missing_pth=yes - fi - if test $have_opensc = no; then - build_scdaemon_extra="${build_scdaemon_extra}${tmp}no pkcs#15" - tmp=", " - fi - if test -n "$build_scdaemon_extra"; then - build_scdaemon_extra="(${build_scdaemon_extra})" - fi -fi - -AM_CONDITIONAL(BUILD_GPG, test "$build_gpg" = "yes") -AM_CONDITIONAL(BUILD_GPGSM, test "$build_gpgsm" = "yes") -AM_CONDITIONAL(BUILD_AGENT, test "$build_agent" = "yes") -AM_CONDITIONAL(BUILD_SCDAEMON, test "$build_scdaemon" = "yes") - - - -# -# Print errors here so that they are visible all -# together and the user can acquire them all together. -# -die=no -if test "$have_gpg_error" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libgpg-error to build this program. -** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libgpg-error -*** (at least version $NEED_GPG_ERROR_VERSION is required.) -***]]) -fi -if test "$have_libgcrypt" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libgcrypt to build this program. -** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ -*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API) is required.) -***]]) -fi -if test "$have_libassuan" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libassuan to build this program. -*** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libassuan/ -*** (at least version $NEED_LIBASSUAN_VERSION is required). -***]]) -fi -if test "$have_ksba" = "no"; then - die=yes - AC_MSG_NOTICE([[ -*** -*** You need libksba to build this program. -*** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/alpha/libksba/ -*** (at least version $NEED_KSBA_VERSION is required). -***]]) -fi -if test "$missing_pth" = "yes"; then - AC_MSG_NOTICE([[ -*** -*** It is strongly suggested to build with support for the -*** GNU Portable Threads Library (Pth). Please install this -*** library first or use --disable-threads to allow building -*** anyway. The library is for example available at -*** ftp://ftp.gnu.org/gnu/pth/ -*** On a Debian GNU/Linux system you can install it using -*** apt-get install libpth-dev -***]]) - if test "$enable_threads" != "no"; then - die=yes - fi -fi - -if test "$die" = "yes"; then - AC_MSG_ERROR([[ -*** -*** Required libraries not found. Please consult the above messages -*** and install them before running configure again. -***]]) -fi - - - -AC_CONFIG_FILES([ m4/Makefile -Makefile -po/Makefile.in -intl/Makefile -jnlib/Makefile -common/Makefile -kbx/Makefile -g10/Makefile -sm/Makefile -agent/Makefile -scd/Makefile -tools/Makefile -doc/Makefile -tests/Makefile -]) -AC_OUTPUT - - - - -echo " - GnuPG v${VERSION} has been configured as follows: - - Platform: $PRINTABLE_OS_NAME ($target) - - OpenPGP: $build_gpg - S/MIME: $build_gpgsm - Agent: $build_agent $build_agent_threaded - Smartcard: $build_scdaemon $build_scdaemon_extra - - Protect tool: $show_gnupg_protect_tool_pgm - Default agent: $show_gnupg_agent_pgm - Default pinentry: $show_gnupg_pinentry_pgm - Default scdaemon: $show_gnupg_scdaemon_pgm - Default dirmngr: $show_gnupg_dirmngr_pgm -" - diff --git a/doc/ChangeLog b/doc/ChangeLog deleted file mode 100644 index bcc288125..000000000 --- a/doc/ChangeLog +++ /dev/null @@ -1,102 +0,0 @@ -2004-06-18 Werner Koch - - * debugging.texi: New. - * gnupg.texi: Include it. - -2004-05-11 Werner Koch - - * gpgsm.texi (Esoteric Options): Add --debug-allow-core-dump. - -2004-05-03 Werner Koch - - * gpg-agent.texi (Agent Options): Add --allow-mark-trusted. - -2004-02-03 Werner Koch - - * contrib.texi (Contributors): Updated from the gpg 1.2.3 thanks - list. - * gpgsm.texi, gpg-agent.texi, scdaemon.texi: Language cleanups. - -2003-12-01 Werner Koch - - * gpgsm.texi (Certificate Options): Add --{enable,disable}-ocsp. - -2003-11-17 Werner Koch - - * scdaemon.texi (Scdaemon Options): Added --allow-admin and - --deny-admin. - -2003-10-27 Werner Koch - - * gpg-agent.texi (Agent GET_CONFIRMATION): New. - -2002-12-04 Werner Koch - - * gpg-agent.texi (Agent Signals): New. - -2002-12-03 Werner Koch - - * gpgsm.texi (Operational Commands): Add --passwd and - --call-protect-tool. - * gpg-agent.texi (Agent PASSWD): New - -2002-11-13 Werner Koch - - * gpg-agent.texi (Invoking GPG-AGENT): Tell about GPG_TTY. - -2002-11-12 Werner Koch - - * gpgsm.texi (Operational Commands): Add --call-dirmngr. - -2002-09-25 Werner Koch - - * gpg-agent.texi (Agent Options): Add --keep-tty and --keep-display. - -2002-09-12 Werner Koch - - * gpg-agent.texi (Invoking GPG-AGENT): Explained how to start only - one instance. - -2002-08-28 Werner Koch - - * gpg-agent.texi (Agent Options): Explained more options. - * scdaemon.texi (Scdaemon Options): Ditto. - -2002-08-09 Werner Koch - - * Makefile.am (gnupg_TEXINFOS): Include contrib.texi. - -2002-08-06 Werner Koch - - * gpgsm.texi: Added more options. - -2002-07-26 Werner Koch - - * assuan.texi: New. - * gpgsm.texi, scdaemon.texi, gpg-agent.texi: Documented the Assuan - protocol used. - -2002-07-22 Werner Koch - - * gnupg.texi, scdaemon.texi, gpg-agent.texi: New. - * contrib.texi, gpl.texi, fdl.texi: New. - * gpgsm.texi: Made this an include file for gnupg.texi. - * Makefile.am: Build gnupg.info instead of gpgsm.info. - -2002-06-04 Werner Koch - - * gpgsm.texi (Invocation): Described the various debug flags. - -2002-05-14 Werner Koch - - * Makefile.am, gpgsm.texi: New. - - Copyright 2002 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index d1d72e834..000000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2002 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -info_TEXINFOS = gnupg.texi - -gnupg_TEXINFOS = \ - gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi\ - debugging.texi contrib.texi gpl.texi fdl.texi - -DISTCLEANFILES = gnupg.tmp gnupg.ops - diff --git a/doc/assuan.texi b/doc/assuan.texi deleted file mode 100644 index 2e2219263..000000000 --- a/doc/assuan.texi +++ /dev/null @@ -1,189 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Assuan -@chapter Description of the Assuan protocol. - -The architecture of the modular GnuPG system is based on a couple of -highly specialized modules which make up a network of client server -communication. A common framework for intermodule communication is -therefore needed and should be implemented in a library. - -Goals: - -@itemize @bullet -@item Common framework for module communication -@item Easy debugging -@item Easy module testing -@item Extendible -@item Optional authentication and encryption facility -@item Usable to access external hardware -@end itemize - - -Design criteria: - -@itemize @bullet -@item Client Server with back channel -@item Use a mainly text based protocol -@item Escape certain control characters -@item Allow indefinite data length -@item Request confidentiality for parts of the communication -@item Dummy module should allow direct linking of client and server. -@item Inline data or descriptor passing for bulk data -@item No protection against DoS needed -@item Subliminal channels are not an issue -@end itemize - -Implementation: - -The implementation is line based with a maximum line size of 1000 -octects. The default IPC mechanism are Unix Domain Sockets. - -On a connect request the server responds either with an okay or an error -status. For authentication check the server may send an Inquiry -Response prior to the first Okay, it may also issue Status messages. -The server must check that the client is allowed to connect, this is -done by requesting the credentials for the peer and comparing them to -those of the server. This avoids attacks based on wrong socket -permissions. - -It may choose to delay the first response in case of an error. The -server never closes the connection - however the lower protocol may do -so after some time of inactivity or when the connection is in an error -state. - -All textual messages are assumed to be in UTF-8 unless otherwise noted. - - -Server responses: - -@table @code -@item OK [] -Request was successful. - -@item ERR @var{errorcode} [] -Request could not be fulfilled. The error codes are mostly application -specific except for a few common ones. - -@item S @var{keyword} -Informational output by the server, still processing the request. - -@item # -Comment line issued only for debugging purposes. Totally ignored. - -@item D -Raw data returned to client. There must be exactly one space after the -'D'. The values for '%', CR and LF must be percent escaped; this is -encoded as %25, %0D and %0A. Only uppercase letters should be used in -the hexadecimal representation. Other characters may be percent escaped -for easier debugging. All these Data lines are considered one data -stream up to the OK or ERR response. Status and Inquiry Responses -may be mixed with the Data lines. - -@item INQUIRE @var{keyword}> -Server needs further information from the client. The client should -answer with a command which is allowed after an inquiry. Note that the -server does not confirm that client command but either continues -processing or ends processing with an error status. Not all commands -are allowed. -@end table - - -A client should only check the first letter of each line and then skip -over to the next token (except for data lines where the raw data starts -exactly after 2 bytes). Lines larger than 1000 bytes should be -treated as a communication error. (The rationale for having a line -length limit is to allow for easier multiplexing of multiple channels). - - -Client requests: - -The server waits for client requests after he sent an Okay or Error. -The client should not issue a request in other cases with the -exception of the CANCEL command. - -@example -@var{command} -@end example - -@var{command} is a one word string without preceding white space. -Parameters are command specific, CR, LF and the percent signs should be -percent escaped as described above. To send a backslash as the last -character it should also be percent escaped. Percent escaping is -allowed anywhere in the parameters but not in the command. The line -ends with a CR, LF or just a LF. - -Not yet implemented feature: If there is a need for a parameter list -longer than the line length limit (1000 characters including command and -CR, LF), the last character of the line (right before the CR/LF or LF) -must be a non-escape encoded backslash. The following line is then -expected to be a continuation of the line with the backslash replaced by -a blank and the line ending removed. - -@example -D -@end example - -Raw data to the server. There must be exactly one space after the 'D'. -The values for '%', CR and LF must be percent escaped; this is encoded -as %25, %0D and %0A. Only uppercase letters should be used in the -hexadecimal representation. Other characters may be percent escaped for -easier debugging. All these Data lines are considered one data stream -up to the OKAY or ERROR response. Status and Inquiry Responses may be -mixed with the Data lines. - -@example -END -@end example - - - -Lines beginning with a @code{#} or empty lines are ignored. This is -useful to comment test scripts. - - -Although the commands are application specific, some of them are used by -all protocols and partly directly supported by the Assuan library: - -@table @code -@item CANCEL -his is the one special command which aborts the current request. it can -be sent at any time and the server will stop its operation right before -it would send the next response line (of any type). - -@item BYE -Close the connect, the server will reply with an @code{OK}. - -@item AUTH -Not yet specified as we don't implement it in the first phase. See my -mail to gpa-dev on 2001-10-25 about the rationale for measurements -against local attacks. - -@item RESET -Reset the connection but not any existing authentication. The server -should release all resources associated with the connection. - -@item END -Used by a client to mark the end of raw data. The server may send END -to indicate a partial end of data. -@end table - - -Error Codes: - -Here we keep a list of error codes used in any Assuan based -protocol. The format is the string @code{ERR}, white space, the error -number, white space, a textual description of the error. - -@table @code - -@item 100 Unknown Command -@item 101 Not Implemented - -@item 301 certificate has been revoked [DirMngr] -@item 302 no CRL known for this certificate [DirMngr] -@item 303 CRL is too old and a new one could not be retrieved [DirMngr] - -@end table diff --git a/doc/contrib.texi b/doc/contrib.texi deleted file mode 100644 index 035b6c251..000000000 --- a/doc/contrib.texi +++ /dev/null @@ -1,124 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Contributors -@unnumbered Contributors to GnuPG -@cindex contributors - -The GnuPG project would like to thank its many contributors. Without -them the project would not have been nearly as successful as it has -been. Any omissions in this list are accidental. Feel free to contact -the maintainer if you have been left out or some of your contributions -are not listed. Please keep this list in alphabetical order. - -@itemize @bullet - -@item -Bernhard Herzog did extensive testing and tracked down a lot of bugs - -@item -Bernhard Reiter made sure that we met the specifications and the -deadlines. He did extensive testing and came up with a lot of suggestions. - -@item -Jan-Oliver Wagner made sure that we met the specifications and the -deadlines. He did extensive testing and came up with a lot of suggestions. - -@item -Karl-Heinz Zimmer had to struggle with all the bugs and misconceptions -while working on Kmail integration. - -@item -Marcus Brinkman cleaned up the Assuan code and fixed bugs all over the place. - -@item -Steffen Hansen had a hard time to write the dirmngr due to -underspecified interfaces. - -@item -Thomas Koester did extensive testing and tracked down a lot of bugs - -@item -Werner Koch designed the system and wrote most of the original code. - -@end itemize - -We'd also like to thank these folks who have contributed a lot of time -and energy working on GnuPG over the years: - -David Shaw, Matthew Skala, Michael Roth, Niklas Hernaeus, Nils -Ellmenreich, Rémi Guyomarch, Stefan Bellon, Timo Schulz and Werner -Koch wrote the code. Birger Langkjer, Daniel Resare, Dokianakis -Theofanis, Edmund GRIMLEY EVANS, Gaël Quéri, Gregory Steuck, Nagy -Ferenc László, Ivo Timmermans, Jacobo Tarri'o Barreiro, Janusz -Aleksander Urbanowicz, Jedi Lin, Jouni Hiltunen, Laurentiu Buzdugan, -Magda Procha'zkova', Michael Anckaert, Michal Majer, Marco d'Itri, -Nilgun Belma Buguner, Pedro Morais, Tedi Heriyanto, Thiago Jung -Bauermann, Rafael Caetano dos Santos, Toomas Soome, Urko Lusa, Walter -Koch, Yosiaki IIDA did the official translations. Mike Ashley wrote -and maintains the GNU Privacy Handbook. David Scribner is the current -FAQ editor. Lorenzo Cappelletti maintains the web site. - -The following people helped greatly by suggesting improvements, -testing, fixing bugs, providing resources and doing other important -tasks: Adam Mitchell, Albert Chin, Alec Habig, Allan Clark, Anand -Kumria, Andreas Haumer, Anthony Mulcahy, Ariel T Glenn, Bob Mathews, -Bodo Moeller, Brendan O'Dea, Brenno de Winter, Brian M. Carlson, Brian -Moore, Brian Warner, Bryan Fullerton, Caskey L. Dickson, Cees van de -Griend, Charles Levert, Chip Salzenberg, Chris Adams, Christian Biere, -Christian Kurz, Christian von Roques, Christopher Oliver, Christian -Recktenwald, Dan Winship, Daniel Eisenbud, Daniel Koening, Dave -Dykstra, David C Niemi, David Champion, David Ellement, David -Hallinan, David Hollenberg, David Mathog, David R. Bergstein, Detlef -Lannert, Dimitri, Dirk Lattermann, Dirk Meyer, Disastry, Douglas -Calvert, Ed Boraas, Edmund GRIMLEY EVANS, Edwin Woudt, Enzo -Michelangeli, Ernst Molitor, Fabio Coatti, Felix von Leitner, fish -stiqz, Florian Weimer, Francesco Potorti, Frank Donahoe, Frank -Heckenbach, Frank Stajano, Frank Tobin, Gabriel Rosenkoetter, Gaël -Quéri, Gene Carter, Geoff Keating, Georg Schwarz, Giampaolo Tomassoni, -Gilbert Fernandes, Greg Louis, Greg Troxel, Gregory Steuck, Gregery -Barton, Harald Denker, Holger Baust, Hendrik Buschkamp, Holger -Schurig, Holger Smolinski, Holger Trapp, Hugh Daniel, Huy Le, Ian -McKellar, Ivo Timmermans, Jan Krueger, Jan Niehusmann, Janusz -A. Urbanowicz, James Troup, Jean-loup Gailly, Jeff Long, Jeffery Von -Ronne, Jens Bachem, Jeroen C. van Gelderen, J Horacio MG, J. Michael -Ashley, Jim Bauer, Jim Small, Joachim Backes, Joe Rhett, John -A. Martin, Johnny Teveßen, Jörg Schilling, Jos Backus, Joseph Walton, -Juan F. Codagnone, Jun Kuriyama, Kahil D. Jallad, Karl Fogel, Karsten -Thygesen, Katsuhiro Kondou, Kazu Yamamoto, Keith Clayton, Kevin Ryde, -Klaus Singvogel, Kurt Garloff, Lars Kellogg-Stedman, L. Sassaman, M -Taylor, Marcel Waldvogel, Marco d'Itri, Marco Parrone, Marcus -Brinkmann, Mark Adler, Mark Elbrecht, Mark Pettit, Markus Friedl, -Martin Kahlert, Martin Hamilton, Martin Schulte, Matt Kraai, Matthew -Skala, Matthew Wilcox, Matthias Urlichs, Max Valianskiy, Michael -Engels, Michael Fischer v. Mollard, Michael Roth, Michael Sobolev, -Michael Tokarev, Nicolas Graner, Mike McEwan, Neal H Walfield, Nelson -H. F. Beebe, NIIBE Yutaka, Niklas Hernaeus, Nimrod Zimerman, N J Doye, -Oliver Haakert, Oskari Jääskeläinen, Pascal Scheffers, Paul D. Smith, -Per Cederqvist, Phil Blundell, Philippe Laliberte, Peter Fales, Peter -Gutmann, Peter Marschall, Peter Valchev, Piotr Krukowiecki, QingLong, -Ralph Gillen, Rat, Reinhard Wobst, Rémi Guyomarch, Reuben Sumner, -Richard Outerbridge, Robert Joop, Roddy Strachan, Roger Sondermann, -Roland Rosenfeld, Roman Pavlik, Ross Golder, Ryan Malayter, Sam -Roberts, Sami Tolvanen, Sean MacLennan, Sebastian Klemke, Serge -Munhoven, SL Baur, Stefan Bellon, Dr.Stefan.Dalibor, Stefan Karrmann, -Stefan Keller, Steffen Ullrich, Steffen Zahn, Steven Bakker, Steven -Murdoch, Susanne Schultz, Ted Cabeen, Thiago Jung Bauermann, Thijmen -Klok, Thomas Roessler, Tim Mooney, Timo Schulz, Todd Vierling, TOGAWA -Satoshi, Tom Spindler, Tom Zerucha, Tomas Fasth, Tommi Komulainen, -Thomas Klausner, Tomasz Kozlowski, Thomas Mikkelsen, Ulf Möller, Urko -Lusa, Vincent P. Broman, Volker Quetschke, W Lewis, Walter Hofmann, -Walter Koch, Wayne Chapeskie, Wim Vandeputte, Winona Brown, Yosiaki -IIDA, Yoshihiro Kajiki and Gerlinde Klaes. - -This software has been made possible by the previous work of Chris -Wedgwood, Jean-loup Gailly, Jon Callas, Mark Adler, Martin Hellmann -Paul Kendall, Philip R. Zimmermann, Peter Gutmann, Philip A. Nelson, -Taher ElGamal, Torbjorn Granlund, Whitfield Diffie, some unknown NSA -mathematicians and all the folks who have worked hard to create -complete and free operating systems. - -And finally we'd like to thank everyone who uses these tools, submits -bug reports and generally reminds us why we're doing this work in the -first place. diff --git a/doc/debugging.texi b/doc/debugging.texi deleted file mode 100644 index e5e3e43fd..000000000 --- a/doc/debugging.texi +++ /dev/null @@ -1,82 +0,0 @@ -@c Copyright (C) 2004 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Debugging -@chapter How to solve problems - -Everone knows that software often does not do what it should do and thus -there is a need to track down problems. We call this debugging in a -reminiscent to the moth jamming a relay in a Mark II box back in 1947. - -Most of the probelsm a merely configuration and user problems but -nevertheless there are the most annoying ones and reposnible for may -gray hairs. We try to give some guidelines here on how to identify and -solve the problem at hand. - - -@menu -* Debugging Tools:: Description of some useful tools - -@end menu - - -@node Debugging Tools -@section Debugging Tools - -The GnuPG distribution comes with a couple of tools, useful to help find -and solving problems. - -@menu -* kbxutil:: Scrutinizing a keybox file. -@end menu - -@node kbxutil -@subsection Scrutinizing a keybox file - -A keybox is a file fomat used to store public keys along with meta -information and indices. The commonly used one is the file -@file{pubring.kbx} in the @file{.gnupg} directory. It contains all -X.509 certificates as well as OpenPGP keys@footnote{Well, OpenPGP keys -are not implemented, @command{gpg} still used the keyring file -@file{pubring.gpg}} . - -@noindent -When called the standard way, e.g.: - -@samp{kbxutil ~/.gnupg/pubring.kbx} - -@noindent -it lists all records (called @acronym{blobs}) with there meta-information -in a human readable format. - -@noindent -To see statistics on the keybox in question, run it using - -@samp{kbxutil --stats ~/.gnupg/pubring.kbx} - -@noindent -and you get an output like: - -@example -Total number of blobs: 99 - header: 1 - empty: 0 - openpgp: 0 - x509: 98 - non flagged: 81 - secret flagged: 0 - ephemeral flagged: 17 -@end example - -In this example you see that the keybox does not have any OpenPGP keys -but contains 98 X.509 cerificates and a total of 17 keys or certificates -are flagges as ephemeral, meaning that they are only temporary stored -(cached) in the keybox and won't get listed using the usual commands -provided by @command{gpgsm} or @command{gpg}. 81 certifcates are stored -in a standard way and directly available from @command{gpgsm}. - - - - - diff --git a/doc/fdl.texi b/doc/fdl.texi deleted file mode 100644 index 6e40e6df9..000000000 --- a/doc/fdl.texi +++ /dev/null @@ -1,401 +0,0 @@ -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@cindex FDL, GNU Free Documentation License -@center Version 1.1, March 2000 - -@display -Copyright @copyright{} 2000 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -written document @dfn{free} in the sense of freedom: to assure everyone -the effective freedom to copy and redistribute it, with or without -modifying it, either commercially or noncommercially. Secondarily, -this License preserves for the author and publisher a way to get -credit for their work, while not being considered responsible for -modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work that contains a -notice placed by the copyright holder saying it can be distributed -under the terms of this License. The ``Document'', below, refers to any -such manual or work. Any member of the public is a licensee, and is -addressed as ``you''. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section of -the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall subject -(or to related matters) and contains nothing that could fall directly -within that overall subject. (For example, if the Document is in part a -textbook of mathematics, a Secondary Section may not explain any -mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, whose contents can be viewed and edited directly and -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup has been designed to thwart or discourage -subsequent modification by readers is not Transparent. A copy that is -not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -@sc{ascii} without markup, Texinfo input format, La@TeX{} input format, -@acronym{SGML} or @acronym{XML} using a publicly available -@acronym{DTD}, and standard-conforming simple @acronym{HTML} designed -for human modification. Opaque formats include PostScript, -@acronym{PDF}, proprietary formats that can be read and edited only by -proprietary word processors, @acronym{SGML} or @acronym{XML} for which -the @acronym{DTD} and/or processing tools are not generally available, -and the machine-generated @acronym{HTML} produced by some word -processors for output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies of the Document numbering more than 100, -and the Document's license notice requires Cover Texts, you must enclose -the copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a publicly-accessible computer-network location containing a complete -Transparent copy of the Document, free of added material, which the -general network-using public has access to download anonymously at no -charge using public-standard network protocols. If you use the latter -option, you must take reasonably prudent steps, when you begin -distribution of Opaque copies in quantity, to ensure that this -Transparent copy will remain thus accessible at the stated location -until at least one year after the last time you distribute an Opaque -copy (directly or through your agents or retailers) of that edition to -the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has less than five). - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section entitled ``History'', and its title, and add to -it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -In any section entitled ``Acknowledgments'' or ``Dedications'', -preserve the section's title, and preserve in the section all the -substance and tone of each of the contributor acknowledgments -and/or dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section as ``Endorsements'' -or to conflict in title with any Invariant Section. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections entitled ``History'' -in the various original documents, forming one section entitled -``History''; likewise combine any sections entitled ``Acknowledgments'', -and any sections entitled ``Dedications''. You must delete all sections -entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, does not as a whole count as a Modified Version -of the Document, provided no compilation copyright is claimed for the -compilation. Such a compilation is called an ``aggregate'', and this -License does not apply to the other self-contained works thus compiled -with the Document, on account of their being thus compiled, if they -are not themselves derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one quarter -of the entire aggregate, the Document's Cover Texts may be placed on -covers that surround only the Document within the aggregate. -Otherwise they must appear on covers around the whole aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License provided that you also include the -original English version of this License. In case of a disagreement -between the translation and the original English version of this -License, the original English version will prevail. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. -@end enumerate - -@page -@appendixsubsec ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.1 - or any later version published by the Free Software Foundation; - with the Invariant Sections being @var{list their titles}, with the - Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}. - A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have no Invariant Sections, write ``with no Invariant Sections'' -instead of saying which ones are invariant. If you have no -Front-Cover Texts, write ``no Front-Cover Texts'' instead of -``Front-Cover Texts being @var{list}''; likewise for Back-Cover Texts. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: diff --git a/doc/gnupg.texi b/doc/gnupg.texi deleted file mode 100644 index 58c995b38..000000000 --- a/doc/gnupg.texi +++ /dev/null @@ -1,174 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename gnupg.info - -@include version.texi - -@macro copyrightnotice -Copyright @copyright{} 2002 Free Software Foundation, Inc. -@end macro -@macro permissionnotice -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.1 or -any later version published by the Free Software Foundation; with the -Invariant Sections being ``GNU General Public License'', the Front-Cover -texts being (a) (see below), and with the Back-Cover Texts being (b) -(see below). A copy of the license is included in the section entitled -``GNU Free Documentation License''. - -(a) The FSF's Front-Cover Text is: - - A GNU Manual - -(b) The FSF's Back-Cover Text is: - - You have freedom to copy and modify this GNU Manual, like GNU - software. Copies published by the Free Software Foundation raise - funds for GNU development. -@end macro - - -@settitle Using the GNU Privacy Guard - -@c Create a separate index for command line options. -@defcodeindex op -@c Merge the standard indexes into a single one. -@syncodeindex fn cp -@syncodeindex vr cp -@syncodeindex ky cp -@syncodeindex pg cp -@syncodeindex tp cp - -@c printing stuff taken from gcc. -@macro gnupgtabopt{body} -@code{\body\} -@end macro -@macro gnupgoptlist{body} -@smallexample -\body\ -@end smallexample -@end macro -@c Makeinfo handles the above macro OK, TeX needs manual line breaks; -@c they get lost at some point in handling the macro. But if @macro is -@c used here rather than @alias, it produces double line breaks. -@iftex -@alias gol = * -@end iftex -@ifnottex -@macro gol -@end macro -@end ifnottex - - -@c Change the font used for @def... commands, since the default -@c proportional one used is bad for names starting __. -@tex -\global\setfont\defbf\ttbshape{10}{\magstep1} -@end tex - -@c %**end of header - -@ifnottex -@dircategory GNU Utilities -@direntry -* gpg: (gnupg). OpenPGP encryption and signing tool. -* gpgsm: (gnupg). S/MIME encryption and signing tool. -@end direntry -This file documents the use and the internals of the GNU Privacy Guard. - -This is Edition @value{EDITION}, last updated @value{UPDATED}, of -@cite{The `GNU Privacy Guard' Manual}, for Version @value{VERSION}. -@sp 1 -Published by the Free Software Foundation@* -59 Temple Place - Suite 330@* -Boston, MA 02111-1307 USA -@sp 1 -@copyrightnotice{} -@sp 1 -@permissionnotice{} -@end ifnottex - -@setchapternewpage odd - -@titlepage -@title Using the GNU Privacy Guard -@subtitle Version @value{VERSION} -@subtitle @value{UPDATED} -@author Werner Koch @code{(wk@@gnupg.org)} - -@page -@vskip 0pt plus 1filll -@copyrightnotice{} -@sp 2 -@permissionnotice{} -@end titlepage -@summarycontents -@contents -@page - - -@node Top -@top Introduction -@cindex introduction - -This manual documents how to use the GNU Privay Guard system as well as -the administration and the architecture. - -@c * Gpg:: Using the OpenPGP protocol. -@menu -* Invoking GPGSM:: Using the S/MIME protocol. -* Invoking GPG-AGENT:: How to launch the secret key daemon. -* Invoking SCDAEMON:: How to handle Smartcards. - -Developer information - -* Assuan:: Description of the Assuan protocol. - -Miscellaneous - -* Debugging:: How to solve problems -* Copying:: GNU General Public License says - how you can copy and share GnuPG -* GNU Free Documentation License:: How you can copy and share this manual. -* Contributors:: People who have contributed to GnuPG. - -Indices - -* Option Index:: Index to command line options. -* Index:: Index of concepts and symbol names. -@end menu - -@include gpgsm.texi -@include gpg-agent.texi -@include scdaemon.texi - -@include assuan.texi - -@include debugging.texi - -@include gpl.texi -@include fdl.texi - -@include contrib.texi - -@c --------------------------------------------------------------------- -@c Indexes -@c --------------------------------------------------------------------- - -@node Option Index -@unnumbered Option Index - -@printindex op - -@node Index -@unnumbered Index - -@printindex cp - -@c --------------------------------------------------------------------- -@c Epilogue -@c --------------------------------------------------------------------- - -@bye - - diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi deleted file mode 100644 index aad0fbb68..000000000 --- a/doc/gpg-agent.texi +++ /dev/null @@ -1,791 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking GPG-AGENT -@chapter Invoking GPG-AGENT -@cindex GPG-AGENT command options -@cindex command options -@cindex options, GPG-AGENT command - -@c man begin DESCRIPTION - -@sc{gpg-agent} is a daemon to manage secret (private) keys independelty -from any protocol. It is used as a backend for @sc{gpg} and @sc{gpgsm} -as well as for a couple of other utilities. - -@noindent -The usual way to run the agent is from the @code{~/.xsession} file: - -@example -eval `gpg-agent --daemon` -@end example - -@noindent -If you don't use an X server, you can also put this into your regular -startup file @code{~/.profile} or @code{.bash_profile}. It is best not -to run multiple instance of the gpg-agent, so you should make sure that -only is running: @sc{gpg-agent} uses an environment variable to inform -clients about the communication parameters. You can write the -content of this environment variable to a file so that you can test for -a running agent. This short script may do the job: - -@smallexample -if test -f $HOME/.gpg-agent-info && \ - kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null; then - GPG_AGENT_INFO=`cat $HOME/.gpg-agent-info` - export GPG_AGENT_INFO -else - eval `gpg-agent --daemon` - echo $GPG_AGENT_INFO >$HOME/.gpg-agent-info -fi -@end smallexample - -@noindent -If you want to use a curses based pinentry (which is usually also the -fallback mode for a GUI based pinentry), you should add these lines to -your @code{.bashrc} or whatever initialization file is used for all shell -invocations: - -@smallexample -GPG_TTY=`tty` -export GPG_TTY -@end smallexample - -It is important that this environment variable always reflects the -output of the @code{tty} command. - -@c man end - -@noindent -@xref{Option Index}, for an index to GPG-AGENTS's commands and options. - -@menu -* Agent Commands:: List of all commands. -* Agent Options:: List of all options. -* Agent Signals:: Use of some signals. -* Agent Examples:: Some usage examples. -* Agent Protocol:: The protocol the agent uses. -@end menu - -@c man begin COMMANDS - -@node Agent Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. The -default mode is to create a socket and listen for commands there. - -@item --daemon -@opindex daemon -Run the program in the background. This option is required to prevent -it from being accidently running in the background. A common way to do -this is: -@example -@end example -$ eval `gpg-agent --daemon` -@end table - - -@c man begin OPTIONS - -@node Agent Options -@section Option Summary - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{gpg-agent.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item -q -@item --quiet -@opindex q -@opindex quiet -Try to be as quiet as possible. - -@item --batch -@opindex batch -Don't invoke a pinentry or do any other thing requiring human interaction. - -@item --faked-system-time @var{epoch} -@opindex faked-system-time -This option is only useful for testing; it sets the system time back or -forth to @var{epoch} which is the number of seconds elapsed since the year -1970. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change at -any time without notice. FLAGS are bit encoded and may be given in -usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @item 12 (4096) - bypass all certificate validation - @end table - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-wait @var{n} -@opindex debug-wait -When running in server mode, wait @var{n} seconds before entering the -actual processing loop and print the pid. This gives time to attach a -debugger. - -@item --no-detach -@opindex no-detach -Don't detach the process from the console. This is manly usefule for -debugging. - -@item -s -@itemx --sh -@itemx -c -@itemx --csh -@opindex s -@opindex sh -@opindex c -@opindex csh -Format the info output in daemon mode for use with the standard Bourne -shell respective the C-shell . The default ist to guess it based on the -environment variable @code{SHELL} which is in almost all cases -sufficient. - -@item --no-grab -@opindex no-grab -Tell the pinentryo not to grab the keyboard and mouse. This option -should in general not be used to avaoid X-sniffing attacks. - -@item --log-file @var{file} -@opindex log-file -Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. - -@item --disable-pth -@opindex disable-pth -Don't allow multiple connections. This option is in general not very -useful. - -@item --allow-mark-trusted -@opindex allow-mark-trusted -Allow clients to mark keys as trusted, i.e. put them into the -@code{trustlist.txt} file. This is by default not allowed to make it -harder for users to inadvertly accept Root-CA keys. - -@item --ignore-cache-for-signing -@opindex ignore-cache-for-signing -This option will let gpg-agent bypass the passphrase cache for all -signing operation. Note that there is also a per-session option to -control this behaviour but this command line option takes precedence. - -@item --default-cache-ttl @var{n} -@opindex default-cache-ttl -Set the time a cache entry is valid to @var{n} seconds. The default are -600 seconds. - -@item --pinentry-program @var{filename} -@opindex pinentry-program -Use program @var{filename} as the PIN entry. The default is installation -dependend and can be shown with the @code{--version} command. - -@item --scdaemon-program @var{filename} -@opindex scdaemon-program -Use program @var{filename} as the Smartcard daemon. The default is -installation dependend and can be shown with the @code{--version} -command. - - -@item --display @var{string} -@itemx --ttyname @var{string} -@itemx --ttytype @var{string} -@itemx --lc-type @var{string} -@itemx --lc-messages @var{string} -@opindex display -@opindex ttyname -@opindex ttytype -@opindex lc-type -@opindex lc-messa -These options are used with the server mode to pass localization -information. - -@item --keep-tty -@itemx --keep-display -@opindex keep-tty -@opindex keep-display -Ignore requests to change change the current @sc{tty} respective the X -window system's @code{DISPLAY} variable. This is useful to lock the -pinentry to pop up at the @sc{tty} or display you started the agent. - - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - -@c -@c Agent Signals -@c -@node Agent Signals -@section Use of some signals. -A running @command{gpg-agent} may be controlled by signals, i.e. using -the @command{kill} command to send a signal to the process. - -Here is a list of supported signals: - -@table @gnupgtabopt - -@item SIGHUP -@cpindex SIGHUP -This signals flushes all chached passphrases and when the program was -started with a configuration file, the configuration file is read again. -Only certain options are honored: @code{quiet}, @code{verbose}, -@code{debug}, @code{debug-all}, @code{no-grab}, @code{pinentry-program}, -@code{default-cache-ttl} and @code{ignore-cache-for-signing}. -@code{scdaemon-program} is also supported but due to the current -implementation, which calls the scdaemon only once, it is not of much -use. - - -@item SIGTERM -@cpindex SIGTERM -Shuts down the process but waits until all current requests are -fulfilled. If the process has received 3 of these signals and requests -are still pending, a shutdown is forced. - -@item SIGINT -@cpindex SIGINT -Shuts down the process immediately. - - -@item SIGUSR1 -@itemx SIGUSR2 -@cpindex SIGUSR1 -@cpindex SIGUSR2 -These signals are used for internal purposes. - -@end table - -@c -@c Examples -@c -@node Agent Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ eval `gpg-agent --daemon` -@end example - -@c man end - - -@c -@c Assuan Protocol -@c -@node Agent Protocol -@section Agent's Assuan Protocol - -The gpg-agent should be started by the login shell and set an -environment variable to tell clients about the socket to be used. -Clients should deny to access an agent with a socket name which does -not match its own configuration. An application may choose to start -an instance of the gpgagent if it does not figure that any has been -started; it should not do this if a gpgagent is running but not -usable. Because gpg-agent can only be used in background mode, no -special command line option is required to activate the use of the -protocol. - -To identify a key we use a thing called keygrip which is the SHA-1 hash -of an canoncical encoded S-Expression of the the public key as used in -Libgcrypt. For the purpose of this interface the keygrip is given as a -hex string. The advantage of using this and not the hash of a -certificate is that it will be possible to use the same keypair for -different protocols, thereby saving space on the token used to keep the -secret keys. - -@menu -* Agent PKDECRYPT:: Decrypting a session key -* Agent PKSIGN:: Signing a Hash -* Agent GENKEY:: Generating a Key -* Agent IMPORT:: Importing a Secret Key -* Agent EXPORT:: Exporting a Secret Key -* Agent ISTRUSTED:: Importing a Root Certificate -* Agent GET_PASSPHRASE:: Ask for a passphrase -* Agent GET_CONFIRMATION:: Ask for confirmation -* Agent HAVEKEY:: Check whether a key is available -* Agent LEARN:: Register a smartcard -* Agent PASSWD:: Change a Passphrase -@end menu - -@node Agent PKDECRYPT -@subsection Decrypting a session key - -The client asks the server to decrypt a session key. The encrypted -session key should have all information needed to select the -appropriate secret key or to delegate it to a smartcard. - -@example - SETKEY -@end example - -Tell the server about the key to be used for decryption. If this is -not used, gpg-agent may try to figure out the key by trying to -decrypt the message with each key available. - -@example - PKDECRYPT -@end example - -The agent checks whether this command is allowed and then does an -INQUIRY to get the ciphertext the client should then send the cipher -text. - -@example - S: INQUIRE CIPHERTEXT - C: D (xxxxxx - C: D xxxx) - C: END -@end example - -Please note that the server may send status info lines while reading the -data lines from the client. The data send is a SPKI like S-Exp with -this structure: - -@example - (enc-val - ( - ( ) - ... - ( ))) -@end example - -Where algo is a string with the name of the algorithm; see the libgcrypt -documentation for a list of valid algorithms. The number and names of -the parameters depend on the algorithm. The agent does return an error -if there is an inconsistency. - -If the decryption was successful the decrypted data is returned by -means of "D" lines. - -Here is an example session: - -@example - C: PKDECRYPT - S: INQUIRE CIPHERTEXT - C: D (enc-val elg (a 349324324) - C: D (b 3F444677CA))) - C: END - S: # session key follows - S: D 1234567890ABCDEF0 - S: OK descryption successful -@end example - - -@node Agent PKSIGN -@subsection Signing a Hash - -The client ask the agent to sign a given hash value. A default key -will be chosen if no key has been set. To set a key a client first -uses: - -@example - SIGKEY -@end example - -This can be used multiple times to create multiple signature, the list -of keys is reset with the next PKSIGN command or a RESET. The server -test whether the key is a valid key to sign something and responds with -okay. - -@example - SETHASH -@end example - -The client can use this command to tell the server about the data -(which usually is a hash) to be signed. - -The actual signing is done using - -@example - PKSIGN -@end example - -Options are not yet defined, but my later be used to choosen among -different algorithms (e.g. pkcs 1.5) - -The agent does then some checks, asks for the passphrase and -if SETHASH has not been used asks the client for the data to sign: - -@example - S: INQUIRE HASHVAL - C: D ABCDEF012345678901234 - C: END -@end example - -As a result the server returns the signature as an SPKI like S-Exp -in "D" lines: - -@example - (sig-val - ( - ( ) - ... - ( ))) -@end example - - -The operation is affected by the option - -@example - OPTION use-cache-for-signing=0|1 -@end example - -The default of @code{1} uses the cache. Setting this option to @code{0} -will lead gpg-agent to ignore the passphrase cache. Note, that there is -also a global command line option for gpg-agent to globally disable the -caching. - - -Here is an example session: - -@example - C: SIGKEY - S: OK key available - C: SIGKEY - S: OK key available - C: PKSIGN - S: # I did ask the user whether he really wants to sign - S: # I did ask the user for the passphrase - S: INQUIRE HASHVAL - C: D ABCDEF012345678901234 - C: END - S: # signature follows - S: D (sig-val rsa (s 45435453654612121212)) - S: OK -@end example - - -@node Agent GENKEY -@subsection Generating a Key - -This is used to create a new keypair and store the secret key inside the -active PSE -w which is in most cases a Soft-PSE. An not yet defined -option allows to choose the storage location. To get the secret key out -of the PSE, a special export tool has to be used. - -@example - GENKEY -@end example - -Invokes the key generation process and the server will then inquire -on the generation parameters, like: - -@example - S: INQUIRE KEYPARM - C: D (genkey (rsa (nbits 1024))) - C: END -@end example - -The format of the key parameters which depends on the algorithm is of -the form: - -@example - (genkey - (algo - (parameter_name_1 ....) - .... - (parameter_name_n ....))) -@end example - -If everything succeeds, the server returns the *public key* in a SPKI -like S-Expression like this: - -@example - (public-key - (rsa - (n ) - (e ))) -@end example - -Here is an example session: - -@example - C: GENKEY - S: INQUIRE KEYPARM - C: D (genkey (rsa (nbits 1024))) - C: END - S: D (public-key - S: D (rsa (n 326487324683264) (e 10001))) - S OK key created -@end example - -@node Agent IMPORT -@subsection Importing a Secret Key - -This operation is not yet supportted by GpgAgent. Specialized tools -are to be used for this. - -There is no actual need because we can expect that secret keys -created by a 3rd party are stored on a smartcard. If we have -generated the key ourself, we do not need to import it. - -@node Agent EXPORT -@subsection Export a Secret Key - -Not implemented. - -Should be done by an extra tool. - -@node Agent ISTRUSTED -@subsection Importing a Root Certificate - -Actually we do not import a Root Cert but provide a way to validate -any piece of data by storing its Hash along with a description and -an identifier in the PSE. Here is the interface desription: - -@example - ISTRUSTED -@end example - -Check whether the OpenPGP primary key or the X.509 certificate with the -given fingerprint is an ultimately trusted key or a trusted Root CA -certificate. The fingerprint should be given as a hexstring (without -any blanks or colons or whatever in between) and may be left padded with -00 in case of an MD5 fingerprint. GPGAgent will answer with: - -@example - OK -@end example - -The key is in the table of trusted keys. - -@example - ERR 304 (Not Trusted) -@end example - -The key is not in this table. - -Gpg needs the entire list of trusted keys to maintain the web of -trust; the following command is therefore quite helpful: - -@example - LISTTRUSTED -@end example - -GpgAgent returns a list of trusted keys line by line: - -@example - S: D 000000001234454556565656677878AF2F1ECCFF P - S: D 340387563485634856435645634856438576457A P - S: D FEDC6532453745367FD83474357495743757435D S - S: OK -@end example - -The first item on a line is the hexified fingerprint where MD5 -ingerprints are @code{00} padded to the left and the second item is a -flag to indicate the type of key (so that gpg is able to only take care -of PGP keys). P = OpenPGP, S = S/MIME. A client should ignore the rest -of the line, so that we can extend the format in the future. - -Finally a client should be able to mark a key as trusted: - -@example - MARKTRUSTED @var{fingerprint} "P"|"S" -@end example - -The server will then pop up a window to ask the user whether she -really trusts this key. For this it will probably ask for a text to -be displayed like this: - -@example - S: INQUIRE TRUSTDESC - C: D Do you trust the key with the fingerprint @@FPR@@ - C: D bla fasel blurb. - C: END - S: OK -@end example - -Known sequences with the pattern @@foo@@ are replaced according to this -table: - -@table @code -@item @@FPR16@@ -Format the fingerprint according to gpg rules for a v3 keys. -@item @@FPR20@@ -Format the fingerprint according to gpg rules for a v4 keys. -@item @@FPR@@ -Choose an appropriate format to format the fingerprint. -@item @@@@ -Replaced by a single @code{@@} -@end table - -@node Agent GET_PASSPHRASE -@subsection Ask for a passphrase - -This function is usually used to ask for a passphrase to be used for -conventional encryption, but may also be used by programs which need -special handling of passphrases. This command uses a syntax which helps -clients to use the agent with minimum effort. - -@example - GET_PASSPHRASE @var{cache_id} [@var{error_message} @var{prompt} @var{description}] -@end example - -@var{cache_id} is expected to be a hex string used for caching a -passphrase. Use a @code{X} to bypass the cache. With no other -arguments the agent returns a cached passphrase or an error. - -@var{error_message} is either a single @code{X} for no error message or -a string to be shown as an error message like (e.g. "invalid -passphrase"). Blanks must be percent escaped or replaced by @code{+}'. - -@var{prompt} is either a single @code{X} for a default prompt or the -text to be shown as the prompt. Blanks must be percent escaped or -replaced by @code{+}. - -@var{description} is a text shown above the entry field. Blanks must be -percent escaped or replaced by @code{+}. - -The agent either returns with an error or with a OK followed by the -hex encoded passphrase. Note that the length of the strings is -implicitly limited by the maximum length of a command. - -@example - CLEAR_PASSPHRASE @var{cache_id} -@end example - -may be used to invalidate the cache entry for a passphrase. The -function returns with OK even when there is no cached passphrase. - - -@node Agent GET_CONFIRMATION -@subsection Ask for confirmation - -This command may be used to ask for a simple confirmation by -presenting a text and 2 bottonts: Okay and Cancel. - -@example - GET_CONFIRMATION @var{description} -@end example - -@var{description}is displayed along with a Okay and Cancel -button. Blanks must be percent escaped or replaced by @code{+}. A -@code{X} may be used to display confirmation dialog with a default -text. - -The agent either returns with an error or with a OK. Note, that the -length of @var{description} is implicitly limited by the maximum -length of a command. - - - -@node Agent HAVEKEY -@subsection Check whether a key is available - -This can be used to see whether a secret key is available. It does -not return any information on whether the key is somehow protected. - -@example - HAVEKEY @var{keygrip} -@end example - -The Agent answers either with OK or @code{No_Secret_Key} (208). The -caller may want to check for other error codes as well. - - -@node Agent LEARN -@subsection Register a smartcard - -@example - LEARN [--send] -@end example - -This command is used to register a smartcard. With the --send -option given the certificates are send back. - - -@node Agent PASSWD -@subsection Change a Passphrase - -@example - PASSWD @var{keygrip} -@end example - -This command is used to interactively change the passphrase of the key -indentified by the hex string @var{keygrip}. - - - diff --git a/doc/gpg.texi b/doc/gpg.texi deleted file mode 100644 index 4ed4f1f76..000000000 --- a/doc/gpg.texi +++ /dev/null @@ -1,1806 +0,0 @@ -\input texinfo -@c This Texinfo document has been automatically generated by -@c docbook2texi from a DocBook documentation. The tool used -@c can be found at: -@c -@c Please send any bug reports, improvements, comments, -@c patches, etc. to Steve Cheng . - -@setfilename gpg.info -@dircategory GnuPG -@direntry -* gpg: (gpg). GnuPG encryption and signing tool. -@end direntry - -@node top -@top gpg -@menu -@end menu - -@majorheading Name -gpg ---- encryption and signing tool - -@majorheading Synopsis - -@majorheading DESCRIPTION -@code{gpg} is the main program for the GnuPG system. - -This man page only lists the commands and options available. -For more verbose documentation get the GNU Privacy Handbook (GPH) or -one of the other documents at http://www.gnupg.org/docs.html . - -Please remember that option parsing stops as soon as a non option is -encountered, you can explicitly stop option parsing by using the -special option "---". - -@majorheading COMMANDS -@code{gpg} recognizes these commands: - -@table @asis -@item -s, ---sign -Make a signature. This command may be combined -with ---encrypt. - -@item ---clearsign -Make a clear text signature. - -@item -b, ---detach-sign -Make a detached signature. - -@item -e, ---encrypt -Encrypt data. This option may be combined with ---sign. - -@item -c, ---symmetric -Encrypt with a symmetric cipher using a passphrase. The default -symmetric cipher used is CAST5, but may be chosen with the ----cipher-algo option. - -@item ---store -Store only (make a simple RFC1991 packet). - -@item ---decrypt @code{file} -Decrypt @code{file} (or stdin if no file is specified) and -write it to stdout (or the file specified with ----output). If the decrypted file is signed, the -signature is also verified. This command differs -from the default operation, as it never writes to the -filename which is included in the file and it -rejects files which don't begin with an encrypted -message. - -@item ---verify @code{sigfile} @code{signed-files} -Assume that @code{sigfile} is a signature and verify it -without generating any output. With no arguments, -the signature packet is read from stdin. If -only a sigfile is given, it may be a complete -signature or a detached signature, in which case -the signed stuff is expected in a file without the -".sig" or ".asc" extension. -With more than -1 argument, the first should be a detached signature -and the remaining files are the signed stuff. To read the signed -stuff from stdin, use @samp{-} as the second filename. -For security reasons a detached signature cannot read the signed -material from stdin without denoting it in the above way. - -@item ---verify-files @code{files} -This is a special version of the ---verify command which does not work with -detached signatures. The command expects the files to be verified either -on the command line or reads the filenames from stdin; each name must be on -separate line. The command is intended for quick checking of many files. - -@item ---encrypt-files @code{files} -This is a special version of the ---encrypt command. The command expects -the files to be encrypted either on the command line or reads the filenames -from stdin; each name must be on separate line. The command is intended -for a quick encryption of multiple files. - -@item ---decrypt-files @code{files} -The same as ---encrypt-files with the difference that files will be -decrypted. The syntax or the filenames is the same. - -@item ---list-keys @code{names} -@itemx ---list-public-keys @code{names} -List all keys from the public keyrings, or just the ones given on the -command line. - -Avoid using the output of this command in scripts or other programs as -it is likely to change as GnuPG changes. See ---with-colons for a -machine-parseable key listing command that is appropriate for use in -scripts and other programs. - -@item ---list-secret-keys @code{names} -List all keys from the secret keyrings, or just the ones given on the -command line. A '#' after the letters 'sec' means that the secret key -is not usable (for example, if it was created via ----export-secret-subkeys). - -@item ---list-sigs @code{names} -Same as ---list-keys, but the signatures are listed too. - -For each signature listed, there are several flags in between the -"sig" tag and keyid. These flags give additional information about -each signature. From left to right, they are the numbers 1-3 for -certificate check level (see ---default-cert-check-level), "L" for a -local or non-exportable signature (see ---lsign-key), "R" for a -nonRevocable signature (see ---nrsign-key), "P" for a signature that -contains a policy URL (see ---cert-policy-url), "N" for a signature -that contains a notation (see ---cert-notation), "X" for an eXpired -signature (see ---ask-cert-expire), and the numbers 1-9 or "T" for 10 -and above to indicate trust signature levels (see the ---edit-key -command "tsign"). - -@item ---check-sigs @code{names} -Same as ---list-sigs, but the signatures are verified. - -@item ---fingerprint @code{names} -List all keys with their fingerprints. This is the -same output as ---list-keys but with the additional output -of a line with the fingerprint. May also be combined -with ---list-sigs or --check-sigs. -If this command is given twice, the fingerprints of all -secondary keys are listed too. - -@item ---list-packets -List only the sequence of packets. This is mainly -useful for debugging. - -@item ---gen-key -Generate a new key pair. This command is normally only used -interactively. - -There is an experimental feature which allows you to create keys -in batch mode. See the file @file{doc/DETAILS} -in the source distribution on how to use this. - -@item ---edit-key @code{name} -Present a menu which enables you to do all key -related tasks: - -@table @asis -@item sign -Make a signature on key of user @code{name} -If the key is not yet signed by the default -user (or the users given with -u), the -program displays the information of the key -again, together with its fingerprint and -asks whether it should be signed. This -question is repeated for all users specified -with -u. - -@item lsign -Same as ---sign but the signature is marked as -non-exportable and will therefore never be used -by others. This may be used to make keys valid -only in the local environment. - -@item nrsign -Same as ---sign but the signature is marked as non-revocable and can -therefore never be revoked. - -@item nrlsign -Combines the functionality of nrsign and lsign to make a signature -that is both non-revocable and -non-exportable. - -@item tsign -Make a trust signature. This is a signature that combines the notions -of certification (like a regular signature), and trust (like the -"trust" command). It is generally only useful in distinct communities -or groups. - -@item revsig -Revoke a signature. For every signature which has been generated by -one of the secret keys, GnuPG asks whether a revocation certificate -should be generated. - -@item trust -Change the owner trust value. This updates the -trust-db immediately and no save is required. - -@item disable -@itemx enable -Disable or enable an entire key. A disabled key can not normally be -used for encryption. - -@item adduid -Create an alternate user id. - -@item addphoto -Create a photographic user id. This will prompt for a JPEG file that -will be embedded into the user ID. A very large JPEG will make for a -very large key. - -@item deluid -Delete a user id. - -@item revuid -Revoke a user id. - -@item addkey -Add a subkey to this key. - -@item delkey -Remove a subkey. - -@item addrevoker -Add a designated revoker. This takes one optional argument: -"sensitive". If a designated revoker is marked as sensitive, it will -not be exported by default (see -export-options). - -@item revkey -Revoke a subkey. - -@item expire -Change the key expiration time. If a subkey is selected, the -expiration time of this subkey will be changed. With no selection, -the key expiration of the primary key is changed. - -@item passwd -Change the passphrase of the secret key. - -@item primary -Flag the current user id as the primary one, removes the primary user -id flag from all other user ids and sets the timestamp of all affected -self-signatures one second ahead. Note that setting a photo user ID -as primary makes it primary over other photo user IDs, and setting a -regular user ID as primary makes it primary over other regular user -IDs. - -@item uid @code{n} -Toggle selection of user id with index @code{n}. -Use 0 to deselect all. - -@item key @code{n} -Toggle selection of subkey with index @code{n}. -Use 0 to deselect all. - -@item check -Check all selected user ids. - -@item showphoto -Display the selected photographic user -id. - -@item pref -List preferences from the selected user ID. This shows the actual -preferences, without including any implied preferences. - -@item showpref -More verbose preferences listing for the selected user ID. This shows -the preferences in effect by including the implied preferences of -3DES (cipher), SHA-1 (digest), and Uncompressed (compression) if they -are not already included in the preference list. - -@item setpref @code{string} -Set the list of user ID preferences to @code{string}, this should be a -string similar to the one printed by "pref". Using an empty string -will set the default preference string, using "none" will set the -preferences to nil. Use "gpg ---version" to get a list of available -algorithms. This command just initializes an internal list and does -not change anything unless another command (such as "updpref") which -changes the self-signatures is used. - -@item updpref -Change the preferences of all user IDs (or just of the selected ones -to the current list of preferences. The timestamp of all affected -self-signatures will be advanced by one second. Note that while you -can change the preferences on an attribute user ID (aka "photo ID"), -GnuPG does not select keys via attribute user IDs so these preferences -will not be used by GnuPG. - -@item toggle -Toggle between public and secret key listing. - -@item save -Save all changes to the key rings and quit. - -@item quit -Quit the program without updating the -key rings. - -@end table - -The listing shows you the key with its secondary -keys and all user ids. Selected keys or user ids -are indicated by an asterisk. The trust value is -displayed with the primary key: the first is the -assigned owner trust and the second is the calculated -trust value. Letters are used for the values: - -@table @asis -@item - -No ownertrust assigned / not yet calculated. - -@item e -Trust -calculation has failed; probably due to an expired key. - -@item q -Not enough information for calculation. - -@item n -Never trust this key. - -@item m -Marginally trusted. - -@item f -Fully trusted. - -@item u -Ultimately trusted. - -@end table - -@item ---sign-key @code{name} -Signs a public key with your secret key. This is a shortcut version of -the subcommand "sign" from ---edit. - -@item ---lsign-key @code{name} -Signs a public key with your secret key but marks it as -non-exportable. This is a shortcut version of the subcommand "lsign" -from ---edit. - -@item ---nrsign-key @code{name} -Signs a public key with your secret key but marks it as non-revocable. -This is a shortcut version of the subcommand "nrsign" from ---edit. - -@item ---delete-key @code{name} -Remove key from the public keyring. In batch mode either ---yes is -required or the key must be specified by fingerprint. This is a -safeguard against accidental deletion of multiple keys. - -@item ---delete-secret-key @code{name} -Remove key from the secret and public keyring. In batch mode the key -must be specified by fingerprint. - -@item ---delete-secret-and-public-key @code{name} -Same as ---delete-key, but if a secret key exists, it will be removed -first. In batch mode the key must be specified by fingerprint. - -@item ---gen-revoke -Generate a revocation certificate for the complete key. To revoke -a subkey or a signature, use the ---edit command. - -@item ---desig-revoke -Generate a designated revocation certificate for a key. This allows a -user (with the permission of the keyholder) to revoke someone else's -key. - -@item ---export @code{names} -Either export all keys from all keyrings (default -keyrings and those registered via option ---keyring), -or if at least one name is given, those of the given -name. The new keyring is written to stdout or to -the file given with option "output". Use together -with ---armor to mail those keys. - -@item ---send-keys @code{names} -Same as ---export but sends the keys to a keyserver. -Option ---keyserver must be used to give the name -of this keyserver. Don't send your complete keyring -to a keyserver - select only those keys which are new -or changed by you. - -@item ---export-all @code{names} -Same as ---export, but also exports keys which -are not compatible with OpenPGP. - -@item ---export-secret-keys @code{names} -@itemx ---export-secret-subkeys @code{names} -Same as ---export, but exports the secret keys instead. -This is normally not very useful and a security risk. -The second form of the command has the special property to -render the secret part of the primary key useless; this is -a GNU extension to OpenPGP and other implementations can -not be expected to successfully import such a key. -See the option ---simple-sk-checksum if you want to import such an -exported key with an older OpenPGP implementation. - -@item ---import @code{files} -@itemx ---fast-import @code{files} -Import/merge keys. This adds the given keys to the -keyring. The fast version is currently just a synonym. - -There are a few other options which control how this command works. -Most notable here is the ---merge-only option which does not insert new keys -but does only the merging of new signatures, user-IDs and subkeys. - -@item ---recv-keys @code{key IDs} -Import the keys with the given key IDs from a keyserver. Option ----keyserver must be used to give the name of this keyserver. - -@item ---refresh-keys @code{key IDs} -Request updates from a keyserver for keys that already exist on the -local keyring. This is useful for updating a key with the latest -signatures, user IDs, etc. Option ---keyserver must be used to give -the name of this keyserver. - -@item ---search-keys @code{names} -Search the keyserver for the given names. Multiple names given here -will be joined together to create the search string for the keyserver. -Option ---keyserver must be used to give the name of this keyserver. - -@item ---update-trustdb -Do trust database maintenance. This command iterates over all keys -and builds the Web-of-Trust. This is an interactive command because it -may have to ask for the "ownertrust" values for keys. The user has to -give an estimation of how far she trusts the owner of the displayed -key to correctly certify (sign) other keys. GnuPG only asks for the -ownertrust value if it has not yet been assigned to a key. Using the ----edit-key menu, the assigned value can be changed at any time. - -@item ---check-trustdb -Do trust database maintenance without user interaction. From time to -time the trust database must be updated so that expired keys or -signatures and the resulting changes in the Web-of-Trust can be -tracked. Normally, GnuPG will calculate when this is required and do -it automatically unless ---no-auto-check-trustdb is set. This command -can be used to force a trust database check at any time. The -processing is identical to that of ---update-trustdb but it skips keys -with a not yet defined "ownertrust". - -For use with cron jobs, this command can be used together with ---batch -in which case the trust database check is done only if a check is -needed. To force a run even in batch mode add the option ---yes. - -@item ---export-ownertrust -Send the ownertrust values to stdout. This is useful for backup -purposes as these values are the only ones which can't be re-created -from a corrupted trust DB. - -@item ---import-ownertrust @code{files} -Update the trustdb with the ownertrust values stored -in @code{files} (or stdin if not given); existing -values will be overwritten. - -@item ---rebuild-keydb-caches -When updating from version 1.0.6 to 1.0.7 this command should be used -to create signature caches in the keyring. It might be handy in other -situations too. - -@item ---print-md @code{algo} @code{files} -@itemx ---print-mds @code{files} -Print message digest of algorithm ALGO for all given files or stdin. -With the second form (or a deprecated "*" as algo) digests for all -available algorithms are printed. - -@item ---gen-random @code{0|1|2} @code{count} -Emit COUNT random bytes of the given quality level. If count is not given -or zero, an endless sequence of random bytes will be emitted. -PLEASE, don't use this command unless you know what you are doing; it may -remove precious entropy from the system! - -@item ---gen-prime @code{mode} @code{bits} @code{qbits} -Use the source, Luke :-). The output format is still subject to change. - -@item ---version -Print version information along with a list -of supported algorithms. - -@item ---warranty -Print warranty information. - -@item -h, ---help -Print usage information. This is a really long list even though it -doesn't list all options. For every option, consult this manual. - -@end table - -@majorheading OPTIONS -Long options can be put in an options file (default -"~/.gnupg/gpg.conf"). Short option names will not work - for example, -"armor" is a valid option for the options file, while "a" is not. Do -not write the 2 dashes, but simply the name of the option and any -required arguments. Lines with a hash ('#') as the first -non-white-space character are ignored. Commands may be put in this -file too, but that is not generally useful as the command will execute -automatically with every execution of gpg. - -@code{gpg} recognizes these options: - -@table @asis -@item -a, ---armor -Create ASCII armored output. - -@item -o, ---output @code{file} -Write output to @code{file}. - -@item ---mangle-dos-filenames -@itemx ---no-mangle-dos-filenames -Older version of Windows cannot handle filenames with more than one -dot. ---mangle-dos-filenames causes GnuPG to replace (rather than add -to) the extension of an output filename to avoid this problem. This -option is off by default and has no effect on non-Windows platforms. - -@item -u, ---local-user @code{name} -Use @code{name} as the user ID to sign. -This option is silently ignored for the list commands, -so that it can be used in an options file. - -@item ---default-key @code{name} -Use @code{name} as default user ID for signatures. If this -is not used the default user ID is the first user ID -found in the secret keyring. - -@item -r, ---recipient @code{name} -@itemx -Encrypt for user id @code{name}. If this option or ---hidden-recipient -is not specified, GnuPG asks for the user-id unless ----default-recipient is given. - -@item -R, ---hidden-recipient @code{name} -@itemx -Encrypt for user id @code{name}, but hide the keyid of the key. This -option hides the receiver of the message and is a countermeasure -against traffic analysis. If this option or ---recipient is not -specified, GnuPG asks for the user-id unless ---default-recipient is -given. - -@item ---default-recipient @code{name} -Use @code{name} as default recipient if option ---recipient is not used and -don't ask if this is a valid one. @code{name} must be non-empty. - -@item ---default-recipient-self -Use the default key as default recipient if option ---recipient is not used and -don't ask if this is a valid one. The default key is the first one from the -secret keyring or the one set with ---default-key. - -@item ---no-default-recipient -Reset ---default-recipient and --default-recipient-self. - -@item ---encrypt-to @code{name} -Same as ---recipient but this one is intended for use -in the options file and may be used with -your own user-id as an "encrypt-to-self". These keys -are only used when there are other recipients given -either by use of ---recipient or by the asked user id. -No trust checking is performed for these user ids and -even disabled keys can be used. - -@item ---hidden-encrypt-to @code{name} -Same as ---hidden-recipient but this one is intended for use in the -options file and may be used with your own user-id as a hidden -"encrypt-to-self". These keys are only used when there are other -recipients given either by use of ---recipient or by the asked user id. -No trust checking is performed for these user ids and even disabled -keys can be used. - -@item ---no-encrypt-to -Disable the use of all ---encrypt-to and --hidden-encrypt-to keys. - -@item -v, ---verbose -Give more information during processing. If used -twice, the input data is listed in detail. - -@item -q, ---quiet -Try to be as quiet as possible. - -@item -z @code{n}, ---compress @code{n} -Set compression level to @code{n}. A value of 0 for @code{n} -disables compression. Default is to use the default -compression level of zlib (normally 6). - -@item -t, ---textmode -@itemx ---no-textmode -Use canonical text mode. ---no-textmode disables this option. If -t -(but not ---textmode) is used together with armoring and signing, this -enables clearsigned messages. This kludge is needed for command-line -compatibility with command-line versions of PGP; normally you would -use ---sign or --clearsign to select the type of the signature. - -@item -n, ---dry-run -Don't make any changes (this is not completely implemented). - -@item -i, ---interactive -Prompt before overwriting any files. - -@item ---batch -@itemx ---no-batch -Use batch mode. Never ask, do not allow interactive commands. ----no-batch disables this option. - -@item ---no-tty -Make sure that the TTY (terminal) is never used for any output. -This option is needed in some cases because GnuPG sometimes prints -warnings to the TTY if ---batch is used. - -@item ---yes -Assume "yes" on most questions. - -@item ---no -Assume "no" on most questions. - -@item ---default-cert-check-level @code{n} -The default to use for the check level when signing a key. - -0 means you make no particular claim as to how carefully you verified -the key. - -1 means you believe the key is owned by the person who claims to own -it but you could not, or did not verify the key at all. This is -useful for a "persona" verification, where you sign the key of a -pseudonymous user. - -2 means you did casual verification of the key. For example, this -could mean that you verified that the key fingerprint and checked the -user ID on the key against a photo ID. - -3 means you did extensive verification of the key. For example, this -could mean that you verified the key fingerprint with the owner of the -key in person, and that you checked, by means of a hard to forge -document with a photo ID (such as a passport) that the name of the key -owner matches the name in the user ID on the key, and finally that you -verified (by exchange of email) that the email address on the key -belongs to the key owner. - -Note that the examples given above for levels 2 and 3 are just that: -examples. In the end, it is up to you to decide just what "casual" -and "extensive" mean to you. - -This option defaults to 0. - -@item ---trusted-key @code{long key ID} -Assume that the specified key (which must be given -as a full 8 byte key ID) is as trustworthy as one of -your own secret keys. This option is useful if you -don't want to keep your secret keys (or one of them) -online but still want to be able to check the validity of a given -recipient's or signator's key. - -@item ---trust-model @code{pgp|classic|always} -Set what trust model GnuPG should follow. The models are: - -@table @asis -@item pgp -This is the web-of-trust combined with trust signatures as used in PGP -5.x and later. This is the default trust model. - -@item classic -This is the standard web-of-trust as used in PGP 2.x and earlier. - -@item always -Skip key validation and assume that used keys are always fully -trusted. You won't use this unless you have installed some external -validation scheme. This option also suppresses the "[uncertain]" tag -printed with signature checks when there is no evidence that the user -ID is bound to the key. - -@end table - -@item ---always-trust -Identical to `---trust-model always' - -@item ---keyserver @code{name} -Use @code{name} as your keyserver. This is the server that ---recv-keys, ----send-keys, and --search-keys will communicate with to receive keys -from, send keys to, and search for keys on. The format of the -@code{name} is a URI: `scheme:[//]keyservername[:port]' The scheme is -the type of keyserver: "hkp" for the Horowitz (or compatible) -keyservers, "ldap" for the NAI LDAP keyserver, or "mailto" for the -Horowitz email keyserver. Note that your particular installation of -GnuPG may have other keyserver types available as well. Keyserver -schemes are case-insensitive. - -Most keyservers synchronize with each other, so there is generally no -need to send keys to more than one server. Using the command "host -l -pgp.net | grep wwwkeys" gives you a list of HKP keyservers. When -using one of the wwwkeys servers, due to load balancing using -round-robin DNS you may notice that you get a different key server -each time. - -@item ---keyserver-options @code{parameters} -This is a space or comma delimited string that gives options for the -keyserver. Options can be prepended with a `no-' to give the opposite -meaning. Valid import-options or export-options may be used here as -well to apply to importing (---recv-key) or exporting (--send-key) a -key from a keyserver. While not all options are available for all -keyserver types, some common options are: - -@table @asis -@item include-revoked -When searching for a key with ---search-keys, include keys that are -marked on the keyserver as revoked. Note that this option is always -set when using the NAI HKP keyserver, as this keyserver does not -differentiate between revoked and unrevoked keys. - -@item include-disabled -When searching for a key with ---search-keys, include keys that are -marked on the keyserver as disabled. Note that this option is not -used with HKP keyservers. - -@item include-subkeys -When receiving a key, include subkeys as potential targets. Note that -this option is not used with HKP keyservers, as they do not support -retrieving keys by subkey id. - -@item use-temp-files -On most Unix-like platforms, GnuPG communicates with the keyserver -helper program via pipes, which is the most efficient method. This -option forces GnuPG to use temporary files to communicate. On some -platforms (such as Win32 and RISC OS), this option is always enabled. - -@item keep-temp-files -If using `use-temp-files', do not delete the temp files after using -them. This option is useful to learn the keyserver communication -protocol by reading the temporary files. - -@item verbose -Tell the keyserver helper program to be more verbose. This option can -be repeated multiple times to increase the verbosity level. - -@item honor-http-proxy -For keyserver schemes that use HTTP (such as HKP), try to access the -keyserver over the proxy set with the environment variable -"http_proxy". - -@item auto-key-retrieve -This option enables the automatic retrieving of keys from a keyserver -when verifying signatures made by keys that are not on the local -keyring. - -Note that this option makes a "web bug" like behavior possible. -Keyserver operators can see which keys you request, so by sending you -a message signed by a brand new key (which you naturally will not have -on your local keyring), the operator can tell both your IP address and -the time when you verified the signature. - -@end table - -@item ---import-options @code{parameters} -This is a space or comma delimited string that gives options for -importing keys. Options can be prepended with a `no-' to give the -opposite meaning. The options are: - -@table @asis -@item allow-local-sigs -Allow importing key signatures marked as "local". This is not -generally useful unless a shared keyring scheme is being used. -Defaults to no. - -@item repair-pks-subkey-bug -During import, attempt to repair the damage caused by the PKS -keyserver bug (pre version 0.9.6) that mangles keys with multiple -subkeys. Note that this cannot completely repair the damaged key as -some crucial data is removed by the keyserver, but it does at least -give you back one subkey. Defaults to no for regular ---import and to -yes for keyserver ---recv-keys. - -@end table - -@item ---export-options @code{parameters} -This is a space or comma delimited string that gives options for -exporting keys. Options can be prepended with a `no-' to give the -opposite meaning. The options are: - -@table @asis -@item include-non-rfc -Include non-RFC compliant keys in the export. Defaults to yes. - -@item include-local-sigs -Allow exporting key signatures marked as "local". This is not -generally useful unless a shared keyring scheme is being used. -Defaults to no. - -@item include-attributes -Include attribute user IDs (photo IDs) while exporting. This is -useful to export keys if they are going to be used by an OpenPGP -program that does not accept attribute user IDs. Defaults to yes. - -@item include-sensitive-revkeys -Include designated revoker information that was marked as -"sensitive". Defaults to no. - -@end table - -@item ---list-options @code{parameters} -This is a space or comma delimited string that gives options used when -listing keys and signatures (that is, ---list-keys, --list-sigs, ----list-public-keys, --list-secret-keys, and the --edit-key functions). -Options can be prepended with a `no-' to give the opposite meaning. -The options are: - -@table @asis -@item show-photos -Causes ---list-keys, --list-sigs, --list-public-keys, and ----list-secret-keys to display any photo IDs attached to the key. -Defaults to no. See also ---photo-viewer. - -@item show-policy-url -Show policy URLs in the ---list-sigs or --check-sigs listings. -Defaults to no. - -@item show-notation -Show signature notations in the ---list-sigs or --check-sigs listings. -Defaults to no. - -@item show-keyserver-url -Show any preferred keyserver URL in the ---list-sigs or --check-sigs -listings. Defaults to no. - -@item show-validity -Display the calculated validity of keys and user IDs during key -listings. Defaults to no. - -@item show-long-keyid -Display all 64 bits (16 digits) of key IDs during key listings, rather -than the more common 32 bit (8 digit) IDs. Defaults to no. - -@item show-unusable-uids -Show revoked and expired user IDs in key listings. Defaults to no. - -@item show-keyring -Display the keyring name at the head of key listings to show which -keyring a given key resides on. Defaults to no. - -@item show-sig-expire -Show signature expiration dates (if any) during ---list-sigs or ----check-sigs listings. Defaults to no. - -@end table - -@item ---verify-options @code{parameters} -This is a space or comma delimited string that gives options used when -verifying signatures. Options can be prepended with a `no-' to give -the opposite meaning. The options are: - -@table @asis -@item show-photos -Display any photo IDs present on the key that issued the signature. -Defaults to no. See also ---photo-viewer. - -@item show-policy-url -Show policy URLs in the signature being verified. Defaults to no. - -@item show-notation -Show signature notations in the signature being verified. Defaults to -no. - -@item show-keyserver-url -Show any preferred keyserver URL in the signature being verified. -Defaults to no. - -@item show-validity -Display the calculated validity of the user IDs on the key that issued -the signature. Defaults to no. - -@item show-long-keyid -Display all 64 bits (16 digits) of key IDs during signature -verification, rather than the more common 32 bit (8 digit) IDs. -Defaults to no. - -@item show-unusable-uids -Show revoked and expired user IDs during signature verification. -Defaults to no. - -@end table - -@item ---show-photos -@itemx ---no-show-photos -Causes ---list-keys, --list-sigs, --list-public-keys, ----list-secret-keys, and verifying a signature to also display the -photo ID attached to the key, if any. See also ---photo-viewer. These -options are deprecated. Use `---list-options [no-]show-photos' and/or -`---verify-options [no-]show-photos' instead. - -@item ---photo-viewer @code{string} -This is the command line that should be run to view a photo ID. "%i" -will be expanded to a filename containing the photo. "%I" does the -same, except the file will not be deleted once the viewer exits. -Other flags are "%k" for the key ID, "%K" for the long key ID, "%f" -for the key fingerprint, "%t" for the extension of the image type -(e.g. "jpg"), "%T" for the MIME type of the image (e.g. "image/jpeg"), -and "%%" for an actual percent sign. If neither %i or %I are present, -then the photo will be supplied to the viewer on standard input. - -The default viewer is "xloadimage -fork -quiet -title 'KeyID 0x%k' -stdin". Note that if your image viewer program is not secure, then -executing it from GnuPG does not make it secure. - -@item ---exec-path @code{string} -Sets a list of directories to search for photo viewers and keyserver -helpers. If not provided, keyserver helpers use the compiled-in -default directory, and photo viewers use the $PATH environment -variable. - -@item ---show-keyring -Display the keyring name at the head of key listings to show which -keyring a given key resides on. This option is deprecated: use -`---list-options [no-]show-keyring' instead. - -@item ---keyring @code{file} -Add @code{file} to the list of keyrings. If @code{file} begins with a -tilde and a slash, these are replaced by the HOME directory. If the -filename does not contain a slash, it is assumed to be in the GnuPG -home directory ("~/.gnupg" if ---homedir is not used). The filename -may be prefixed with a scheme: - -"gnupg-ring:" is the default one. - -It might make sense to use it together with ---no-default-keyring. - -@item ---secret-keyring @code{file} -Same as ---keyring but for the secret keyrings. - -@item ---primary-keyring @code{file} -Designate @code{file} as the primary public keyring. This means that -newly imported keys (via ---import or keyserver --recv-from) will go to -this keyring. - -@item ---trustdb-name @code{file} -Use @code{file} instead of the default trustdb. If @code{file} begins -with a tilde and a slash, these are replaced by the HOME directory. If -the filename does not contain a slash, it is assumed to be in the -GnuPG home directory ("~/.gnupg" if ---homedir is not used). - -@item ---homedir @code{directory} -Set the name of the home directory to @code{directory} If this -option is not used it defaults to "~/.gnupg". It does -not make sense to use this in a options file. This -also overrides the environment variable "GNUPGHOME". - -@item ---charset @code{name} -Set the name of the native character set. This is used -to convert some strings to proper UTF-8 encoding. If this option is not used, the default character set is determined -from the current locale. A verbosity level of 3 shows the used one. -Valid values for @code{name} are: - -@table @asis -@item iso-8859-1 -This is the Latin 1 set. - -@item iso-8859-2 -The Latin 2 set. - -@item iso-8859-15 -This is currently an alias for -the Latin 1 set. - -@item koi8-r -The usual Russian set (rfc1489). - -@item utf-8 -Bypass all translations and assume -that the OS uses native UTF-8 encoding. - -@end table - -@item ---utf8-strings -@itemx ---no-utf8-strings -Assume that the arguments are already given as UTF8 strings. The default -(---no-utf8-strings) -is to assume that arguments are encoded in the character set as specified -by ---charset. These options affect all following arguments. Both options may -be used multiple times. - -@item ---options @code{file} -Read options from @code{file} and do not try to read -them from the default options file in the homedir -(see ---homedir). This option is ignored if used -in an options file. - -@item ---no-options -Shortcut for "---options /dev/null". This option is -detected before an attempt to open an option file. -Using this option will also prevent the creation of a -"~./gnupg" homedir. - -@item ---load-extension @code{name} -Load an extension module. If @code{name} does not contain a slash it is -searched for in the directory configured when GnuPG was built -(generally "/usr/local/lib/gnupg"). Extensions are not generally -useful anymore, and the use of this option is deprecated. - -@item ---debug @code{flags} -Set debugging flags. All flags are or-ed and @code{flags} may -be given in C syntax (e.g. 0x0042). - -@item ---debug-all -Set all useful debugging flags. - -@item ---enable-progress-filter -Enable certain PROGRESS status outputs. This option allows frontends -to display a progress indicator while gpg is processing larger files. -There is a slight performance overhead using it. - -@item ---status-fd @code{n} -Write special status strings to the file descriptor @code{n}. -See the file DETAILS in the documentation for a listing of them. - -@item ---logger-fd @code{n} -Write log output to file descriptor @code{n} and not to stderr. - -@item ---attribute-fd @code{n} -Write attribute subpackets to the file descriptor @code{n}. This is -most useful for use with ---status-fd, since the status messages are -needed to separate out the various subpackets from the stream -delivered to the file descriptor. - -@item ---sk-comments -@itemx ---no-sk-comments -Include secret key comment packets when exporting secret keys. This -is a GnuPG extension to the OpenPGP standard, and is off by default. -Please note that this has nothing to do with the comments in clear -text signatures or armor headers. ---no-sk-comments disables this -option. - -@item ---comment @code{string} -@itemx ---no-comments -Use @code{string} as a comment string in clear text signatures and -ASCII armored messages or keys (see ---armor). The default behavior is -not to use a comment string. ---comment may be repeated multiple times -to get multiple comment strings. ---no-comments removes all comments. - -@item ---emit-version -@itemx ---no-emit-version -Force inclusion of the version string in ASCII armored output. ----no-emit-version disables this option. - -@item ---sig-notation @code{name=value} -@itemx ---cert-notation @code{name=value} -@itemx -N, ---set-notation @code{name=value} -Put the name value pair into the signature as notation data. -@code{name} must consist only of printable characters or spaces, and -must contain a '@@' character. This is to help prevent pollution of -the IETF reserved notation namespace. The ---expert flag overrides the -'@@' check. @code{value} may be any printable string; it will be -encoded in UTF8, so you should check that your ---charset is set -correctly. If you prefix @code{name} with an exclamation mark, the -notation data will be flagged as critical (rfc2440:5.2.3.15). ----sig-notation sets a notation for data signatures. --cert-notation -sets a notation for key signatures (certifications). ---set-notation -sets both. - -There are special codes that may be used in notation names. "%k" will -be expanded into the key ID of the key being signed, "%K" into the -long key ID of the key being signed, "%f" into the fingerprint of the -key being signed, "%s" into the key ID of the key making the -signature, "%S" into the long key ID of the key making the signature, -"%g" into the fingerprint of the key making the signature (which might -be a subkey), "%p" into the fingerprint of the primary key of the key -making the signature, and "%%" results in a single "%". %k, %K, and -%f are only meaningful when making a key signature (certification). - -@item ---show-notation -@itemx ---no-show-notation -Show signature notations in the ---list-sigs or --check-sigs listings -as well as when verifying a signature with a notation in it. These -options are deprecated. Use `---list-options [no-]show-notation' -and/or `---verify-options [no-]show-notation' instead. - -@item ---sig-policy-url @code{string} -@itemx ---cert-policy-url @code{string} -@itemx ---set-policy-url @code{string} -Use @code{string} as a Policy URL for signatures (rfc2440:5.2.3.19). -If you prefix it with an exclamation mark, the policy URL packet will -be flagged as critical. ---sig-policy-url sets a a policy url for data -signatures. ---cert-policy-url sets a policy url for key signatures -(certifications). ---set-policy-url sets both. - -The same %-expandos used for notation data are available here as well. - -@item ---show-policy-url -@itemx ---no-show-policy-url -Show policy URLs in the ---list-sigs or --check-sigs listings as well -as when verifying a signature with a policy URL in it. These options -are deprecated. Use `---list-options [no-]show-policy-url' and/or -`---verify-options [no-]show-policy-url' instead. - -@item ---sig-keyserver-url @code{string} -Use @code{string} as a preferred keyserver URL for data signatures. If -you prefix it with an exclamation mark, the keyserver URL packet will -be flagged as critical. - -The same %-expandos used for notation data are available here as well. - -@item ---set-filename @code{string} -Use @code{string} as the filename which is stored inside messages. -This overrides the default, which is to use the actual filename of the -file being encrypted. - -@item ---for-your-eyes-only -@itemx ---no-for-your-eyes-only -Set the `for your eyes only' flag in the message. This causes GnuPG -to refuse to save the file unless the ---output option is given, and -PGP to use the "secure viewer" with a Tempest-resistant font to -display the message. This option overrides ---set-filename. ----no-for-your-eyes-only disables this option. - -@item ---use-embedded-filename -Try to create a file with a name as embedded in the data. -This can be a dangerous option as it allows to overwrite files. - -@item ---completes-needed @code{n} -Number of completely trusted users to introduce a new -key signer (defaults to 1). - -@item ---marginals-needed @code{n} -Number of marginally trusted users to introduce a new -key signer (defaults to 3) - -@item ---max-cert-depth @code{n} -Maximum depth of a certification chain (default is 5). - -@item ---cipher-algo @code{name} -Use @code{name} as cipher algorithm. Running the program -with the command ---version yields a list of supported -algorithms. If this is not used the cipher algorithm is -selected from the preferences stored with the key. - -@item ---digest-algo @code{name} -Use @code{name} as the message digest algorithm. Running the program -with the command ---version yields a list of supported algorithms. - -@item ---compress-algo @code{name} -Use compression algorithm @code{name}. "zlib" is RFC1950 ZLIB -compression. "zip" is RFC-1951 ZIP compression which is used by PGP. -"uncompressed" or "none" disables compression. If this option is not -used, the default behavior is to examine the recipient key preferences -to see which algorithms the recipient supports. If all else fails, -ZIP is used for maximum compatibility. Note, however, that ZLIB may -give better compression results if that is more important, as the -compression window size is not limited to 8k. - -@item ---cert-digest-algo @code{name} -Use @code{name} as the message digest algorithm used when signing a -key. Running the program with the command ---version yields a list of -supported algorithms. Be aware that if you choose an algorithm that -GnuPG supports but other OpenPGP implementations do not, then some -users will not be able to use the key signatures you make, or quite -possibly your entire key. - -@item ---s2k-cipher-algo @code{name} -Use @code{name} as the cipher algorithm used to protect secret keys. -The default cipher is CAST5. This cipher is also used for -conventional encryption if ---personal-cipher-preferences and ----cipher-algo is not given. - -@item ---s2k-digest-algo @code{name} -Use @code{name} as the digest algorithm used to mangle the passphrases. -The default algorithm is SHA-1. - -@item ---s2k-mode @code{n} -Selects how passphrases are mangled. If @code{n} is 0 a plain -passphrase (which is not recommended) will be used, a 1 adds a salt to -the passphrase and a 3 (the default) iterates the whole process a -couple of times. Unless ---rfc1991 is used, this mode is also used for -conventional encryption. - -@item ---simple-sk-checksum -Secret keys are integrity protected by using a SHA-1 checksum. This -method will be part of an enhanced OpenPGP specification but GnuPG -already uses it as a countermeasure against certain attacks. Old -applications don't understand this new format, so this option may be -used to switch back to the old behaviour. Using this this option -bears a security risk. Note that using this option only takes effect -when the secret key is encrypted - the simplest way to make this -happen is to change the passphrase on the key (even changing it to the -same value is acceptable). - -@item ---disable-cipher-algo @code{name} -Never allow the use of @code{name} as cipher algorithm. -The given name will not be checked so that a later loaded algorithm -will still get disabled. - -@item ---disable-pubkey-algo @code{name} -Never allow the use of @code{name} as public key algorithm. -The given name will not be checked so that a later loaded algorithm -will still get disabled. - -@item ---no-sig-cache -Do not cache the verification status of key signatures. -Caching gives a much better performance in key listings. However, if -you suspect that your public keyring is not save against write -modifications, you can use this option to disable the caching. It -probably does not make sense to disable it because all kind of damage -can be done if someone else has write access to your public keyring. - -@item ---no-sig-create-check -GnuPG normally verifies each signature right after creation to protect -against bugs and hardware malfunctions which could leak out bits from -the secret key. This extra verification needs some time (about 115% -for DSA keys), and so this option can be used to disable it. -However, due to the fact that the signature creation needs manual -interaction, this performance penalty does not matter in most settings. - -@item ---auto-check-trustdb -@itemx ---no-auto-check-trustdb -If GnuPG feels that its information about the Web-of-Trust has to be -updated, it automatically runs the ---check-trustdb command internally. -This may be a time consuming process. ---no-auto-check-trustdb -disables this option. - -@item ---throw-keyid -Do not put the keyids into encrypted packets. This option hides the -receiver of the message and is a countermeasure against traffic -analysis. It may slow down the decryption process because all -available secret keys are tried. - -@item ---no-throw-keyid -Resets the ---throw-keyid option. - -@item ---not-dash-escaped -This option changes the behavior of cleartext signatures -so that they can be used for patch files. You should not -send such an armored file via email because all spaces -and line endings are hashed too. You can not use this -option for data which has 5 dashes at the beginning of a -line, patch files don't have this. A special armor header -line tells GnuPG about this cleartext signature option. - -@item ---escape-from-lines -@itemx ---no-escape-from-lines -Because some mailers change lines starting with "From " to ">From -" it is good to handle such lines in a special way when creating -cleartext signatures to prevent the mail system from breaking the -signature. Note that all other PGP versions do it this way too. -Enabled by default. ---no-escape-from-lines disables this option. - -@item ---passphrase-fd @code{n} -Read the passphrase from file descriptor @code{n}. If you use -0 for @code{n}, the passphrase will be read from stdin. This -can only be used if only one passphrase is supplied. -Don't use this option if you can avoid it. - -@item ---command-fd @code{n} -This is a replacement for the deprecated shared-memory IPC mode. -If this option is enabled, user input on questions is not expected -from the TTY but from the given file descriptor. It should be used -together with ---status-fd. See the file doc/DETAILS in the source -distribution for details on how to use it. - -@item ---use-agent -@itemx ---no-use-agent -Try to use the GnuPG-Agent. Please note that this agent is still under -development. With this option, GnuPG first tries to connect to the -agent before it asks for a passphrase. ---no-use-agent disables this -option. - -@item ---gpg-agent-info -Override the value of the environment variable -@samp{GPG_AGENT_INFO}. This is only used when ---use-agent has been given - -@item Compliance options -These options control what GnuPG is compliant to. Only one of these -options may be active at a time. Note that the default setting of -this is nearly always the correct one. See the INTEROPERABILITY WITH -OTHER OPENPGP PROGRAMS section below before using one of these -options. - -@table @asis -@item ---gnupg -Use standard GnuPG behavior. This is essentially OpenPGP behavior -(see ---openpgp), but with some additional workarounds for common -compatibility problems in different versions of PGP. This is the -default option, so it is not generally needed, but it may be useful to -override a different compliance option in the gpg.conf file. - -@item ---openpgp -Reset all packet, cipher and digest options to strict OpenPGP -behavior. Use this option to reset all previous options like ----rfc1991, --force-v3-sigs, --s2k-*, --cipher-algo, --digest-algo and ----compress-algo to OpenPGP compliant values. All PGP workarounds are -disabled. - -@item ---rfc2440 -Reset all packet, cipher and digest options to strict RFC-2440 -behavior. Note that this is currently the same thing as ---openpgp. - -@item ---rfc1991 -Try to be more RFC-1991 (PGP 2.x) compliant. - -@item ---pgp2 -Set up all options to be as PGP 2.x compliant as possible, and warn if -an action is taken (e.g. encrypting to a non-RSA key) that will create -a message that PGP 2.x will not be able to handle. Note that `PGP -2.x' here means `MIT PGP 2.6.2'. There are other versions of PGP 2.x -available, but the MIT release is a good common baseline. - -This option implies `---rfc1991 --disable-mdc --no-force-v4-certs ----no-sk-comment --escape-from-lines --force-v3-sigs ----no-ask-sig-expire --no-ask-cert-expire --cipher-algo IDEA ----digest-algo MD5 --compress-algo 1'. It also disables --textmode -when encrypting. - -@item ---pgp6 -Set up all options to be as PGP 6 compliant as possible. This -restricts you to the ciphers IDEA (if the IDEA plugin is installed), -3DES, and CAST5, the hashes MD5, SHA1 and RIPEMD160, and the -compression algorithms none and ZIP. This also disables ----throw-keyid, and making signatures with signing subkeys as PGP 6 -does not understand signatures made by signing subkeys. - -This option implies `---disable-mdc --no-sk-comment --escape-from-lines ----force-v3-sigs --no-ask-sig-expire' - -@item ---pgp7 -Set up all options to be as PGP 7 compliant as possible. This is -identical to ---pgp6 except that MDCs are not disabled, and the list of -allowable ciphers is expanded to add AES128, AES192, AES256, and -TWOFISH. - -@item ---pgp8 -Set up all options to be as PGP 8 compliant as possible. PGP 8 is a -lot closer to the OpenPGP standard than previous versions of PGP, so -all this does is disable ---throw-keyid and set --escape-from-lines. -The allowed algorithms list is the same as ---pgp7 with the addition of -the SHA-256 digest algorithm. - -@end table - -@item ---force-v3-sigs -@itemx ---no-force-v3-sigs -OpenPGP states that an implementation should generate v4 signatures -but PGP versions 5 and higher only recognize v4 signatures on key -material. This option forces v3 signatures for signatures on data. -Note that this option overrides ---ask-sig-expire, as v3 signatures -cannot have expiration dates. ---no-force-v3-sigs disables this -option. - -@item ---force-v4-certs -@itemx ---no-force-v4-certs -Always use v4 key signatures even on v3 keys. This option also -changes the default hash algorithm for v3 RSA keys from MD5 to SHA-1. ----no-force-v4-certs disables this option. - -@item ---force-mdc -Force the use of encryption with a modification detection code. This -is always used with the newer ciphers (those with a blocksize greater -than 64 bits), or if all of the recipient keys indicate MDC support in -their feature flags. - -@item ---disable-mdc -Disable the use of the modification detection code. Note that by -using this option, the encrypted message becomes vulnerable to a -message modification attack. - -@item ---allow-non-selfsigned-uid -@itemx ---no-allow-non-selfsigned-uid -Allow the import and use of keys with user IDs which are not -self-signed. This is not recommended, as a non self-signed user ID is -trivial to forge. ---no-allow-non-selfsigned-uid disables. - -@item ---allow-freeform-uid -Disable all checks on the form of the user ID while generating a new -one. This option should only be used in very special environments as -it does not ensure the de-facto standard format of user IDs. - -@item ---ignore-time-conflict -GnuPG normally checks that the timestamps associated with keys and -signatures have plausible values. However, sometimes a signature -seems to be older than the key due to clock problems. This option -makes these checks just a warning. See also ---ignore-valid-from for -timestamp issues on subkeys. - -@item ---ignore-valid-from -GnuPG normally does not select and use subkeys created in the future. -This option allows the use of such keys and thus exhibits the -pre-1.0.7 behaviour. You should not use this option unless you there -is some clock problem. See also ---ignore-time-conflict for timestamp -issues with signatures. - -@item ---ignore-crc-error -The ASCII armor used by OpenPGP is protected by a CRC checksum against -transmission errors. Sometimes it happens that the CRC gets mangled -somewhere on the transmission channel but the actual content (which is -protected by the OpenPGP protocol anyway) is still okay. This option -will let gpg ignore CRC errors. - -@item ---ignore-mdc-error -This option changes a MDC integrity protection failure into a warning. -This can be useful if a message is partially corrupt, but it is -necessary to get as much data as possible out of the corrupt message. -However, be aware that a MDC protection failure may also mean that the -message was tampered with intentionally by an attacker. - -@item ---lock-once -Lock the databases the first time a lock is requested -and do not release the lock until the process -terminates. - -@item ---lock-multiple -Release the locks every time a lock is no longer -needed. Use this to override a previous ---lock-once -from a config file. - -@item ---lock-never -Disable locking entirely. This option should be used only in very -special environments, where it can be assured that only one process -is accessing those files. A bootable floppy with a stand-alone -encryption system will probably use this. Improper usage of this -option may lead to data and key corruption. - -@item ---no-random-seed-file -GnuPG uses a file to store its internal random pool over invocations. -This makes random generation faster; however sometimes write operations -are not desired. This option can be used to achieve that with the cost of -slower random generation. - -@item ---no-verbose -Reset verbose level to 0. - -@item ---no-greeting -Suppress the initial copyright message. - -@item ---no-secmem-warning -Suppress the warning about "using insecure memory". - -@item ---no-permission-warning -Suppress the warning about unsafe file and home directory (---homedir) -permissions. Note that the permission checks that GnuPG performs are -not intended to be authoritative, but rather they simply warn about -certain common permission problems. Do not assume that the lack of a -warning means that your system is secure. - -Note that the warning for unsafe ---homedir permissions cannot be -supressed in the gpg.conf file, as this would allow an attacker to -place an unsafe gpg.conf file in place, and use this file to supress -warnings about itself. The ---homedir permissions warning may only be -supressed on the command line. - -@item ---no-mdc-warning -Suppress the warning about missing MDC integrity protection. - -@item ---no-armor -Assume the input data is not in ASCII armored format. - -@item ---no-default-keyring -Do not add the default keyrings to the list of -keyrings. - -@item ---skip-verify -Skip the signature verification step. This may be -used to make the decryption faster if the signature -verification is not needed. - -@item ---with-colons -Print key listings delimited by colons. Note that the output will be -encoded in UTF-8 regardless of any ---charset setting. This format is -useful when GnuPG is called from scripts and other programs as it is -easily machine parsed. The details of this format are documented in -the file doc/DETAILS, which is included in the GnuPG source -distribution. - -@item ---with-key-data -Print key listings delimited by colons (like ---with-colons) and print the public key data. - -@item ---with-fingerprint -Same as the command ---fingerprint but changes only the format of the output -and may be used together with another command. - -@item ---fast-list-mode -Changes the output of the list commands to work faster; this is achieved -by leaving some parts empty. Some applications don't need the user ID and -the trust information given in the listings. By using this options they -can get a faster listing. The exact behaviour of this option may change -in future versions. - -@item ---fixed-list-mode -Do not merge primary user ID and primary key in ---with-colon listing -mode and print all timestamps as seconds since 1970-01-01. - -@item ---list-only -Changes the behaviour of some commands. This is like ---dry-run but -different in some cases. The semantic of this command may be extended in -the future. Currently it only skips the actual decryption pass and -therefore enables a fast listing of the encryption keys. - -@item ---no-literal -This is not for normal use. Use the source to see for what it might be useful. - -@item ---set-filesize -This is not for normal use. Use the source to see for what it might be useful. - -@item ---emulate-md-encode-bug -GnuPG versions prior to 1.0.2 had a bug in the way a signature was encoded. -This options enables a workaround by checking faulty signatures again with -the encoding used in old versions. This may only happen for ElGamal signatures -which are not widely used. - -@item ---show-session-key -Display the session key used for one message. See ---override-session-key -for the counterpart of this option. - -We think that Key-Escrow is a Bad Thing; however the user should -have the freedom to decide whether to go to prison or to reveal the content of -one specific message without compromising all messages ever encrypted for one -secret key. DON'T USE IT UNLESS YOU ARE REALLY FORCED TO DO SO. - -@item ---override-session-key @code{string} -Don't use the public key but the session key @code{string}. The format of this -string is the same as the one printed by ---show-session-key. This option -is normally not used but comes handy in case someone forces you to reveal the -content of an encrypted message; using this option you can do this without -handing out the secret key. - -@item ---ask-sig-expire -@itemx ---no-ask-sig-expire -When making a data signature, prompt for an expiration time. If this -option is not specified, the expiration time is "never". ----no-ask-sig-expire disables this option. - -@item ---ask-cert-expire -@itemx ---no-ask-cert-expire -When making a key signature, prompt for an expiration time. If this -option is not specified, the expiration time is "never". ----no-ask-cert-expire disables this option. - -@item ---expert -@itemx ---no-expert -Allow the user to do certain nonsensical or "silly" things like -signing an expired or revoked key, or certain potentially incompatible -things like generating deprecated key types. This also disables -certain warning messages about potentially incompatible actions. As -the name implies, this option is for experts only. If you don't fully -understand the implications of what it allows you to do, leave this -off. ---no-expert disables this option. - -@item ---merge-only -Don't insert new keys into the keyrings while doing an import. - -@item ---allow-secret-key-import -This is an obsolete option and is not used anywhere. - -@item ---try-all-secrets -Don't look at the key ID as stored in the message but try all secret keys in -turn to find the right decryption key. This option forces the behaviour as -used by anonymous recipients (created by using ---throw-keyid) and might come -handy in case where an encrypted message contains a bogus key ID. - -@item ---enable-special-filenames -This options enables a mode in which filenames of the form -@file{-&n}, where n is a non-negative decimal number, -refer to the file descriptor n and not to a file with that name. - -@item ---no-expensive-trust-checks -Experimental use only. - -@item ---group @code{name=value1 value2 value3 ...} -Sets up a named group, which is similar to aliases in email programs. -Any time the group name is a recipient (-r or ---recipient), it will -be expanded to the values specified. - -The values are @code{key IDs} or fingerprints, but any key description -is accepted. Note that a value with spaces in it will be treated as -two different values. Note also there is only one level of expansion -- you cannot make an group that points to another group. When used -from the command line, it may be necessary to quote the argument to -this option to prevent the shell from treating it as multiple -arguments. - -@item ---no-groups -Clear the ---group list. - -@item ---preserve-permissions -Don't change the permissions of a secret keyring back to user -read/write only. Use this option only if you really know what you are doing. - -@item ---personal-cipher-preferences @code{string} -Set the list of personal cipher preferences to @code{string}, this list -should be a string similar to the one printed by the command "pref" in -the edit menu. This allows the user to factor in their own preferred -algorithms when algorithms are chosen via recipient key preferences. -The most highly ranked cipher in this list is also used for the ----symmetric encryption command. - -@item ---personal-digest-preferences @code{string} -Set the list of personal digest preferences to @code{string}, this list -should be a string similar to the one printed by the command "pref" in -the edit menu. This allows the user to factor in their own preferred -algorithms when algorithms are chosen via recipient key preferences. -The most highly ranked digest algorithm in this list is algo used when -signing without encryption (e.g. ---clearsign or --sign). The default -value is SHA-1. - -@item ---personal-compress-preferences @code{string} -Set the list of personal compression preferences to @code{string}, this -list should be a string similar to the one printed by the command -"pref" in the edit menu. This allows the user to factor in their own -preferred algorithms when algorithms are chosen via recipient key -preferences. The most highly ranked algorithm in this list is also -used when there are no recipient keys to consider (e.g. ---symmetric). - -@item ---default-preference-list @code{string} -Set the list of default preferences to @code{string}, this list should -be a string similar to the one printed by the command "pref" in the -edit menu. This affects both key generation and "updpref" in the edit -menu. - -@end table - -@majorheading How to specify a user ID -There are different ways to specify a user ID to GnuPG; here are some -examples: - -@table @asis -@item -@item 234567C4 -@itemx 0F34E556E -@itemx 01347A56A -@itemx 0xAB123456 -Here the key ID is given in the usual short form. - -@item 234AABBCC34567C4 -@itemx 0F323456784E56EAB -@itemx 01AB3FED1347A5612 -@itemx 0x234AABBCC34567C4 -Here the key ID is given in the long form as used by OpenPGP -(you can get the long key ID using the option ---with-colons). - -@item 1234343434343434C434343434343434 -@itemx 123434343434343C3434343434343734349A3434 -@itemx 0E12343434343434343434EAB3484343434343434 -@itemx 0xE12343434343434343434EAB3484343434343434 -The best way to specify a key ID is by using the fingerprint of -the key. This avoids any ambiguities in case that there are duplicated -key IDs (which are really rare for the long key IDs). - -@item =Heinrich Heine -Using an exact to match string. The equal sign indicates this. - -@item -Using the email address part which must match exactly. The left angle bracket -indicates this email address mode. - -@item +Heinrich Heine duesseldorf -All words must match exactly (not case sensitive) but can appear in -any order in the user ID. Words are any sequences of letters, -digits, the underscore and all characters with bit 7 set. - -@item Heine -@itemx *Heine -By case insensitive substring matching. This is the default mode but -applications may want to explicitly indicate this by putting the asterisk -in front. - -@end table - -Note that you can append an exclamation mark to key IDs or -fingerprints. This flag tells GnuPG to use exactly the given primary -or secondary key and not to try to figure out which secondary or -primary key to use. - -@majorheading RETURN VALUE -The program returns 0 if everything was fine, 1 if at least -a signature was bad, and other error codes for fatal errors. - -@majorheading EXAMPLES -@table @asis -@item gpg -se -r @code{Bob} @code{file} -sign and encrypt for user Bob - -@item gpg ---clearsign @code{file} -make a clear text signature - -@item gpg -sb @code{file} -make a detached signature - -@item gpg ---list-keys @code{user_ID} -show keys - -@item gpg ---fingerprint @code{user_ID} -show fingerprint - -@item gpg ---verify @code{pgpfile} -@itemx gpg ---verify @code{sigfile} @code{files} -Verify the signature of the file but do not output the data. The second form -is used for detached signatures, where @code{sigfile} is the detached -signature (either ASCII armored of binary) and @code{files} are the signed -data; if this is not given the name of the file holding the signed data is -constructed by cutting off the extension (".asc" or ".sig") of -@code{sigfile} or by asking the user for the filename. - -@end table - -@majorheading ENVIRONMENT -@table @asis -@item HOME -Used to locate the default home directory. - -@item GNUPGHOME -If set directory used instead of "~/.gnupg". - -@item GPG_AGENT_INFO -Used to locate the gpg-agent; only honored when ----use-agent is set. The value consists of 3 colon delimited fields: -The first is the path to the Unix Domain Socket, the second the PID of -the gpg-agent and the protocol version which should be set to 1. When -starting the gpg-agent as described in its documentation, this -variable is set to the correct value. The option ---gpg-agent-info can -be used to override it. - -@item http_proxy -Only honored when the keyserver-option -honor-http-proxy is set. - -@end table - -@majorheading FILES -@table @asis -@item ~/.gnupg/secring.gpg -The secret keyring - -@item ~/.gnupg/secring.gpg.lock -and the lock file - -@item ~/.gnupg/pubring.gpg -The public keyring - -@item ~/.gnupg/pubring.gpg.lock -and the lock file - -@item ~/.gnupg/trustdb.gpg -The trust database - -@item ~/.gnupg/trustdb.gpg.lock -and the lock file - -@item ~/.gnupg/random_seed -used to preserve the internal random pool - -@item ~/.gnupg/gpg.conf -Default configuration file - -@item ~/.gnupg/options -Old style configuration file; only used when gpg.conf -is not found - -@item /usr[/local]/share/gnupg/options.skel -Skeleton options file - -@item /usr[/local]/lib/gnupg/ -Default location for extensions - -@end table - -@majorheading WARNINGS -Use a *good* password for your user account and a *good* passphrase -to protect your secret key. This passphrase is the weakest part of the -whole system. Programs to do dictionary attacks on your secret keyring -are very easy to write and so you should protect your "~/.gnupg/" -directory very well. - -Keep in mind that, if this program is used over a network (telnet), it -is *very* easy to spy out your passphrase! - -If you are going to verify detached signatures, make sure that the -program knows about it; either be giving both filenames on the -command line or using @samp{-} to specify stdin. - -@majorheading INTEROPERABILITY WITH OTHER OPENPGP PROGRAMS -GnuPG tries to be a very flexible implementation of the OpenPGP -standard. In particular, GnuPG implements many of the "optional" -parts of the standard, such as the RIPEMD/160 hash, and the ZLIB -compression algorithms. It is important to be aware that not all -OpenPGP programs implement these optional algorithms and that by -forcing their use via the ---cipher-algo, --digest-algo, ----cert-digest-algo, or --compress-algo options in GnuPG, it is -possible to create a perfectly valid OpenPGP message, but one that -cannot be read by the intended recipient. - -For example, as of this writing, no version of official PGP supports -the BLOWFISH cipher algorithm. If you use it, no PGP user will be -able to decrypt your message. The same thing applies to the ZLIB -compression algorithm. By default, GnuPG uses the OpenPGP preferences -system that will always do the right thing and create messages that -are usable by all recipients, regardless of which OpenPGP program they -use. Only override this safe default if you know what you are doing. - -If you absolutely must override the safe default, or if the -preferences on a given key are invalid for some reason, you are far -better off using the ---pgp2, --pgp6, --pgp7, or --pgp8 options. These -options are safe as they do not force any particular algorithms in -violation of OpenPGP, but rather reduce the available algorithms to a -"PGP-safe" list. - -@majorheading BUGS -On many systems this program should be installed as setuid(root). This -is necessary to lock memory pages. Locking memory pages prevents the -operating system from writing memory pages to disk. If you get no -warning message about insecure memory your operating system supports -locking without being root. The program drops root privileges as soon -as locked memory is allocated. - -@bye diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi deleted file mode 100644 index 4bb688c44..000000000 --- a/doc/gpgsm.texi +++ /dev/null @@ -1,848 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking GPGSM -@chapter Invoking GPGSM -@cindex GPGSM command options -@cindex command options -@cindex options, GPGSM command - -@c man begin DESCRIPTION - -@sc{gpgsm} is a tool similar to @sc{gpg} to provide digital encryption -and signing servicesd on X.509 certificates and the CMS protocoll. It -is mainly used as a backend for S/MIME mail processing. @sc{gpgsm} -includes a full features certificate management and complies with all -rules defined for the German Sphinx project. - -@c man end - -@xref{Option Index}, for an index to GPGSM's commands and options. - -@menu -* GPGSM Commands:: List of all commands. -* GPGSM Options:: List of all options. -* GPGSM Examples:: Some usage examples. - -Developer information: -* Unattended Usage:: Using @sc{gpgsm} from other programs. -* GPGSM Protocol:: The protocol the server mode uses. -@end menu - -@c man begin COMMANDS - -@node GPGSM Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@menu -* General Commands:: Commands not specific to the functionality. -* Operational Commands:: Commands to select the type of operation. -* Certificate Management:: How to manage certificates. -@end menu - -@node General Commands -@subsection Commands not specific to the function - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. -@end table - - - -@node Operational Commands -@subsection Commands to select the type of operation - -@table @gnupgtabopt -@item --encrypt -@opindex encrypt -Perform an encryption. - -@item --decrypt -@opindex decrypt -Perform a decryption; the type of input is automatically detmerined. It -may either be in binary form or PEM encoded; automatic determination of -base-64 encoding is not done. - -@item --sign -@opindex sign -Create a digital signature. The key used is either the fist one found -in the keybox or thise set with the -u option - -@item --verify -@opindex verify -Check a signature file for validity. Depending on the arguments a -detached signatrue may also be checked. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. - -@item --call-dirmngr @var{command} [@var{args}] -@opindex call-dirmngr -Behave as a Dirmngr client issuing the request @var{command} with the -optional list of @var{args}. The output of the Dirmngr is printed -stdout. Please note that file names given as arguments should have an -absulte file name (i.e. commencing with @code{/} because they are -passed verbatim to the Dirmngr and the working directory of the -Dirmngr might not be the same as the one of this client. Currently it -is not possible to pass data via stdin to the Dirmngr. @var{command} -should not contain spaces. - -This is command is required for certain maintaining tasks of the dirmngr -where a dirmngr must be able to call back to gpgsm. See the Dirmngr -manual for details. - -@item --call-protect-tool @var{arguments} -@opindex call-protect-tool -Certain maintenance operations are done by an external program call -@command{gpg-protect-tool}; this is usually not installed in a directory -listed in the PATH variable. This command provides a simple wrapper to -access this tool. @var{arguments} are passed verbatim to this command; -use @samp{--help} to get a list of supported operations. - - -@end table - - -@node Certificate Management -@subsection How to manage the certificate and keys - -@table @gnupgtabopt -@item --gen-key -@opindex gen-key -Generate a new key and a certificate request. - -@item --list-keys -@itemx -k -@opindex list-keys -List all available certificates stored in the local key database. - -@item --list-secret-keys -@itemx -K -@opindex list-secret-keys -List all available certificates for which a corresponding a secret key -is available. - -@item --list-external-keys @var{pattern} -@opindex list-keys -List certificates matching @var{pattern} using an external server. This -utilizes the @code{dirmngr} service. - -@item --dump-keys -@opindex dump-keys -List all available certificates stored in the local key database using a -format useful mainly for debugging. - -@item --dump-secret-keys -@opindex dump-secret-keys -List all available certificates for which a corresponding a secret key -is available using a format useful mainly for debugging. - -@item --dump-external-keys @var{pattern} -@opindex dump-keys -List certificates matching @var{pattern} using an external server. -This utilizes the @code{dirmngr} service. It uses a format useful -mainly for debugging. - -@item --keydb-clear-some-cert-flags -@opindex keydb-clear-some-cert-flags -This is a debugging aid to reset certain flags in the key database -which are used to cache certain certificate stati. It is especially -useful if a bad CRL or a weird running OCSP reponder did accidently -revoke certificate. There is no security issue with this command -because gpgsm always make sure that the validity of a certificate is -checked right before it is used. - -@item --delete-keys @var{pattern} -@opindex delete-keys -Delete the keys matching @var{pattern}. - -@item --export [@var{pattern}] -@opindex export -Export all certificates stored in the Keybox or those specified by the -optional @var{pattern}. When using along with the @code{--armor} option -a few informational lines are prepended before each block. - -@item --export-secret-key-p12 @var{key-id} -@opindex export -Export the private key and the certificate identified by @var{key-id} -in a PKCS#12 format. When using along with the @code{--armor} option -a few informational lines are prepended to the output. Note, that the -PKCS#12 format is higly insecure and this command is only provided if -there is no other way to exchange the private key. - -@item --learn-card -@opindex learn-card -Read information about the private keys from the smartcard and import -the certificates from there. This command utilizes the @sc{gpg-agent} -and in turn the @sc{scdaemon}. - -@item --passwd @var{user_id} -@opindex passwd -Change the passphrase of the private key belonging to the certificate -specified as @var{user_id}. Note, that changing the passphrase/PIN of a -smartcard is not yet supported. - -@end table - - -@node GPGSM Options -@section Option Summary - -GPGSM comes features a bunch ofoptions to control the exact behaviour -and to change the default configuration. - -@menu -* Configuration Options:: How to change the configuration. -* Certificate Options:: Certificate related options. -* Input and Output:: Input and Output. -* CMS Options:: How to change how the CMS is created. -* Esoteric Options:: Doing things one usually don't want to do. -@end menu - -@c man begin OPTIONS - -@node Configuration Options -@subsection How to change the configuration - -These options are used to change the configuraton and are usually found -in the option file. - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{gpgsm.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item --policy-file @var{filename} -@opindex policy-file -Change the default name of the policy file to @var{filename}. - -@item --agent-program @var{file} -@opindex agent-program -Specify an agent program to be used for secret key operations. The -default value is the @file{/usr/local/bin/gpg-agent}. This is only used -as a fallback when the envrionment variable @code{GPG_AGENT_INFO} is not -set or a running agent can't be connected. - -@item --dirmngr-program @var{file} -@opindex dirmnr-program -Specify a dirmngr program to be used for @acronym{CRL} checks. The -default value is @file{/usr/sbin/dirmngr}. This is only used as a -fallback when the environment variable @code{DIRMNGR_INFO} is not set or -a running dirmngr can't be connected. - -@item --no-secmem-warning -@opindex no-secmem-warning -Don't print a warning when the so called "secure memory" can't be used. - - - -@end table - - -@node Certificate Options -@subsection Certificate related options - -@table @gnupgtabopt - -@item --enable-policy-checks -@itemx --disable-policy-checks -@opindex enable-policy-checks -@opindex disable-policy-checks -By default policy checks are enabled. These options may be used to -change it. - -@item --enable-crl-checks -@itemx --disable-crl-checks -@opindex enable-crl-checks -@opindex disable-crl-checks -By default the @acronym{CRL} checks are enabled and the DirMngr is used -to check for revoked certificates. The disable option is most useful -with an off-line network connection to suppress this check. - -@item --force-crl-refresh -@opindex force-crl-refresh -Tell the dirmngr to reload the CRL for each request. For better -performance, the dirmngr will actually optimize this by suppressing -the loading for short time intervalls (e.g. 30 minutes). This option -is useful to make sure that a fresh CRL is available for certificates -hold in the keybox. The suggested way of doing this is by using it -along with the option @code{--with-validation} for a ke listing -command. This option should not be used in a configuration file. - -@item --enable-ocsp -@itemx --disable-ocsp -@opindex enable-ocsp -@opindex disable-ocsp -Be default @acronym{OCSP} checks are disabled. The enable opton may -be used to enable OCSP checks via Dirmngr. If @acronym{CRL} checks -are also enabled, CRLs willbe used as a fallback if for some reason an -OCSP request won't succeed. - -@end table - -@node Input and Output -@subsection Input and Output - -@table @gnupgtabopt -@item --armor -@itemx -a -@opindex armor -@opindex -a -Create PEM encoded output. Default is binary output. - -@item --base64 -@opindex base64 -Create Base-64 encoded output; i.e. PEM without the header lines. - -@item --assume-armor -@opindex assume-armor -Assume the input data is PEM encoded. Default is to autodetect the -encoding but this is may fail. - -@item --assume-base64 -@opindex assume-base64 -Assume the input data is plain base-64 encoded. - -@item --assume-binary -@opindex assume-binary -Assume the input data is binary encoded. - -@item --local-user @var{user_id} -@item -u @var{user_id} -@opindex local-user -@opindex -u -Set the user(s) to be used for signing. The default is the first -secret key found in the database. - -@item --with-key-data -@opindex with-key-data -Displays extra information with the @code{--list-keys} commands. Especially -a line tagged @code{grp} is printed which tells you the keygrip of a -key. This string is for example used as the file name of the -secret key. - -@item --with-validation -@opindex with-validation -When doing a key listing, do a full validation check for each key and -print the result. This is usually a slow operation because it -requires a CRL lookup and other operations. - -@item --with-md5-fingerprint -For standard key listings, also print the MD5 fingerprint of the -certificate. - -@end table - -@node CMS Options -@subsection How to change how the CMS is created. - -@table @gnupgtabopt -@item --include-certs @var{n} -Using @var{n} of -2 includes all certificate except for the root cert, --1 includes all certs, 0 does not include any certs, 1 includes only -the signers cert (this is the default) and all other positive -values include up to @var{n} certificates starting with the signer cert. - -@end table - - - -@node Esoteric Options -@subsection Doing things one usually don't want todo. - - -@table @gnupgtabopt - -@item --faked-system-time @var{epoch} -@opindex faked-system-time -This option is only useful for testing; it sets the system time back or -forth to @var{epoch} which is the number of seconds elapsed since the year -1970. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change -at any time without notice; using @code{--debug-levels} is the -preferred method to select the debug verbosity. FLAGS are bit encoded -and may be given in usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @end table - -Note, that all flags set using this option may get overriden by -@code{--debug-level}. - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-allow-core-dump -@opindex debug-allow-core-dump -Usually gpgsm tries to avoid dumping core by well written code and by -disabling core dumps for security reasons. However, bugs are pretty -durable beasts and to squash them it is sometimes useful to have a core -dump. This option enables core dumps unless the Bad Thing happened -before the option parsing. - -@item --debug-no-chain-validation -@opindex debug-no-chain-validation -This is actually not a debugging option but only useful as such. It -lets gpgsm bypass all certificate chain validation checks. - -@item --debug-ignore-expiration -@opindex debug-ignore-expiration -This is actually not a debugging option but only useful as such. It -lets gpgsm ignore all notAfter dates, this is used by the regresssion -tests. - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - - - -@c -@c Examples -@c -@node GPGSM Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ gpgsm -er goo@@bar.net ciphertext -@end example - -@c man end - - - -@c --------------------------------- -@c The machine interface -@c -------------------------------- -@node Unattended Usage -@section Unattended Usage - -@sc{gpgsm} is often used as a backend engine by other software. To help -with this a machine interface has been defined to have an unambiguous -way to do this. This is most likely used with the @code{--server} command -but may also be used in the standard operation mode by using the -@code{--status-fd} option. - -@menu -* Automated signature checking:: Automated signature checking. -@end menu - -@node Automated signature checking,,,Unattended Usage -@section Automated signature checking - -It is very important to understand the semantics used with signature -verification. Checking a signature is not as simple as it may sound and -so the ooperation si a bit complicated. In mosted cases it is required -to look at several status lines. Here is a table of all cases a signed -message may have: - -@table @asis -@item The signature is valid -This does mean that the signature has been successfully verified, the -certificates are all sane. However there are two subcases with -important information: One of the certificates may have expired or a -signature of a message itself as expired. It is a sound practise to -consider such a signature still as valid but additional information -should be displayed. Depending on the subcase @sc{gpgsm} will issue -these status codes: - @table @asis - @item signature valid and nothing did expire - @code{GOODSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - @item signature valid but at least one certificate has expired - @code{EXPKEYSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - @item signature valid but expired - @code{EXPSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} - Note, that this case is currently not implemented. - @end table - -@item The signature is invalid -This means that the signature verification failed (this is an indication -of af a transfer error, a programm error or tampering with the message). -@sc{gpgsm} issues one of these status codes sequences: - @table @code - @item @code{BADSIG} - @item @code{GOODSIG}, @code{VALIDSIG} @code{TRUST_NEVER} - @end table - -@item Error verifying a signature -For some reason the signature could not be verified, i.e. it can't be -decided whether the signature is valid or invalid. A common reason for -this is a missing certificate. - -@end table - - -@c -@c Assuan Protocol -@c -@node GPGSM Protocol -@section The Protocol the Server Mode Uses. - -Description of the protocol used to access GPGSM. GPGSM does implement -the Assuan protocol and in addition provides a regular command line -interface which exhibits a full client to this protocol (but uses -internal linking). To start gpgsm as a server the commandline "gpgsm ---server" must be used. Additional options are provided to select the -communication method (i.e. the name of the socket). - -We assume that the connection has already been established; see the -Assuan manual for details. - -@menu -* GPGSM ENCRYPT:: Encrypting a message. -* GPGSM DECRYPT:: Decrypting a message. -* GPGSM SIGN:: Signing a message. -* GPGSM VERIFY:: Verifying a message. -* GPGSM GENKEY:: Generating a key. -* GPGSM LISTKEYS:: List available keys. -* GPGSM EXPORT:: Export certificates. -* GPGSM IMPORT:: Import certificates. -* GPGSM DELETE:: Delete certificates. -@end menu - - -@node GPGSM ENCRYPT -@subsection Encrypting a Message - -Before encrytion can be done the recipient must be set using the -command: - -@example - RECIPIENT @var{userID} -@end example - -Set the recipient for the encryption. @var{userID} should be the -internal representation of the key; the server may accept any other way -of specification. If this is a valid and trusted recipient the server -does respond with OK, otherwise the return is an ERR with the reason why -the recipient can't be used, the encryption will then not be done for -this recipient. If the policy is not to encrypt at all if not all -recipients are valid, the client has to take care of this. All -@code{RECIPIENT} commands are cumulative until a @code{RESET} or an -successful @code{ENCRYPT} command. - -@example - INPUT FD=@var{n} [--armor|--base64|--binary] -@end example - -Set the file descriptor for the message to be encrypted to @var{n}. -Obviously the pipe must be open at that point, the server establishes -its own end. If the server returns an error the client should consider -this session failed. - -The @code{--armor} option may be used to advice the server that the -input data is in @acronym{PEM} format, @code{--base64} advices that a -raw base-64 encoding is used, @code{--binary} advices of raw binary -input (@acronym{BER}). If none of these options is used, the server -tries to figure out the used encoding, but this may not always be -correct. - -@example - OUTPUT FD=@var{n} [--armor|--base64] -@end example - -Set the file descriptor to be used for the output (i.e. the encrypted -message). Obviously the pipe must be open at that point, the server -establishes its own end. If the server returns an error he client -should consider this session failed. - -The option armor encodes the output in @acronym{PEM} format, the -@code{--base64} option applies just a base 64 encoding. No option -creates binary output (@acronym{BER}). - -The actual encryption is done using the command - -@example - ENCRYPT -@end example - -It takes the plaintext from the @code{INPUT} command, writes to the -ciphertext to the file descriptor set with the @code{OUTPUT} command, -take the recipients from all the recipients set so far. If this command -fails the clients should try to delete all output currently done or -otherwise mark it as invalid. GPGSM does ensure that there won't be any -security problem with leftover data on the output in this case. - -This command should in general not fail, as all necessary checks have -been done while setting the recipients. The input and output pipes are -closed. - - -@node GPGSM DECRYPT -@subsection Decrypting a message - -Input and output FDs are set the same way as in encryption, but -@code{INPUT} refers to the ciphertext and output to the plaintext. There -is no need to set recipients. GPGSM automatically strips any -@acronym{S/MIME} headers from the input, so it is valid to pass an -entire MIME part to the INPUT pipe. - -The encryption is done by using the command - -@example - DECRYPT -@end example - -It performs the decrypt operation after doing some check on the internal -state. (e.g. that all needed data has been set). Because it utilizes -the GPG-Agent for the session key decryption, there is no need to ask -the client for a protecting passphrase - GpgAgent takes care of this by -requesting this from the user. - - -@node GPGSM SIGN -@subsection Signing a Message - -Signing is usually done with these commands: - -@example - INPUT FD=@var{n} [--armor|--base64|--binary] -@end example - -This tells GPGSM to read the data to sign from file descriptor @var{n}. - -@example - OUTPUT FD=@var{m} [--armor|--base64] -@end example - -Write the output to file descriptor @var{m}. If a detached signature is -requested, only the signature is written. - -@example - SIGN [--detached] -@end example - -Sign the data set with the INPUT command and write it to the sink set by -OUTPUT. With @code{--detached}, a detached signature is created -(surprise). - -The key used for signining is the default one or the one specified in -the configuration file. To get finer control over the keys, it is -possible to use the command - -@example - SIGNER @var{userID} -@end example - -to the signer's key. @var{userID} should be the -internal representation of the key; the server may accept any other way -of specification. If this is a valid and trusted recipient the server -does respond with OK, otherwise the return is an ERR with the reason why -the key can't be used, the signature will then not be created using -this key. If the policy is not to sign at all if not all -keys are valid, the client has to take care of this. All -@code{SIGNER} commands are cumulative until a @code{RESET} is done. -Note that a @code{SIGN} does not reset this list of signers which is in -contrats to the @code{RECIPIENT} command. - - -@node GPGSM VERIFY -@subsection Verifying a Message - -To verify a mesage the command: - -@example - VERIFY -@end example - -is used. It does a verify operation on the message send to the input FD. -The result is written out using status lines. If an output FD was -given, the signed text will be written to that. If the signature is a -detached one, the server will inquire about the signed material and the -client must provide it. - -@node GPGSM GENKEY -@subsection Generating a Key - -This is used to generate a new keypair, store the secret part in the -@acronym{PSE} and the public key in the key database. We will probably -add optional commands to allow the client to select whether a hardware -token is used to store the key. Configuration options to GPGSM can be -used to restrict the use of this command. - -@example - GENKEY -@end example - -GPGSM checks whether this command is allowed and then does an -INQUIRY to get the key parameters, the client should then send the -key parameters in the native format: - -@example - S: INQUIRE KEY_PARAM native - C: D foo:fgfgfg - C: D bar - C: END -@end example - -Please note that the server may send Status info lines while reading the -data lines from the client. After this the key generation takes place -and the server eventually does send an ERR or OK response. Status lines -may be issued as a progress indicator. - - -@node GPGSM LISTKEYS -@subsection List available keys - -To list the keys in the internal database or using an external key -provider, the command: - -@example - LISTKEYS @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed during the search) -quoting is required: Spaces are to be translated into "+" or into "%20"; -in turn this requires that the usual escape quoting rules are done. - -@example - LISTSECRETKEYS @var{pattern} -@end example - -Lists only the keys where a secret key is available. - -The list commands commands are affected by the option - -@example - OPTION list-mode=@var{mode} -@end example - -where mode may be: -@table @code -@item 0 -Use default (which is usually the same as 1). -@item 1 -List only the internal keys. -@item 2 -List only the external keys. -@item 3 -List internal and external keys. -@end table - -Note that options are valid for the entire session. - - -@node GPGSM EXPORT -@subsection Export certificates - -To export certificate from the internal key database the command: - -@example - EXPORT @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed) quoting is -required: Spaces are to be translated into "+" or into "%20"; in turn -this requires that the usual escape quoting rules are done. - -The format of the output depends on what was set with the OUTPUT -command. When using @acronym{PEM} encoding a few informational lines -are prepended. - - -@node GPGSM IMPORT -@subsection Import certificates - -To import certificates into the internal key database, the command - -@example - IMPORT -@end example - -is used. The data is expected on the file descriptor set with the -@code{INPUT} command. Certain checks are performend on the -certificate. Note that the code will also handle PKCS\#12 files and -import private keys; a helper program is used for that. - - -@node GPGSM DELETE -@subsection Delete certificates - -To delete certificate the command - -@example - DELKEYS @var{pattern} -@end example - -is used. To allow multiple patterns (which are ORed) quoting is -required: Spaces are to be translated into "+" or into "%20"; in turn -this requires that the usual escape quoting rules are done. - -The certificates must be specified unambiguously otherwise an error is -returned. - diff --git a/doc/gpl.texi b/doc/gpl.texi deleted file mode 100644 index ca0508fad..000000000 --- a/doc/gpl.texi +++ /dev/null @@ -1,397 +0,0 @@ -@node Copying -@appendix GNU GENERAL PUBLIC LICENSE - -@cindex GPL, GNU General Public License -@center Version 2, June 1991 - -@display -Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. -59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@appendixsubsec Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software---to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - -@iftex -@appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end iftex -@ifinfo -@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end ifinfo - -@enumerate -@item -This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The ``Program'', below, -refers to any such program or work, and a ``work based on the Program'' -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term ``modification''.) Each licensee is addressed as ``you''. - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - -@item -You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -@item -You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - -@enumerate a -@item -You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change. - -@item -You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any -part thereof, to be licensed as a whole at no charge to all third -parties under the terms of this License. - -@item -If the modified program normally reads commands interactively -when run, you must cause it, when started running for such -interactive use in the most ordinary way, to print or display an -announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide -a warranty) and that users may redistribute the program under -these conditions, and telling the user how to view a copy of this -License. (Exception: if the Program itself is interactive but -does not normally print such an announcement, your work based on -the Program is not required to print an announcement.) -@end enumerate - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - -@item -You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - -@enumerate a -@item -Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections -1 and 2 above on a medium customarily used for software interchange; or, - -@item -Accompany it with a written offer, valid for at least three -years, to give any third party, for a charge no more than your -cost of physically performing source distribution, a complete -machine-readable copy of the corresponding source code, to be -distributed under the terms of Sections 1 and 2 above on a medium -customarily used for software interchange; or, - -@item -Accompany it with the information you received as to the offer -to distribute corresponding source code. (This alternative is -allowed only for noncommercial distribution and only if you -received the program in object code or executable form with such -an offer, in accord with Subsection b above.) -@end enumerate - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -@item -You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -@item -Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - -@item -If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -@item -If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - -@item -The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and ``any -later version'', you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - -@item -If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -@iftex -@heading NO WARRANTY -@end iftex -@ifinfo -@center NO WARRANTY -@end ifinfo - -@item -BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - -@item -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. -@end enumerate - -@iftex -@heading END OF TERMS AND CONDITIONS -@end iftex -@ifinfo -@center END OF TERMS AND CONDITIONS -@end ifinfo - -@page -@unnumberedsec How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and an idea of what it does.} -Copyright (C) 19@var{yy} @var{name of author} - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -@end smallexample - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - -@smallexample -Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} -Gnomovision comes with ABSOLUTELY NO WARRANTY; for details -type `show w'. This is free software, and you are welcome -to redistribute it under certain conditions; type `show c' -for details. -@end smallexample - -The hypothetical commands @samp{show w} and @samp{show c} should show -the appropriate parts of the General Public License. Of course, the -commands you use may be called something other than @samp{show w} and -@samp{show c}; they could even be mouse-clicks or menu items---whatever -suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a ``copyright disclaimer'' for the program, if -necessary. Here is a sample; alter the names: - -@smallexample -@group -Yoyodyne, Inc., hereby disclaims all copyright -interest in the program `Gnomovision' -(which makes passes at compilers) written -by James Hacker. - -@var{signature of Ty Coon}, 1 April 1989 -Ty Coon, President of Vice -@end group -@end smallexample - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi deleted file mode 100644 index 51ec4b34c..000000000 --- a/doc/scdaemon.texi +++ /dev/null @@ -1,387 +0,0 @@ -@c Copyright (C) 2002 Free Software Foundation, Inc. -@c This is part of the GnuPG manual. -@c For copying conditions, see the file gnupg.texi. - -@node Invoking SCDAEMON -@chapter Invoking the SCDAEMON -@cindex SCDAEMON command options -@cindex command options -@cindex options, SCDAEMON command - -@c man begin DESCRIPTION - -The @sc{scdaeon} is a daemon to manage smartcards. It is usually -invoked by gpg-agent and in general not used directly. - -@c man end - -@xref{Option Index}, for an index to GPG-AGENTS's commands and options. - -@menu -* Scdaemon Commands:: List of all commands. -* Scdaemon Options:: List of all options. -* Scdaemon Examples:: Some usage examples. -* Scdaemon Protocol:: The protocol the daemon uses. -@end menu - -@c man begin COMMANDS - -@node Scdaemon Commands -@section Commands - -Commands are not distinguished from options execpt for the fact that -only one one command is allowed. - -@table @gnupgtabopt -@item --version -@opindex version -Print the program version and licensing information. Not that you can -abbreviate this command. - -@item --help, -h -@opindex help -Print a usage message summarizing the most usefule command-line options. -Not that you can abbreviate this command. - -@item --dump-options -@opindex dump-options -Print a list of all available options and commands. Not that you can -abbreviate this command. - -@item --server -@opindex server -Run in server mode and wait for commands on the @code{stdin}. This is -default mode is to create a socket and listen for commands there. - -@item --daemon -@opindex daemon -Run the program in the background. This option is required to prevent -it from being accidently running in the background. - -@item --print-atr -@opindex print-atr -This is mainly a debugging command, used to print the ATR -(Answer-To-Reset) of a card and exit immediately. - -@end table - - -@c man begin OPTIONS - -@node Scdaemon Options -@section Option Summary - -@table @gnupgtabopt - -@item --options @var{file} -@opindex options -Reads configuration from @var{file} instead of from the default -per-user configuration file. The default configuration file is named -@file{scdaemon.conf} and expected in the @file{.gnupg} directory directly -below the home directory of the user. - -@item -v -@item --verbose -@opindex v -@opindex verbose -Outputs additional information while running. -You can increase the verbosity by giving several -verbose commands to @sc{gpgsm}, such as @samp{-vv}. - -@item --debug-level @var{level} -@opindex debug-level -Select the debug level for investigating problems. @var{level} may be -one of: - - @table @code - @item none - no debugging at all. - @item basic - some basic debug messages - @item advanced - more verbose debug messages - @item expert - even more detailed messages - @item guru - all of the debug messages you can get - @end table - -How these messages are mapped to the actual debugging flags is not -specified and may change with newer releaes of this program. They are -however carefully selected to best aid in debugging. - -@item --debug @var{flags} -@opindex debug -This option is only useful for debugging and the behaviour may change at -any time without notice. FLAGS are bit encoded and may be given in -usual C-Syntax. The currently defined bits are: - - @table @code - @item 0 (1) - X.509 or OpenPGP protocol related data - @item 1 (2) - values of big number integers - @item 2 (4) - low level crypto operations - @item 5 (32) - memory allocation - @item 6 (64) - caching - @item 7 (128) - show memory statistics. - @item 9 (512) - write hashed data to files named @code{dbgmd-000*} - @item 10 (1024) - trace Assuan protocol - @item 12 (4096) - bypass all certificate validation - @end table - -@item --debug-all -@opindex debug-all -Same as @code{--debug=0xffffffff} - -@item --debug-wait @var{n} -@opindex debug-wait -When running in server mode, wait @var{n} seconds before entering the -actual processing loop and print the pid. This gives time to attach a -debugger. - -@item --debug-sc @var{n} -@opindex debug-sc -Set the debug level of the OpenSC library to @var{n}. - -@item --no-detach -@opindex no-detach -Don't detach the process from the console. This is manly usefule for -debugging. - -@item --log-file @var{file} -@opindex log-file -Append all logging output to @var{file}. This is very helpful in -seeing what the agent actually does. - -@item --reader-port @var{number} -When the program has been build without OpenSC support, this option must -be used to specify the port of the card terminal. A value of 0 refers -to the first serial device; add 32768 to access USB devices. The -default is 32768 (first USB device). - -@item --ctapi-driver @var{library} -Use @var{library} to access the smartcard reader. The current default -is @code{libtowitoko.so}. - - -@item --allow-admin -@itemx --deny-admin -@opindex allow-admin -@opindex deny-admin -This enables the use of Admin class commands for card application -where this is supported. Currently we support it for the OpenPGP -card. Deny is the default. This commands is useful to inhibit -accidental access to admin class command which could ultimately lock -the card through worng PIN numbers. - -@end table - -All the long options may also be given in the configuration file after -stripping off the two leading dashes. - - -@c -@c Examples -@c -@node Scdaemon Examples -@section Examples - -@c man begin EXAMPLES - -@example -$ scdaemon --server -v -@end example - -@c man end - -@c -@c Assuan Protocol -@c -@node Scdaemon Protocol -@section Scdaemon's Assuan Protocol - -The SC-Daemon should be started by the system to provide access to -external tokens. Using Smartcards on a multi-user system does not -make much sense expcet for system services, but in this case no -regular user accounts are hosted on the machine. - -A client connects to the SC-Daemon by connecting to the socket named -@file{/var/run/scdaemon/socket}, configuration information is read from -@var{/etc/scdaemon.conf} - -Each connection acts as one session, SC-Daemon takes care of -syncronizing access to a token between sessions. - -@menu -* Scdaemon SERIALNO:: Return the serial number. -* Scdaemon LEARN:: Read all useful information from the card. -* Scdaemon READCERT:: Return a certificate. -* Scdaemon READKEY:: Return a public key. -* Scdaemon PKSIGN:: Signing data with a Smartcard. -* Scdaemon PKDECRYPT:: Decrypting data with a Smartcard. -* Scdaemon GETATTR:: Read an attribute's value. -* Scdaemon SETATTR:: Update an attribute's value. -* Scdaemon GENKEY:: Generate a new key on-card. -* Scdaemon RANDOM:: Return random bytes generate on-card. -* Scdaemon PASSWD:: Change PINs. -* Scdaemon CHECKPIN:: Perform a VERIFY operation. -@end menu - -@node Scdaemon SERIALNO -@subsection Return the serial number - -This command should be used to check for the presence of a card. It is -special in that it can be used to reset the card. Most other commands -will return an error when a card change has been detected and the use of -this function is therefore required. - -Background: We want to keep the client clear of handling card changes -between operations; i.e. the client can assume that all operations are -done on the same card unless he call this function. - -@example - SERIALNO -@end example - -Return the serial number of the card using a status reponse like: - -@example - S SERIALNO D27600000000000000000000 0 -@end example - -The trailing 0 should be ignored for now, it is reserved for a future -extension. The serial number is the hex encoded value identified by -the @code{0x5A} tag in the GDO file (FIX=0x2F02). - - - -@node Scdaemon LEARN -@subsection Read all useful information from the card - -@example - LEARN [--force] -@end example - -Learn all useful information of the currently inserted card. When -used without the force options, the command might do an INQUIRE -like this: - -@example - INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp> -@end example - -The client should just send an @code{END} if the processing should go on -or a @code{CANCEL} to force the function to terminate with a cancel -error message. The response of this command is a list of status lines -formatted as this: - -@example - S KEYPAIRINFO @var{hexstring_with_keygrip} @var{hexstring_with_id} -@end example - -If there is no certificate yet stored on the card a single "X" is -returned in @var{hexstring_with_keygrip}. - -@node Scdaemon READCERT -@subsection Return a certificate - -@example - READCERT @var{hexified_certid} -@end example - -This function is used to read a certificate identified by -@var{hexified_certid} from the card. - - -@node Scdaemon READKEY -@subsection Return a public key - -@example -READKEY @var{hexified_certid} -@end example - -Return the public key for the given cert or key ID as an standard -S-Expression. - - - -@node Scdaemon PKSIGN -@subsection Signing data with a Smartcard - -To sign some data the caller should use the command - -@example - SETDATA @var{hexstring} -@end example - -to tell scdaemon about the data to be signed. The data must be given in -hex notation. The actual signing is done using the command - -@example - PKSIGN @var{keyid} -@end example - -where @var{keyid} is the hexified ID of the key to be used. The key id -may have been retrieved using the command @code{LEARN}. - - -@node Scdaemon PKDECRYPT -@subsection Decrypting data with a Smartcard - -To decrypt some data the caller should use the command - -@example - SETDATA @var{hexstring} -@end example - -to tell scdaemon about the data to be decrypted. The data must be given in -hex notation. The actual decryption is then done using the command - -@example - PKDECRYPT @var{keyid} -@end example - -where @var{keyid} is the hexified ID of the key to be used. - - -@node Scdaemon GETATTR -@subsection Read an attribute's value. - -TO BE WRITTEN. - -@node Scdaemon SETATTR -@subsection Update an attribute's value. - -TO BE WRITTEN. - -@node Scdaemon GENKEY -@subsection Generate a new key on-card. - -TO BE WRITTEN. - -@node Scdaemon RANDOM -@subsection Return random bytes generate on-card. - -TO BE WRITTEN. - - -@node Scdaemon PASSWD -@subsection Change PINs. - -TO BE WRITTEN. - - -@node Scdaemon CHECKPIN -@subsection Perform a VERIFY operation. - -TO BE WRITTEN. - - diff --git a/g10/ChangeLog b/g10/ChangeLog deleted file mode 100644 index 0e87c2f46..000000000 --- a/g10/ChangeLog +++ /dev/null @@ -1,8948 +0,0 @@ -2004-04-30 Werner Koch <wk@gnupg.org> - - * g10.c (main) <gpgconf>: Use gpg.conf and not /dev/null as - default filename. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * card-util.c (card_edit): Remove PIN verification. - (generate_card_keys): New arg SERIALNO. Do PIN verification here - after resetting forced_chv1. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * card-util.c (change_name): Check that the NAME is not too long. - (change_url): Likewise. - (change_login): Likewise. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * g10.c: New options --gpgconf-list, --debug-level and --log-file - (set_debug): Add arg DEBUG_LEVEL. - (main): Look at less and less version specific config files. From - gnupg 1.3. - -2004-02-17 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO. - * passphrase.c (agent_open): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * gpgv.c: Removed g10defs.h. - - * Makefile.am: Include cmacros.am for common flags. - -2004-02-11 Werner Koch <wk@gnupg.org> - - * openfile.c (try_make_homedir): Use GNUPG_DEFAULT_HOMEDIR. - * gpgv.c (main): Ditto. - * g10.c (main): Ditto. - -2004-01-19 Moritz Schulte <mo@g10code.com> - - * keygen.c (do_generate_keypair): Print member fname, instead of - newfname, again. - (do_generate_keypair): Don't try to execute certain pieces of code - in case an error occured. - (gen_card_key): Don't print out a message, which is already - printed by do_generate_keypair(). - -2004-01-18 Moritz Schulte <mo@g10code.com> - - * keygen.c (do_generate_keypair): Print member fname, instead of - newfname. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * card-util.c (print_name): Fixed bad format string usage. - (print_isoname): Ditto. - - * trustdb.c (check_regexp): s/exp/expr/. - - * keyedit.c (trustsig_prompt): Removed a "> 255" term; it is - always false due to the data type. - - * passphrase.c (agent_get_passphrase): Use xasprintf and avoid - non-literal format strings. - - * tdbio.c (upd_hashtable, drop_from_hashtable, lookup_hashtable): - Fixed log_error format string bugs. Kudos to the now working - gcc-3.3 -Wformat-nonliteral and Florian Weimer's investigations in - gnupg 1.2.3. - -2003-12-15 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (protect_secret_key): Use gry_create_nonce for the - IV; there is not need for real strong random here and it even - better protect the random bits used for the key. - -2003-11-16 Moritz Schulte <mo@g10code.com> - - * signal.c: Removed unused file. - -2003-11-10 Moritz Schulte <mo@g10code.com> - - * Makefile.am (INCLUDES): Added: @LIBGCRYPT_CFLAGS@. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * call-agent.c (learn_status_cb, scd_genkey_cb): Fixed faulty use - of !spacep(). - -2003-10-20 Werner Koch <wk@gnupg.org> - - * card-util.c (card_edit): New command "passwd". Add logic to - check the PIN in advance. - (card_status): Add new args to return the serial number. Changed - all callers. - * call-agent.c (agent_scd_checkpin): New. - -2003-10-08 Werner Koch <wk@gnupg.org> - - * call-agent.c (agent_scd_getattr): Don't clear the passed info - structure, so that it can indeed be updated. - - * card-util.c (fpr_is_zero): New. - (generate_card_keys): New. - (card_edit): New command "generate". - * keygen.c (generate_keypair): New arg CARD_SERIALNO, removed call - to check_smartcard. - (check_smartcard,show_smartcard): Removed. - (show_sha1_fpr,fpr_is_zero): Removed. - -2003-10-01 Werner Koch <wk@gnupg.org> - - * card-util.c: Tweaked to use this source also under 1.3. - -2003-09-30 Werner Koch <wk@gnupg.org> - - * keylist.c (print_card_serialno): New. - (list_keyblock_print): Use it here. - - * card-util.c (toggle_forcesig): New. - (card_edit): New command "forcesig". - - * card-util.c (print_name, print_isoname): Use 0 and not LF fro - the max_n arg of tty_print_utf8_string2. - - * call-agent.c (agent_scd_getattr): New. - (learn_status_cb): Release values before assignment so that it can - be used by getattr to update the structure. - - * card-util.c (change_pin): Simplified. We now have only a PIN - and an Admin PIN. - -2003-09-27 Werner Koch <wk@gnupg.org> - - * sign.c (do_sign): Removed disabled testcode. - -2003-09-26 Timo Schulz <twoaday@freakmail.de> - - * card_status (card_status): Do not use fputs since the fp - parameter can be NULL. This fixes a segv. - -2003-09-24 Werner Koch <wk@gnupg.org> - - * card-util.c (print_isoname,card_status): Handle opt.with_colons. - (print_sha1_fpr_colon): New. - -2003-09-23 Werner Koch <wk@gnupg.org> - - Merged most of David Shaw's changes in 1.3 since 2003-06-03. - - * Makefile.am: Include W32LIBS where appropriate. - - * armor.c (parse_hash_header,armor_filter): Drop TIGER/192 support. - * g10.c (print_hex,print_mds): Ditto. - * pkclist.c (algo_available): Ditto. - - * armor.c (armor_filter): Allow using --comment multiple times to - get multiple Comment header lines. --no-comments resets list. - * options.h, g10.c (main): Ditto. Deprecate --default-comment in - favor of --no-comments. - - * g10.c (main): Trim --help to commonly used options. Remove -f. - - * g10.c (main): Add --multifile as an alias to turn --encrypt into - --encrypt-files (plus --verify-files, --decrypt-files). Error out - if --multifile is used with the commands that don't support it yet. - - * encode.c (use_mdc), g10.c (main): Use RFC1991 and RFC2440 - directly to check for MDC usability. Do not set the force_mdc or - disable_mdc flags since there is no point any longer. - - * g10.c (main): Use "keyserver-url" instead of - "preferred-keyserver" for the sake of short and simple commands. - (add_keyserver_url): Clarify a few strings. It's a - "preferred keyserver URL". - * keyedit.c (keyedit_menu): Ditto. - * sign.c (mk_notation_policy_etc): Ditto. - - * main.h, keygen.c (keygen_add_keyserver_url): Signature callback - for adding a keyserver URL. - * keyedit.c (keyedit_menu, menu_set_keyserver_url): New command to - set preferred keyserver to specified (or all) user IDs. - * build-packet.c (build_sig_subpkt): Set preferred keyserver flag - while building a preferred keyserver subpacket. - - * keylist.c (show_policy_url, show_keyserver_url): URLs might be - UTF8. - - * keyedit.c (menu_addrevoker): Fix leaking a few bytes. - - * keyedit.c (show_key_with_all_names): Use list-option - show-long-keyid in main --edit-key display. - - * keyedit.c (print_and_check_one_sig): Use list-option - show-long-keyid in --edit-key "check" function. - - * passphrase.c (agent_send_all_options): Make use of $GPG_TTY. - - * g10.c (main): Disable use-agent if passphrase-fd is given - later. Suggested by Kurt Garloff. - - * exec.c, g10.c, gpgv.c, passphrase.c, photoid.c: - s/__MINGW32__/_WIN32/ to help building on native Windows - compilers. Requested by Brian Gladman. From Werner on stable - branch. - - * options.h, g10.c (main): Add list-option - list-preferred-keyserver. - - * keyedit.c (change_passphrase): When responding 'no' to the blank - passphrase question, re-prompt for a new passphrase. This is bug - #202. - - * mainproc.c (check_sig_and_print): Use two different preferred - keyserver displays - one if the key is not present (to tell the - user where to get the key), the other if it is present (to tell - the user where the key can be refreshed). - - * packet.h, parse-packet.c (parse_signature): Set flag if a - preferred keyserver is present. - - * keylist.c (list_keyblock_print): Show keyserver url in listings - with list-option show-keyserver-url. - - * mainproc.c (check_sig_and_print): Get the uid validity before - printing any sig results to avoid munging the output with trustdb - warnings. - - * g10.c (main): Don't include --show-keyring in --help as it is - deprecated. - - * options.skel: Note that keyserver.pgp.com isn't synchronized, - and explain the roundrobin a bit better. - - * sig-check.c (check_key_signature2), import.c (import_one, - import_revoke_cert, chk_self_sigs, delete_inv_parts, - collapse_uids, merge_blocks): Make much quieter during import of - slightly munged, but recoverable, keys. Use log_error for - unrecoverable import failures. - - * keyring.c (keyring_rebuild_cache): Comment. - - * sign.c (mk_notation_and_policy): Making a v3 signature with - notations or policy urls is an error, not an info (i.e. increment - the errorcount). Don't print the notation or policy url to stdout - since it can be mixed into the output stream when piping and munge - the stream. - - * packet.h, sig-check.c (signature_check2, do_check, - do_check_messages): Provide a signing-key-is-revoked flag. Change - all callers. - - * status.h, status.c (get_status_string): New REVKEYSIG status tag - for a good signature from a revoked key. - - * mainproc.c (do_check_sig, check_sig_and_print): Use it here. - - * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare - actual signatures on import rather than using keyid or class - matching. This does not change actual behavior with a key, but - does mean that all sigs are imported whether they will be used or - not. - - * parse-packet.c (parse_signature): Don't give "signature packet - without xxxx" warnings for experimental pk algorithms. An - experimental algorithm may not have a notion of (for example) a - keyid (i.e. PGP's x.509 stuff). - - * options.h, g10.c (main), keylist.c (list_keyblock_print), - keyedit.c (print_and_check_one_sig): New "show-sig-expire" - list-option to show signature expiration dates (if any). - - * options.h, g10.c (main, add_keyserver_url): Add - --sig-preferred-keyserver to implant a "where to get my key" - subpacket into a signature. - - * sign.c (mk_notation_and_policy): Rename to - mk_notation_policy_etc and add preferred keyserver support for - signatures. - - * keygen.c (do_add_key_flags): Don't set the certify flag for - subkeys. - (ask_algo): Provide key flags for DSA, Elgamal_e, and Elgamal - subkeys. - (generate_keypair): Provide key flags for the default DSA/Elgamal - keys. - - * sig-check.c (signature_check, signature_check2, - check_key_signature, check_key_signature2): Allow passing NULLs - for unused parameters in the x2 form of each function to avoid the - need for dummy variables. getkey.c, mainproc.c: Change all - callers. - - * trustdb.h, trustdb.c (read_trust_options): New. Returns items - from the trustdb version record. - * keylist.c (public_key_list): Use it here for the new "tru" - record. - * gpgv.c (read_trust_options): Stub. - - * keyedit.c (show_key_with_all_names): Use list-option - show-validity in --edit-key interface as well. - - * options.h, g10.c (main), mainproc.c (check_sig_and_print): Add - verify-options "show-validity" and "show-long-keyid" to show - trustdb validity and long keyids during (file) signature - verification. - - * packet.h, main.h, sig-check.c (signature_check2) - (check_key_signature2, do_check): If ret_pk is set, fill in the pk - used to verify the signature. Change all callers in getkey.c, - mainproc.c, and sig-check.c. - - * keylist.c (list_keyblock_colon): Use the ret_pk from above to - put the fingerprint of the signing key in "sig" records during a - --with-colons --check-sigs. This requires --no-sig-cache as well - since we don't cache fingerprints. - - * parse-packet.c (parse_signature): No need to reserve 8 bytes for - the unhashed signature cache any longer. - - * misc.c (pct_expando): Add two new expandos - signer's - fingerprint (%g), and signer's primary fingerprint (%p). - - * g10.c (main): Add --rfc2440 alias for --openpgp since in a few - months, they won't be the same thing. - - * keyserver.c (parse_keyserver_uri): Accept "http" as an alias for - "hkp", since it is occasionally written that way. - (keyserver_spawn): Use ascii_isspace to avoid locale issues. - - * keygen.c (ask_user_id): Make --allow-freeform-uid apply to the - email field as well as the name field, and allow mixing fields - when it is set. - - * trustdb.c (validate_one_keyblock): Certifications on revoked or - expired uids do not count in the web of trust. - - * signal.c (init_one_signal, pause_on_sigusr, do_block): Only use - sigprocmask() if we have sigset_t, and only use sigaction() if we - have struct sigaction. This is for Forte c89 on Solaris which - seems to define only the function call half of the two pairs by - default. - (pause_on_sigusr): Typo. - (do_block): If we can't use sigprocmask() and sigset_t, try to get - the number of signals from NSIG as well as MAXSIG, and if we - can't, fail with an explanation. - - * signal.c, tdbio.c: Comment out the transaction code. It was not - used in this version, and was causing some build problems on - quasi-posix platforms (Solaris and Forte c89). - - * keylist.c (list_keyblock_colon): Don't include validity values - when listing secret keys since they can be incorrect and/or - misleading. This is a temporary kludge, and will be handled - properly in 1.9/2.0. - - * mainproc.c (check_sig_and_print): Only show the "key available - from" preferred keyserver line if the key is not currently - present. - - * keyedit.c (sign_uids): Do not sign expired uids without --expert - (same behavior as revoked uids). Do not allow signing a user ID - without a self-signature. --expert overrides. Add additional - prompt to the signature level question. - (menu_expire): When changing expiration dates, don't replace - selfsigs on revoked uids since this would effectively unrevoke - them. There is also no point in replacing expired selfsigs. This - is bug #181 - - * g10.c (add_notation_data): Make sure that only ascii is passed - to iscntrl. Noted by Christian Biere. - * getkey.c (classify_user_id2): Replaced isspace by spacep - * keygen.c (ask_user_id): Ditto. - (get_parameter_algo): Ditto. - * keyedit.c (keyedit_menu): Ditto. - * tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/. - * revoke.c (ask_revocation_reason): - * keyserver.c (keyserver_spawn): Dito. - - * parse-packet.c (parse): Disallow old style partial length for - all key material packets to avoid possible corruption of keyrings. - - * import.c (import_keys_internal): Invalidate the cache so that - the file descriptor gets closed. Fixes bug reported by Juan - F. Codagnone. - - * options.h, g10.c (main), main.h, keylist.c (show_keyserver_url), - mainproc.c (check_sig_and_print), parse-packet.c (dump_sig_subpkt, - parse_one_sig_subpkt, can_handle_critical): Add read-only support - for preferred keyserver subpackets. They're basically policy URLs - with a different name. Add a verify-option - "show-preferred-keyserver" to turn them on and off (on by default, - as per stable branch). - - * g10.c (main): Add "--set-notation" as alias to "--notation-data" - this is to make things consistent with --set-policy-url meaning - both sigs and certs. - - * options.h, g10.c (main), keylist.c (list_keyblock_print): Add - "show-validity" and "show-long-keyid" list-options. - - * gpgv.c (get_validity, trust_value_to_string): Stubs. - - * g10.c (main): Use SAFE_VERSION instead of VERSION in the - version-specific gpg.conf file so it can be overridden on RISCOS. - - * keyedit.c (show_key_with_all_names): Fix assertion failure when - using toggle to see a secret key. Reported by Maxim Britov. - - -2003-09-22 Timo Schulz <twoaday@freakmail.de> - - * card-util.c (card_status): Free pk in case of an error - and return if the card is no OpenPGP card. - -2003-09-18 Werner Koch <wk@gnupg.org> - - * g10.c: New command --card-edit. - * card-util.c (card_status): Use tty_fprintf for all output. - (print_sha1_fpr, print_isoname): Ditto. - (get_one_name,change_name, change_url, change_login,change_lang) - (change_sex): New; taken from keygen.c. - * keygen.c (smartcard_get_one_name, smartcard_change_name) - (smartcard_change_url, smartcard_change_login_data) - (smartcard_change_lang, smartcard_change_sex): Removed. - (check_smartcard): Removed most menu items. - -2003-09-06 Werner Koch <wk@gnupg.org> - - * misc.c (openpgp_pk_algo_usage): Allow AUTH where SIGN is allowed. - - * keygen.c (ask_passphrase): No need to allocated S2K in secure - memory. - -2003-09-04 Werner Koch <wk@gnupg.org> - - * keygen.c (do_add_key_flags, parse_parameter_usage) - (do_generate_keypair): Add support the proposed AUTH key flag. - * getkey.c (fixup_uidnode, merge_selfsigs_main) - (merge_selfsigs_subkey, premerge_public_with_secret): Ditto. - * keylist.c (print_capabilities): Ditto. - -2003-08-25 Timo Schulz <twoaday@freakmail.de> - - * pkglue.c (mpi_from_sexp): New. Used to factor out - some common code. - -2003-08-24 Werner Koch <wk@gnupg.org> - - * keygen.c (do_generate_keypair): Print a reminder to use --gen-revoke. - -2003-08-18 Timo Schulz <twoaday@freakmail.de> - - * encode.c (encode_sesskey): Checked the code and removed - the warning since all compatibility checks with PGP succeeded. - * mainproc.c (symkey_decrypt_sesskey): Better check for the - algorithm and check the return values of some functions. - * mdc.c (use_mdc): Simplified. - -2003-08-07 Werner Koch <wk@gnupg.org> - - * pkglue.c (pk_sign): Fix last change. - (pk_verify): Check for valid DATA array so that we don't segv in - Libgcrypt. - (pk_verify): Ditto. - -2003-08-06 Werner Koch <wk@gnupg.org> - - * pkglue.c (pk_sign): Allow signing using RSA. - -2003-08-05 Werner Koch <wk@gnupg.org> - - * Makefile.am (install-data-local): Dropped check for the ancient - gpgm tool. - (bin_PROGRAMS): Renamed gpg to gpg2 and gpgv to gpgv2. This is so - that it won't conflict with the current stable version of gpg. - - * pkglue.c (pk_check_secret_key): New. - * seckey-cert.c (do_check): Reenable this test here again. - - * g10.c (main): Add command -K as an alias for - --list-secret-keys. Command "-k" is now an alias to --list-keys. - Remove special treatment of -kv and -kvv. - (set_cmd): Ditto. - (main): Strip a "-cvs" suffix when testing for a version specific - config file. - - * status.h, status.c, g10.c [USE_SHM_COPROCESSING]: Removed. This - is not any longer available. - -2003-07-29 Werner Koch <wk@gnupg.org> - - * g10.c (main): Add secmem features and set the random seed file. - (g10_exit): Update the random seed file. - - * parse-packet.c (parse_signature,read_protected_v3_mpi) - (parse_key): Fixed use of mpi_set_opaque. - * keygen.c (gen_card_key): Ditto. - -2003-07-28 Werner Koch <wk@gnupg.org> - - * status.c (progress_cb): Adjusted for use with Libcgrypt. - (set_status_fd): Register that callback. - - * keygen.c (smartcard_change_login_data): New. - (smartcard_change_lang): New. - (smartcard_change_sex): New. - (check_smartcard): Add menu entries to edit the above. - (gen_elg,gen_dsa,gen_rsa): Reimplemented in terms of Libgcrypt. - (genhelp_protect, genhelp_factors, key_from_sexp): New. - * comment.c (make_comment_node_from_buffer): New. - (make_comment_node): Reimplemented in terms of above. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-07-24 Werner Koch <wk@gnupg.org> - - * g10.c: New command --card-status. - * card-util.c (card_status): New. - * call-agent.c (learn_status_cb): Parse more information. - - * keylist.c (print_pubkey_info): Add FP arg for optional printing - to a stream. Changed all callers. - -2003-07-23 Werner Koch <wk@gnupg.org> - - * keygen.c (generate_keypair): Create an AUTHKEYTYPE entry for cards. - (do_generate_keypair): Abd generate the authkey. - (check_smartcard): Changed menu accordingly. - -2003-07-22 Werner Koch <wk@gnupg.org> - - * g10.c: New command --change-pin. - * card-util.c: New. - * call-agent.c (agent_scd_change_pin): New. - (agent_release_card_info): New. - * keygen.c (check_smartcard): Use it here. - -2003-07-16 Werner Koch <wk@gnupg.org> - - * export.c (parse_export_options): New option sexp-format. - (export_seckeys,export_secsubkeys): Check sexp-format option. - (do_export): Ignore armor for sexp format. - (do_export_stream): Handle sexp-format. - (write_sexp_line,write_sexp_keyparm, build_sexp_seckey): New. - (build_sexp): New. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * options.h (DBG_CIPHER): Reintroduced it. - * seskey.c (encode_session_key): Debug output of the session key. - - * pubkey-enc.c (get_it): Handle card case. - * call-agent.c (agent_scd_pkdecrypt): New. - * pkglue.c (pk_encrypt): Add RSA support. - - * g10.c (main): Default to --use-agent. - - * keygen.c (show_smartcard): Print info about the public key. - (check_smartcard): Check for existing key here. - (gen_card_key): And not anymore here. - (fpr_is_zero): New. - (generate_keypair): Generate both keys for a card. - (smartcard_change_url): Nw. - -2003-07-02 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (is_secret_key_protected): Let it handle mode 1002. - -2003-07-01 Werner Koch <wk@gnupg.org> - - * keygen.c (gen_card_key): Obviously we should use the creation - date received from SCDAEMON, so that the fingerprints will match. - * sign.c (do_sign): Pass the serialno to the sign code. - * keyid.c (serialno_and_fpr_from_sk): New. - -2003-06-30 Werner Koch <wk@gnupg.org> - - * call-agent.h (agent_card_info_s): Add field serialno. - * call-agent.c (store_serialno): New. - (learn_status_cb): Store the serial number. - * keygen.c (gen_card_key): Store the serial number - (check_smartcard): New argument to return the serial number. - (generate_keypair): Get the serial number from check_smartcard and - store it as a parameter. - * parse-packet.c (parse_key): Use the protect.iv field to store the - serial number. - * build-packet.c (do_secret_key): Write the serial number. - -2003-06-27 Werner Koch <wk@gnupg.org> - - * seckey-cert.c (check_secret_key): Bypass the unprotection for - mode 1002. - * sign.c (do_sign): Handle card case (i.e. mode 1002). - -2003-06-26 Werner Koch <wk@gnupg.org> - - * build-packet.c (do_secret_key): Implement special protection - mode 1002. - * parse-packet.c (parse_key): Likewise. - - * keygen.c (smartcard_gen_key): New. - * call-agent.c (agent_scd_setattr): New. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * Makefile.am: Removed signal.c - - * g10.c (emergency_cleanup): New. - (main): Use gnupg_init_signals and register malloc for assuan. - -2003-06-23 Werner Koch <wk@gnupg.org> - - * keyid.c (do_fingerprint_md): Made it work again. - -2003-06-19 Werner Koch <wk@gnupg.org> - - Fixed all "==" comparisons against error code constants to use - gpg_err_code(). - - * import.c (import_secret_one): - (import_revoke_cert): - (chk_self_sigs): - - * misc.c (openpgp_md_map_name): Check also for the Hx format. - (openpgp_cipher_map_name): Check also for the Sx format. - (pubkey_get_npkey): Adjusted for changed gcrypt API. - (pubkey_get_nskey): Ditto. - (pubkey_get_nsig): Ditto. - (pubkey_get_nenc): Ditto. - -2003-06-18 Werner Koch <wk@gnupg.org> - - Finished the bulk of changes for gnupg 1.9. This included - switching to libgcrypt functions, using shared error codes from - libgpg-error, replacing the old functions we used to have in - ../util by those in ../jnlib and ../common, renaming the malloc - functions and a couple of types. Note, that not all changes are - listed below becuause they are too similar and done at far too - many places. As of today the code builds using the current - libgcrypt from CVS but it is very unlikely that it actually works. - - * sig-check.c (cmp_help): Removed. Was never used. - - * pkglue.c: New. Most stuff taken from gnupg 1.1.2. - * pkglue.h: New. - - * misc.c (pull_in_libs): Removed. - - * keygen.c (count_chr): New. - (ask_user_id): Removed faked RNG support. - - * misc.c (openpgp_md_map_name,openpgp_cipher_map_name) - (openpgp_pk_map_name): New. - - * skclist.c (build_sk_list): Removed faked RNG support. - (is_insecure): Removed. - - * comment.c (make_mpi_comment_node): Use gcry MPI print function. - - * keyid.c (v3_keyid): New. - - * misc.c (mpi_write,mpi_write_opaque,mpi_read,mpi_read_opaque) - (mpi_print): New. Taken from gnupg 1.1.2. - (checksum_mpi): Replaced by implementation from 1.1.2. - - * g10.c (my_strusage): Renamed from strusage and return NULL - instead calling a default function. - (add_to_strlist2): New. Taken from ../util/strgutil.c of gnupg 1.2. - - * plaintext.c (handle_plaintext): New arg CREATE_FILE to cope with - the fact that gpg-error does not have this error code anymore. - - * mainproc.c (symkey_decrypt_sesskey): Ditto. - - * seskey.c (make_session_key): Adjusted for use with libgcrypt. - (encode_session_key): Ditto. - (do_encode_md): Ditto. - (encode_md_value): Ditto. - - * keyring.c: Use libgpg-error instead of READ_ERROR etc. - - * g10.c: Adjusted all algorithm name/id mapping functions. - (set_debug): Pass MPI and CRYPTO debug values to libgcrypt. - - * Makefile.am (INCLUDES): Define LOCALEDIR and the default error - source. - - * g10.c (i18n_init): s/G10_LOCALEDIR/LOCALEDIR/. - - Renamed m_alloc et al to xmalloc et al. - s/g10_errstr/gpg_strerror/ - s/MPI/gcry_mpi_t/ - Adjusted all md_open calls to the libgcrypt API. - - * build-packet.c (do_comment): Return error code from iobuf write - function. - (do_user_id): Ditto. - (do_public_key): Ditto. - - * Makefile.am: Add new files, link gpg with libgpg-error. - * g10.c, options.h: New option --agent-program. - * call-agent.c: New. - * gpg.h, call-agent.h: New. - -2003-06-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keylist.c (list_keyblock_print): Add - "show-validity" and "show-long-keyid" list-options. - - * gpgv.c (get_validity, trust_value_to_string): Stubs. - - * g10.c (main): Use SAFE_VERSION instead of VERSION in the - version-specific gpg.conf file so it can be overridden on RISCOS. - -2003-06-01 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main), keylist.c (show_policy_url, show_notation), - mainproc.c (check_sig_and_print): Emulate the old policy and - notation behavior (display by default). Send to status-fd whether - it is displayed on the screen or not. - - * g10.c (main): Since we now have some options in devel that won't - work in a stable branch gpg.conf file, try for a version-specific - gpg.conf-VERSION file before falling back to gpg.conf. - - * main.h, options.h: Move various option flags to options.h. - -2003-05-31 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (check_sig_and_print), main.h, keylist.c - (show_policy, show_notation): Collapse the old print_notation_data - into show_policy() and show_notation() so there is only one - function to print notations and policy URLs. - - * options.h, main.h, g10.c (main), keyedit.c - (print_and_check_one_sig), keylist.c (list_one, - list_keyblock_print), pkclist.c (do_edit_ownertrust), sign.c - (mk_notation_and_policy): New "list-options" and "verify-options" - commands. These replace the existing - --show-photos/--no-show-photos, - --show-notation/--no-show-notation, - --show-policy-url/--no-show-policy-url, and --show-keyring - options. The new method is more flexible since a user can specify - (for example) showing photos during sig verification, but not in - key listings. The old options are emulated. - - * main.h, misc.c (parse_options): New general option line - parser. Fix the bug in the old version that did not handle report - syntax errors after a valid entry. - - * import.c (parse_import_options), export.c - (parse_export_options): Call it here instead of duplicating the - code. - -2003-05-30 David Shaw <dshaw@jabberwocky.com> - - * keylist.c (list_one): Don't show the keyring filename when in - --with-colons mode. Actually translate "Keyring" string. - - * mainproc.c (proc_tree): We can't currently handle multiple - signatures of different classes or digests (we'd pretty much have - to run a different hash context for each), but if they are all the - same, make an exception. This is Debian bug #194292. - - * sig-check.c (check_key_signature2): Make string translatable. - - * packet.h, getkey.c (fixup_uidnode): Mark real primary uids - differently than assumed primaries. - - * keyedit.c (no_primary_warning): Use the differently marked - primaries here in a new function to warn when an --edit-key - command might rearrange the self-sig dates enough to change which - uid is primary. - (menu_expire, menu_set_preferences): Use no_primary_warning() - here. - - * Makefile.am: Use @DLLIBS@ for -ldl. - -2003-05-26 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (premerge_public_with_secret): Made "no secret subkey - for" warning a verbose item and translatable. (From wk on stable - branch) - - * sig-check.c (check_key_signature2): Made "no subkey for subkey - binding packet" a verbose item instead of a !quiet one. There are - too many garbled keys out in the wild. (From wk on stable branch) - - * filter.h: Remove const from WHAT. (From wk on stable branch) - - * progress.c (handle_progress): Store a copy of - NAME. (progress_filter): Release WHAT, make sure not to print a - NULL WHAT. (From wk on stable branch) - - * openfile.c (open_sigfile): Adjust free for new progress - semantics. (From wk on stable branch) - - * plaintext.c (ask_for_detached_datafile): Don't dealloc - pfx->WHAT. (From wk on stable branch) - - * seckey-cert.c (do_check): Issue the RSA_OR_IDEA status when the - cipher algo is IDEA to make it easier to track down the - problem. (From twoaday on stable branch) - -2003-05-24 David Shaw <dshaw@jabberwocky.com> - - * armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, - build-packet.c, getkey.c, keydb.c, openfile.c, plaintext.c, - status.c, gpgv.c, keygen.c, options.h, sig-check.c, tdbio.h, - encode.c, mainproc.c, parse-packet.c, signal.c, textfilter.c: Edit - all preprocessor instructions to remove whitespace before the '#'. - This is not required by C89, but there are some compilers out - there that don't like it. - -2003-05-21 David Shaw <dshaw@jabberwocky.com> - - * trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename - is_disabled to cache_disabled_value, which now takes a pk and not - just the keyid. This is for speed since there is no need to - re-fetch a key when we already have that key handy. Cache the - result of the check so we don't need to hit the trustdb more than - once. - - * getkey.c (skip_disabled): New function to get a pk and call - is_disabled on it. (key_byname): Use it here. - - * packet.h, getkey.c (skip_disabled), keylist.c - (print_capabilities): New "pk_is_disabled" macro to retrieve the - cached disabled value if available, and fill it in via - cache_disabled_value if not available. - - * trustdb.c (get_validity): Cache the disabled value since we have - it handy and it might be useful later. - - * parse-packet.c (parse_key): Clear disabled flag when parsing a - new key. Just in case someone forgets to clear the whole key. - - * getkey.c (merge_selfsigs_main): Add an "if all else fails" path - for setting a single user ID primary when there are multiple set - primaries all at the same second, or no primaries set and the most - recent user IDs are at the same second, or no signed user IDs at - all. This is arbitrary, but deterministic. - - * exec.h, photoid.h: Add copyright message. - - * keylist.c (list_keyblock_print): Don't dump attribs for - revoked/expired/etc uids for non-colon key listings. This is for - consistency with --show-photos. - - * main.h, keylist.c (dump_attribs), mainproc.c - (check_sig_and_print): Dump attribs if --attrib-fd is set when - verifying signatures. - - * g10.c (main): New --gnupg option to disable the various - --openpgp, --pgpX, etc. options. This is the same as --no-XXXX - for those options. - - * revoke.c (ask_revocation_reason): Clear old reason if user - elects to repeat question. This is bug 153. - - * keyedit.c (sign_uids): Show keyid of the key making the - signature. - -2003-05-21 Werner Koch <wk@gnupg.org> - - * progress.c (handle_progress) - * sign.c (write_plaintext_packet) - * encode.c (encode_simple,encode_crypt): Make sure that a filename - of "-" is considered to be stdin so that iobuf_get_filelength - won't get called. This fixes bug 156 reported by Gregery Barton. - -2003-05-02 David Shaw <dshaw@jabberwocky.com> - - * packet.h, build-packet.c (build_sig_subpkt), export.c - (do_export_stream), import.c (remove_bad_stuff, import), - parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt): Remove - vestigal code for the old sig cache subpacket. This wasn't - completely harmless as it caused subpacket 101 to disappear on - import and export. - - * options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, - sign.c, encode.c, getkey.c, revoke.c: The current flags for - different levels of PGP-ness are massively complex. This is step - one in simplifying them. No functional change yet, just use a - macro to check for compliance level. - - * sign.c (sign_file): Fix bug that causes spurious compression - preference warning. - - * sign.c (clearsign_file): Fix bug that prevents proper warning - message from appearing when clearsigning in --pgp2 mode with a - non-v3 RSA key. - - * main.h, misc.c (compliance_option_string, compliance_string, - compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file, - clearsign_file), encode.c (encode_crypt, - write_pubkey_enc_from_list): New functions to put the "this - message may not be usable...." warning in one place. - - * options.h, g10.c (main): Part two of the simplification. Use a - single enum to indicate what we are compliant to (1991, 2440, - PGPx, etc.) - - * g10.c (main): Show errors for failure in export, send-keys, - recv-keys, and refresh-keys. - - * options.h, g10.c (main): Give algorithm warnings for algorithms - chosen against the --pgpX and --openpgp rules. - - * keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in - --openpgp mode. - - * sign.c (sign_file), pkclist.c (algo_available): Allow passing a - hint of 0. - -2003-05-01 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (create_version_record): Only create new trustdbs with - TM_CLASSIC or TM_PGP. - - * trustdb.h, trustdb.c (trust_string, get_ownertrust_string, - get_validity_string, ask_ownertrust, validate_keys), pkclist.c - (do_edit_ownertrust): Rename trust_string to trust_value_to_string - for naming consistency. - - * trustdb.h, trustdb.c (string_to_trust_value): New function to - translate a string to a trust value. - - * g10.c (main): Use string_to_trust_value here for - --force-ownertrust. - - * options.h, g10.c (main), trustdb.c (trust_model_string, - init_trustdb, check_trustdb, update_trustdb, get_validity, - validate_one_keyblock): An "OpenPGP" trust model is misleading - since there is no official OpenPGP trust model. Use "PGP" - instead. - -2003-04-30 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Comments. - - * exec.c (exec_write): Cast NULL to void* to properly terminate - varargs list. - - * keyedit.c (show_key_with_all_names): Just for safety, catch an - invalid pk algorithm. - - * sign.c (make_keysig_packet): Crucial that the call to mksubpkt - comes LAST before the calls to finalize the sig as that makes it - possible for the mksubpkt function to get a reliable pointer to - the subpacket area. - - * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a - particular user ID, use that ID as the one to ask about when - prompting whether to use the key anyway. - (build_pk_list): Similar change here when adding keys to the - recipient list. - - * trustdb.c (update_validity): Fix bug that prevented more than - one validity record per trust record. - (get_validity): When retrieving validity for a (user) supplied - user ID, return the validity for that user ID only, and do not - fall back to the general key validity. - (validate_one_keyblock): Some commentary on whether - non-self-signed user IDs belong in the web of trust (arguably, - they do). - -2003-04-27 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Add --no-textmode. - - * export.c (do_export_stream), keyedit.c (show_key_with_all_names, - menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c - (show_photos), sign.c (mk_notation_and_policy), trustdb.c - (get_validity, reset_trust_records, validate_keys): Make some - strings translatable. - - * mainproc.c (check_sig_and_print): Show digest algorithm and sig - class when verifying a sig with --verbose on, and add version, pk - and hash algorithms and sig class to VALIDSIG. - - * parse-packet.c (enum_sig_subpkt): Make a warning message a - --verbose warning message since we don't need to warn every time - we see an unknown critical (we only need to invalidate the - signature). - - * trustdb.c (init_trustdb): Check the trustdb options even with - TM_AUTO since the auto may become TM_CLASSIC or TM_OPENPGP. - -2003-04-26 David Shaw <dshaw@jabberwocky.com> - - * sign.c (do_sign): Show the hash used when making a signature in - verbose mode. - - * tdbio.h, tdbio.c (tdbio_read_model): New function to return the - trust model used in a given trustdb. - - * options.h, g10.c (main), trustdb.c (init_trustdb, check_trustdb, - update_trustdb): Use tdbio_read_model to implement an "auto" trust - model which is set via the trustdb. - -2003-04-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_revoke_cert): Remove ultimate trust when - revoking an ultimately trusted key. - - * keyedit.c (sign_uids): Allow replacing expired signatures. - Allow duplicate signatures with --expert. - - * pkclist.c (check_signatures_trust): Don't display a null - fingerprint when checking a signature with --always-trust enabled. - - * filter.h (progress_filter_context_t), progress.c - (handle_progress), plaintext.c (ask_for_detached_datafile, - hash_datafiles): Fix compiler warnings. Make "what" constant. - - * build-packet.c (do_plaintext): Do not create invalid literal - packets with >255-byte names. - -2003-04-15 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CFLAGS): Make use of AM_CFLAGS and AM_LDFLAGS. - - * g10.c, options.h: New option --enable-progress-filter. - * progress.c (handle_progress): Make use of it. - -2003-04-15 Marcus Brinkmann <marcus@g10code.de> - - * progress.c: New file. - * Makefile.am (common_source): Add progress.c. - * filter.h (progress_filter_context_t): New type. - (progress_filter, handle_progress): New prototypes. - * main.h (open_sigfile): New argument for prototype. - * openfile.c (open_sigfile): New argument to install progress - filter. - * encode.c (encode_simple): New variable PFX. Register - progress filter. Install text_filter after that. - (encode_crypt): Likewise. - * sign.c (sign_file): Likewise. - (clearsign_file): Likewise. - * decrypt.c (decrypt_message): Likewise. - (decrypt_messages): Likewise. - * verify.c (verify_signatures): Likewise. - (verify_one_file): Likewise. - * plaintext.c (hash_datafiles): Likewise. - (ask_for_detached_datafile): Likewise. - -2003-04-10 Werner Koch <wk@gnupg.org> - - * passphrase.c (read_passphrase_from_fd): Do a dummy read if the - agent is to be used. Noted by Ingo Klöcker. - (agent_get_passphrase): Inhibit caching when we have no - fingerprint. This is required for key generation as well as for - symmetric only encryption. - - * passphrase .c (agent_get_passphrase): New arg CANCELED. - (passphrase_to_dek): Ditto. Passed to above. Changed all - callers to pass NULL. - * seckey-cert.c (do_check): New arg CANCELED. - (check_secret_key): Terminate loop when canceled. - - * keyedit.c (change_passphrase): Pass ERRTEXT untranslated to - passphrase_to_dek and translate where appropriate. - * seckey-cert.c (check_secret_key): Ditto. - * keygen.c (ask_passphrase): Ditto. - * passphrase.c (agent_get_passphrase): Translate the TRYAGAIN_TEXT. - Switch the codeset to utf-8. - -2003-04-09 Werner Koch <wk@gnupg.org> - - * decrypt.c (decrypt_messages): Fixed error handling; the function - used to re-loop with same file after an error. Reported by Joseph - Walton. - -2003-04-08 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), import.c (parse_import_options, - fix_pks_corruption): It's really PKS corruption, not HKP - corruption. Keep the old repair-hkp-subkey-bug command as an - alias. - - * g10.c (main): Rename --no-version to --no-emit-version for - consistency. Keep --no-version as an alias. - -2003-04-04 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (algo_available): PGP 8 can use the SHA-256 hash. - - * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Remove - unused code. - -2003-04-01 Werner Koch <wk@gnupg.org> - - * mainproc.c (check_sig_and_print): Add primary key fpr to VALIDSIG - status. - -2003-03-24 David Shaw <dshaw@jabberwocky.com> - - * keydb.h: Err on the side of making an unknown signature a SIG - rather than a CERT. - - * import.c (delete_inv_parts): Discard any key signatures that - aren't key types (i.e. 0x00, 0x01, etc.) - - * g10.c (main): Add deprecated option warning for - --list-ownertrust. Add --compression-algo alias for - --compress-algo. Change --version output strings to match - "showpref" strings, and make translatable. - - * status.c (do_get_from_fd): Accept 'y' as well as 'Y' for - --command-fd boolean input. - - * trustdb.c: Fix typo (DISABLE_REGEXP -> DISABLE_REGEX) - - * keyedit.c (show_key_with_all_names_colon): Show no-ks-modify - flag. - -2003-03-11 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyserver.c (kopts): Add "try-dns-srv" - keyserver option. Defaults to on. - - * passphrase.c (agent_get_passphrase): Fix memory leak with - symmetric messages. Fix segfault with symmetric messages. Fix - incorrect prompt with symmetric messages. - -2003-03-10 Werner Koch <wk@gnupg.org> - - * compress.c (init_uncompress): Use a 15 bit window size so that - the output of implementations which don't run for PGP 2 - compatibility won't get garbled. - -2003-03-04 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (validate_keys): Mask the ownertrust when building the - list of fully valid keys so that disabled keys are still counted - in the web of trust. - (get_ownertrust_with_min): Do the same for the minimum ownertrust - calculation. - - * parse-packet.c (dump_sig_subpkt): Show the notation names for - not-human-readable notations. Fix cosmetic off-by-one length - counter. - - * options.skel: Add explantion and commented-out - "no-mangle-dos-filenames". - - * mainproc.c (proc_encrypted): Make string translatable. - - * keyserver.c (keyserver_spawn): Quote ':', '%', and any 8-bit - characters in the uid strings sent to the keyserver helper. - - * keyring.c (keyring_rebuild_cache): Lock the keyring while - rebuilding the signature caches to prevent another gpg from - tampering with the temporary copy. - - * keygen.c (keygen_set_std_prefs): Include AES192 and AES256 in - default prefs. - - * keyedit.c (show_prefs): Make strings translatable. - - * keydb.c: Double the maximum number of keyrings to 40. - - * gpgv.c (main): Fix bug #113 - gpgv should accept the - --ignore-time-conflict option. - - * g10.c (main): --openpgp disables --pgpX. Double the amount of - secure memory to 32k (keys are getting bigger these days). - - * Makefile.am: Makefile.am: Use @CAPLIBS@ to link in -lcap if we - are using capabilities. - -2003-02-26 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Include various pieces of - information about the key in the data sent to the keyserver - helper. This allows the helper to use it in instructing a remote - server which may not have any actual OpenPGP smarts in parsing - keys. - - * main.h, export.c (export_pubkeys_stream, do_export_stream): Add - ability to return only the first match in an exported keyblock for - keyserver usage. This should be replaced at some point with a - more flexible solution where each key can be armored seperately. - -2003-02-22 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file): Do not push textmode filter onto an unopened - IOBUF (segfault). Noted by Marcus Brinkmann. Push and - reinitialize textmode filter for each file in a multiple file - list. - - * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Set - and show the keyserver no-modify flag. - - * keygen.c (add_keyserver_modify): New. - (keygen_upd_std_prefs): Call it here. - (keygen_set_std_prefs): Accept "ks-modify" and "no-ks-modify" as - prefs to set and unset keyserver modify flag. - - * g10.c (main): Accept "s1" in addition to "idea" to match the - other ciphers. - - * main.h, misc.c (idea_cipher_warn): We don't need this if IDEA - has been disabled. - -2003-02-21 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Don't put AES or CAST5 in - default prefs if they are disabled. - - * g10.c (main): Use 3DES instead of CAST5 if we don't have CAST5 - support. Use 3DES for the s2k cipher in --openpgp mode. - (print_mds): #ifdef all of the optional digest algorithms. - -2003-02-12 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (classify_user_id, classify_user_id2): Make - 'exact' a per-desc item. Merge into one function since - 'force_exact' is no longer needed. - (key_byname): Use new classify_user_id function, and new exact - flag in KEYDB_SEARCH_DESC. - - * keyring.h, keyring.c (keyring_search): Return an optional index - to show which KEYDB_SEARCH_DESC was the matching one. - - * keydb.h, keydb.c (keydb_search): Rename to keydb_search2, and - pass the optional index to keyring_search. Add a macro version of - keydb_search that calls this new function. - - * export.c (do_export_stream): If the keyid! syntax is used, - export only that specified key. If the key in question is a - subkey, export the primary plus that subkey only. - -2003-02-11 David Shaw <dshaw@jabberwocky.com> - - * exec.c (set_exec_path): Add debugging line. - - * g10.c (print_hex, print_mds): Print long hash strings a lot - neater. This assumes at least an 80-character display, as there - are a few other similar assumptions here and there. Users who - need unformatted hashes can still use with-colons. Check that - SHA384 and 512 are available before using them as they are no - longer always available. - - * Makefile.am: Use a local copy of libexecdir along with @PACKAGE@ - as GNUPG_LIBEXECDIR so it can be easily overridden at make time. - -2003-02-04 David Shaw <dshaw@jabberwocky.com> - - * armor.c (parse_hash_header, armor_filter): Accept the new SHAs - in the armor Hash: header. - - * g10.c (print_hex): Print long hash strings a little neater. - (print_mds): Add the new SHAs to the hash list. - -2003-02-02 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_revuid): Properly handle a nonselfsigned uid on - a v4 key (treat as a v4 revocation). - - * import.c (print_import_check): Do not re-utf8 convert user IDs. - -2003-01-27 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (list_node): Show signature expiration date in - with-colons sig records. - - * keylist.c (list_keyblock_colon), mainproc.c (list_node): Show - trust sig information in with-colons sig records. - -2003-01-16 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_group): Trim whitespace after a group name so it does - not matter where the user puts the = sign. - - * options.skel: Comment out the first three lines in case someone - manually copies the skel file to their homedir. - - * sign.c (clearsign_file): Only use pgp2mode with v3 keys and - MD5. This matches what we do when decoding such messages and - prevents creating a message (v3+RIPEMD/160) that we can't verify. - - * sig-check.c (signature_check2): Use G10ERR_GENERAL as the error - for signature digest conflict. BAD_SIGN implies that a signature - was checked and we may try and print out a user ID for a key that - doesn't exist. - -2003-01-15 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (init_trustdb, get_validity): Don't use a changed - trust model to indicate a dirty trustdb, and never auto-rebuild a - dirty trustdb with the "always" trust model. - - * g10.c (add_group): Last commit missed the \t ;) - -2003-01-14 David Shaw <dshaw@jabberwocky.com> - - * packet.h, parse-packet.c (setup_user_id), free-packet.c - (free_user_id), keydb.h, keyid.c (namehash_from_uid): New function - to rmd160-hash the contents of a user ID packet and cache it in - the uid object. - - * keylist.c (list_keyblock_colon): Use namehash in field 8 of - uids. Show dates for creation (selfsig date), and expiration in - fields 6 and 7. - - * trustdb.c (get_validity, get_validity_counts, update_validity): - Use new namehash function rather than hashing it locally. - -2003-01-14 Werner Koch <wk@gnupg.org> - - * g10.c (add_group): Fixed group parsing to allow more than one - delimiter in a row and also allow tab as delimiter. - -2003-01-12 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (tdbio_set_dbname): Fix assertion failure with - non-fully-qualified trustdb names. - -2003-01-11 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (get_validity_info, get_ownertrust_info, - trust_letter): Simplify by returning a ? for error directly. - - * keyedit.c (show_key_with_all_names): Use get_validity_string and - get_ownertrust_string to show full word versions of trust - (i.e. "full" instead of 'f'). - - * trustdb.h, trustdb.c (get_ownertrust_string, - get_validity_string): Same as get_ownertrust_info, and - get_validity_info, except returns a full string. - - * trustdb.c (get_ownertrust_with_min): New. Same as - 'get_ownertrust' but takes the min_ownertrust value into account. - -2003-01-10 David Shaw <dshaw@jabberwocky.com> - - * armor.c (armor_filter): Comment about PGP's end of line tab - problem. - - * trustdb.h, trustdb.c (trust_letter): Make - static. (get_ownertrust_info, get_validity_info): Don't mask the - trust level twice. - - * trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info), - keylist.c (list_keyblock_colon), keyedit.c - (show_key_with_all_names_colon, menu_revuid): Pass a user ID in - rather than a namehash, so we only have to do the hashing in one - place. - - * packet.h, pkclist.c (build_pk_list), free-packet.c - (release_public_key_parts): Remove unused namehash element for - public keys. - -2003-01-07 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Warn when setting an IDEA - preference when IDEA is not available. - -2003-01-06 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (get_validity_info): 'd' for disabled is not a - validity value any more. - - * packet.h, tdbio.h, tdbio.c (tdbio_read_record, - tdbio_write_record), trustdb.c (update_validity): Store temporary - full & marginal counts in the trustdb. - (clear_validity, get_validity_counts): Return and clear temp - counts. - (store_validation_status): Keep track of which keyids have been - stored. - (validate_one_keyblock, validate_key_list): Use per-uid copies of - the full & marginal counts so they can be recalled for multiple - levels. - (validate_keys): Only use unused keys for each new round. - (reset_unconnected_keys): Rename to reset_trust_records, and only - skip specifically excluded records. - - * keylist.c (print_capabilities): Show 'D' for disabled keys in - capabilities section. - - * trustdb.c (is_disabled): Remove incorrect comment. - -2003-01-03 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): Only do the work to create the status - display for interactive import if status is enabled. - - * keyring.c (keyring_search): skipfnc didn't work properly with - non-keyid searches. Noted by Stefan Bellon. - - * getkey.c (merge_selfsigs_main): Remove some unused code and make - sure that the pk selfsigversion member accounts for 1F direct - sigs. - -2003-01-02 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Don't assume that try_make_homedir - terminates but check again for the existence of the directory and - continue then. - * openfile.c (copy_options_file): Print a warning if the skeleton - file has active options. - -2002-12-29 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (merge_selfsigs_main), main.h, sig-check.c - (check_key_signature2): Pass the ultimately trusted pk directly to - check_key_signature2 to avoid going through the key selection - mechanism. This prevents a deadly embrace when two keys without - selfsigs each sign the other. - -2002-12-27 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_refresh): Don't print the "refreshing..." - line if there are no keys to refresh or if there is no keyserver - set. - - * getkey.c (merge_selfsigs_main): Any valid user ID should make a - key valid, not just the last one. This also fixes Debian bug - #174276. - -2002-12-27 Stefan Bellon <sbellon@sbellon.de> - - * import.c (print_import_check): Changed int to size_t. - -2002-12-27 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu, menu_revuid): Add "revuid" feature to - revoke a user ID. This is the same as issuing a revocation for - the self-signature, but a much simpler interface to do it. - -2002-12-26 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (key_byname): Flag to enable or disable - including disabled keys. Keys specified via keyid (i.e. 0x...) - are always included. - - * getkey.c (get_pubkey_byname, get_seckey_byname2, - get_seckey_bynames), keyedit.c (keyedit_menu, menu_addrevoker): - Include disabled keys in these functions. - - * pkclist.c (build_pk_list): Do not include disabled keys for -r - or the key prompt. Do include disabled keys for the default key - and --encrypt-to. - - * trustdb.h, trustdb.c (is_disabled): New skipfnc for skipping - disabled keys. - - * gpgv.c (is_disabled): Stub. - - * keygen.c (keygen_add_key_expire): Properly handle updating a key - expiration to a no-expiration value. - - * keyedit.c (enable_disable_key): Comment. - - * import.c (import_one): When in interactive mode and --verbose, - don't repeat some key information twice. - -2002-12-22 Timo Schulz <ts@winpt.org> - - * import.c (print_import_check): New. - (import_one): Use it here. - Use merge_keys_and_selfsig in the interactive mode to avoid - wrong key information. - * status.h: Add new status code. - * status.c: Ditto. - -2002-12-13 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (do_we_trust): Tweak language to refer to the "named - user" rather than "owner". Noted by Stefan Bellon. - - * trustdb.h, trustdb.c (trustdb_pending_check): New function to - check if the trustdb needs a check. - - * import.c (import_keys_internal): Used here so we don't rebuild - the trustdb if it is still clean. - (import_one, chk_self_sigs): Only mark trustdb dirty if the key - that is being imported has any sigs other than self-sigs. - Suggested by Adrian von Bidder. - - * options.skel: Include the required '=' sign in the sample - 'group' option. Noted by Stefan Bellon. - - * import.c (chk_self_sigs): Don't try and check a subkey as if it - was a signature. - -2002-12-11 David Shaw <dshaw@jabberwocky.com> - - * tdbio.c (tdbio_read_record, tdbio_write_record): Compact the - RECTYPE_TRUST records a bit. - - * g10.c (main): Comment out --list-trust-path until it can be - implemented. - - * import.c (import_one): Warn when importing an Elgamal primary - that this may take some time (to verify self-sigs). - (chk_self_sigs): Try and cache all self-sigs so the keyblock is - written to the keyring with a good rich cache. - - * keygen.c (ask_algo): Make the Elgamal sign+encrypt warning - stronger, and remove the RSA sign+encrypt warning. - -2002-12-06 Stefan Bellon <sbellon@sbellon.de> - - * options.h: Fixed typo (mangle_dos_names instead of - mangle_dos_filenames). - -2002-12-05 Werner Koch <wk@gnupg.org> - - * g10.c: New options --[no-]mangle-dos-filenames. - * options.h (opt): Added mangle-dos-filenames. - * openfile.c (open_outfile) [USE_ONLY_8DOT3]: Truncate the - filename only when this option is set; this is the default. - -2002-12-04 David Shaw <dshaw@jabberwocky.com> - - * main.h, keyedit.c, keygen.c: Back out previous (2002-12-01) - change. Minimal isn't always best. - - * sign.c (update_keysig_packet): Use the current time rather then - a modification of the original signature time. Make sure that - this doesn't cause a time warp. - - * keygen.c (keygen_add_key_expire): Properly handle a key - expiration date in the past (use a duration of 0). - - * keyedit.c (menu_expire): Use update_keysig_packet so any sig - subpackets are maintained during the update. - - * build-packet.c (build_sig_subpkt): Mark sig expired or unexpired - when the sig expiration subpacket is added. - (build_sig_subpkt_from_sig): Handle making an expiration subpacket - from a sig that has already expired (use a duration of 0). - - * packet.h, sign.c (update_keysig_packet), keyedit.c - (menu_set_primary_uid, menu_set_preferences): Add ability to issue - 0x18 subkey binding sigs to update_keysig_packet and change all - callers. - - * trustdb.c (validate_keys): Show trust parameters when building - the trustdb, and make sure that the version record update was - successful. - (init_trustdb): If the current parameters aren't what was used for - building the trustdb, the trustdb is invalid. - - * tbio.c (tdbio_db_matches_options): Update to work with new - trustdbs. - -2002-12-03 David Shaw <dshaw@jabberwocky.com> - - * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): Store - trust model in the trustdb version record. - (tdbio_update_version_record): New function to update version - record values during a trustdb check or update. - (tdbio_dump_record): Show trust model in dump. - - * trustdb.c (validate_keys): Call tdbio_update_version_record on - success so that the correct options are stored in the trustdb. - - * options.h: rearrange trust models so that CLASSIC is 0 and - OPENPGP is 1. - - * options.h, g10.c (main), encode.c (write_pubkey_enc_from_list), - pkclist.c (algo_available), revoke.c (gen_revoke): Add --pgp8 - mode. This is basically identical to --pgp7 in all ways except - that signing subkeys, v4 data sigs (including expiration), and SK - comments are allowed. - - * getkey.c (finish_lookup): Comment. - - * main.h, keylist.c (reorder_keyblock), keyedit.c (keyedit_menu): - Reorder user ID display in the --edit-key menu to match that of - the --list-keys display. - - * g10.c (add_notation_data): Fix initialization. - -2002-12-01 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_expire): Don't lose key flags when changing the - expiration date of a subkey. This is not the most optimal - solution, but it is minimal change on the stable branch. - - * main.h, keygen.c (do_copy_key_flags): New function to copy key - flags, if any, from one sig to another. - (do_add_key_expire): New function to add key expiration to a sig. - (keygen_copy_flags_add_expire): New version of - keygen_add_key_expire that also copies key flags. - (keygen_add_key_flags_and_expire): Use do_add_key_expire. - - * import.c (fix_hkp_corruption): Comment. - -2002-11-25 Stefan Bellon <sbellon@sbellon.de> - - * plaintext.c (handle_plaintext) [__riscos__]: If nooutput is set, - no filetype is needed obviously. - -2002-11-24 David Shaw <dshaw@jabberwocky.com> - - * main.h, misc.c (default_cipher_algo, default_compress_algo): - New. Return the default algorithm by trying - --cipher-algo/--compress-algo, then the first item in the pref - list, then s2k-cipher-algo or ZIP. - - * sign.c (sign_file, sign_symencrypt_file), encode.c - (encode_simple, encode_crypt): Call default_cipher_algo and - default_compress_algo to get algorithms. - - * g10.c (main): Allow pref selection for compress algo with - --openpgp. - - * mainproc.c (proc_encrypted): Use --s2k-digest-algo for - passphrase mangling rather than --digest-algo. - - * sign.c (hash_for): If --digest-algo is not set, but - --personal-digest-preferences is, then use the first hash - algorithm in the personal list. If the signing algorithm is DSA, - then use the first 160-bit hash algorithm in the personal list. - If --pgp2 is set and it's a v3 RSA key, use MD5. - - * g10.c (main), keydb.c (keydb_add_resource, - keydb_locate_writable): Rename --default-keyring as - --primary-keyring. Stefan wins the naming contest. - -2002-11-23 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_notation_data): Disallow notation names that do not - contain a '@', unless --expert is set. This is to help prevent - people from polluting the (as yet unused) IETF namespace. - - * main.h: Comments about default algorithms. - - * photoid.c (image_type_to_string): Comments about 3-letter file - extensions. - - * encode.c (encode_simple), passphrase.c (passphrase_to_dek), - sign.c (sign_symencrypt_file): Use --s2k-digest-algo for - passphrase mangling rather than --digest-algo. - -2002-11-21 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Properly handle an empty - preference string. - - * misc.c (string_to_compress_algo): "none" is a bad choice since - it conflicts with the "none" in setpref. - -2002-11-14 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Allow compression algorithm names as the argument - to --compress-algo. The old algorithm names still work for - backwards compatibility. - - * misc.c (string_to_compress_algo): Allow "none" as an alias for - "uncompressed". - -2002-11-13 Stefan Bellon <sbellon@sbellon.de> - - * getkey.c (get_pubkey_byfprint_fast): Fixed type incompatibility, - was unsigned char instead of byte. - -2002-11-13 David Shaw <dshaw@jabberwocky.com> - - * encode.c (encode_simple): Make sure that files larger than about - 4G use partial length encoding. This is required because OpenPGP - allows only for 32 bit length fields. From Werner on stable - branch. - - * getkey.c (get_pubkey_direct): Renamed to... - (get_pubkey_fast): this and made extern. - (get_pubkey_byfprint_fast): New. From Werner on stable branch. - - * keydb.h, import.c (import_one): Use get_pubkey_fast instead of - get_pubkey. We don't need a merged key and actually this might - lead to recursions. - (revocation_present): Likewise for search by fingerprint. From - Werner on stable branch. - - * g10.c (main): Try to create the trustdb even for non-colon-mode - list-key operations. This is required because getkey needs to - know whether a a key is ultimately trusted. From Werner on stable - branch. - - * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; - we don't need it here as it behaves more like a Posix system. - From Werner on stable branch. - - * passphrase.c (agent_get_passphrase): Ditto. From Werner on - stable branch. - - * tdbio.c (MY_O_BINARY): Need binary mode with Cygwin. From - Werner on stable branch. - - * g10.c, gpgv.c (main) [__CYGWIN32__]: Don't get the homedir from - the registry. From Werner on stable branch. - - * keyedit.c (show_key_with_all_names_colon): Make --with-colons - --edit display match the validity and trust of --with-colons - --list-keys. - - * passphrase.c (agent_send_all_options): Fix compile warning. - - * keylist.c (list_keyblock_colon): Validity for subkeys should - match that of the primary key, and not that of the last user ID. - - * getkey.c (merge_selfsigs): Revoked/expired/invalid primary keys - carry these facts onto all their subkeys, but only after the - subkey has a chance to be marked valid. This is to fix an - incorrect "invalid public key" error verifying a signature made by - a revoked signing subkey, with a valid unrevoked primary key. - -2002-11-09 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_send_all_options): Use tty_get_ttyname to - get the default ttyname. - -2002-11-07 David Shaw <dshaw@jabberwocky.com> - - * keyring.h, keyring.c (keyring_register_filename): Return the - pointer if a given keyring is registered twice. - - * keydb.h, keydb.c (keydb_add_resource): Use flags to indicate a - default keyring. - (keydb_locate_writable): Prefer the default keyring if possible. - - * g10.c (main): Add --default-keyring option. - -2002-11-06 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), trustdb.c (ask_ownertrust): Add - --force-ownertrust option for debugging purposes. This allows - setting a whole keyring to a given trust during an - --update-trustdb. Not for normal use - it's just easier than - hitting "4" all the time to test a large trustdb. - - * pubkey-enc.c (get_session_key): With hidden recipients or try a - given passphrase against all secret keys rather than trying all - secret keys in turn. Don't if --try-all-secrets or --status-fd is - enabled. - - * passphrase.c (passphrase_to_dek): Mode 1 means do a regular - passphrase query, but don't prompt with the key info. - - * seckey-cert.c (do_check, check_secret_key): A negative ask count - means to enable passphrase mode 1. - - * keydb.h, getkey.c (enum_secret_keys): Add flag to include - secret-parts-missing keys (or not) in the list. - -2002-11-05 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): When --with-colons is - enabled, don't try and fit the search output to the screen size - - just dump the whole list. - -2002-11-04 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): When --with-colons is - enabled, just dump the raw keyserver protocol to stdout and don't - print the menu. - - * keyserver.c (show_prompt): Don't show a prompt when command-fd - is being used. - - * trustdb.c (trust_model_string, check_trustdb, update_trustdb, - validate_one_keyblock): It's not clear what a trustdb rebuild or - check means with a trust model other than "classic" or "openpgp", - so disallow this. - -2002-11-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main): Add --trust-model option. Current - models are "openpgp" which is classic+trustsigs, "classic" which - is classic only, and "always" which is the same as the current - option --always-trust (which still works). Default is "openpgp". - - * trustdb.c (validate_one_keyblock): Use "openpgp" trust model to - enable trust sigs. - - * gpgv.c (main), mainproc.c (check_sig_and_print), pkclist.c - (do_we_trust, do_we_trust_pre, check_signatures_trust): Use new - --trust-model option in place of --always-trust. - - * keyedit.c (sign_mk_attrib, trustsig_prompt, sign_uids, - keyedit_menu): Prompt for and create a trust signature with - "tsign". This is functional, but needs better UI text. - - * build-packet.c (build_sig_subpkt): Able to build trust and - regexp subpackets. - - * pkclist.c (do_edit_ownertrust): Comment. - -2002-11-02 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (set_one_pref, keygen_set_std_prefs): Allow using the - full algorithm name (CAST5, SHA1) rather than the short form (S3, - H2). - - * main.h, keygen.c (keygen_get_std_prefs), keyedit.c - (keyedit_menu): Return and use a fake uid packet rather than a - string since we already have a nice parser/printer in - keyedit.c:show_prefs. - - * main.h, misc.c (string_to_compress_algo): New. - -2002-11-01 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Add --no-throw-keyid. - - * keydb.h, encode.c (write_pubkey_enc_from_list), g10.c (main), - pkclist.c (build_pk_list): Add --hidden-recipient (-R) and - --hidden-encrypt-to, which do a single-user variation on - --throw-keyid. The "hide this key" flag is carried in bit 0 of - the pk_list flags field. - - * keyserver.c (parse_keyrec): Fix shadowing warning. - -2002-10-31 Stefan Bellon <sbellon@sbellon.de> - - * compress.c (init_compress) [__riscos__]: Use - riscos_load_module() to load ZLib module. - - * g10.c (main) [__riscos__]: Renames due to changes in riscos.c - (e.g. prefixes all RISC OS specific functions with riscos_*). - * photoid.c (show_photos) [__riscos__]: Likewise. - * signal.c (got_fatal_signal) [__riscos__]: Likewise. - - * trustdb.c (check_regexp) [__riscos__]: Branch to RISC OS RegEx - handling. - -2002-10-31 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (do_plaintext), encode.c (encode_sesskey, - encode_simple, encode_crypt), sign.c (write_plaintext_packet): Use - wipememory() instead of memset() to wipe sensitive memory as the - memset() might be optimized away. - -2002-10-30 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (check_regexp): Modern regexps require REG_EXTENDED. - -2002-10-29 David Shaw <dshaw@jabberwocky.com> - - * packet.h, trustdb.h, trustdb.c (trust_string): New. Return a - string like "fully trusted", "marginally trusted", etc. - (get_min_ownertrust): New. Return minimum ownertrust. - (update_min_ownertrust): New. Set minimum ownertrust. - (check_regexp): New. Check a regular epression against a user ID. - (ask_ownertrust): Allow specifying a minimum value. - (get_ownertrust_info): Follow the minimum ownertrust when - returning a letter. - (clear_validity): Remove minimum ownertrust when a key becomes - invalid. - (release_key_items): Release regexp along with the rest of the - info. - (validate_one_keyblock, validate_keys): Build a trust sig chain - while validating. Call check_regexp for regexps. Use the minimum - ownertrust if the user does not specify a genuine ownertrust. - - * pkclist.c (do_edit_ownertrust): Only allow user to select a - trust level greater than the minimum value. - - * parse-packet.c (can_handle_critical): Can handle critical trust - and regexp subpackets. - - * trustdb.h, trustdb.c (clear_ownertrusts), delkey.c - (do_delete_key), import.c (import_one): Rename clear_ownertrust to - clear_ownertrusts and have it clear the min_ownertrust value as - well. - - * keylist.c (list_keyblock_print): Indent uid to match pub and - sig. - - * keyedit.c (print_and_check_one_sig, show_key_and_fingerprint, - menu_addrevoker), keylist.c (list_keyblock_print, - print_fingerprint): Show "T" or the trust depth for trust - signatures, and add spaces to some strings to make room for it. - - * packet.h, parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt, - parse_signature): Parse trust signature values. - - * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): - Reserve a byte for the minimum ownertrust value (for use with - trust signatures). - -2002-10-29 Stefan Bellon <sbellon@sbellon.de> - - * build-packet.c (calc_plaintext, do_plaintext): Removed RISC OS - specific filetype parts (it's now done in make_basename()). - - * plaintext.c (handle_plaintext): Tidied up RISC OS specific - filetype parts. - - * encode.c (encode_simple, encode_crypt): Added argument to - make_basename() call. - - * sign.c (write_plaintext_packet): Added argument to - make_basename() call. - -2002-10-28 Stefan Bellon <sbellon@sbellon.de> - - * build-packet.c (calc_plaintext, do_plaintext): Added filetype - handling for RISC OS' file types. - - * plaintext.c (handle_plaintext) [__riscos__]: Added filetype - handling for RISC OS' file types. - -2002-10-23 David Shaw <dshaw@jabberwocky.com> - - * main.h, import.c (sec_to_pub_keyblock, import_secret_one, - parse_import_options), g10.c (main): New import-option - "convert-sk-to-pk" to convert a secret key into a public key - during import. It is on by default. - -2002-10-23 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_it): Fix segv, test for revoked only when PK - has been assigned. - -2002-10-18 Timo Schulz <ts@winpt.org> - - * keylist.c: (print_pubkey_info): New. - (print_seckey_info): New. - * main.h: Prototypes for the new functions. - * delkey.c (do_delete_key): Use it here. - * revoke.c (gen_desig_revoke): Ditto. - -2002-10-17 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_edit_ownertrust): Show all user IDs. This should - be enhanced to also show the current trust level. Suggested by - Florian Weimer. - -2002-10-17 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Handle --strict and --no-strict from the command - line before the options file is loaded. - -2002-10-15 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Disable --textmode when encrypting (symmetric or - pk) in --pgp2 mode as PGP 2 can't handle the unknown length - literal packet. Reported by Michael Richardson. - -2002-10-14 David Shaw <dshaw@jabberwocky.com> - - * keyserver-internal.h, keyserver.c (print_keyrec, parse_keyrec, - show_prompt, keyserver_search_prompt, keyserver_spawn): Go to - version 1 of the keyserver protocol. This is a better design, - similar to --with-colons, that allows for keys with multiple user - IDs rather than using multiple keys. It also matches the machine - readable pksd format. Also use a prettier --search-keys listing - format that can fill different size windows (currently set at 24 - lines). - -2002-10-12 Werner Koch <wk@gnupg.org> - - * keygen.c (print_status_key_created): New. - (do_generate_keypair): Use it to print the fingerprint. - (generate_subkeypair): Likewise. - -2002-10-11 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_addrevoker): Properly back out if the signature - fails. Also, do not allow appointing the same revoker twice, and - report ALREADY_SIGNED if the user tries it. - -2002-10-07 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_keys_internal): Missed one s/inp/inp2/. - - * keylist.c (print_capabilities): Properly indicate per-key - capabilities of sign&encrypt primary keys that have - secret-parts-missing (i.e. no capabilities at all) - - * mainproc.c (symkey_decrypt_sesskey): Fix compiler warning. - -2002-10-04 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (get_pubkey_direct): Don't cache keys retrieved via - this function as they may not have all their fields filled in. - - * sig-check.c (signature_check2): Use new is_primary flag to check - rather than comparing main_keyid with keyid as this still works in - the case of a not fully filled in pk. - -2002-10-04 Werner Koch <wk@gnupg.org> - - * import.c (import_keys_internal): s/inp/inp2/ to avoid shadowing - warning. - - * passphrase.c (agent_get_passphrase): Fixed signed/unsigned char - problem in %-escaping. Noted by Ingo Klöcker. - -2002-10-03 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main): Add --strict and --no-strict to switch - the log_warning severity level from info to error. - - * keylist.c (print_capabilities): Secret-parts-missing keys should - show that fact in the capabilities, and only primary signing keys - can certify other keys. - - * packet.h, parse_packet.c (parse_key): Add is_primary flag for - public keys (it already exists for secret keys). - -2002-10-02 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_secret_one): Check for an illegal (>110) - protection cipher when importing a secret key. - - * keylist.c (list_keyblock_print): Show a '#' for a - secret-parts-missing key. - - * parse_packet.c (parse_key): Some comments. - - * revoke.c (gen_revoke): Remove some debugging code. - - * trustdb.c (verify_own_keys): Make trusted-key a non-deprecated - option again. - - * seckey-cert.c (do_check): Don't give the IDEA warning unless the - cipher in question is in fact IDEA. - -2002-10-01 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): Make sure that a newly imported key - starts with a clean ownertrust. - -2002-10-01 Werner Koch <wk@gnupg.org> - - * getkey.c (get_pubkey_direct): New. - (merge_selfsigs_main): Use it here to look for an ultimately - trusted key. Using the full get_pubkey might lead to an - infinitive recursion. - -2002-09-29 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (parse_keyserver_uri): Force the keyserver URI - scheme to lowercase to be case-insensitive. - -2002-09-28 David Shaw <dshaw@jabberwocky.com> - - * export.c (do_export_stream): Comment. - - * sig-check.c (check_key_signature2): Properly handle a - non-designated revocation import. - -2002-09-26 Werner Koch <wk@gnupg.org> - - * g10.c (set_homedir): New. Changed all direct assignments to use - this. - * gpgv.c (set_homedir): Ditto. - -2002-09-25 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: Link gpg with EGDLIBS (i.e. NETLIBS) as EGD uses - sockets. Remove the old NETLIBS variable since the keyserver - stuff is no longer internal. - -2002-09-24 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_keys_stream): Fix compiler type warning. - - * keyring.c (keyring_rebuild_cache), sig-check.c - (check_key_signature2), import.c (import, chk_self_sigs): Minor - language cleanups. - -2002-09-23 Stefan Bellon <sbellon@sbellon.de> - - * main.h: Introduced fast-import as import option. Removed - fast as separate option from prototypes. - * import.c (parse_import_options): Added fast-import option. - (import_*): Removed fast as separate option. - * g10.c (main): Added option fast-import, removed old fast - as separate argument. - * keyserver.c (keyserver_spawn): Removed old fast as separate - argument. - -2002-09-22 Stefan Bellon <sbellon@sbellon.de> - - * import.c (import_keys, import_keys_stream, - import_keys_internal): Added trustdb update/check to key import if - not fast-import and interactive set/no-auto-check-trustdb unset. - Avoided function clone by introducing import_keys_internal. - -2002-09-19 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Properly handle line truncation. - Don't leak memory (~10-20 bytes) on searches. - (keyserver_search_prompt): Cleanup. - - * keylist.c (list_keyblock_colon): Show 1F direct key signatures - in --with-colons listing. - -2002-09-16 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_addrevoker): The direct key signature for - revocation keys must be at least v4 to carry the revocation key - subpacket. Add a PGP 2.x warning for revocation keys. - -2002-09-14 David Shaw <dshaw@jabberwocky.com> - - * g10.c (check_permissions): Rearrange strings to make translating - easier (don't incorporate string parts). - - * keyedit.c (sign_uids): Make strings translatable. - - * sig-check.c (check_key_signature2): Make string translatable. - -2002-09-13 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (check_revocation_keys): Move.... - * main.h, sig-check.c (check_revocation_keys): to here. Also - return the signature_check error code rather than 0/1 and cache - the sig result. - - * sig-check.c (check_key_signature2): Divert to - check_revocation_keys if a revocation sig is made by someone other - than the pk owner. - - * getkey.c (merge_selfsigs_main): Tidy. - -2002-09-13 Werner Koch <wk@gnupg.org> - - * g10.c (main) [__MINGW32__]: Activate oLoadExtension. - -2002-09-12 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am, hkp.c, hkp.h, keyserver.c (keyserver_work): Remove - internal HKP support. - - * keyserver.c (keyserver_spawn): Remove whitespace after keyserver - commands. - -2002-09-10 David Shaw <dshaw@jabberwocky.com> - - * exec.c (expand_args): Remove loop left over from earlier - implementation. - (exec_write): Missed one tick. - -2002-09-10 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: Removed option --emulate-checksum-bug. - * misc.c (checksum_u16_nobug): Removed. - (checksum_u16): Removed the bug emulation. - (checksum_mpi): Ditto. - (checksum_mpi_counted_nbits): Removed and replaced all calls - with checksum_mpi. - - * parse-packet.c (read_protected_v3_mpi): New. - (parse_key): Use it here to store it as an opaque MPI. - * seckey-cert.c (do_check): Changed the v3 unprotection to the new - why to store these keys. - (protect_secret_key): Likewise. - * build-packet.c (do_secret_key): And changed the writing. - - * tdbio.c (tdbio_set_dbname, open_db): Use new macro MY_O_BINARY - to avoid silly ifdefs. - (open_db): Fallback to RDONLY so that gpg may be used from a - RO-medium. - - * encode.c (encode_simple): Make sure we don't use an ESK packet - when we don't have a salt in the S2K. - - * misc.c (pct_expando) <case f>: Make sure that LEN is initialized. - - * exec.c (exec_finish): Use ticks to denote filenames in messages. - (make_tempdir, exec_write): Changed format of messages. - - * keyserver.c (print_keyinfo): Release USERID in on error. - (keyserver_work) [!DISABLE_KEYSERVER_HELPERS]: Exclude the unused - code. - -2002-09-09 Werner Koch <wk@gnupg.org> - - * parse-packet.c (make_attribute_uidname): Add new ar MAX_NAMELEN - for sanity checks. Changed both callers. Limit the size of an %s. - - * options.skel: Comment lock-once out, so that this file does not - change anything when copied to a new home directory. - * openfile.c (try_make_homedir): Don't exit after copying the - option skeleton. - - * options.h: Don't use a comma when declaring variables over more - than one line. - - * mainproc.c (symkey_decrypt_sesskey): Check length of the session - key. - - * hkp.c (dehtmlize): Use ascii_tolower to protect against weird - locales. Cast the argument for isspace for the sake of broken - HP/UXes. - (parse_hkp_index): s/ascii_memcasecmp/ascii_strncasecmp/. - - * g10.c: Removed option --emulate-3des-s2k-bug. - - * passphrase.c (hash_passphrase): Was used here. - - * export.c (parse_export_options) - * keyserver.c (parse_keyserver_options) - * import.c (parse_import_options) - * g10.c (check_permissions): s/ascii_memcasecmp/ascii_strncasecmp/. - -2002-09-09 David Shaw <dshaw@jabberwocky.com> - - * g10.c (add_group): Use '=' to separate group name from group - members. Use a better error message for when no = is found. - - * hkp.c (hkp_export): Use CRLF in headers. - -2002-09-03 David Shaw <dshaw@jabberwocky.com> - - * mainproc.c (print_pkenc_list): Don't increment the error counter - when printing the list of keys a message was encrypted to. This - would make gpg give a non-zero exit code even for completely valid - messages if the message was encrypted to more than one key that - the user owned. - -2002-09-02 Werner Koch <wk@gnupg.org> - - * g10.c (main): Try to set a default character set. Print the - used one in verbosity level 3. - * gpgv.c (main): Try to set a default character set. - - * status.c, status.h (STATUS_IMPORT_OK): New. - * import.c (import_one,import_secret_one): Print new status. - -2002-08-30 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (build_pk_list): Add new status code to indicate an - untrusted user. This (or a disabled key) fail with "unavailable - pubkey" (G10ERR_UNU_PUBKEY). - - * pkclist.c (build_pk_list): Fail if any recipient keys are - unusable. - - * options.skel: The PGP LDAP keyserver is back. Use MIT keyserver - as a sample rather than cryptnet as cryptnet does not support - searching yet. - - * keyedit.c (show_key_with_all_names): Fix error message - (preferences are userid/selfsig and not key specific). - -2002-08-30 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_we_trust_pre): Changed the wording of a warning. - - * encode.c (encode_simple,encode_crypt): Use new style CTB for - compressssed packets when using MDC. We need to do this so that - concatenated messages are properly decrypted. Old style - compression assumes that it is the last packet; given that we - can't determine the length in advance, the uncompressor does not - know where to start. Actually we should use the new CTB always - but this would break PGP 2 compatibility. - - * parse-packet.c (parse): Special treatment for new style CTB - compressed packets. - - * build-packet.c (do_mdc): Removed. Was not used. - (do_encrypted_mdc): Count in the version number and the MDC packet. - -2002-08-28 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check_messages, do_check): Show keyid in error - messages. - - * keyserver.c (print_keyinfo): More readable key listings for - --search-keys responses. - -2002-08-26 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index, dehtmlize): Move HTML functionality into - new "dehtmlize" function. Remove HTML before trying to parse each - line from the keyserver. If the keyserver provides key type - information in the listing, use it. - -2002-08-23 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check, do_check_messages): Emit the usual sig - warnings even for cached sigs. This also serves to protect - against missing a sig expiring while cached. - - * getkey.c (merge_selfsigs_main): Don't check UID self-sigs twice. - -2002-08-22 David Shaw <dshaw@jabberwocky.com> - - * import.c (clean_subkeys, chk_self_sigs): Merge clean_subkeys - into chk_self_sigs. This improves efficiency as the same - signatures are not checked multiple times. Clarify when a subkey - is revoked (any revocation signature, even if it is dated before - the binding signature). - - * getkey.c (merge_selfsigs_subkey): Subkey revocation comments. - - * keylist.c (list_one): Stats are only for public key listings. - - * g10.c (main), options.skel: Default should be include-revoked - for keyserver operations. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * import.c (import_print_stats): Print new non_imported counter - which is currently not used because we terminate on errors. - -2002-08-20 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Document no-include-attributes for - keyserver-options. - - * keylist.c, keyedit.c, keyserver.c, sign.c: Some TODOs and - comments. - - * export.c (do_export_stream): Fix noop bug in exporting sensitive - revocation keys. - - * pkclist.c (do_edit_ownertrust): Comment out the option for - showing trust paths until it can be implemented. - -2002-08-19 Werner Koch <wk@gnupg.org> - - * getkey.c (get_user_id_native): Renamed to .. - (get_user_id_printable): this. Filter out all dangerous - characters. Checked all usages. - (get_user_id_string_native): Renamed to.. - (get_user_id_string_printable): this. Filter out all dangerous - characters. Checked all usages. - * keyedit.c (show_basic_key_info): New. - * keylist.c (print_fingerprint): New mode 3. - * import.c (import_one): Use new function to display the user ID. - -2002-08-16 Timo Schulz <ts@winpt.org> - - * g10.c (main): Enable opt.interactive. - - * import.c (import_one): Ask the user if the key shall be - imported when the interactive mode is used. Useful to extract - selected keys from a file. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * seckey-cert.c: Workaround to allow decryption of v3 keys created - with a bug in the mpi_get_secure_buffer. - -2002-08-14 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Properly handle really large keys - (5 digit key length) in HKP searches. - -2002-08-13 David Shaw <dshaw@jabberwocky.com> - - * encode.c (encode_simple): Fix problem with using compression - algo 2 and symmetric compressed files. - - * encode.c (encode_simple, encode_crypt): If we are not using a - MDC, compress even if a file is already compressed. This is to - help against the chosen ciphertext attack. - - * pkclist.c (select_algo_from_prefs): Fix requested algorithm bug - so the request succeeds even if the requested algorithm is not the - first found. - - * cipher.c (write_header), encode.c (use_mdc, encode_simple, - encode_crypt, encrypt_filter), g10.c (main): Be more eager to use - a MDC. We use a MDC if the keys directly support it, if the keys - list AES (any) or TWOFISH anywhere in the prefs, or if the cipher - chosen does not have a 64 bit blocksize. - -2002-08-08 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Some language tweaks, and remove the - load-extension section for random gatherers. - - * keyring.c (create_tmp_file, rename_tmp_file): Create tmp files - with user-only permissions, but restore the original permissions - if the user has something special set. - - * openfile.c (copy_options_file): Create new options file - (gpg.conf) with user-only permissions. - - * keydb.c (keydb_add_resource): Create new keyrings with user-only - permissions. - - * tdbio.c (tdbio_set_dbname): Create new trustdbs with user-only - permissions. - -2002-08-07 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (signature_check2): Sanity check that the md has a - context for the hash that the sig is expecting. This can happen - if a onepass sig header does not match the actual sig, and also if - the clearsign "Hash:" header is missing or does not match the - actual sig. - - * keyedit.c (menu_revsig): Properly show a uid is revoked without - restarting gpg. This is Debian bug 124219, though their supplied - patch will not do the right thing. - - * main.h, tdbio.c (tdbio_set_dbname), misc.c (removed - check_permissions), keydb.c (keydb_add_resource), g10.c (main, - check_permissions): Significant reworking of the permission check - mechanism. The new behavior is to check everything in the homedir - by checking the homedir itself. If the user wants to put - (possibly shared) keyrings outside the homedir, they are not - checked. The options file and any extension files are checked - wherever they are, as well as their enclosing directories. This - is Debian bug 147760. - -2002-08-06 Stefan Bellon <sbellon@sbellon.de> - - * g10.c (main): Use of EXTSEP_S in new gpg.conf string. - * openfile.c (copy_options_file): Ditto. - -2002-08-06 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), mainproc.c (proc_encrypted): - --ignore-mdc-error option to turn a MDC check error into a - warning. - - * encode.c (encode_crypt), g10.c (main), sign.c (sign_file, - clearsign_file): Use the same --pgpX warning string everywhere to - ease translations. - - * encode.c (write_pubkey_enc_from_list): Warn when using - --throw-keyid with --pgpX. Noted by Vedaal Nistar. - - * revoke.c (export_minimal_pk, gen_desig_revoke, gen_revoke): - Export a minimal pk along with the revocation cert when in --pgpX - mode so that PGP can import it. - -2002-08-06 Werner Koch <wk@gnupg.org> - - * options.skel: Changed comments. - - * g10.c (main): Try to use "gpg.conf" as default option file. - * openfile.c (copy_options_file): Changed name of created file. - -2002-08-02 Werner Koch <wk@gnupg.org> - - * Makefile.am (LDFLAGS): Removed DYNLINK_LDFLAGS. - -2002-07-30 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), mainproc.c (proc_encrypted): Return a - decryption failed error if a MDC does not verify. Warn if a MDC - is not present (can disable via --no-mdc-warning). - - * exec.c (exec_write), g10.c (main), keyserver.c - (keyserver_spawn): Use new DISABLE_KEYSERVER_PATH rather than - FIXED_EXEC_PATH. - -2002-07-28 David Shaw <dshaw@jabberwocky.com> - - * sig-check.c (do_check): Properly validate v4 sigs with no hashed - section at all. - -2002-07-25 Werner Koch <wk@gnupg.org> - - * delkey.c (do_delete_key): Always allow to delete a key in batch mode - when specified by fingerprint. Suggested by Enzo Michelangeli. - -2002-07-25 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_revsig): Change "revsig" to honor selected uids - so the user can revoke sigs from particular uids only. - - * keylist.c (list_keyblock_print): Don't display expired uids in - --list-keys unless -v and not --list-sigs (just like revoked - uids). - - * exec.c, export.c, import.c, keyedit.c, keyserver.c, misc.c: - "Warning" -> "WARNING" - -2002-07-24 David Shaw <dshaw@jabberwocky.com> - - * main.h, import.c (parse_import_options, fix_hkp_corruption, - import_one, delete_inv_parts), g10.c (main): New import-option - "repair-hkp-subkey-bug", which repairs as much as possible the HKP - mangling multiple subkeys bug. It is on by default for keyserver - receives, and off by default for regular --import. - - * main.h, import.c (import, import_one, delete_inv_parts), hkp.c - (hkp_ask_import), keyserver.c (keyserver_spawn): Use keyserver - import options when doing keyserver receives. - - * options.h, exec.h, exec.c (set_exec_path, exec_write), g10.c - (main), keyserver.c (keyserver_spawn): If the user does not use - "exec-path", completely replace $PATH with GNUPG_LIBEXECDIR before - calling the keyserver helper. If the user does use "exec-path", - append GNUPG_LIBEXECDIR after the specified path. - -2002-07-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (parse_import_options), export.c - (parse_export_options): Fix offset problem with reversed ("no-") - meanings. - - * import.c (delete_inv_parts): Discard subkey signatures (0x18 and - 0x28) if found in the userid section of the key. - - * sig-check.c (signature_check2): Signatures made by invalid - subkeys (bad/missing binding sig) are also invalid. - - * keylist.c (print_fingerprint): Show the primary as well as the - secondary key fingerprint in modes 1 & 2. - -2002-07-22 David Shaw <dshaw@jabberwocky.com> - - * options.h, main.h, g10.c (main), import.c - (parse_import_options, delete_inv_parts), keyserver.c - (parse_keyserver_options): add new --import-options option. The - only current flag is "allow-local-sigs". - - * g10.c (main): Don't disable MDC in pgp7 mode. - - * options.h, g10.c (main), keyserver.c (parse_keyserver_options): - Remove old keyserver-option include-attributes now that there is - an export-option for the same thing. - - * options.h, main.h, export.c (parse_export_options, - do_export_stream), g10.c (main): add new --export-options option. - Current flags are "include-non-rfc", "include-local-sigs", - "include-attributes", and "include-sensitive-revkeys". - - * options.h, hkp.c (hkp_export), keyserver.c - (parse_keyserver_options, keyserver_spawn): try passing unknown - keyserver options to export options, and if successful, use them - when doing a keyserver --send-key. - - * build-packet.c (build_sig_subpkt): We do not generate - SIGSUBPKT_PRIV_VERIFY_CACHE anymore. - - * revoke.c (gen_desig_revoke): Lots more comments about including - sensitive revkeys along with the revocation sig itself. - - * keyserver.c (parse_keyserver_options): Simpler implementation - that can skip one pass over the options. - -2002-07-18 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu, menu_addrevoker): Allow specifying - "sensitive" as an argument to an addrevoker command. This sets - the 0x40 sensitive revoker flag. - - * revoke.c (gen_desig_revoke): When generating a designated - revocation, include the direct key sig that contains the - designated revoker subpacket. This allows sensitive designated - revocation subpackets to be exported. Also indicate which - revokers are sensitive in the first place. - -2002-07-17 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names_colon): The 0x40 class bit in - a designated revoker means "sensitive", not "local". It's - exportable under the right circumstances. - - * main.h, options.h, export.c (do_export_stream), g10.c (main), - hkp.c (hkp_export), keyserver.c (keyserver_spawn: Add a flag to - skip attribute packets and their signatures while exporting. This - is to accomodate keyservers (pksd again) that choke on attributes. - Use keyserver-option "include-attributes" to control it. This - defaults to ON (i.e. don't skip). - -2002-07-09 David Shaw <dshaw@jabberwocky.com> - - * options.h, keyserver.c (parse_keyserver_uri, keyserver_spawn, - keyserver_work), hkp.c (hkp_ask_import, hkp_export, hkp_search): - Use a much more strict reading of RFC-2396 for the keyserver URIs. - Specifically, don't try and be smart about checking the value of - ":port" so long as it is all digits, and properly handle opaque - data (those scheme specific parts that do not start with "//"). - -2002-07-04 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (get_default_photo_command, show_photos): Honor - FIXED_PHOTO_VIEWER and DISABLE_PHOTO_VIEWER. - - * mainproc.c (check_sig_and_print): Use --show-photos to show - photos when verifying a sig made by a key with a photo. - - * keyserver.c (parse_keyserver_uri): Properly parse a URI with no - :port section and an empty file path, but with a terminating '/'. - (keyserver_work): Honor DISABLE_KEYSERVER_HELPERS. - - * hkp.c (hkp_ask_import): Display keyserver URI as a URI, but only - if verbose. - - * exec.c, g10.c: USE_EXEC_PATH -> FIXED_EXEC_PATH - -2002-07-03 David Shaw <dshaw@jabberwocky.com> - - * exec.h, exec.c (set_exec_path, exec_write), g10.c (main): If - USE_EXEC_PATH is defined at compile time, use it to lock the - exec-path and not allow the user to change it. - -2002-07-02 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyserver.c (keyserver_refresh): - Maintain and use the original keyserver URI for cosmetics rather - than trying to recreate it when needed. - - * mainproc.c (check_sig_and_print): Properly disregard expired - uids. Make sure that the first uid listed is a real uid and not - an attribute (attributes should only be listed in the "aka" - section). When there are no valid textual userids, try for an - invalid textual userid before using any attribute uid. - -2002-07-01 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Fix a few typos, clarify "group", and remove - sample photo viewers for Win32 since they are the defaults now. - - * parse-packet.c (make_attribute_uidname), keylist.c - (dump_attribs): Fix two typecast warnings. - - * packet.h, build-packet.c (build_attribute_subpkt), exec.c - (expand_args), mkdtemp.c (mkdtemp), photoid.c - (parse_image_header): Fix some signedness compiler warnings. - -2002-07-01 Werner Koch <wk@gnupg.org> - - * photoid.c (get_default_photo_command): Also use __MINGW32__ - instead of HAVE_DOSISH_SYSTEM. - - * encode.c (encode_symmetric): Do not use the new encryption code. - -2002-06-30 Werner Koch <wk@gnupg.org> - - * photoid.c: Use __MINGW32__ to include windows because - HAVE_DOSISH_SYSTEM is also set for OS/2 and plain DOS. Provide - constant missing in older mingw installations. - -2002-06-21 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Moved RISC OS specific stuff to util/riscos.c - and include/util.h. - - * gpgv.c [__riscos__]: Likewise. - -2002-06-20 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, pkclist.c (select_algo_from_prefs): Allow passing a - suggested algorithm which will be used if available. - - * encode.c (encode_crypt, encrypt_filter), sign.c (sign_file): Use - new select_algo_from_prefs feature to check if forcing an - algorithm would violate the recipient preferences. - - * photoid.c (get_default_photo_command, show_photos): Use - different default viewers on different platforms. Currently we - have Win 9x, Win NT (2k, xp), Mac OSX, RISC OS, and "everybody - else". These are #ifdefs as much as possible to avoid clutter. - - * g10.c (strusage, build_list), keyedit.c (show_prefs), main.h, - misc.c (compress_algo_to_string, check_compress_algo), pkclist.c - (algo_available), keygen.c (keygen_set_std_prefs): New - algo_to_string and check functions for compress algorithms. - -2002-06-20 Werner Koch <wk@gnupg.org> - - * misc.c (setsysinfo): Removed a #warning for Alpha's uniligedn - trap disabling - it is quite possible that this is a debug relict. - -2002-06-20 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Added image file system feature. - - * gpgv.c [__riscos__]: Added image file system feature. - - * photoid.c (show_photos) [__riscos__]: Set RISC OS filetype of - photo id according to MIME type. - -2002-06-19 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Don't leak memory when failing out of a - bad HKP keyserver. - - * g10.c (add_notation_data): Relax slightly the rules as to what - can go into a notation name - 2440 allows "@", for example. - -2002-06-17 David Shaw <dshaw@jabberwocky.com> - - * import.c (clean_subkeys, import_one): Only allow at most 1 - binding sig and at most 1 revocation sig on a subkey, as per - 2440:11.1. - - * hkp.c (parse_hkp_index, hkp_search): Error if the keyserver - returns an unparseable HKP response. - -2002-06-15 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names), keylist.c - (list_keyblock_print): Show "[expired]" before expired uids. - - * keyedit.c (show_key_with_all_names_colon), mainproc.c - (list_node), keylist.c (list_keyblock_colon): Show flag 'e' for - expired user ids. Use "uat" for user attribute packets instead of - "uid". Also use '<count> <length>' rather than the fake user id - string on attributes. - - * keygen.c (keygen_add_revkey): Remove unused code. - - * misc.c (check_permissions): Check directory permissions - properly - they are not special files. - - * pkclist.c (expand_id, expand_group, build_pk_list): When - expanding groups before building a pk list, inherit flags from the - original pre-expanded string. - - * pubkey-enc.c (is_algo_in_prefs): Don't use prefs from expired - uids. - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * free-packet.c (copy_signature): Properly copy a signature that - carries a revocation key on it. - - * pkclist.c (expand_id, expand_group, build_pk_list): Groups now - work properly when used in the "Enter the user ID" prompt. - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (show_key_with_all_names): Display warning if a user - tries to show prefs on a v3 key with a v3 selfsig. - - * kbnode.c (dump_kbnode): Show if a uid is expired. - - * import.c (merge_blocks, import_revoke_cert): Show user ID - receiving a revocation certificate. - - * free-packet.c (cmp_user_ids): Properly compare attribute ids. - - * pkclist.c (expand_groups): Maintain the strlist flags while - expanding. Members of an expansion inherit their flags from the - expansion key. - - * options.h, cipher.c (write_header), g10.c (main), keygen.c - (keygen_set_std_prefs): remove the personal_mdc flag. It no - longer serves a purpose now that the personal preference lists are - split into cipher/digest/zip. - -2002-06-14 Timo Schulz <ts@winpt.org> - - * skclist.c (is_insecure): Implemented. - -2002-06-12 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Properly handle PROGRAM responses - when they have a CRLF ending. Noted by Keith Ray. - - * keyserver.c (keyserver_spawn): Handle CRLF endings from - keyserver helpers. Also don't leak the last line worth of memory - from the keyserver response. - - * main.h, misc.c (deprecated_warning): New function to warn about - deprecated options and commands. - - * g10.c (main), keyserver-internal.h, keyserver.c - (parse_keyserver_uri): Use new deprecated function to warn about - honor-http-proxy, auto-key-retrieve, and x-broken-hkp. - -2002-06-11 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: link gpg with NETLIBS for the built-in HKP access. - -2002-06-10 David Shaw <dshaw@jabberwocky.com> - - * options.h, keyserver.c (keyserver_opts), g10.c (main): New - keyserver option "include-subkeys". This feature already existed, - but now can be turned off. It defaults to on. - - * options.h, keyserver.c (parse_keyserver_options, - keyserver_spawn): There are now enough options to justify making a - structure for the keyserver options rather than a page of - if-then-else-if-then-etc. - - * getkey.c (merge_keys_and_selfsig, merge_selfsigs_main): Fix bug - in calculating key expiration dates. - -2002-06-09 David Shaw <dshaw@jabberwocky.com> - - * keydb.h, getkey.c (get_user_id_native), import.c (import_one): - Display user ID while importing a key. Note this applies to both - --import and keyserver --recv-keys. - - * exec.c (exec_finish): Log unnatural exit (core dump, killed - manually, etc) for fork/exec/pipe child processes. - -2002-06-08 Timo Schulz <ts@winpt.org> - - * encode.c (encode_symmetric): Disable the compat flag - when the expert mode is enabled. - -2002-06-07 David Shaw <dshaw@jabberwocky.com> - - * options.skel, options.h, main.h, keydb.h, pkclist.c - (build_pk_list, expand_groups), g10.c (main, add_group): Add new - "group" command to allow one name to expand into multiple keys. - For simplicity, and to avoid potential loops, we only expand once - - you can't make an alias that points to an alias. - - * main.h, g10.c (main), keygen.c (build_personal_digest_list): - Simplify the default digest list - there is really no need for the - other hashes since they will never be used after SHA-1 in the - list. - - * options.skel, options.h, g10.c (main), hkp.c (hkp_ask_import, - hkp_export, hkp_search), keyserver.c (parse_keyserver_options, - parse_keyserver_uri, keyserver_work, keyserver_refresh): Make the - "x-broken-hkp" keyserver scheme into keyserver-option - "broken-http-proxy". Move honor_http_proxy into - keyserver_options. Canonicalize the three variations of "hkp", - "x-hkp", and "x-broken-hkp" into "hkp". - -2002-06-07 Stefan Bellon <sbellon@sbellon.de> - - * g10.c [__riscos__]: Added --attribute-file to do the same as - --attribute-fd, but with a filename not a fd as argument. - Added magic symbol for RISC OS to use different memory management. - - * gpgv.c [__riscos__]: Added magic symbol for RISC OS to use - different memory management. - -2002-06-06 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), keygen.c (build_personal_digest_list): Put - in a default digest preference list consisting of SHA-1, followed - by every other installed digest except MD5. Note this is the same - as having no digest preference at all except for SHA-1 being - favored. - - * options.h, g10.c (main), keygen.c (keygen_set_std_prefs), - pkclist.c (select_algo_from_prefs): Split - --personal-preference-list into three: - --personal-{cipher|digest|compress}-preferences. This allows a - user to set one without affecting another (i.e. setting only a - digest pref doesn't imply an empty cipher pref). - - * exec.c (exec_read): This is a safer way of guessing the return - value of system(). Noted by Stefan Bellon. - -2002-06-05 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Be more robust with keyservers - returning very unparseable responses. - - * exec.c (exec_read): Catch and display an error when the remote - process exits unnaturally (i.e. segfault) so the user knows what - happened. Also fix exec_write stub which has a different number - of arguments now. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * encode.c (encode_simple): Ignore the new mode for RFC1991. - * mainproc.c (symkey_decrypt_sesskey): Better check for weird - keysizes. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * encode.c (encode_sesskey): New. - (encode_simple): Use it here. But by default we use the compat - mode which supress to generate encrypted session keys. - -2002-06-05 Timo Schulz <ts@winpt.org> - - * mainproc.c (symkey_decrypt_sesskey): New. - (proc_symkey_enc): Support for encrypted session keys. - -2002-06-04 David Shaw <dshaw@jabberwocky.com> - - * sign.c (hash_for, sign_file): When encrypting and signing at the - same time, consult the various hash prefs to pick a hash algorithm - to use. Pass in a 160-bit hint if any of the signing keys are - DSA. - - * keydb.h, pkclist.c (select_algo_from_prefs, algo_available): - Pass a "hints" opaque pointer in to let the caller give hints as - to what algorithms would be acceptable. The only current hint is - for PREFTYPE_HASH to require a 160-bit hash for DSA. Change all - callers in encode.c (encode_crypt, encrypt_filter) and sign.c - (sign_file). If we settle on MD5 as the best algorithm based - solely on recepient keys and SHA1 is also a possibility, use SHA1 - unless the user intentionally chose MD5. This is as per 2440:13. - - * exec.c (make_tempdir): Fix duplicated filename problem. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * packet.h, parse-packet.c (enum_sig_subpkt): Report back from - enum_sig_subpkt when a subpacket is critical and change all - callers in keylist.c (show_policy_url, show_notation), mainproc.c - (print_notation_data), and pkclist.c (do_show_revocation_reason). - - * keylist.c (show_policy_url, show_notation): Display if the - policy or notation is critical. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), keylist.c (dump_attribs, set_attrib_fd, - list_keyblock_print, list_keyblock_colon), status.h, status.c - (get_status_string): New --attribute-fd feature to dump the - contents of attribute subpackets for frontends. If --status-fd is - also used, then a new status tag ATTRIBUTE is provided for each - subpacket. - - * packet.h, getkey.c (fixup_uidnode, merge_selfsigs_main, - merge_selfsigs_subkey), parse-packet.c (setup_user_id): Keep track - of the expiration time of a user ID, and while we're at it, use - the expired flag from the selfsig rather than reparsing the - SIG_EXPIRE subpacket. - - * photoid.c (generate_photo_id): When adding a new photo ID, - showing the photo for confirmation is not safe when noninteractive - since the "user" may not be able to dismiss a viewer window. - Noted by Timo Schulz. - -2002-06-03 David Shaw <dshaw@jabberwocky.com> - - * options.skel: Sample photo viewers for Win32. - - * misc.c (pct_expando): Use the seckey for %k/%K if the pubkey is - not available. - - * photoid.h, photoid.c (show_photos): Include the seckey in case a - user tries to view a photo on a secret key, and change all callers - in keyedit.c (menu_showphoto), keylist.c (list_keyblock_print), - and photoid.c (generate_photo_id). - -2002-06-02 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (show_photos): Work properly when not called with a - public key. - -2002-05-31 David Shaw <dshaw@jabberwocky.com> - - * sign.c (mk_notation_and_policy): Free unneeded buffer. - - * hkp.c (parse_hkp_index): Properly handle the '&' character - (i.e. "&amp;") in HKP responses. - - * getkey.c (merge_selfsigs_main): Fix reversed expiration time - check with self-sigs. - - * keyedit.c (sign_uids): When making a new self-sig on a v3 key, - make a v3 self-sig unless it is currently a v3 self-sig being - promoted to v4. - -2002-05-31 Timo Schulz <ts@winpt.org> - - * pkclist.c (do_show_revocation_reason): Don't use capital - letters for non-interactive output. - (show_revocation_reason): Now it is global. - * pubkey-enc.c (get_it): Show if the key has been revoked. - -2002-05-30 David Shaw <dshaw@jabberwocky.com> - - * sign.c (write_signature_packets, sign_file, clearsign_file, - sign_symencrypt_file): Make a v4 signature if a policy URL or - notation is set, unless v3 sigs are forced via rfc1991 or - force-v3-sigs. Also remove some doubled code and clarify an error - message (we don't sign in PGP2 mode - just detach-sign). - - * parse-packet.c (parse_one_sig_subpkt): Add KS_FLAGS to the "any - size" section. - -2002-05-29 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs, add_feature_mdc): Use "mdc" and - "no-mdc" in the prefs string to allow switching on and off the MDC - feature. This is needed to properly export a key from GnuPG for - use on PGP which does not support MDC - without this, MDC-capable - implementations will still try and generate MDCs which will break - PGP. - - * keygen.c (keygen_get_std_prefs): Show "[mdc]" in prefs string if - it is enabled. - - * options.h, g10.c (main), cipher.c (write_header), keygen.c - (keygen_set_std_prefs): For consistency, allow the user to specify - mdc/no-mdc in the --personal-preference-list. If disabled, it - acts just like --disable-mdc. - -2002-05-29 David Shaw <dshaw@jabberwocky.com> - - * options.h, exec.c: Add some debugging info, using the 1024 debug - flag. - - * exec.c (win_system): New system()-like function for win32 that - does not return until the child process terminates. Of course, - this doesn't help if the process itself exits before it is - finished. - -2002-05-29 Werner Koch <wk@gnupg.org> - - * encode.c (encode_simple): Intialize PKT when --no-literal is used. - - * keyedit.c (show_key_with_all_names_colon): Renamed the record - for revocation keys to "rvk". - -2002-05-27 Werner Koch <wk@gnupg.org> - - * keyedit.c (show_key_with_all_names_colon): New. - (show_key_with_all_names): Divert to new function when required. - Sanitize printing of revoker name. - -2002-05-27 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Handle setting sig flags for - certain subpacket types (notation, policy url, exportable, - revocable). keyedit.c (sign_mk_attrib): Flags no longer need to - be set here. - - * packet.h, parse-packet.c (parse_one_sig_subpkt), build-packet.c - (build_sig_subpkt): Call parse_one_sig_subpkt to sanity check - buffer lengths before building a sig subpacket. - -2002-05-26 David Shaw <dshaw@jabberwocky.com> - - * sign.c (mk_notation_and_policy): Include secret key to enable %s - expandos, and pass notations through pct_expando as well. - - * main.h, misc.c (pct_expando): Add %s and %S expandos for - signer's keyid. - -2002-05-25 David Shaw <dshaw@jabberwocky.com> - - * g10.c (strusage, build_list): Add compress algorithms to - --version list. Show algorithm numbers when --verbose --version - is done. - -2002-05-22 David Shaw <dshaw@jabberwocky.com> - - * options.h, main.h, keygen.c (keygen_set_set_prefs, - keygen_get_std_prefs, keygen_upd_std_prefs), keyedit.c - (keyedit_menu), g10.c (main), pkclist.c (select_algo_from_prefs): - Add --personal-preference-list which allows the user to factor in - their own preferred algorithms when the preference lists are - consulted. Obviously, this does not let the user violate a - recepient's preferences (and the RFC) - this only influences the - ranking of the agreed-on (and available) algorithms from the - recepients. Suggested by David Hollenberg. - - * options.h, keygen.c (keygen_set_std_prefs), g10.c (main): Rename - --preference-list to --default-preference-list (as that is what it - really is), and make it a true default in that if the user selects - "default" they get this list and not the compiled-in list. - -2002-05-22 Werner Koch <wk@gnupg.org> - - * g10.c (main): Add missing LF in a info printout and made it - translatable. Noted by Michael Tokarev. - -2002-05-21 Werner Koch <wk@gnupg.org> - - * g10.c (main): Removed the undef of USE_SHM_COPROCESSING which - was erroneously introduced on 2002-01-09. - - * signal.c (got_fatal_signal): Don't write the Nul to stderr. - Reported by David Hollenberg. - -2002-05-18 David Shaw <dshaw@jabberwocky.com> - - * main.h, g10.c (main), revoke.c (gen_desig_revoke): Generate a - designated revocation via --desig-revoke - - * keyedit.c (keyedit_menu, menu_addrevoker): New "addrevoker" - command to add a designated revoker to a key. - -2002-05-17 David Shaw <dshaw@jabberwocky.com> - - * gpgv.c: Add stub for get_ownertrust(). - - * g10.c (main): --allow-freeform-uid should be implied by - OpenPGP. Add --no-allow-freeform-uid. - - * keyedit.c (sign_uids): Issue a warning when signing a - non-selfsigned uid. - - * getkey.c (merge_selfsigs_main): If a key has no selfsigs, and - allow-non-selfsigned-uid is not set, still try and make the key - valid by checking all uids for a signature from an ultimately - trusted key. - -2002-05-16 David Shaw <dshaw@jabberwocky.com> - - * main.h, keygen.c (keygen_add_revkey): Add revocation key - subpackets to a signature (callable by - make_keysig_packet). (write_direct_sig): Write a 1F direct key - signature. (parse_revocation_key): Parse a string in - algo:fpr:sensitive format into a revocation - key. (get_parameter_revkey, do_generate_keypair): Call above - functions when prompted from a batch key generation file. - - * build-packet.c (build_sig_subpkt): Allow multiple revocation key - subpackets in a single sig. - - * keydb.h, getkey.c (get_seckey_byfprint): Same as - get_pubkey_byfprint, except for secret keys. We only know the - fingerprint of a revocation key, so this is needed to retrieve the - secret key needed to issue a revokation. - - * packet.h, parse-packet.c (parse_signature, parse_revkeys): Split - revkey parsing off into a new function that can be used to reparse - after manipulating the revkey list. - - * sign.c (make_keysig_packet): Ability to make 1F direct key - signatures. - -2002-05-15 David Shaw <dshaw@jabberwocky.com> - - * options.skel: keyserver.pgp.com is gone, so list pgp.surfnet.nl - as a sample LDAP server instead. - - * getkey.c (merge_selfsigs_main): Properly handle multiple - revocation keys in a single packet. Properly handle revocation - keys that are in out-of-order packets. Remove duplicates in - revocation key list. - -2002-05-14 Timo Schulz <ts@winpt.org> - - * exec.c (make_tempdir) [MINGW32]: Added missing '\'. - -2002-05-14 Stefan Bellon <sbellon@sbellon.de> - - * exec.c (make_tempdir): Make use of EXTSEP_S instead of hardcoded - dot as extension separator. - -2002-05-13 David Shaw <dshaw@jabberwocky.com> - - * photoid.c (show_photos): Use the long keyid as the filename for - the photo. Use the short keyid as the filename on 8.3 systems. - - * exec.h, exec.c (make_tempdir, exec_write, exec_finish): Allow - caller to specify filename. This should make things easier on - windows and macs where the file extension is required, but a whole - filename is even better. - - * keyedit.c (show_key_with_all_names, show_prefs): Show proper - prefs for a v4 key uid with no selfsig at all. - - * misc.c (check_permissions): Don't check permissions on - non-normal files (pipes, character devices, etc.) - -2002-05-11 Werner Koch <wk@gnupg.org> - - * mainproc.c (proc_symkey_enc): Avoid segv in case the parser - encountered an invalid packet. - - * keyserver.c (keyserver_export): Get confirmation before sending - all keys. - -2002-05-10 Stefan Bellon <sbellon@sbellon.de> - - * g10.c, hkp.c, keyedit.c, keyserver.c: Replaced all occurrances - of strcasecmp with ascii_strcasecmp and all occurrances of - strncasecmp with ascii_memcasecmp. - -2002-05-10 David Shaw <dshaw@jabberwocky.com> - - * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Show - assumed prefs for hash and compression as well as the cipher pref. - Show assumed prefs if there are no prefs at all on a v4 - self-signed key. - - * options.h, g10.c (main), sign.c (make_keysig_packet): New - --cert-digest-algo function to override the default key signing - hash algorithm. - -2002-05-09 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (merge_selfsigs_main): Make sure the revocation key - list starts clean as this function may be called more than once - (e.g. from functions in --edit). - - * g10.c, encode.c (encode_crypt), sign.c (sign_file, - sign_symencrypt_file): Make --compress-algo work like the - documentation says. It should be like --cipher-algo and - --digest-algo in that it can override the preferences calculation - and impose the setting the user wants. No --compress-algo setting - allows the usual preferences calculation to take place. - - * main.h, compress.c (compress_filter): use new - DEFAULT_COMPRESS_ALGO define, and add a sanity check for compress - algo value. - -2002-05-08 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (select_algo_from_prefs): There is an assumed - compression preference for uncompressed data. - -2002-05-07 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), getkey.c (finish_lookup), pkclist.c - (algo_available): --pgp7, identical to --pgp6 except that it - permits a few algorithms that PGP 7 added: AES128, AES192, AES256, - and TWOFISH. Any more of these --pgpX flags, and it'll be time to - start looking at a generic --emulate-pgp X option. - - * export.c (do_export_stream): Warn the user when exporting a - secret key if it or any of its secret subkeys are protected with - SHA1 while simple_sk_checksum is set. - - * parse-packet.c (parse_key): Show when the SHA1 protection is - used in --list-packets. - - * options.h, build-packet.c (do_comment), g10.c (main): Rename - --no-comment as --sk-comments/--no-sk-comments (--no-comment still - works) and make the default be --no-sk-comments. - -2002-05-07 Werner Koch <wk@gnupg.org> - - * keygen.c (get_parameter_algo): Never allow generation of the - deprecated RSA-E or RSA-S flavors of PGP RSA. - (ask_algo): Allow generation of RSA sign and encrypt in expert - mode. Don't allow ElGamal S+E unless in expert mode. - * helptext.c: Added entry keygen.algo.rsa_se. - -2002-05-07 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): If --expert is set, allow re-signing a - uid to promote a v3 self-sig to a v4 one. This essentially - deletes the old v3 self-sig and replaces it with a v4 one. - - * packet.h, parse-packet.c (parse_key), getkey.c - (merge_keys_and_selfsig, merge_selfsigs_main): a v3 key with a v4 - self-sig must never let the v4 self-sig express a key expiration - time that extends beyond the original v3 expiration time. - -2002-05-06 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): When making a self-signature via "sign" - don't ask about sig level or expiration, and include the usual - preferences and such for v4 self-sigs. (menu_set_preferences): - Convert uids from UTF8 to native before printing. - - * keyedit.c (sign_uids): Convert uids from UTF8 to native before - printing. (menu_set_primary_uid): Show error if the user tries to - make a uid with a v3 self-sig primary. - -2002-05-05 David Shaw <dshaw@jabberwocky.com> - - * import.c (import_one): When merging with a key we already have, - don't let a key conflict (same keyid but different key) stop the - import: just skip the bad key and continue. - - * exec.c (make_tempdir): Under Win32, don't try environment - variables for temp directories - GetTempDir tries environment - variables internally, and it's better not to second-guess it in - case MS adds some sort of temp dir handling to Windows at some - point. - -2002-05-05 Timo Schulz <ts@winpt.org> - - * mainproc.c (proc_symkey_enc): Don't ask for a passphrase - in the list only mode. - -2002-05-05 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_refresh): --refresh-keys implies - --merge-only so as not to import keys with keyids that match the - ones being refreshed. Noted by Florian Weimer. - -2002-05-04 Stefan Bellon <sbellon@sbellon.de> - - * free-packet.c (copy_public_key): Don't call m_alloc(0), therefore - added consistency check for revkey and numrefkeys. - - * getkey.c (check_revocation_keys): Added consistency check for - revkey and numrefkeys. - - * keyedit.c (show_key_with_all_names): Likewise. - -2002-05-03 David Shaw <dshaw@jabberwocky.com> - - * photoid.c: Provide default image viewer for Win32. - - * misc.c (pct_expando): %t means extension, not name ("jpg", not - "jpeg"). - - * keyserver.c (keyserver_spawn), photoid.c (show_photos), exec.h, - exec.c: Allow the caller to determine the temp file extension when - starting an exec_write and change all callers. - - * keyedit.c (sign_uids): Nonrevocable key signatures cause an - automatic promotion to v4. - - * exec.c: Provide stubs for exec_ functions when NO_EXEC is - defined. - -2002-05-02 David Shaw <dshaw@jabberwocky.com> - - * photoid.h, photoid.c (parse_image_header, image_type_to_string): - Useful functions to return data about an image. - - * packet.h, parse-packet.c (make_attribute_uidname, - parse_attribute_subpkts, parse_attribute), photoid.h, photoid.c - (show_photos): Handle multiple images in a single attribute - packet. - - * main.h, misc.c (pct_expando), sign.c (mk_notation_and_policy), - photoid.c (show_photos): Simpler expando code that does not - require using compile-time string sizes. Call - image_type_to_string to get image strings (i.e. "jpg", - "image/jpeg"). Change all callers. - - * keyedit.c (menu_showphoto), keylist.c (list_keyblock_print): - Allow viewing multiple images within a single attribute packet. - - * gpgv.c: Various stubs for link happiness. - -2002-05-02 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt), keyedit.c (sign_uids), - options.h, sign.c (mk_notation_and_policy), g10.c (main, - add_notation_data, add_policy_url (new), check_policy_url - (removed)): Allow multiple policy URLs on a given signature. - Split "--notation-data" into "--cert-notation" and - "--sig-notation" so the user can set different policies for key - and data signing. For backwards compatibility, "--notation-data" - sets both, as before. - -2002-05-02 Werner Koch <wk@gnupg.org> - - * options.skel: Removed the comment on trusted-keys because this - option is now deprecated. - -2002-05-01 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_adduid): 2440bis04 says that multiple attribute - packets on a given key are legal. - - * keyserver.c (keyserver_refresh): the fake v3 keyid hack applies - to "mailto" URLs as well since they are also served by pksd. - -2002-04-29 Werner Koch <wk@gnupg.org> - - Added a copyright year for files changed this year. - -2002-04-25 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New options --display, --ttyname, --ttytype, - --lc-ctype, --lc-messages to be used with future versions of the - gpg-agent. - * passphrase.c (agent_send_option,agent_send_all_options): New. - (agent_open): Send options to the agent. - - * trustdb.c (update_ownertrust, clear_ownertrust): Do an explicit - do_sync because revalidation_mark does it only if when the - timestamp actually changes. - -2002-04-23 David Shaw <dshaw@jabberwocky.com> - - * main.h, keygen.c (do_generate_keypair), keylist.c - (print_signature_stats, list_all, list_one, list_keyblock, - list_keyblock_print, list_keyblock_colon): After generating a new - key, show the key information (name, keyid, fingerprint, etc.) - Also do not print uncheckable signatures (missing key..) in - --check-sigs. Print statistics (N missing keys, etc.) after - --check-sigs. - - * keyedit.c (sign_uids): When signing a key with an expiration - date on it, the "Do you want your signature to expire at the same - time?" question should default to YES. - -2002-04-22 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_plaintext), packet.h, plaintext.c - (handle_plaintext): Fix bug in handling literal packets with - zero-length data (no data was being confused with partial body - length). - - * misc.c (pct_expando), options.skel: %t means extension ("jpg"). - %T means MIME type ("image/jpeg"). - - * import.c (import_one): Only trigger trust update if the keyring - is actually changed. - - * export.c (do_export_stream): Missing a m_free. - -2002-04-22 Stefan Bellon <sbellon@sbellon.de> - - * keyid.c (expirestr_from_sk, expirestr_from_sig): Added _() to - string constant. - - * exec.c (make_tempdir) [__riscos__]: Better placement of - temporary file. - -2002-04-20 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (generate_subkeypair): 2440bis04 adds that creating - subkeys on v3 keys is a MUST NOT. - - * getkey.c (finish_lookup): The --pgp6 "use the primary key" - behavior should only apply while data signing and not encryption. - Noted by Roger Sondermann. - -2002-04-19 Werner Koch <wk@gnupg.org> - - * keygen.c (keygen_set_std_prefs): Put back 3DES because the RFC - says it is good form to do so. - -2002-04-19 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_deluid): Only cause a trust update if we delete - a non-revoked user id. - - * hkp.c (hkp_ask_import), keyserver.c (parse_keyserver_options, - keyserver_spawn), options.h: Remove fast-import keyserver option - (no longer meaningful). - - * g10.c (main), keyedit.c (sign_uids), options.h: Change - --default-check-level to --default-cert-check-level as it makes - clear what it operates on. - - * g10.c (main): --pgp6 also implies --no-ask-sig-expire. - - * delkey.c (do_delete_key): Comment. - - * keyedit.c (sign_uids, keyedit_menu, menu_deluid, menu_delsig, - menu_expire, menu_revsig, menu_revkey): Only force a trustdb check - if we did something that changes it. - - * g10.c: add "--auto-check-trustdb" to override a - "--no-auto-check-trustdb" - -2002-04-19 Werner Koch <wk@gnupg.org> - - * tdbio.c (tdbio_write_nextcheck): Return a status whether the - stamp was actually changed. - * trustdb.c (revalidation_mark): Sync the changes. Removed the - sync operation done by its callers. - (get_validity): Add logic for maintaining a pending_check flag. - (clear_ownertrust): New. - - * keyedit.c (sign_uids): Don't call revalidation_mark depending on - primary_pk. - (keyedit_menu): Call revalidation_mark after "trust". - (show_key_with_all_names): Print a warning on the wrong listed key - validity. - - * delkey.c (do_delete_key): Clear the owenertrust information when - deleting a public key. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * seskey.c (encode_md_value): Print an error message if a wrong - digest algorithm is used with DSA. Changed all callers to cope - with a NULL return. Problem noted by Imad R. Faiad. - -2002-04-18 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (mark_usable_uid_certs): Properly handle nonrevocable - signatures that can expire. In short, the only thing that can - override an unexpired nonrevocable signature is another unexpired - nonrevocable signature. - - * getkey.c (finish_lookup): Always use primary signing key for - signatures when --pgp6 is on since pgp6 and 7 do not understand - signatures made by signing subkeys. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * trustdb.c (validate_keys): Never schedule a nextcheck into the - past. - (validate_key_list): New arg curtime use it to set next_expire. - (validate_one_keyblock): Take the current time from the caller. - (clear_validity, reset_unconnected_keys): New. - (validate_keys): Reset all unconnected keys. - - * getkey.c (premerge_public_with_secret): Fixed 0x12345678! syntax - for use with secret keys. - (lookup): Advance the searchmode after a search FIRST. - - * seckey-cert.c (do_check): Always calculate the old checksum for - use after unprotection. - - * g10.c, options.skel: New option --no-escape-from. Made - --escape-from and --force-v3-sigs the default and removed them - from the options skeleton. - -2002-04-16 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_key): Support a SHA1 checksum as per - draft-rfc2440-bis04. - * packet.h (PKT_secret_key): Add field sha1chk. - * seckey-cert.c (do_check): Check the SHA1 checksum - (protect_secret_key): And create it. - * build-packet.c (do_secret_key): Mark it as sha-1 protected. - * g10.c, options.h: New option --simple-sk-checksum. - -2002-04-13 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_signature): Minor fix - signatures should - expire at their expiration time and not one second later. - - * keygen.c (proc_parameter_file): Allow specifying preferences - string (i.e. "s5 s2 z1 z2", etc) in a batchmode key generation - file. - - * keyedit.c (keyedit_menu): Print standard error message when - signing a revoked key (no new translation). - - * getkey.c (merge_selfsigs): Get the default set of key prefs from - the real (not attribute) primary uid. - -2002-04-12 David Shaw <dshaw@jabberwocky.com> - - * pkclist.c (build_pk_list): Fix bug that allowed a key to be - selected twice in batch mode if one instance was the default - recipient and the other was an encrypt-to. Noted by Stefan - Bellon. - - * parse-packet.c (dump_sig_subpkt): Show data in trust and regexp - sig subpackets. - - * keyedit.c (keyedit_menu): Use new function real_uids_left to - prevent deleting the last real (i.e. non-attribute) uid. Again, - according to the attribute draft. (menu_showphoto): Make another - string translatable. - -2002-04-11 David Shaw <dshaw@jabberwocky.com> - - * build-packet.c (build_sig_subpkt): Delete subpackets from both - hashed and unhashed area on update. (find_subpkt): No longer - needed. - - * keyedit.c (sign_uids): With --pgp2 on, refuse to sign a v3 key - with a v4 signature. As usual, --expert overrides. Try to tweak - some strings to a closer match so they can all be translated in - one place. Use different helptext keys to allow different help - text for different questions. - - * keygen.c (keygen_upd_std_prefs): Remove preferences from both - hashed and unhashed areas if they are not going to be used. - -2002-04-10 David Shaw <dshaw@jabberwocky.com> - - * misc.c (pct_expando), options.skel: Use %t to indicate type of a - photo ID (in this version, it's always "jpeg"). Also tweak string - expansion loop to minimize reallocs. - - * mainproc.c (do_check_sig): Variable type fix. - - * keyedit.c (menu_set_primary_uid): Differentiate between true - user IDs and attribute user IDs when making one of them primary. - That is, if we are making a user ID primary, we alter user IDs. - If we are making an attribute packet primary, we alter attribute - packets. This matches the language in the latest attribute packet - draft. - - * keyedit.c (sign_uids): No need for the empty string hack. - - * getkey.c (fixup_uidnode): Only accept preferences from the - hashed segment of the self-sig. - -2002-04-10 Werner Koch <wk@gnupg.org> - - * tdbio.c (migrate_from_v2): Fixed the offset to read the old - ownertrust value and only add entries to the table if we really - have a value. - -2002-04-08 David Shaw <dshaw@jabberwocky.com> - - * status.h, status.c (get_status_string): Add KEYEXPIRED, EXPSIG, - and EXPKEYSIG. Add "deprecated-use-keyexpired-instead" to - SIGEXPIRED. - - * sig-check.c (do_check): Start transition from SIGEXPIRED to - KEYEXPIRED, since the actual event is signature verification by an - expired key and not an expired signature. (do_signature_check, - packet.h): Rename as signature_check2, make public, and change all - callers. - - * mainproc.c (check_sig_and_print, do_check_sig): Use status - EXPSIG for an expired, but good, signature. Add the expiration - time (or 0) to the VALIDSIG status line. Use status KEYEXPSIG for - a good signature from an expired key. - - * g10.c (main): remove checks for no arguments now that argparse - does it. - -2002-04-06 Werner Koch <wk@gnupg.org> - - * keyring.c (keyring_get_keyblock): Disable the keylist mode here. - - * encode.c (encode_simple, encode_crypt): Only test on compressed - files if a compress level was not explicity set. - - * keygen.c (keygen_set_std_prefs): Removed Blowfish and Twofish - from the list of default preferences, swapped the preferences of - RMD160 and SHA1. Don't include a preference to 3DES unless the - IDEA kludge gets used. - - * free-packet.c (free_packet): call free_encrypted also for - PKT_ENCRYPTED_MDC. - - * compress.c (release_context): New. - (handle_compressed): Allocate the context and setup a closure to - release the context. This is required because there is no - guarabntee that the filter gets popped from the chain at the end - of the function. Problem noted by Timo and probably also the - cause for a couple of other reports. - (compress_filter): Use the release function if set. - - * tdbio.c [__CYGWIN32__]: Don't rename ftruncate. Noted by - Disastry. - - * parse-packet.c (parse_signature): Put parens around a bit test. - - * exec.c (make_tempdir): Double backslash for TMP directory - creation under Windows. Better strlen the DIRSEP_S constants for - allocation measurements. - - * decrypt.c (decrypt_messages): Release the passphrase aquired - by get_last_passphrase. - -2002-04-02 Werner Koch <wk@gnupg.org> - - * Makefile.am (EXTRA_DIST): Removed OPTIONS an pubring.asc - they - are no longer of any use. - -2002-04-03 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (parse_keyserver_options): fix auto-key-retrieve to - actually work as a keyserver-option (noted by Roger Sondermann). - - * keylist.c (reorder_keyblock): do not reorder the primary - attribute packet - the first user ID must be a genuine one. - -2002-03-31 David Shaw <dshaw@jabberwocky.com> - - * keylist.c (list_keyblock_colon): Fix ownertrust display with - --with-colons. - - * keygen.c (generate_user_id), photoid.c (generate_photo_id): - Properly initialize the user ID refcount. A few more "y/n" -> - "y/N" in photoid.c. - - * keyedit.c (ask_revoke_sig): Warn the user if they are about to - revoke an expired sig (not a problem, but they should know). Also - tweak a few prompts to change "y/n" to "y/N", which is how most - other prompts are written. - - * keyserver.c (keyserver_search_prompt): Control-d escapes the - keyserver search prompt. - - * pkclist.c (show_revocation_reason & callers): If a subkey is - considered revoked solely because the parent key is revoked, print - the revocation reason from the parent key. - - * trustdb.c (get_validity): Allow revocation/expiration to apply - to a uid/key with no entry in the trustdb. - -2002-03-29 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (printunquoted): unquote backslashes from keyserver - searches - - * hkp.c (write_quoted): quote backslashes from keyserver searches - -2002-03-26 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_keysize): Removed the warning for key sizes > 1536. - -2002-03-25 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Use 2 strings and not a %s so that - translations can be done the right way. - * helptext.c: Fixed small typo. - -2002-03-23 David Shaw <dshaw@jabberwocky.com> - - * import.c (append_uid, merge_sigs): it is okay to import - completely non-signed uids now (with --allow-non-selfsigned-uid). - - * getkey.c (get_primary_uid, merge_selfsigs_main): do not choose - an attribute packet (i.e. photo) as primary uid. This prevents - oddities like "Good signature from [image of size 2671]". This is - still not perfect (one can still select an attribute packet as - primary in --edit), but is closer to the way the draft is going. - - * g10.c (build_list): algorithms should include 110. - - * g10.c (main): --pgp2 implies --no-ask-sig-expire and - --no-ask-cert-expire as those would cause a v4 sig/cert. - - * armor.c (is_armor_header): be more lenient in what constitutes a - valid armor header (i.e. -----BEGIN blah blah-----) as some - Windows programs seem to add spaces at the end. --openpgp makes - it strict again. - -2002-03-18 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): Properly handle a "no - keys found" case from the internal HKP code (external HKP is ok). - Also, make a COUNT -1 (i.e. streamed) keyserver response a little - more efficient. - - * g10.c (main): Add --no-allow-non-selfsigned-uid - -2002-03-17 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): --openpgp implies --allow-non-selfsigned-uid. - - * getkey.c (merge_selfsigs_main): If none of the uids are primary - (because none are valid) then pick the first to be primary (but - still invalid). This is for cosmetics in case some display needs - to print a user ID from a non-selfsigned key. Also use - --allow-non-selfsigned-uid to make such a key valid and not - --always-trust. The key is *not* automatically trusted via - --allow-non-selfsigned-uid. - - * mainproc.c (check_sig_and_print): Make sure non-selfsigned uids - print [uncertain] on verification even though one is primary now. - - * getkey.c (merge_selfsigs): If the main key is not valid, then - neither are the subkeys. - - * import.c (import_one): Allow --allow-non-selfsigned-uid to work - on completely unsigned keys. Print the uids in UTF8. Remove - mark_non_selfsigned_uids_valid(). - - * keyedit.c (show_key_with_all_names): Show revocation key as - UTF8. - - * sign.c (clearsign_file): Allow --not-dash-escaped to work with - v3 keys. - -2002-03-14 Werner Koch <wk@gnupg.org> - - * main.h: Changed the default algorithms to CAST5 and SHA1. - -2002-03-13 David Shaw <dshaw@jabberwocky.com> - - * import.c (chk_self_sigs): Show which user ID a bad self-sig - (invald sig or unsupported public key algorithm) resides on. - - * import.c (chk_self_sigs): any valid self-sig should mark a user - ID or subkey as valid - otherwise, an attacker could DoS the user - by inventing a bogus invalid self-signature. - -2002-03-07 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): make a few more strings translatable. - - * options.h, options.skel, g10.c (main), gpgv.c, mainproc.c - (check_sig_and_print), keyserver.c (parse_keyserver_options): - --auto-key-retrieve should really be a keyserver-option variable. - - * import.c (revocation_present): new function to print a warning - if a key is imported that has been revoked by designated revoker, - but the designated revoker is not present to verify the - revocation. If keyserver-options auto-key-retrieve is set, try - and fetch the designated revoker from the keyserver. - - * import.c (import_one): call revocation_present after importing a - new key. Note that this applies to --import, --recv-keys, and - --search-keys. - - * keyserver-internal.h, keyserver.c (keyserver_import_fprint): - import via fingerprint (for revocation keys). - - * keyserver.c (keyserver_import_keyid): much simpler - implementation now that we're using KEYDB_SEARCH_DESC internally. - -2002-03-04 David Shaw <dshaw@jabberwocky.com> - - * revoke.c (gen_revoke): do not prompt for revocation reason for - v3 revocations (unless force-v4-certs is on) since they wouldn't - be used anyway. - - * keyedit.c (menu_revsig): show the status of the sigs - (exportable? revocable?) to the user before prompting for which - sig to revoke. Also, make sure that local signatures get local - revocations. - - * keyedit.c (ask_revoke_sig): remind the user which sigs are - local. - - * g10.c (main): Add "exec-path" variable to override PATH for - execing programs. - - * export.c (do_export_stream): properly check return code from - classify_user_id to catch unclassifiable keys. - -2002-03-03 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (parse_signature): variable type tweak for RISC - OS (from Stefan) - -2002-02-28 David Shaw <dshaw@jabberwocky.com> - - * getkey.c (check_revocation_keys): New function to check a - revocation against a list of potential revocation keys. Note the - loop-breaking code here. This is to prevent blowing up if A is - B's revocation key, while B is also A's. Note also that this is - written so that a revoked revoker can still issue revocations: - i.e. If A revokes B, but A is revoked, B is still revoked. I'm - not completely convinced this is the proper behavior, but it - matches how PGP does it. It does at least have the advantage of - much simpler code - my first version of this had lots of loop - maintaining code so you could chain revokers many levels deep and - if D was revoked, C was not, which meant that B was, and so on. - It was sort of scary, actually. - - * getkey.c (merge_selfsigs_main): Add any revocation keys onto the - pk. This is particularly interesting since we normally only get - data from the most recent 1F signature, but you need multiple 1F - sigs to properly handle revocation keys (PGP does it this way, and - a revocation key could be marked "sensitive" and hence in a - different signature). Also, if a pk has a revocation key set, - check for revocation sigs that were not made by us - if made by a - valid revocation key, mark the pk revoked. - - * packet.h, getkey.c (cache_public_key): do not cache key if - "dont_cache" is set. This allows the revocation key code to look - up a key and return information that may be inaccurate to prevent - loops without caching the fake data. - - * packet.h, sig-check.c (do_signature_check): Record if a - signature was made by a revoked pk. - - * packet.h, parse-packet.c (parse_one_sig_subpkt, - can_handle_critical, parse_signature): Get revocation key - information out of direct sigs. - - * keylist.c (list_keyblock_print): don't assume that the presence - of a 0x20 signature means the key is revoked. With revocation - keys, this may not be true if the revocation key is not around to - verify it or if verification failed. Also, 0x1F should get listed - as "sig", and not "unexpected signature class". - - * keyedit.c (show_key_with_all_names): Add a flag for printing - revoker information and change all callers. - - * import.c (merge_blocks): merge in any new direct key (0x1F) - sigs. - - * import.c (import_revoke_cert): don't keep processing after a - revocation is rejected. - - * import.c (delete_inv_parts): Allow importing a revocation - signature even if it was not issued by the key. This allows a - revocation key to issue it. Of course, the sig still needs to be - checked before we trust it. - - * free-packet.c (copy_public_key): Include a new copy of the - revocation keys when duping a pk. - - * free-packet.c (free_seckey_enc, release_public_key_parts): Free - any revocation keys that are attached to a sig or pk. - - * export.c (do_export_stream): Do not export signatures with - "sensitive" revocation keys in them. - -2002-02-27 David Shaw <dshaw@jabberwocky.com> - - * export.c (do_export_stream): Do not include v3 keys in a - --export-secret-subkeys export. - - * getkey.c (merge_selfsigs_main): If a key isn't valid (say, - because of no self-signature), allow --always-trust to force it - valid so it can be trusted. - -2002-02-25 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (hkp_ask_import), hkp.h, keyserver.c (all): treat key - lists internally as fingerprints when possible. All this is via - KEYDB_SEARCH_DESC - no point in reinventing the wheel. This allows - the helper program to search the keyserver by fingerprint if - desired (and the keyserver supports it). Note that automatic - fingerprint promotion during refresh only applies to v4 keys as a - v4 fingerprint can be easily changed into a long or short key id, - and a v3 cannot. - - * pubkey-enc.c, getkey.c, misc.c, main.h: Take two copies of - hextobyte() from pubkey-enc.c and getkey.c and make them into one - copy in misc.c. - -2002-02-22 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_search_prompt): Detect a "no keys found" - case even if the helper program does not explicitly say how many - keys were found. - - * hkp.c (parse_hkp_index): Bug fix - don't report non-revoked keys - as revoked in HKP key searches. - -2002-02-19 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_trust): Made parsing more robust. - -2002-02-19 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Catch corruption in HKP index lines - (can be caused by broken or malicious keyservers). - - * keyserver.c (keyserver_work): Add KEYSERVER_NOT_SUPPORTED for - unsupported actions (say, a keyserver that has no way to search, - or a readonly keyserver that has no way to add). Also add a - USE_EXTERNAL_HKP define to disable the internal HKP keyserver - code. - -2002-02-14 Werner Koch <wk@gnupg.org> - - * g10.c: New option --no-use-agent. - - * pkclist.c (check_signatures_trust): Always print the warning for - unknown and undefined trust. Removed the did_add cruft. Reported - by Janusz A. Urbanowicz. - -2002-02-11 David Shaw <dshaw@jabberwocky.com> - - * hkp.c (parse_hkp_index): Bug fix - properly handle user IDs with - colons (":") in them while HKP searching. - -2002-02-09 David Shaw <dshaw@jabberwocky.com> - - * misc.c (pct_expando): More comments. - - * keydb.h, sign.c (mk_notation_and_policy): Clarify what is a sig - and what is a cert. A sig has sigclass 0x00, 0x01, 0x02, or 0x40, - and everything else is a cert. - - * g10.c (main), keyedit.c (keyedit_menu): Add a "nrlsign" for - nonrevocable and local key signatures. - - * g10.c (main): Add a --no-force-mdc to undo --force-mdc. - - * options.h, g10.c (main), cipher.c (write_header): Add a knob to - --disable-mdc/--no-disable-mdc. Off by default, of course, but is - used in --pgp2 and --pgp6 modes. - - * pkclist.c (build_pk_list): Allow specifying multiple users in - the "Enter the user ID" loop. Enter a blank line to stop. Show - each key+id as it is added. - - * keylist.c (show_policy_url), mainproc.c (print_notation_data): - It is not illegal (though possibly silly) to have multiple policy - URLs in a given signature, so print all that are present. - - * hkp.c (hkp_search): More efficient implementation of URL-ifying - code. - -2002-02-04 David Shaw <dshaw@jabberwocky.com> - - * main.h, misc.c (pct_expando): New function to generalize - %-expando processing in any arbitrary string. - - * photoid.c (show_photo): Call the new pct_expando function rather - than expand strings internally. - - * sign.c (mk_notation_and_policy): Show policy URLs and notations - when making a signature if show-policy/show-notation is on. - %-expand policy URLs during generation. This lets the user have - policy URLs of the form "http://notary.jabberwocky.com/keysign/%K" - which will generate a per-signature policy URL. - - * main.h, keylist.c (show_policy_url, show_notation): Add amount - to indent so the same function can be used in key listings as well - as during sig generation. Change all callers. - -2002-02-04 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c, options.h (parse_keyserver_options, keyidlist): - Workaround for the pksd and OKS keyserver bug that calculates v4 - RSA keyids as if they were v3. The workaround/hack is to fetch - both the v4 (e.g. 99242560) and v3 (e.g. 68FDDBC7) keyids. This - only happens for key refresh while using the HKP scheme and the - refresh-add-fake-v3-keyids keyserver option must be set. This - should stay off by default. - -2002-02-03 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Bug fix - do not append keys to - each other when --sending more than one. - -2002-02-02 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c (main), keyedit.c (sign_uids), sign.c - (mk_notation_and_policy): Split "--set-policy-url" into - "--cert-policy-url" and "--sig-policy-url" so the user can set - different policies for key and data signing. For backwards - compatibility, "--set-policy-url" sets both, as before. - -2002-01-30 Werner Koch <wk@gnupg.org> - - * g10.c (main): --gen-random --armor does now output a base64 - encoded string. - -2002-01-28 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main), options.h, pkclist.c (algo_available): --pgp6 - flag. This is not nearly as involved as --pgp2. In short, it - turns off force_mdc, turns on no_comment, escape_from, and - force_v3_sigs, and sets compression to 1. It also restricts the - user to IDEA (if present), 3DES, CAST5, MD5, SHA1, and RIPEMD160. - See the comments above algo_available() for lots of discussion on - why you would want to do this. - -2002-01-27 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (keygen_set_std_prefs): Comment - - * keyedit.c (sign_uids): Bug fix - when signing with multiple - secret keys at the same time, make sure each key gets the sigclass - prompt. - - * exec.c (exec_finish): Close the iobuf and FILE before trying to - waitpid, so the remote process will get a SIGPIPE and exit. This - is only a factor when using a pipe to communicate. - - * exec.c (exec_write): Disable cache-on-close of the fd iobuf (is - this right? Why is a fd iobuf cached at all?) - -2002-01-26 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --gpg-agent-info - * passphrase.c (agent_open): Let it override the environment info. - * seckey-cert.c (check_secret_key): Always try 3 times when the - agent is enabled. - * options.skel: Describe --use-agent. - -2002-01-24 David Shaw <dshaw@jabberwocky.com> - - * pubkey-enc.c (is_algo_in_prefs, get_it): Only check preferences - against keys with v4 self sigs - there is really little point in - warning for every single non-IDEA message encrypted to an old key. - - * pkclist.c (select_algo_from_prefs): Only put in the fake IDEA - preference if --pgp2 is on. - - * mainproc.c (check_sig_and_print): Print "Expired" for expired - but good signatures (this still prints "BAD" for expired but bad - signatures). - -2002-01-23 David Shaw <dshaw@jabberwocky.com> - - * keygen.c (ask_keysize): Cosmetic: don't present a RSA signing - key as a "keypair" which can be 768 bits long (as RSA minimum is - 1024). - - * pubkey-enc.c (is_algo_in_prefs): Allow IDEA as a fake preference - for v3 keys with v3 selfsigs. - -2002-01-22 David Shaw <dshaw@jabberwocky.com> - - * packet.h, getkey.c (merge_selfsigs_main), pkclist.c - (select_algo_from_prefs): Implement the fake IDEA preference as - per RFC2440:12.1. This doesn't mean that IDEA will be used (the - plugin may not be present), but it does mean that a v3 key with a - v3 selfsig has an implicit IDEA preference instead of 3DES. v3 - keys with v4 selfsigs use preferences as normal. - - * encode.c (encode_crypt): if select_algo_from_prefs fails, this - means that we could not find a cipher that both keys like. Since - all v4 keys have an implicit 3DES preference, this means there is - a v3 key with a v3 selfsig in the list. Use 3DES in this case as - it is the safest option (we know the v4 key can handle it, and - we'll just hope the v3 key is being used in an implementation that - can handle it). If --pgp2 is on, warn the user what we're doing - since it'll probably break PGP2 compatibility. - - * g10.c (main): Do not force using IDEA for encrypted files in - --pgp2 mode - let the fake IDEA preference choose this for us for - better compatibility when encrypting to multiple keys, only some - of which are v3. - - * keygen.c (keygen_set_std_prefs): Put 3DES on the end of the - default cipher pref list (RFC2440: "...it is good form to place it - there explicitly."). If the user has the IDEA plugin installed, - put a preference for IDEA *after* 3DES to effectively disable its - use for everything except encrypting along with v3 keys. - - * encode.c, g10.c, sign.c: Change the PGP2 warning line from - "... will not be usable ..." to "... may not be usable ..." as the - user could be using one of the enhanced PGP2 variations. - - * helptext.c: Revise the sign_uid.class help text as suggested by - Stefan. - -2002-01-20 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_to_dek): Add tryagain_text arg to be - used with the agent. Changed all callers. - (agent_get_passphrase): Likewise and send it to the agent - * seckey-cert.c (do_check): New arg tryagain_text. - (check_secret_key): Pass the string to do_check. - * keygen.c (ask_passphrase): Set the error text is required. - * keyedit.c (change_passphrase): Ditto. - - * passphrase.c (agent_open): Disable opt.use_agent in case of a - problem with the agent. - (agent_get_passphrase): Ditto. - (passphrase_clear_cache): Ditto. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_open): Add support for the new Assuan based - gpg-agent. New arg to return the used protocol version. - (agent_get_passphrase): Implemented new protocol here. - (passphrase_clear_cache): Ditto. - (readline): New. - -2002-01-15 Timo Schulz <ts@winpt.org> - - * encode.c (encode_crypt_files): Fail if --output is used. - - * g10.c: New command --decrypt-files. - - * decrypt.c (decrypt_messages): New. - -2002-01-09 David Shaw <dshaw@jabberwocky.com> - - * g10.c, misc.c, gpgv.c: move idea_cipher_warn to misc.c so gpgv.c - doesn't need a stub for it any longer. - - * g10.c (get_temp_dir), main.h: no longer used (it's in exec.c now) - - * g10.c (main), delkey.c (delete_keys), main.h : Allow - --delete-key (now --delete-keys, though --delete-key still works, - of course) to delete multiple keys in one go. This applies to - --delete-secret-key(s) and --delete-secret-and-public-key(s) as - well. - -2002-01-09 Timo Schulz <ts@winpt.org> - - * encode.c (encode_crypt_files): Now it behaves like verify_files. - - * g10.c (main): We don't need to check argc for encode_crypt_files - any longer. - -2002-01-09 Timo Schulz <ts@winpt.org> - - * exec.c: Include windows.h for dosish systems. - -2002-01-08 Timo Schulz <ts@winpt.org> - - * g10.c (main): New description for --encrypt-files. - -2002-01-08 Werner Koch <wk@gnupg.org> - - * g10.c (main): Must register the secring for encryption because - it is needed to figure out the default recipient. Reported by - Roger Sondermann. - -2002-01-05 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (menu_adduid): Require --expert before adding a photo - ID to a v3 key, and before adding a second photo ID to any key. - - * keyedit.c (keyedit_menu): Don't allow adding photo IDs in - rfc1991 or pgp2 mode. - - * getkey.c (merge_selfsigs_subkey): Permit v3 subkeys. Believe it - or not, this is allowed by rfc 2440, and both PGP 6 and PGP 7 work - fine with them. - - * g10.c, options.h, keyedit.c, sign.c: Move the "ask for - expiration" switch off of --expert, which was getting quite - overloaded, and onto ask-sig-expire and ask-cert-expire. Both - default to off. - - * g10.c (main): Change the default compression algo to 1, to be - more OpenPGP compliant (PGP also uses this, so it'll help with - interoperability problems as well). - - * encode.c (encode_crypt): Handle compression algo 2, since the - default is now 1. - - * build-packet.c (build_attribute_subpkt): Fix off-by-one error. - -2002-01-05 Werner Koch <wk@gnupg.org> - - * g10.c (main): Do not register the secret keyrings for certain - commands. - - * keydb.c (keydb_add_resource): Use access to test for keyring - existence. This avoids cached opened files which are bad under - RISC OS. - -2002-01-04 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file, sign_symencrypt_file): always use one-pass - packets unless rfc1991 is enabled. This allows a signature made - with a v3 key to work in PGP 6 and 7. Signatures made with v4 - keys are unchanged. - - * g10.c (main): Disallow non-detached signatures in PGP2 mode. - Move the "you must use files and not pipes" PGP2 warning up so all - the PGP2 stuff is together. - - * encode.c (encode_simple): Use the actual filesize instead of - partial length packets in the internal literal packet from a - symmetric message. This breaks PGP5(?), but fixes PGP2, 6, and 7. - It's a decent tradeoff. Note there was only an issue with - old-style RFC1991 symmetric messages. 2440-style messages in 6 - and 7 work with or without partial length packets. - -2002-01-03 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Removed --no-default-check-level option, as it is - not consistent with other "default" options. Plus, it is the same - as saying --default-check-level 0. - - * exec.c (exec_read): Disallow caching tempfile from child - process, as this keeps the file handle open and can cause unlink - problems on some platforms. - - * keyserver.c (keyserver_search_prompt): Minor tweak - don't - bother to transform keyids into textual form if they're just going - to be transformed back to numbers. - -2002-01-03 Timo Schulz <ts@winpt.org> - - * g10.c: New command --encrypt-files. - - * verify.c (print_file_status): Removed the static because - encode_crypt_files also uses this function. - - * main.h (print_files_status): New. - (encode_crypt_files): New. - - * encode.c (encode_crypt_files): New. - -2002-01-02 Stefan Bellon <sbellon@sbellon.de> - - * keyserver.c: Moved util.h include down in order to avoid - redefinition problems on RISC OS. - - * keyring.c (keyring_lock): Only lock keyrings that are writable. - - * keyring.c (keyring_update_keyblock): Close unused iobuf. - - * hkp.c (parse_hkp_index, hkp_search) [__riscos__]: Changed - unsigned char* to char* because of compiler issues. - - * exec.c (exec_finish) [__riscos__]: Invalidate close cache so - that file can be unlinked. - -2001-12-28 David Shaw <dshaw@jabberwocky.com> - - * g10.c (main): Use a different strlist to check extensions since - they need to be handled seperately now. - - * misc.c,main.h (check_permissions): Properly handle permission - and ownership checks on files in the lib directory - (e.g. /usr/local/lib/gnupg), which are owned by root and are - world-readable, and change all callers to specify extension or - per-user file. - - * photoid.c (show_photo), keyserver.c (keyserver_spawn): Bug fix - - don't call exec_finish if exec_write fails. - - * keyserver.c (keyserver_spawn): Look for OPTIONS from the - keyserver helper - specifically, a "OUTOFBAND" option for the - email keyserver. - - * mainproc.c (list_node), keylist.c (list_keyblock_colon), - import.c (delete_inv_parts), export.c (do_export_stream): Use - signature flags for exportability check rather than re-parsing the - subpacket. - - * keyid.c, keydb.h (get_lsign_letter): No longer needed. - -2001-12-27 David Shaw <dshaw@jabberwocky.com> - - * exec.c (exec_finish): Show errors when temp files cannot be - deleted for whatever reason. - - * exec.c (exec_read): Don't rely on WEXITSTATUS being present. - - * exec.c (make_tempdir): Add temp file creator for win32. Don't - create an incoming temp file if the exec is write-only. - - * keyserver.c (keyserver_spawn): Clean up error handling, for when - the spawn fails. - - * photoid.c (show_photo): Clean up error handling. - - * misc.c (check_permissions): Neaten. - -2001-12-25 David Shaw <dshaw@jabberwocky.com> - - * mkdtemp.c (mkdtemp): Add copyleft info and tweak the 'X' counter - to be a bit simpler. - - * keyserver.c, photoid.c: Remove unused headers left over from - when the exec functions lived there. - -2001-12-23 Timo Schulz <ts@winpt.org> - - * misc.c (check_permissions): Do not use it for W32 systems. - - * tdbio.c (migrate_from_v2): Define ftruncate as chsize() for W32. - - * mkdtemp.c: W32 support. - - * photoid.c: Ditto. - - * exec.c: Ditto. - -2001-12-22 David Shaw <dshaw@jabberwocky.com> - - * exec.c (make_tempdir): avoid compiler warning with const - - * mkdtemp.c (mkdtemp): catch the empty ("") string case in case - someone repurposes mkdtemp at some point. - - * photoid.c (generate_photo_id, show_photo): some type changes - from Stefan Bellon. - - * exec.c (make_tempdir): handle Win32 systems, suggested by Timo - Schulz. - -2001-12-22 Werner Koch <wk@gnupg.org> - - * encode.c (encode_simple, encode_crypt): i18n 2 strings. - -2001-12-22 Timo Schulz <ts@winpt.org> - - * encode.c (encode_simple, encode_crypt): Use is_file_compressed - to avoid to compress compressed files. - -2001-12-22 Werner Koch <wk@gnupg.org> - - * keyserver.c (keyserver_spawn): Removed some variables - declaration due to shadowing warnings. - - * build-packet.c (build_attribute_subpkt): s/index/idx/ to avoid - compiler warnig due to index(3). - - * getkey.c (get_ctx_handle): Use KEYDB_HANDLE as return value. - * keylist.c (list_one): Made resname const. - - * keyedit.c (keyedit_menu): Allow "addphoto" only when --openpgp is - not used. - - * options.skel: Changed one example photo viewer to qiv. - -2001-12-21 David Shaw <dshaw@jabberwocky.com> - - * Makefile.am: add exec.c, exec.h, photoid.c, and photoid.h - - * build-packet.c (build_attribute_subpkt): new function to build - the raw attribute subpacket. Note that attribute subpackets have - the same format as signature subpackets. - - * exec.c: new file with generic exec-a-program functionality. - Used by both photo IDs and keyserver helpers. This is pretty much - the same code that used to be keyserver specific, with some - changes to be usable generically. - - * free-packet.c (free_attributes (new)): function to free an - attribute packet. - - * gpgv.c: added stub show_photo - - * keyedit.c (keyedit_menu, menu_adduid, menu_showphoto): can add a - photo (calls generate_photo_id), or display a photo (calls - show_photo) from the --edit menu. New commands are "addphoto", - and "delphoto" (same as "deluid"). - - * keylist.c (list_keyblock_print): show photos during key list if - --show-photos enabled. - - * keyserver.c (keyserver_spawn): use the generic exec_xxx - functions to call keyserver helper. - - * g10.c, options.h: three new options - --{no-}show-photos, and - --photo-viewer to give the command line to display a picture. - - * options.skel: instructions for the photo viewer - - * parse-packet.c (parse_user_id, setup_user_id (new)): common code - for both user IDs and attribute IDs moved to setup_user_id. - - * parse-packet.c (make_attribute_uidname (new)): constructs a fake - "name" for attribute packets (e.g. "[image of size ...]") - - * parse-packet.c (parse_attribute (replaces parse_photo_id), - parse_attribute_subpkts): Builds an array of individual - attributes. Currently only handles attribute image / type jpeg - subpackets. - - * sign.c (hash_uid): Fix bug in signing attribute (formerly - photo_id) packets. - - * packet.h, and callers: globally change "photo_id" to "attribute" - and add structures for attributes. The packet format is generic - attributes, even though the only attribute type thus far defined - is jpeg. - -2001-12-21 David Shaw <dshaw@jabberwocky.com> - - * parse-packet.c (can_handle_critical): Can handle critical - revocation subpackets now. - - * trustdb.c (mark_usable_uid_certs): Disregard revocations for - nonrevocable sigs. Note that this allows a newer revocable - signature to override an older nonrevocable signature. - - * sign.c (make_keysig_packet): add a duration field and change all - callers. This makes make_keysig_packet closer to - write_signature_packets and removes some duplicated expiration - code. - - * keyedit.c (keyedit_menu, menu_revsig, sign_uids, - sign_mk_attrib): Add nrsign command, don't allow revoking a - nonrevocable signature, - - * g10.c (main): Add --nrsign option to nonrevocably sign a key - from the command line. - - * build-packet.c (build_sig_subpkt_from_sig): Comment to explain - the use of CRITICAL. - -2001-12-21 Werner Koch <wk@gnupg.org> - - * g10.c. options.h : New option --show-keyring - * getkey.c (get_ctx_handle): New. - * keylist.c (list_one): Implement option here. By David Champion. - -2001-12-20 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (keyserver_spawn): Use mkdtemp() to make temp - directory. - - * mkdtemp.c: replacement function for those platforms that don't - have mkdtemp (make a temp directory securely). - -2001-12-19 David Shaw <dshaw@jabberwocky.com> - - * misc.c (check_permissions): New function to stat() and ensure - the permissions of GNUPGHOME and the files have safe permissions. - - * keydb.c (keydb_add_resource): Check keyring permissions. - - * tdbio.c (tdbio_set_dbname): Check permissions of trustdb.gpg - - * keyserver.c (keyserver_spawn): Disable keyserver schemes that - involve running external programs if the options file has unsafe - permissions or ownership. - - * g10.c, options.h: New option --no-permission-warning to disable - the permission warning message(s). This also permits use of the - keyserver if it had been disabled (see above). Also check the - permissions/ownership of random_seed. - - * keyserver.c (keyserver_spawn): The new glibc prints a warning - when using mktemp() (the code was already secure, but the warning - was bound to cause confusion). Use a different implementation - based on get_random_bits() instead. Also try a few times to get - the temp dir before giving up. - -2001-12-19 Werner Koch <wk@gnupg.org> - - * g10.c, passphrase.c [CYGWIN32]: Allow this as an alias for MINGW32. - -2001-12-18 David Shaw <dshaw@jabberwocky.com> - - * g10.c (idea_cipher_warn): Add a flag to show the warning always - or once per session and change all callers (show always except for - the secret key protection and unknown cipher from an encrypted - message errors). Also make the strings translatable. - - * pubkey-enc.c (get_it): Add the IDEA cipher warning if the user - tries to decrypt an IDEA encrypted message without the IDEA - plugin. - - * keyserver.c (parse_keyserver_uri): More strict checking of the - keyserver URI. Specifically, fail if the ":port" section is - anything except a number between 1 and 65535. - -2001-12-17 David Shaw <dshaw@jabberwocky.com> - - * keyserver.c (print_keyinfo): No need to check for - control/illegal characters, as utf8_to_native does this for us. - - * mainproc.c (proc_encrypted): Use generic IDEA warning. - - * gpgv.c: add stub for idea_cipher_warn - - * g10.c, hkp.c, keyserver.c: Fix capitalization and plural issues. - - * encode.c (encode_crypt), sign.c (sign_file, clearsign_file): - disable pgp2 mode after the message is no longer pgp2 compatible. - - * g10.c (main): Tweak the PGP2.x IDEA warning to use the generic - warning, and not merely fail if the IDEA plugin isn't there. - - * g10.c (main, idea_cipher_warn), keygen.c (set_one_pref), - seckey-cert.c (do_check): Add a generic IDEA warning for when the - IDEA plugin is not present. This pops up when the user uses - "--cipher-algo idea", when setpref is used to set a "S1" - preference, and when a secret key protected with IDEA is used. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * keyserver.c (keyserver_spawn): Assert that we have dropped privs. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_session_key): Check that the public key - algorithm is indeed usable for en/decryption. This avoid a - strange error message from pubkey_decrypt if for some reasons a - bad algorithm indentifier is passed. - -2001-12-12 David Shaw <dshaw@jabberwocky.com> - - * Fixed some types for portability. Noted by Stefan Bellon. - -2001-12-11 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_export): Do not print possible control characters - from a keyserver response. - (parse_hkp_index): Made uid an unsigned char* because it is passed to - isspace(). - (hkp_search): Ditto for the char* vars. - - * g10.c (main): Print the IDEA warning also for -c and -se. - - * g10.c (get_temp_dir): Assert that we have dropped privs - - * encode.c (encode_crypt): Include the first key into the --pgp2 - check. - -2001-12-07 David Shaw <dshaw@jabberwocky.com> - - * g10.c, options.h: New option --pgp2. This is identical to - "--rfc1991 --cipher-algo idea --compress-algo 1 --digest-algo md5 - --force_v3_sigs" with the addition of an warning to advise the - user not to use a pipe (which would break pgp2 compatibility). - - * encode.c (encode_crypt): warn if the user tries to encrypt to - any key that is not RSA and <= 2048 bits when the --pgp2 option is - used. - - * sign.c (sign_file, clearsign_file): When using --pgp2, make a v3 - sig, and warn if the signature is made with a non-v3 key. - -2001-12-05 David Shaw <dshaw@jabberwocky.com> - - * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Prompt - for sig expiration if --expert is set and --force-v3-sigs is not - set (v3 sigs cannot expire). - - * mainproc.c (check_sig_and_print): After checking a sig, print - expiration status. This causes a error return if the sig is - expired. - - * build-packet.c (build_sig_subpkt_from_sig): Include a critical - sig expiration subpacket if the sig is to expire. - - * keyedit.c (sign_uids): Do not sign an expired key unless - --expert is set, in which case prompt. Also, offer to expire a - signature when the key the user is signing expires. - - * keygen.c (ask_expire_interval): Add a value to determine whether - to prompt for a key or sig expiration and change all callers. - - * keyid.c: New functions: expirestr_from_sig and - colon_expirestr_from_sig. - - * keylist.c (list_keyblock_colon): Show sig expiration date in the - --with-colons listing. - - * sign.c (make_keysig_packet, write_signature_packets): Pass in an - optional timestamp for the signature packet, and change all - callers. - - * keyedit.c (sign_mk_attrib): Include a critical expiration - subpacket in the signature if an expiration date is given. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (sign_uids): If the user tries to sign a - locally-signed key, allow the cert to be promoted to a full - exportable signature. This essentially deletes the old - non-exportable sig, and replaces it with a new exportable one. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * keyedit.c (keyedit_menu): Do not allow signing a revoked key - unless --expert is set, and ask even then. - - * keyedit.c (sign_uids): Do not allow signing a revoked UID unless - --expert is set, and ask even then. - - * g10.c, options.h : New option --expert - -2001-11-16 David Shaw <dshaw@jabberwocky.com> - - * Allow the user to select no compression via "--compress-algo 0" - on the command line. - - * keyedit.c (show_prefs): Show compression preferences in the - long-form "showpref" style. - - * keygen.c (set_one_pref): Permit setting a no-compression ("Z0") - preference. - - * getkey.c (fixup_uidnode): Fix compression preference corruption - bug. - -2001-12-02 David Shaw <dshaw@jabberwocky.com> - - * g10.c: Add advisory --for-your-eyes-only option as per section - 5.9 of 2440. - -2001-12-05 David Shaw <dshaw@jabberwocky.com> - - * Force a V4 sig if the user has a notation or policy URL set. - -2001-12-04 David Shaw <dshaw@jabberwocky.com> - - * g10.c: Add options --keyserver-options, --temp-directory, and - auto-key-retrieve (the opposite of no-auto-key-retrieve). - - * hkp.c (hkp_search): New function to handle searching a HKP - keyserver for a key - - * hkp.c (hkp_ask_import, hkp_export): Pretty large changes to make - them communicate via the generic functions in keyserver.c - - * keyserver.c: new file with generic keyserver routines for - getting keys from a keyserver, sending keys to a keyserver, and - searching for keys on a keyserver. Calls the internal HKP stuff - in hkp.c for HKP keyserver functions. Other calls are handled by - an external program which is spawned and written to and read from - via pipes. Platforms that don't have pipes use temp files. - -2001-11-20 David Shaw <dshaw@jabberwocky.com> - - * options.h, g10.c: New options show-notation, no-show-notation, - default-check-level, no-default-check-level, show-policy-url, - no-show-policy-url. - - * packet.h, sign.c (make_keysig_packet), parse-packet.c - (parse_signature), free-packet.c (free_seckey_enc): Fill in - structures for notation, policy, sig class, exportability, etc. - - * keyedit.c, keylist.c (print_and_check_one_sig, - list_keyblock_print): Show flags in signature display for cert - details (class, local, notation, policy, revocable). If selected, - show the notation and policy url. - - * keyedit.c (sign_uids): Prompt for and use different key sig - classes. - - * helptext.c (helptexts): Add help text to explain different - key signature classes - -2001-11-26 David Shaw <dshaw@jabberwocky.com> - - * trustdb.c (mark_usable_uid_certs): Fix segfault from bad - initialization and fix reversed key signature expiration check. - -2001-11-09 Werner Koch <wk@gnupg.org> - - * export.c (do_export_stream): Put all given names into a search - description and change the loop so that all matching names are - returned. - -2001-11-08 Werner Koch <wk@gnupg.org> - - * pubkey-enc.c (get_it): To reduce the number of questions on the - MLs print the the name of cipher algorithm 1 with the error message. - - * mainproc.c: Changed the way old rfc1991 encryption cipher is - selected. Based on a patch by W Lewis. - - * pkclist.c (do_edit_ownertrust): Allow to skip over keys, the non - working "show info" is now assigned to "i" - * trustdb.c (ask_ownertrust, validate_keys): Implement a real quit - here. Both are by David Shaw. - - * trustdb.c (validate_keys): Make sure next_exipire is initialized. - - * sign.c (make_keysig_packet): Use SHA-1 with v4 RSA keys. - - * g10.c, options.h : New option --[no-]froce-v4-certs. - * sign.c (make_keysig_packet): Create v4 sigs on v4 keys even with - a v3 key. Use that new option. By David Shaw - - * revoke.c (ask_revocation_reason): Allow to select "no reason". - By David Shaw. - - * keyid.c (fingerprint_from_sk): Calculation of an v3 fpr was - plain wrong - nearly the same code in fingerprint_from_pk is correct. - - * build-packet.c (do_secret_key): Added a few comments to the code. - -2001-11-07 Werner Koch <wk@gnupg.org> - - * g10.c (main): Print a warning when -r is used w/o encryption. - Suggested by Pascal Scheffers. - -2001-10-23 Werner Koch <wk@gnupg.org> - - * keyedit.c (keyedit_menu): Changed helptext for showpref - command. Suggested by Reinhard Wobst. - - * keyring.c (keyring_search): When marking the offtbl ready, take - into account that we may have more than one keyring. - -2001-10-22 Werner Koch <wk@gnupg.org> - - * Makefile.am: Do not use OMIT_DEPENDENCIES - - * build-packet.c (build_sig_subpkt): Default is now to put all - types of subpackets into the hashed area and only list those which - should go into the unhashed area. - -2001-10-18 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Rearranged the way we keep track - of the resource. There will now be an entry for each keyring here - and not in keyring.c itself. Store a token to allow creation of a - keyring handle. Changed all functions to utilize this new design. - (keydb_locate_writable): Make a real implementation. - * keyring.c (next_kr): Removed and changed all callers to set the - resource directly from the one given with the handle. - (keyring_is_writable): New. - (keyring_rebuild_cache): Add an arg to pass the token from keydb. - -2001-10-17 Werner Koch <wk@gnupg.org> - - * keyring.c (keyring_search): Enabled word search mode but print a - warning that it is buggy. - -2001-10-11 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_ask_import): No more need to set the port number for - the x-hkp scheme. - (hkp_export): Ditto. - -2001-10-06 Stefan Bellon <sbellon@sbellon.de> - - * passphrase.c [__riscos__]: Disabled agent specific stuff. - * g10.c: New option --no-force-v3-sigs. - -2001-10-04 Werner Koch <wk@gnupg.org> - - * export.c (do_export_stream): Do not push the compress filter - here because the context would run out of scope due to the - iobuf_close done by the caller. - (do_export): Do it here instead. - -2001-09-28 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Always use the primary key to sign keys. - * getkey.c (finish_lookup): Hack to return only the primary key if - a certification key has been requested. - - * trustdb.c (cmp_kid_for_make_key_array): Renamed to - (validate_one_keyblock): this and changed arg for direct calling. - (make_key_array): Renamed to - (validate_one_keyblock): this and changed args for direct calling. - (mark_usable_uid_certs, validate_one_keyblock) - (validate_key_list): Add next_expire arg to keep track of - expiration times. - (validate_keys): Ditto for UTKs and write the stamp. - - * tdbio.c (migrate_from_v2): Check return code of tbdio_sync. - - * tdbdump.c (import_ownertrust): Do a tdbio_sync(). - - * keyring.c: Made the offtbl an global object. - -2001-09-27 Werner Koch <wk@gnupg.org> - - * pkclist.c (do_edit_ownertrust): Allow settin of ultimate trust. - - * trustdb.c (mark_keyblock_seen): New. - (make_key_array): Use it to mark the subkeys too. - (validate_keys): Store validity for ultimatly trusted keys. - -2001-09-26 Werner Koch <wk@gnupg.org> - - * pkclist.c (check_signatures_trust, do_we_trust): Removed the - invocation of add_ownertrust. Minor changes to the wording. - (add_ownertrust, add_ownertrust_cb): Removed. - - * trustdb.c (get_validity): Allow to lookup the validity using a - subkey. - - * trustdb.c (new_key_hash_table): Increased the table size to 1024 - and changed the masks accordingly. - (validate): Changed stats printing. - (mark_usable_uid_certs): New. - (cmp_kid_for_make_key_array): Does now check the signatures and - figures out a usable one. - -2001-09-25 Werner Koch <wk@gnupg.org> - - * keyring.c (new_offset_item,release_offset_items) - (new_offset_hash_table, lookup_offset_hash_table) - (update_offset_hash_table, update_offset_hash_table_from_kb): New. - (keyring_search): Use a offset table to optimize search for - unknown keys. - (keyring_update_keyblock, keyring_insert_keyblock): Insert new - offsets. - * getkey.c (MAX_UNK_CACHE_ENTRIES): Removed the unknown keys - caching code. - - * g10.c, options.h, import.c: Removed the entire - allow-secret-key-import stuff because the validity is now - controlled by other means. - - * g10.c: New command --rebuild-keydb-caches. - * keydb.c (keydb_rebuild_caches): New. - * keyring.c (do_copy): Moved some code to - (create_tmp_file, rename_tmp_file, write_keyblock): new functions. - (keyring_rebuild_cache): New. - - * packet.h (PKT_ring_trust): Add sigcache field. - * parse-packet.c (parse_trust): Parse sigcache. - * keyring.c (do_copy): Always insert a sigcache packet. - (keyring_get_keyblock): Copy the sigcache packet to the signature. - * sig-check.c (cache_sig_result): Renamed from - cache_selfsig_result. Changed implementation to use the flag bits - and changed all callers. - (mdc_kludge_check): Removed this unused code. - (do_check): Do not set the sig flags here. - - * import.c (read_block): Make sure that ring_trust packets are - never imported. - * export.c (do_export_stream): and never export them. - - * trustdb.c (make_key_array): Skip revoked and expired keys. - -2001-09-24 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --no-auto-check-trustdb. - - * keygen.c (do_generate_keypair): Set newly created keys to - ultimately trusted. - - * tdbio.h, tdbio.c: Removed all support for records DIR, KEY, UID, - PREF, SIG, SDIR and CACH. Changed migration function to work - direct on the file. - (tdbio_read_nextcheck): New. - (tdbio_write_nextcheck): New. - -2001-09-21 Werner Koch <wk@gnupg.org> - - Revamped the entire key validation system. - * trustdb.c: Complete rewrite. No more validation on demand, - removed some functions, adjusted to all callers to use the new - and much simpler interface. Does not use the LID anymore. - * tdbio.c, tdbio.h: Add new record types trust and valid. Wrote a - migration function to convert to the new trustdb layout. - * getkey.c (classify_user_id2): Do not allow the use of the "#" - prefix. - * keydb.h: Removed the TDBIDX mode add a skipfnc to the - descriptor. - * keyring.c (keyring_search): Implemented skipfnc. - - * passphrase.c (agent_open): Add missing bracket. Include windows.h. - -2001-09-19 Werner Koch <wk@gnupg.org> - - * keylist.c (print_fingerprint): Renamed from fingerprint, made - global available. Added new arg to control the print style. - * mainproc.c (print_fingerprint): Removed. - * pkclist.c (print_fpr, fpr_info): Removed and changed callers to - use print_fingerprint. - * keyedit.c (show_fingerprint): Ditto. - - * passphrase.c (writen, readn) - (agent_open, agent_close) - (agent_get_passphrase) - (passphrase_clear_cache): Support for W32. Contributed by Timo. - - * import.c (import_one): Release keydb handles at 2 more places. - - * keyring.c (keyring_release): Close the iobuf. - (keyring_get_keyblock): Init ret_kb to NULL and store error contidion. - - * import.c (import_new_stats_handle): New. - (import_release_stats_handle): New. - (import_print_stats): Renamed from static fnc print_stats. - (import_keys, import_keys_stream): Add an optional status handle - arg and changed all callers. - * hkp.c (hkp_ask_import): Add an stats_handle arg and changed all - callers. - - * mainproc.c (print_pkenc_list): Use print_utf8_string2(). - -2001-09-18 Werner Koch <wk@gnupg.org> - - * g10.c: New command --refresh-keys. - * hkp.c (hkp_refresh_keys): New. Contributed by Timo Schulz. - - * parse-packet.c (parse): Stop on impossible packet lengths. - -2001-09-17 Werner Koch <wk@gnupg.org> - - * mainproc.c (print_notation_data): Wrap notation data status lines - after 50 chars. - - * mainproc.c (proc_pubkey_enc): Make option try-all-secrets work. - By disastry@saiknes.lv. - -2001-09-14 Werner Koch <wk@gnupg.org> - - * parse-packet.c (dump_sig_subpkt): List key server preferences - and show the revocable flag correctly. Contributed by David Shaw. - -2001-09-09 Werner Koch <wk@gnupg.org> - - * keyedit.c (keyedit_menu): No need to define another p. - - * keylist.c (print_capabilities): s/used/use/ so that it - does not shadow a global. - * sign.c (sign_file): Renamed arg encrypt to encryptflag - * keygen.c: Replaced all "usage" by "use". - * misc.c (openpgp_pk_algo_usage): Ditto. - - * pubkey-enc.c (get_it): Renamed arg k to enc so that the later - defined k does not shadow it. - - * parse-packet.c (parse_gpg_control): No need to define another i. - - * getkey.c (get_pubkey_byfprint): Must use the enum values and not - the fprint_len. - * keyring.c (keyring_search): Removed a non-sense break. Both - bugs pointed out by Stefan. - -2001-09-07 Werner Koch <wk@gnupg.org> - - * status.c, status.h: Added NO_RECP and ALREADY_SIGNED. - * pkclist.c (build_pk_list): Issue NO_RECP. - * keyedit.c (sign_uids): Added experimental ALREADY_SIGNED - - * hkp.c (hkp_import): Use log_error. Bug reported by Neal H - Walfield. - - * getkey.c (classify_user_id2): Change args to take the desc union - direct. It was a stupid idea to pass the individual fields of an - union to this function. Changed all callers. - (classify_user_id): Ditto and allow to pass NULL as the description. - -2001-09-06 Werner Koch <wk@gnupg.org> - - * getkey.c (fixup_uidnode): Features flag is now a bit vector. - * keygen.c (add_feature_mdc): Ditto. - - Revamped the entire key I/O code to be prepared for other ways of - key storages and to get rid of the existing shit. GDBM support has - gone. - * keydb.c: New - * keyring.c, keyring.h: New. - * ringedit.c: Removed. Moved some stuff to keyring.c - * getkey.c: Changed everything related to the key retrieving - functions which are now using the keydb_ functions. - (prepare_search, word_match_chars, word_match) - (prepare_word_match, compare_name): Moved to keyring.c - (get_pubkey_byname): Removed ctx arg and add ret_kdbhd - arg. Changed all callers. - (key_byname): Use get_pubkey_end to release the context and take - new ret_kbdhd arg. Changed all callers. - (classify_user_id2): Fill the 16 byte fingerprint up with 4 null - bytes not with zero bytes of value 4, tsss. - * import.c (import_one): Updated to use the new keydb interface. - (import_secret_one): Ditto. - (import_revoke_cert): Ditto. - * delkey.c (do_delete_key): Ditto. - * keyedit.c (keyedit_menu): Ditto. - (get_keyblock_byname): Removed. - * revoke.c (gen_revoke): Ditto. - * export.c (do_export_stream): Ditto. - * trustdb.c (update_trustdb): Ditto. - * g10.c, gpgv.c (main): Renamed add_keyblock_resource to - keydb_add_resource. - * Makefile.am: Added and removed files. - - * keydb.h: Moved KBNODE typedef and MAX_FINGERPRINT_LEN to - * global.h: this new header. - -2001-09-03 Werner Koch <wk@gnupg.org> - - * passphrase.c (agent_get_passphrase): Changed nread to size_t. - (passphrase_clear_cache): Ditto. - - * keyid.c (mk_datestr): Avoid trigraphs. - (fingerprint_from_pk): Cache the keyid in the pk. - - * options.h: Add opt.with_fingerprint so that we know whether the - corresponding options was used. - * g10.c (main): Set it here. - * pkclist.c (check_signatures_trust): Always print fingerprint - when this option is used. Mixed a minor memory leak. - - * status.c, status.h: New status INV_RECP. - * pkclist.c (build_pk_list): Issue this status. - -2001-08-31 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_key,parse_pubkeyenc) - (parse_signature): Return error on reading bad MPIs. - - * mainproc.c (check_sig_and_print): Always print the user ID even - if it is not bound by a signature. Use the primary UID in the - status messages and encode them in UTF-8 - * status.c (write_status_text_and_buffer): New. - -2001-08-30 Werner Koch <wk@gnupg.org> - - * packet.h (sigsubpkttype_t): Add SIGSUBPKT_FEATURES. - (PKT_public_key, PKT_user_id): Add a flag for it. - * parse-packet.c, build-packet.c: Add support for them. - * getkey.c (fixup_uidnode, merge_selfsigs): Set the MDC flags. - * keygen.c (add_feature_mdc): New. - (keygen_upd_std_prefs): Always set the MDC feature. - * keyedit.c (show_prefs): List the MDC flag - * pkclist.c (select_mdc_from_pklist): New. - * encode.c (encode_crypt, encrypt_filter): Test whether MDC - should be used. - * cipher.c (write_header): Set MDC use depending on the above test. - Print more status info. - - * delkey.c (do_delete_key): Kludge to delete a secret key with no - public key available. - - * ringedit.c (find_secret_keyblock_direct): New. - * getkey.c (seckey_available): Simplified. - - * ringedit.c (cmp_seckey): Now compares the secret key against the - public key while ignoring all secret parts. - (keyring_search): Use a public key packet as arg. Allow to search - for subnkeys - (search): Likewise. Changed all callers. - (find_secret_keyblock_bypk): New. - (find_secret_keyblock_byname): First locate the pubkey and then - find the correponding secret key. - * parse-packet.c (parse): Renamed pkttype arg to onlykeypkts and - changed code accordingly. Changed all callers. - (search_packet): Removed pkttype arg. - * keyedit.c (keyedit_menu): First locate the public key and then - try to locate a secret key. - - * ringedit.c (locate_keyblock_by_fpr): Removed. - (locate_keyblock_by_keyid): Removed. - (find_keyblock_bysk): Removed. - - * sig-check.c (check_key_signature2): Print the keyid along with - the wrong sig class errors. - -2001-08-24 Werner Koch <wk@gnupg.org> - - * sign.c (sign_file): Stripped the disabled comment packet code. - (sign_file, sign_symencrypt_file): Moved common code to .. - (write_onepass_sig_packets): .. this new function. - (sign_file, clearsign_file, sign_symencrypt_file): Moved common - code to - (write_signature_packets): this new function. - (write_signature_packets, make_keysig_packet) - (update_keysig_packet): Moved common code to - (hash_uid, hash_sigclass_to_magic): these new functions - (sign_file, sign_symencrypt_file): Moved common code to - (write_plaintext_packet): this new function. - -2001-08-21 Stefan Bellon <sbellon@sbellon.de> - - * trustdb.c (query_trust_info): Changed trustlevel to signed int. - * g10.c [__riscos__]: Fixed handling of --use-agent --lock-multiple. - -2001-08-20 Werner Koch <wk@gnupg.org> - - * encr-data.c (decrypt_data): Keep track on whether we already - printed information about the used algorithm. - * mainproc.c (proc_encrypted): Removed the non-working IDEA hack - and print a message about the assumed algorithm. - * passphrase.c (passphrase_to_dek): Use the same algorithm as above. - (proc_symkey_enc): Print the algorithm, so that the user knows it - before entering the passphrase. - (proc_pubkey_enc, proc_pubkey_enc): Zero the DEK out. - * encode.c (encode_crypt, encrypt_filter): Ditto. - - * g10.c: Allow for --sign --symmetric. - * sign.c (sign_and_symencrypt): New. - - Applied patches from Stefan Bellon <sbellon@sbellon.de> to support - RISC OS. Nearly all of these patches are identified by the - __riscos__ macro. - * compress.c: Added a couple of casts. - * g10.c [__riscos__]: Some patches and new options foo-file similar - to all foo-fd options. - * gpgv.c, openfile.c, ringedit.c, tdbio.c: Minor fixes. Mainly - replaced hardcoded path separators with EXTSEP_S like macros. - * passprase.c [__riscos__]: Disabled agent stuff - * trustdb.c (check_trust): Changed r_trustlevel to signed int to - avoid mismatch problems in pkclist.c - * pkclist.c (add_ownertrust): Ditto. - * plaintext.c (handle_plaintext) [__riscos__]: Print a note when - file can't be created. - * options.h [__riscos__]: Use an extern unless included from the - main module. - * signal.c (got_fatal_signal) [__riscos__]: Close all files. - -2001-08-14 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_algo): New arg r_usage. Allow for RSA keys. - (gen_rsa): Enabled the code. - (do_create): Enabled RSA branch. - (parse_parameter_usage): New. - (proc_parameter_file): Handle usage parameter. - (read_parameter_file): Ditto. - (generate_keypair): Ditto. - (generate_subkeypair): Ditto. - (do_generate_keypair): Ditto. - (do_add_key_flags): New. - (keygen_add_std_prefs): Use the new function. - (keygen_add_key_flags_and_expire): New. - (write_selfsig, write_keybinding): Handle new usage arg. - * build-packet.c (build_sig_subpkt): Make sure that key flags go - into the hashed area. - - * keygen.c (write_uid): Initialize the reference cunter. - - * keyedit.c (keyedit_menu): No more need to update the trustdb for - preferences. Added calls to merge keblock. - - * kbnode.c (dump_kbnode): Print some more flags. - -2001-08-10 Werner Koch <wk@gnupg.org> - - Revamped the preference handling. - - * packet.h (prefitem_t, preftype_t): New. - (PKT_public_key): Added a uid field. - (PKT_user_id): Added field to store preferences and a reference - counter. - * parse-packet.c (parse_user_id,parse_photo_id): Initialize them - * free-packet.c (free_user_id): Free them. - (copy_user_id): Removed. - (scopy_user_id): New. - (cmp_user_ids): Optimized for identical pointers. - (release_public_key_parts): Release the uid. - (copy_public_key_with_new_namehash): Removed. - (copy_prefs): New. - * keyedit.c (menu_adduid): Use the new shallow copy user id. - (show_prefs): Adjusted implementation. - (keyedit_menu): No more need to update the trustdb after changing - preferences. - * getkey.c (fixup_uidnode): Store preferences. - (find_by_name): Return a user id packet and remove namehash stuff. - (lookup): Removed the unused namehash stuff. - (finish_lookup): Added foundu arg. - (pk_from_block): Removed the namehash arg and changed all callers. - (merge_selfsigs): Copy prefs to all keys. - * trustdb.c (get_pref_data): Removed. - (is_algo_in_prefs): Removed. - (make_pref_record): Deleted and removed all class. - * pkclist.c (select_algo_from_prefs): Adjusted for the new - preference implementation. - * pubkey-enc.c (is_algo_in_prefs): New. - (get_it): Use that new function. - -2001-08-09 Werner Koch <wk@gnupg.org> - - * build-packet.c (build_sig_subpkt): Fixed calculation of - newarea->size. - - * g10.c (main): New option "--preference-list" - * keyedit.c (keyedit_menu): New commands "setpref" and "updpref". - (menu_set_preferences): New. - * keygen.c (keygen_set_std_prefs): New. - (set_one_pref): New. - (check_zip_algo): New. - (keygen_get_std_prefs): New. - (keygen_upd_std_prefs): New - (keygen_add_std_prefs): Move the pref setting code into the above fnc. - * build-packet.c (build_sig_subpkt): Updated the list of allowed - to update subpackets. - -2001-08-08 Werner Koch <wk@gnupg.org> - - * packet.h (subpktarea_t): New. - (PKT_signature): Use that type for hashed_data and unhashed_data and - removed the _data prefix from those fields. Changed all users. - * parse-packet.c (parse_signature): Changed allocation for that. - (parse_sig_subpkt): Changed declaration - (enum_sig_subpkt): Ditto and changed implementation accordingly. - * free-packet.c (cp_subpktarea): Renamed from cp_data_block and - adjusted implementation. Changed caller. - * sig-check.c (mdc_kludge_check): Adjusted the hashing. - (do_check): Ditto. - * sign.c (sign_file, clearsign_file, make_keysig_packet, - update_keysig_packet): Ditto. - * build-packet.c (build_sig_subpkt): Partial rewrite. - (find_subpkt): Adjusted and made static. - (delete_sig_subpkt): Adjusted. - (do_signature): Ditto. - - * keygen.c (ask_keysize): Do not print the notes about suggested - key sizes if just a DSA key is generated. - - * trustdb.c (add_ultimate_key): s/log_error/log_info/ for - duplicated inserted trusted keys. - -2001-08-07 Werner Koch <wk@gnupg.org> - - * sign.c (sleep): Redefine for W32. - - * g10.c, options.h: Set new flag opt.no_homedir_creation when - --no-options is given. - * openfile.c (try_make_homedir): Don't create the homedir in that case. - -2001-08-03 Werner Koch <wk@gnupg.org> - - * armor.c (armor_filter): Removed the default comment string - because it could get us in trouble due to translations using non - ascii characters. - -2001-08-01 Werner Koch <wk@gnupg.org> - - * keylist.c (list_keyblock_print): Do not list revoked UIDs unless - in verbose mode and we do no signature listing. - - * getkey.c (finish_lookup): Skip subkeys which are not yet valid. - * g10.c, options.h: New option --ignore-valid-from. - - * sign.c (make_keysig_packet): Added new sigversion argument to - allow the caller to force generation of required signature - version. Changed all callers. Suggested by Thomas Roessler. - - * keyedit.c (sign_uids): Force v4 signature generation for local - sigs. Removed the check for local signature and pre-v4 keys. - -2001-07-27 Werner Koch <wk@gnupg.org> - - * keyedit.c (sign_uids): Check that we are not trying to to a - lsign with a pre-v4 key. Bug noticed by Thomas Roessler. - -2001-07-26 Werner Koch <wk@gnupg.org> - - * parse-packet.c (parse_photo_id): Reset all variables. - * getkey.c (merge_selfsigs_main): Removed checks on PHOTO_ID - because this is handled identically to a user ID. - -2001-07-06 Werner Koch <wk@gnupg.org> - - * cipher.c (write_header): Don't use MDC with --rfc1991. Suggested - by disastry@saiknes.lv. - -2001-07-05 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --preserve-permissions. - * ringedit.c (add_keyblock_resource): Use it here - (keyring_copy): and here. - - * trustdb.c (verify_own_keys): Be more silent on --quiet. - Suggested by Thomas Roessler. - * sig-check.c (check_key_signature2): Ditto. - * mainproc.c (proc_encrypted, proc_tree): Ditto - * getkey.c (lookup): Ditto. - -2001-07-04 Werner Koch <wk@gnupg.org> - - * ringedit.c (add_keyblock_resource): Restore filename in case of error. - -2001-06-25 Werner Koch <wk@gnupg.org> - - * kbnode.c (dump_kbnode): Print the signature timestamp. - - * keyedit.c (keyedit_menu): New menu point "primary". - (change_primary_uid_cb): New. - (menu_set_primary_uid): New. - * sign.c (update_keysig_packet): New. - * build-packet.c (build_sig_subpkt): Put the primary UID flag into - the hashed area. Allow update of some more packets. - -2001-06-15 Werner Koch <wk@gnupg.org> - - * getkey.c (merge_selfsigs): Exit gracefully when a secret key is - encountered. May happen if a secret key is in public keyring. - Reported by Francesco Potorti. - -2001-06-12 Werner Koch <wk@gnupg.org> - - * getkey.c (compare_name): Use ascii_memistr(), ascii_memcasecmp() - * keyedit.c (keyedit_menu): Use ascii_strcasecmp(). - * armor.c (radix64_read): Use ascii_toupper(). - * ringedit.c (do_bm_search): Ditto. - * keygen.c (read_parameter_file): Ditto. - * openfile.c (CMP_FILENAME): Ditto. - * g10.c (i18n_init): We can now use just LC_ALL. - -2001-05-29 Werner Koch <wk@gnupg.org> - - * keygen.c (generate_subkeypair): Print a warning if a subkey is - created on a v3 key. Suggested by Brian M. Carlson. - -2001-05-27 Werner Koch <wk@gnupg.org> - - * keyid.c (get_lsign_letter): New. - * keylist.c (list_keyblock_colon): Use it here. - * mainproc.c (list_node): and here. - - * getkey.c, packet.h, free-packet.c: Removed that useless key - created field; I dunno why I introducded this at all - the - creation time is always bound to the key packet and subject to - fingerprint calculation etc. - - * getkey.c (fixup_uidnode): Add keycreated arg and use this - instead of the signature timestamp to calculate the - help_key_expire. Bug reported by David R. Bergstein. - (merge_selfsigs_main): Correct key expiration time calculation. - (merge_selfsigs_subkey): Ditto. - -2001-05-25 Werner Koch <wk@gnupg.org> - - * revoke.c (gen_revoke): Add a cast to a tty_printf arg. - * delkey.c (do_delete_key): Ditto. - * keyedit.c (print_and_check_one_sig): Ditto. - (ask_revoke_sig): Ditto. - (menu_revsig): Ditto. - (check_all_keysigs): Removed unused arg. - -2001-05-23 Werner Koch <wk@gnupg.org> - - * g10.c (opts): Typo fix by Robert C. Ames. - -2001-05-06 Werner Koch <wk@gnupg.org> - - * revoke.c: Small typo fix - -2001-05-04 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_clear_cache): Shortcut if agent usage - is not enabled. - -2001-05-01 Werner Koch <wk@gnupg.org> - - * passphrase.c (writen): Replaced ssize_t by int. Thanks to - to Robert Joop for reporting that SunOS 4.1.4 does not have it. - -2001-04-28 Werner Koch <wk@gnupg.org> - - * getkey.c (merge_public_with_secret): pkttype was not set to subkey. - -2001-04-27 Werner Koch <wk@gnupg.org> - - * skclist.c (build_sk_list): Changed one log_debug to log_info. - -2001-04-25 Werner Koch <wk@gnupg.org> - - * keyedit.c (show_prefs): Add a verbose mode. - (show_key_with_all_names): Pass verbose flag for special value of - with_pref. - (keyedit_menu): New command "showpref" - (show_key_with_all_names): Mark revoked uids and the primary key. - -2001-04-24 Werner Koch <wk@gnupg.org> - - * getkey.c (get_primary_uid): Return a different string in case of - error and made it translatable. - - * build-packet.c (do_secret_key): Ugly, we wrote a zero - instead of the computed ndays. Thanks to M Taylor for complaining - about a secret key import problem. - -2001-04-23 Werner Koch <wk@gnupg.org> - - * hkp.c (hkp_ask_import): Allow to specify a port number for the - keyserver. Add a kudge to set the no_shutdown flag. - (hkp_export): Ditto. - * options.skel: Document the changes - -2001-04-20 Werner Koch <wk@gnupg.org> - - * options.skel: Add some more comments. - -2001-04-19 Werner Koch <wk@gnupg.org> - - * keyid.c (mk_datestr): New. Handles negative times. We must do - this because Windoze segvs on negative times passed to gmtime(). - Changed all datestr_from function to use this one. - - * keyid.c, keyid.h (colon_strtime): New. To implement the - fixed-list-mode. - (colon_datestr_from_pk): New. - (colon_datestr_from_sk): New. - (colon_datestr_from_sig): New. - * keylist.c (list_keyblock_colon): Use these functions here. - * mainproc.c (list_node): Ditto. - -2001-04-18 Werner Koch <wk@gnupg.org> - - * openfile.c (open_sigfile): Fixed the handling of ".sign". - * mainproc.c (proc_tree): Use iobuf_get_real_fname. - Both are by Vincent Broman. - -2001-04-14 Werner Koch <wk@gnupg.org> - - * getkey.c (fixup_uidnode): Removed check for !sig which is - pointless here. Thanks to Jan Niehusmann. - -2001-04-10 Werner Koch <wk@gnupg.org> - - * sig-check.c (check_key_signature2): Use log_info instead of - log_error so that messed up keys do not let gpg return an error. - Suggested by Christian Kurz. - - * getkey.c (merge_selfsigs_main): Do a fixup_uidnode only if we - have both, uid and sig. Thanks to M Taylor. - -2001-04-05 Werner Koch <wk@gnupg.org> - - * armor.c (unarmor_pump_new,unarmor_pump_release): New. - (unarmor_pump): New. - * pipemode.c (pipemode_filter): Use the unarmor_pump to handle - armored or non-armored detached signatures. We can't use the - regular armor_filter becuase this does only chack for armored - signatures the very first time. In pipemode we may have a mix of - armored and binary detached signatures. - * mainproc.c (proc_tree): Do not print the "old style" notice when - this is a pipemode processes detached signature. - (proc_plaintext): Special handling of pipemode detached sigs. - - * packet.h (CTRLPKT_PLAINTEXT_MARK): New. - * parse-packet.c (create_gpg_control): New. - * kbnode.c (dump_kbnode): Support it here. - * mainproc.c (check_sig_and_print): Fixed the check for bad - sequences of multiple signatures. - (proc_plaintext): Add the marker packet. - (proc_tree): We can now check multiple detached signatures. - -2001-04-02 Werner Koch <wk@gnupg.org> - - The length of encrypted packets for blocksizes != 8 was not - correct encoded. I think this is a minor problem, because we - usually use partial length packets. Kudos to Kahil D. Jallad for - pointing this out. - * packet.h: Add extralen to PKT_encrypted. - * cipher.c (write_header): Set extralen. - * build-packet.c (do_encrypted): Use extralen instead of const 10. - (do_encrypted_mdc): Ditto. - * parse-packet.c (parse_encrypted): Set extralen to 0 because we - don't know it here. - -2001-03-30 Werner Koch <wk@gnupg.org> - - * getkey.c (premerge_public_with_secret): Changed wording an add - the keyID to the info message. - -2001-03-29 Werner Koch <wk@gnupg.org> - - * getkey.c (premerge_public_with_secret): Use log_info instead of - log_error when no secret key was found for a public one. - Fix the usage if the secret parts of a key are not available. - - * openfile.c (ask_outfile_name): Trim spaces. - (open_outfile): Allow to enter an alternate filename. Thanks to - Stefan Bellon. - * plaintext.c (handle_plaintext): Ditto. - -2001-03-28 Werner Koch <wk@gnupg.org> - - * mainproc.c (do_check_sig): Allow direct key and subkey - revocation signature. - * sig-check.c (check_key_signature2): Check direct key signatures. - Print the signature class along with an error. - -2001-03-27 Werner Koch <wk@gnupg.org> - - * packet.h: Add a missing typedef to an enum. Thanks to Stefan Bellon. - - * g10.c: New option --no-sig-create-check. - * sign.c (do_sign): Implement it here. - * g10.c: New option --no-sig-cache. - * sig-check.c (check_key_signature2): Implement it here. - (cache_selfsig_result): and here. - - * keylist.c (list_keyblock): Removed debugging stuff. - - * getkey.c (cache_public_key): Made global. - * keygen.c (write_selfsig, write_keybinding): Cache the new key. - - * getkey.c (key_byname): Add new arg secmode and changed all - callers to request explicitly the mode. Deriving this information - from the other supplied parameters does not work if neither pk nor - sk are supplied. - -2001-03-25 Werner Koch <wk@gnupg.org> - - * packet.h (ctrlpkttype_t): New. - * mainproc.c (add_gpg_control,proc_plaintext,proc_tree): Use the - new enum values. - * pipemode.c (make_control): Ditto. - * armor.c (armor_filter): Ditto. - -2001-03-24 Werner Koch <wk@gnupg.org> - - * sign.c (do_sign): Verify the signature right after creation. - -2001-03-23 Werner Koch <wk@gnupg.org> - - * status.c, status.h (STATUS_UNEXPECTED): New. - * mainproc.c (do_proc_packets): And emit it here. - -2001-03-21 Werner Koch <wk@gnupg.org> - - * status.c: Add sys/types.h so that it runs on Ultrix. Reported - by Georg Schwarz.x - - * build-packet.c (build_sig_subpkt): Fixed generaton of packet - length header in case where 2 bytes headers are needed. Thanks to - Piotr Krukowiecki. - -2001-03-19 Werner Koch <wk@gnupg.org> - - * g10.c (main): the default keyring is no always used unless - --no-default-keyring is given. - - * ringedit.c (add_keyblock_resource): invalidate cache after file - creation. - -2001-03-15 Werner Koch <wk@gnupg.org> - - * keygen.c (ask_algo): Changed the warning of the ElGamal S+E Algo. - - * keylist.c (print_capabilities): New. - (list_keyblock_colon): and use it here. - -2001-03-13 Werner Koch <wk@gnupg.org> - - * main.c, options.h: New option --fixed_list_mode. - * keylist.c (list_keyblock_colon): use it here. - - * getkey.c (merge_keys_and_selfsig): Divert merging of public keys - to the function used in key selection.. - * keylist.c (is_uid_valid): Removed. - (list_keyblock): Splitted into .. - (list_keyblock_print, list_keyblock_colon): .. these. - functions. Changed them to use the flags set in the key lookup code. - (reorder_keyblock): New, so that primary user IDs are listed first. - - * ringedit.c (keyring_copy): flush the new iobuf chaces before - rename or remove operations. This is mainly needed for W32. - - * hkp.c [HAVE_DOSISH_SYSTEM]: Removed the disabled code because we - have now W32 socket support in ../util/http.c - - * skclist.c (key_present_in_sk_list): New. - (is_duplicated_entry): New. - (build_sk_list): Check for duplicates and do that before unlocking. - -2001-03-12 Werner Koch <wk@gnupg.org> - - * armor.c (parse_header_line): Removed double empty line check. - (parse_header_line): Replaced trim_trailing_ws with a counting - function so that we can adjust for the next read. - - * options.skel: Fixed 3 typos. By Thomas Klausner. Replaced the - keyserver example by a better working server. - - * parse-packet.c (parse_symkeyenc): Return Invalid_Packet on error. - (parse_pubkeyenc): Ditto. - (parse_onepass_sig): Ditto. - (parse_plaintext): Ditto. - (parse_encrypted): Ditto. - (parse_signature): Return error at other places too. - (parse_key): Ditto. - * g10.c (main): Set opt.list_packets to another value when invoked - with the --list-packets command. - * mainproc.c (do_proc_packets): Don's stop processing when running - under --list-packets command. - - * signal.c (do_sigaction): Removed. - (init_one_signal): New to replace the above. Needed to support - systems without sigactions. Suggested by Dave Dykstra. - (got_fatal_signal,init_signals): Use the above here. - (do_block): Use sigset() if sigprocmask() is not available. - - * armor.c (parse_hash_header): Test on TIGER192, which is the - correct value as per rfc2440. By Edwin Woudt. - -2001-03-08 Werner Koch <wk@gnupg.org> - - * misc.c: Include time.h. By James Troup. - - * getkey.c: Re-enabled the unknown user Id and PK caches and - increased their sizes. - - * getkey.c (merge_selfsigs_main): Set expire date and continue - processing even if we found a revoked key. - (merge_selfsigs_subkeys): Ditto. - - * packet.h: Add an is_revoked flag to the user_id packet. - * getkey.c (fixup_uidnode): Set that flag here. - (merge_selfsigs_main): Fix so that the latest signature is used to - find the self-signature for an UID. - * parse-packet.c (parse_user_id): Zero out all fields. - * mainproc.c (check_sig_and_print): Print the primary user ID - according the the node flag and then all other non-revoked user IDs. - (is_uid_revoked): Removed; it is now handled by the key selection code. - - Changed the year list of all copyright notices. - -2001-03-07 Werner Koch <wk@gnupg.org> - - * getkey.c (finish_lookup): Print an info message only in verbose mode. - -2001-03-05 Werner Koch <wk@gnupg.org> - - * packet.h: Replaced sigsubpkt_t value 101 by PRIV_VERIFY_CACHE. - We have never used the old value, so we can do this without any harm. - * parse-packet.c (dump_sig_subpkt): Ditto. - (parse_one_sig_subpkt): Parse that new sub packet. - * build-packet.c (build_sig_subpkt): Removed the old one from the - hashed area. - (delete_sig_subpkt): New. - (build_sig_subpkt): Allow an update of that new subpkt. - * sig-check.c (check_key_signature2): Add verification caching - (cache_selfsig_result): New. - * export.c (do_export_stream): Delete that sig subpkt before exporting. - * import.c (remove_bad_stuff): New. - (import): Apply that function to all imported data - -2001-03-03 Werner Koch <wk@gnupg.org> - - * getkey.c: Introduced a new lookup context flag "exact" and used - it in all place where we once used primary. - (classify_user_id2): Replaced the old function and add an extra - argument to return whether an exact keyID has been requested. - (key_byname): Removed the unused ctx.primary flag - (get_seckey_byname2): Ditto. - (finish_lookup): Changed debugging output. - -2001-03-02 Werner Koch <wk@gnupg.org> - - * keylist.c (list_one): Remove the merge key calls. - -2001-03-01 Werner Koch <wk@gnupg.org> - - * getkey.c (finish_lookup): Don't use it if we no specific usage - has been requested. - (merge_selfsigs_main): fix UID only if we have an signature. - (lookup): Return UNU_PUBKEY etc. instead of NO_PUBKEY if we found - a key but the requested usage does not allow this key. - * import.c (import_one): Take UNU_PUBKEY into account. - * mainproc.c (list_node): Ditto. - * keylist.c (list_keyblock): Ditto. - * keyedit.c (print_and_check_one_sig): Ditto. - -2001-02-09 Werner Koch <wk@gnupg.org> - - * delkey.c (delete_key): Removed that silly assert which rendered - the whole new stuff meaningless. - -2001-02-08 Werner Koch <wk@gnupg.org> - - * getkey.c (key_byname): It can happen that we have both, sk and pk - NULL, fix for that. - - * parse-packet.c (parse_one_sig_subpkt): Add support for - primary_uid and key_flags. - (can_handle_critical): Ditto - - * parse-packet.c (parse_encrypted): Fixed listing of pktlen for - MDC packets. - - * getkey.c: Backported the version of this file from gpg 1.1. this - involved some changes in other files too. - * parse-packet.c (parse_key): Clear req_usage. - * skclist.c (build_sk_list): Use req_usage to pass the usage - information to the lookup function. - * pkclist.c (build_pk_list): Ditto. - * free-packet.c (copy_public_parts_to_secret_key): New. - * keydb.h: Add IS_* macros to check the sig_class. - * misc.c (openpgp_cipher_test_algo): New. - (openpgp_pk_test_algo): New. - (openpgp_pk_algo_usage): New. - (openpgp_md_test_algo): New. - * packet.h: Add a few fields to PKT_{public,secret}_key and - PKT_user_id. - * seckey-cert.c (do_check): Use the new main_keyid field. - -2001-02-04 Werner Koch <wk@gnupg.org> - - * encr-data.c (decrypt_data): Catch error when we had problems to - parse the encrypted packet. By Timo. - -2001-01-29 Werner Koch <wk@gnupg.org> - - * g10.c (main): --batch does now set nogreeting. - - * delkey.c (do_delete_key): Fixed delete-both functionality. - -2001-01-22 Werner Koch <wk@gnupg.org> - - * g10.c: New command --delete-secret-and-public-key. - * delkey.c (delete_key): Add new arg allow_both. - (do_delete_key): Move most stuff from above to this new function. - -2001-01-12 Werner Koch <wk@gnupg.org> - - * passphrase.c (passphrase_to_dek): Use MD5 when IDEA is installed - and we have no S2K. - * mainproc.c (proc_encrypted): Likewise - -2001-01-11 Werner Koch <wk@gnupg.org> - - * sig-check.c (do_check): Print the signature key expire message - only in verbose mode and added the keyID. - -2001-01-09 Werner Koch <wk@gnupg.org> - - * status.c, status.h: New status USERID_HINT. - (write_status_text): Replace LF and CR int text by C-escape sequence. - - * passphrase.c (passphrase_to_dek): Fixed the NEED_PASSPHRASE - output. It does now always print 2 keyIDs. Emit the new - USERID_HINT. - -2001-01-08 Werner Koch <wk@gnupg.org> - - * g10.c, options.h: New option --no-expensive-trust-checks. - * keylist.c (list_keyblock): Act on this option. - -2001-01-04 Werner Koch <wk@gnupg.org> - - * g10.c (main): Set homedir only in the pre-parsing phase and - replace backslashes in the W32 version. - -2001-01-03 Werner Koch <wk@gnupg.org> - - * status.c, status.h : New status KEY_CREATED - * keygen.c (do_generate_keypair,generate_subkeypair): Emit it. - -2000-12-28 Werner Koch <wk@gnupg.org> - - * signal.c (got_fatal_signal): Remove lockfiles here because the - atexit stuff does not work due to the use of raise. Suggested by - Peter Fales. - * gpgv.c (remove_lockfiles): New stub. - -2000-12-19 Werner Koch <wk@gnupg.org> - - * status.c, status.h (cpr_get_no_help): New. - * keyedit.c (keyedit_menu): Use it here because we have our own - help list here. - -2000-12-18 Werner Koch <wk@gnupg.org> - - * mainproc.c (print_failed_pkenc): Don't print the sometimes - confusing message about unavailabe secret key. Renamed ... - (print_pkenc_list): ... to this and introduced failed arg. - (proc_encrypted): Print the failed encryption keys and then - the one to be used. - (proc_pubkey_enc): Store also the key we are going to use. - - * mainproc.c (check_sig_and_print): Don't list revoked user IDs. - (is_uid_revoked): New. - -2000-12-08 Werner Koch <wk@gnupg.org> - - * pipemode.c: Made the command work. Currently only for - non-armored detached signatures. - * mainproc.c (release_list): Reset the new pipemode vars. - (add_gpg_control): Handle the control packets for pipemode - * status.c, status.h: New stati {BEGIN,END}_STREAM. - -2000-12-07 Werner Koch <wk@gnupg.org> - - * g10.c: New option --allow-secret-key-import. - * import.c (import_keys,import_keys_stream): Honor this option. - (import): New arg allow_secret and pass that arg down to ... - (import_secret_one): to this and print a warning if secret key - importing is not allowed. - -2000-12-05 Werner Koch <wk@gnupg.org> - - * cipher.c (cipher_filter): Moved the end_encryption status ... - * encode.c (encode_simple,encode_crypt): to here - * sign.c (sign_file): and here. - - * status.c (mywrite): Removed. - (get_status_string): Removed the LFs from the strings. - (set_status_fd,is_status_enabed,write_status_text, - write_status_buffer): Replaced all mywrite by stdio calls and use - fdopen to create a strem. This is needed to make things smoother - in the W32 version. - -2000-12-04 Werner Koch <wk@gnupg.org> - - * import.c (merge_blocks): Increment n_sigs for revocations. - -2000-11-30 Werner Koch <wk@gnupg.org> - - * g10.c (main): Use iobuf_translate_file_handle for all options - with filehandles as arguments. This is function does some magic - for the W32 API. - - * verify.c (verify_signatures): Add a comment rant about the - detached signature problem. - * mainproc.c (proc_tree): Issue an error if a detached signature - is assumed but a standard one was found. - * plaintext.c (hash_datafiles): Don't fall back to read signature - from stdin. - * openfile.c (open_sigfile): Print verbose message only if the - file could be accessed. - -2000-11-24 Werner Koch <wk@gnupg.org> - - * passphrase.c [HAVE_DOSISH_SYSTEM]: Disabled all the agent stuff. - -2000-11-16 Werner Koch <wk@gnupg.org> - - * g10.c: New option --use-agent - * passphrase.c (agent_open,agent_close): New. - (agent_get_passphrase,agent_clear_passphrase): New. - (passphrase_clear_cache): New. - (passphrase_to_dek): Use the agent here. - * seckey-cert.c (do_check): Clear cached passphrases. - -2000-11-15 Werner Koch <wk@gnupg.org> - - * status.c (write_status_text): Moved the big switch to ... - (get_status_string): ... new function. - (write_status_buffer): New. - - * status.c (mywrite): New and replaced all write() by this. - - * status.c, status.h: Add 3 status lcodes for notaions and policy. - * mainproc.c (print_notation_data): Do status output of notations. - -2000-11-13 Werner Koch <wk@gnupg.org> - - * sign.c (clearsign_file): Use LF macro to print linefeed. - -2000-11-11 Paul Eggert <eggert@twinsun.com> - - Clean up the places in the code that incorrectly use "long" or - "unsigned long" for file offsets. The correct type to use is - "off_t". The difference is important on large-file hosts, - where "off_t" is longer than "long". - - * keydb.h (struct keyblock_pos_struct.offset): - Use off_t, not ulong, for file offsets. - * packet.h (dbg_search_packet, dbg_copy_some_packets, - search_packet, copy_some_packets): Likewise. - * parse-packet.c (parse, dbg_search_packet, search_packet, - dbg_copy_some_packets, copy_some_packets): Likewise. - * ringedit.c (keyring_search): Likewise. - - * parse-packet.c (parse): Do not use %lu to report file - offsets in error diagnostics; it's not portable. - * ringedit.c (keyring_search): Likewise. - -2000-11-09 Werner Koch <wk@gnupg.org> - - * g10.c (main): New option --enable-special-filenames. - -2000-11-07 Werner Koch <wk@gnupg.org> - - * g10.c (main): New command --pipemode. - * pipemode.c: New. - -2000-10-23 Werner Koch <wk@gnupg.org> - - * armor.c (armor_filter): Changed output of hdrlines, so that a CR - is emitted for DOS systems. - - * keygen.c (read_parameter_file): Add a cast for isspace(). - - * status.c (myread): Use SIGINT instead of SIGHUP for DOS. - -2000-10-19 Werner Koch <wk@gnupg.org> - - * g10.c: New option --ignore-crc-error - * armor.c (invalid_crc): New. - (radix64_read): Act on new option. - - * openfile.c (try_make_homedir): Klaus Singvogel fixed a stupid - error introduced on Sep 6th. - -2000-10-18 Werner Koch <wk@gnupg.org> - - * misc.c (print_cipher_algo_note): Don't print the note for AES. - Changed wording. - -2000-10-16 Werner Koch <wk@gnupg.org> - - * mainproc.c (do_proc_packets): Hack to fix the problem that - signatures are not detected when there is a MDC packet but no - compression packet. - - * g10.c (print_hashline): New. - (print_mds): Use above func with --with-colons. - - * mainproc.c (check_sig_and_print): Detect multiple signatures - and don't verify them. - -2000-10-14 Werner Koch <wk@gnupg.org> - - * mainproc.c (add_onepass_sig): There is an easier solution to the - error fixed yesterday; just check that we only have onepass - packets. However, the other solution provides an cleaner - interface and opens the path to get access to other information - from the armore headers. - (release_list): Reset some more variables. - -2000-10-13 Werner Koch <wk@gnupg.org> - - * mainproc.c (add_gpg_control): New. - (do_proc_packets): use it. - (proc_plaintext): Changed logic to detect clearsigns. - (proc_tree): Check the cleartext sig with some new code. - - * packet.h: New packet PKT_GPG_CONTROL. - * parse-packet.c (parse_gpg_control): New. - * misc.c (get_session_marker): New. - * armor.c (armor_filter): Replaced the faked 1-pass packet by the - new control packet. - - * keyedit.c (keyedit_menu): Allow batchmode with a command_fd. - * status.c (my_read): New. - (do_get_from_fd): use it. - -2000-10-12 Werner Koch <wk@gnupg.org> - - * keygen.c (keygen_add_std_prefs): Add Rijndael to the prefs. - -2000-10-07 Werner Koch <wk@gnupg.org> - - * gpgv.c: Add more stubs for ununsed code to make the binary smaller. - -Wed Oct 4 15:50:18 CEST 2000 Werner Koch <wk@openit.de> - - * sign.c (hash_for): New arg to take packet version in account, changed - call callers. - - * gpgv.c: New. - * Makefile.am: Rearranged source files so that gpgv can be build with - at least files as possible. - -Mon Sep 18 12:13:52 CEST 2000 Werner Koch <wk@openit.de> - - * hkp.c (not_implemented): Print a notice for W32 - -Fri Sep 15 18:40:36 CEST 2000 Werner Koch <wk@openit.de> - - * keygen.c (keygen_add_std_prefs): Changed order of preferences to - twofish, cast5, blowfish. - - * pkclist.c (algo_available): Removed hack to disable Twofish. - -Thu Sep 14 17:45:11 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (dump_sig_subpkt): Dump key flags. Print special - warning in case of faked ARRs. - - * getkey.c (finsih_lookup): Hack so that for v4 RSA keys the subkey - is used for encryption. - -Thu Sep 14 14:20:38 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c (main): Default S2K algorithms are now SHA1 and CAST5 - this - should solve a lot of compatibility problems with other OpenPGP - apps because those algorithms are SHOULD and not optional. The old - way to force it was by using the --openpgp option whith the drawback - that this would disable a couple of workarounds for PGP. - - * g10.c (main): Don't set --quite along with --no-tty. By Frank Tobin. - - * misc.c (disable_core_dump): Don't display a warning here but a return - a status value and ... - * g10.c (main): ...print warnining here. Suggested by Sam Roberts. - -Wed Sep 13 18:12:34 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (keyedit_menu): Allow to use "debug" on the secret key. - - * ringedit.c (cmp_seckey): Fix for v4 RSA keys. - * seckey-cert.c (do_check): Workaround for PGP 7 bug. - -Wed Sep 6 17:55:47 CEST 2000 Werner Koch <wk@openit.de> - - * misc.c (print_pubkey_algo_note): Do not print the RSA notice. - * sig-check.c (do_signature_check): Do not emit the RSA status message. - * pubkey-enc.c (get_session_key): Ditto. - - * encode.c (encode_simple, encode_crypt): Fix for large files. - * sign.c (sign_file): Ditto. - -Wed Sep 6 14:59:09 CEST 2000 Werner Koch <wk@openit.de> - - * passphrase.c (hash_passphrase): Removed funny assert. Reported by - David Mathog. - - * openfile.c (try_make_homedir): Changes for non-Posix systems. - * g10.c (main): Take the default homedir from macro. - - * g10.c: The --trusted-key option is back. - * trustdb.c (verify_own_key): Handle this option. - (add_ultimate_key): Moved stuff from verify_own_key to this new func. - (register_trusted_key): New. - -Fri Aug 25 16:05:38 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (dump_sig_subpkt): Print info about the ARR. - - * openfile.c (overwrite_filep): Always return okay if the file is - called /dev/null. - (make_outfile_name): Add ".sign" to the list of know extensions. - (open_sigfile): Ditto. - -Wed Aug 23 19:52:51 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New option --allow-freeform-uid. By Jeroen C. van Gelderen. - * keygen.c (ask_user_id): Implemented here. - -Fri Aug 4 14:23:05 CEST 2000 Werner Koch <wk@openit.de> - - * status.c (do_get_from_fd): Ooops, we used fd instead of opt.command_fd. - Thanks to Michael Tokarev. - -Tue Aug 1 20:06:23 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New opttion --try-all-secrets on suggestion from Matthias Urlichs. - * pubkey-enc.c (get_session_key): Quite easy to implement here. - -Thu Jul 27 17:33:04 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New option --merge-only. Suggested by Brendan O'Dea. - * import.c (import_one): Implemented it here - (import_secret_one): Ditto. - (print_stats): and give some stats. - -Thu Jul 27 12:01:00 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New options --show-session-key and --override-session-key - * pubkey-enc.c (hextobyte): New. - (get_override_session_key): New. - * mainproc.c (proc_pubkey_enc): Add session-key stuff. - * status.h, status.c (STATUS_SESSION_KEY): New. - -Thu Jul 27 10:02:38 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c (main): Use setmode(O_BINARY) for MSDOS while generating random bytes - (print_mds): Likewise for stdin. - * plaintext.c (handle_plaintext): Likewise for stdout. - -Mon Jul 24 10:30:17 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (menu_expire): expire date for primary key can be set again. - -Wed Jul 19 11:26:43 CEST 2000 Werner Koch <wk@openit.de> - - * keylist.c (is_uid_valid): New. - (list_keyblock): Print validity information for all user IDs. Note, this - has to be done at other places too; for now we have only minimal support. - -Wed Jul 12 13:32:06 CEST 2000 Werner Koch <wk@openit.de> - - * helptext.c, pkclist.c: s/superseeded/superseded/ - -Mon Jul 10 16:08:57 CEST 2000 Werner Koch <wk@openit.de> - - * parse-packet.c (enum_sig_subpkt): Fixed testing on crtitical bit in case - of a NULL buffer. Reported by Peter Marschall. - -Wed Jul 5 13:28:45 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c, keyid.c: Add some _() - - * argparse.c: Changed the flag to suppress --version handling to also - suppress --help. - -Wed Jun 28 11:54:44 CEST 2000 Werner Koch <wk@openit.de> - - * armor.c (armor_filter): Set sigclass to 0 in case of non-dash-escaped - clearsig. This makes this mode work again. - - * mainproc.c (proc_tree): Fixed handling of one-pass-sig packets in textmode. - Disabled the ugly workaround for PGP 5 - let's see whether thi breaks less - cases. Found by Ted Cabeen. - - * options.h (DBG_HASHING): New. All commented md_start_debug are now - controlled by this debug option. - - * sign.c (print_status_sig_created): New and called from 2 places. - - * keygen.c (gen_rsa): New, but commented. - (ask_algo): Commented support for RSA. - - * seckey-cert.c (protect_secret_key): Started to fix the code for v4 RSA - keys - it is not solved yet. However, we have time until, Sep 20th ;) - -Wed Jun 14 12:27:09 CEST 2000 Werner Koch <wk@openit.de> - - * status.c (init_shm_coprocessing): Changed the sequence of the get,attach - to cope with the changes in newer Linux kernels. This bug has been found - by <dmitri@advantrix.com> who also proposed this solution. Hopefully - this does not break gpg on to many systems. - - * cipher.c (write_header): Protect the IV with the MDC too. - * encr-data.c (decrypt_data): Likewise. - -Fri Jun 9 10:09:52 CEST 2000 Werner Koch <wk@openit.de> - - * g10.c: New options --no-auto-key-retrieve - * options.h (auto_key_retrieve): New. - * mainproc.c (check_sig_and_print): Implemented that. - -Wed Jun 7 19:19:09 CEST 2000 Werner Koch <wk@openit.de> - - * sig-check.c (do_check): Use EMULATE_MDENCODE also on v4 packets. - -Wed Jun 7 17:25:38 CEST 2000 Werner Koch <wk@openit.de> - - * cipher.c (write_header): Use plain CFB mode for MDC encrypted packets. - * encr-data.c (decrypt_data): Ditto. - -Mon Jun 5 23:41:54 CEST 2000 Werner Koch <wk@openit.de> - - * seskey.c (do_encode_md, encode_md_value): Add new arg v3compathack to work - around a bug in old versions. - * sig-check.c (do_check): use the aboved workaround when enabled. - * g10.c: New option --emulate-md-decode-bug - -Mon Jun 5 12:37:43 CEST 2000 Werner Koch <wk@openit.de> - - * build-packet.c (do_mdc): New. - (do_encrypted_mdc): Changed for the new proposal. - * parse-packet.c (parse_mdc): New. - (parse_encrypted): Fixed for the new proposal. - * packet.h (PKT_MDC): New. - * cipher.c (cipher_filter): Build the MDC packet here. - * g10.c (main): Enable --force-mdc. - * encr-data.c (mdc_decode_filter): Fixed for new MDC method - - * options.h(rfc2440): New. - * g10.c (main): Changed the selected values for --openpgp to not include - optional algorithms. - -Thu May 18 11:38:54 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (keyedit_menu): Add a keyword arg to the prompt. - - * status.c, status.h: Added 3 new status tokens. - * status.c (do_get_from_fd): New. - (cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt, - cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work - with the new function. - * g10.c: Add new option --command-fd. - - * status.c (progress_cb): New. - (set_status_fd): Register progress functions - -Fri May 12 14:01:20 CEST 2000 Werner Koch <wk@openit.de> - - * delkey.c (delete_key): Add 2 new status messages - * status.c, status.h (STATUS_DELETE_PROBLEM): New. - - Fixed years of copyright in all source files. - -Mon May 1 17:08:14 CEST 2000 Werner Koch <wk@openit.de> - - * trustdb.c (propagate_validity): Fixed the bug that only one uid - gets fully trusted even when all are signed by an ultimate key. - -Mon May 1 15:38:04 CEST 2000 Werner Koch <wk@openit.de> - - * getkey.c (key_byname): Always returned a defined context. Fixed - a segv for invalid user id specifications. Reported by Walter Koch. - - * getkey.c (get_user_id): I18ned "no user id" string. By Walter. - - * pkclist.c (do_show_revocation_reason): Typo fixes. - * helptext.c: Ditto. - - * armor.c (armor_filter): Fixed some CRLF issues. By Mike McEwan. - -Fri Apr 14 19:37:08 CEST 2000 Werner Koch <wk@openit.de> - - * pkclist.c (do_show_revocation_reason): New. - (show_revocation_reason): New and called at various places. - - * g10.c (main): Fixed small typo. - - * pkclist.c (do_we_trust): Act on always_trust but not for revoked - keys. Suggested by Chip Salzenberg. - - * g10.c: New option --lock-never. - - * ringedit.c (get_writable_keyblock_file): New. - * keygen.c (do_generate_keypair): Use this instead of the hardwired one. - - * keygen.c (ask_user_id): Check that the email address is in the - correct field. Suggested by Christian Kurz. - -Mon Apr 10 13:34:19 CEST 2000 Werner Koch <wk@openit.de> - - * keyedit.c (show_key_with_all_names): s/sbb/ssb/ - -Tue Mar 28 14:26:58 CEST 2000 Werner Koch <wk@openit.de> - - * trustdb.c (verify_own_keys): Do not print warning about unprotected - key when in quiet mode. - -Wed Mar 22 13:50:24 CET 2000 Werner Koch <wk@openit.de> - - * mainproc.c (print_userid): Do UTF8 conversion before printing. - * import.c (import_one): Ditto. - (import_secret_one): Ditto. - (delete_inv_parts): Ditto. - -Thu Mar 16 16:20:23 CET 2000 Werner Koch <wk@openit.de> - - * keylist.c (print_key_data): Handle a NULL pk gracefully. - - * getkey.c (merge_one_pk_and_selfsig): Fixed silly code for - getting the primary keys keyID but kept using the one from the - subkey. - * pubkey-enc.c (get_it): Print a note for expired subkeys. - - * getkey.c (has_expired): New. - (subkeys_expiretime): New. - (finish_lookup): Check for expired subkeys needed for encryption. - (merge_keys_and_selfsig): Fixed expiration date merging for subkeys. - - * keylist.c (list_keyblock): Print expiration time for "sub". - (list_one): Add missing merging for public keys. - * mainproc.c (list_node): Ditto. - -2000-03-14 13:49:38 Werner Koch (wk@habibti.openit.de) - - * keygen.c (keyedit_menu): Do not allow to use certain commands - while the secret key is selected. - -2000-03-09 12:53:09 Werner Koch (wk@habibti.openit.de) - - * keygen.c (ask_expire_interval): Movede parsig to ... - (parse_expire_string): ... this new function. And some new control - commands. - (proc_parameter_file): Add expire date parsing. - (do_generate_keypair): Allow the use of specified output files. - -2000-03-08 10:38:38 Werner Koch (wk@habibti.openit.de) - - * keygen.c (ask_algo): Removed is_v4 return value and the commented - code to create Elg keys in a v3 packet. Removed the rounding - of key sizes here. - (do_create): Likewise removed arg v4_packet. - (gen_elg): Likewise removed arg version. Now rounding keysizes here. - (gen_dsa): Rounding keysize now here. - (release_parameter_list): New - (get_parameter*): New. - (proc_parameter_file): New. - (read_parameter_file): New. - (generate_keypair): Splitted. Now uses read_parameter_file when in - batch mode. Additional argument to specify a parameter file. - (do_generate_keypair): Main bulk of above fucntion and uses the - parameter list. - (do_create): Don't print long notice in batch mode. - * g10.c (main): Allow batched key generation. - -Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de> - - * pubkey-enc.c (get_it): Print a note about unknown cipher algos. - - * g10.c (opts): Add a note to the help listing about the man page - and removed some options from the help listing. - - * keyedit.c (print_and_check_one_sig): Use a new function to truncate - the output of the user ID. Suggested by Jan-Benedict Glaw. - -Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de> - - * helptext.c: typo fix. - -Thu Feb 17 13:39:32 CET 2000 Werner Koch <wk@gnupg.de> - - * revoke.c: Removed a bunch of commented code. - - * packet.h (SIGSUBPKT_REVOC_REASON): New. - * build-packet.c (build_sig_subpkt): Support new sub packet. - * parse-packet.c (parse_one_sig_subpkt): Ditto. - (dump_sig_subpkt): Ditto. - * revoke.c (ask_revocation_reason): New. - (release_revocation_reason_info): New. - (revocation_reason_build_cb): New. - (gen_revoke): Ask for reason. - * main.h (struct revocation_reason_info): Add declaration. - * keyedit.c (menu_revsig): Add support for revocation reason. - (menu_revkey): Ditto. - (sign_uid_mk_attrib): Renamed to ... - (sign_mk_attrib): ... this, made static and add support for reasons. - -Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de> - - * build-packet.c (build_packet): Fixed fixing of old comment packets. - - * import.c (import_keys): Fixed importing from stdin when called with - nnames set to zero as it normally happens. - -Mon Feb 14 14:30:20 CET 2000 Werner Koch <wk@gnupg.de> - - * sig-check.c (check_key_signature2): Add new arg r_expired. - (do_signature_check): New arg to pass it down to ... - (do_check): New arg r-expire which is set when the signature - has expired. - * trustdb.c (check_sig_record): Set SIGF_EXPIRED flag and set - the expiretime to zero so that thi signature will not be checked - anymore. - -Fri Feb 11 17:44:40 CET 2000 Werner Koch <wk@gnupg.de> - - * g10.c (g10_exit): Update the random seed_file. - (main): Set the random seed file. New option --no-random-seed-file. - -Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de> - - * keyedit.c (menu_expire): Fixed segv due to unitialized sub_pk. - By Rémi. - -Thu Feb 10 11:39:41 CET 2000 Werner Koch <wk@gnupg.de> - - * keylist.c (list_keyblock): Don't print warnings in the middle of - regulat output lines. By Rémi. - - * sig-check.c: Include options.h - -Wed Feb 9 15:33:44 CET 2000 Werner Koch <wk@gnupg.de> - - * gpg.c: New option --ignore-time-conflict - * sig-check.c (do_check): Implemented this option. - * trustdb.c (check_trust): Ditto. - * sign.c (do_sign): Ditto. - * keygen.c (generate_subkeypair): Ditto. - - * encode.c (encode_simple): use iobuf_cancel after open failure. - Reported by Huy Le. - -Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de> - - * packet.h (STRING2KEY): Changed mode from byte to int. - * parse-packet.c (parse_key): Add the special GNU protection stuff - * build-packet.c (so_secret_key): Ditto. - * seckey-cert.c (do_check): Ditto. - * keyedit.c (change_passphrase): Ditto. - * export.c (export_secsubkeys): New. - (do_export_stream): Hack to export the primary key using mode 1001. - * g10.c: New command --export-secret-subkeys - -Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de> - - * armor.c (is_armored): Check for 1-pass-sig packets. Reported by - David Hallinan <hallinan@rtd.com>. - (armor_filter): Replaced one LF by the LF macro. Reported by - Wolfgang Redtenbacher. - -Wed Jan 5 11:51:17 CET 2000 Werner Koch <wk@gnupg.de> - - * g10.c (main): Reset new global flag opt.pgp2_workarounds - when --openpgp is used. - * mainproc.c (proc_plaintext): Do the PGP2,5 workarounds only - when the global flag is set. - (proc_tree): Ditto. - * textfilter.c (copy_clearsig_text): Ditto. - * armor.c (armor_filter): Ditto. - - * g10.c: New option --list-only - * mainproc.c (proc_tree): Don't do it if opt.list_only is active. - (proc_pubkey_enc): Implement option. - - * status.h, status.c ({BEGIN,END}_{EN,DE}CRYPTION): New. - * cipher.c (cipher_filter): New status outputs. - * mainproc.c (proc_encrypted): New status outputs. - -Fri Dec 31 14:08:15 CET 1999 Werner Koch <wk@gnupg.de> - - * armor.c (armor_filter): Made the "Comment:" header translatable. - - * hkp.c (hkp_import): Make sure that the program does not return - success when there is a connection problem. Reported by Phillip Jones. - -Sun Dec 19 15:22:26 CET 1999 Werner Koch <wk@gnupg.de> - - * armor.c (LF): Use this new macro at all places where a line LF - is needed. This way DOSish textfiles should be created when the - input data is also in dos mode. - * sign.c (LF): Ditto. - * textfilter.c (LF): Ditto. - (copy_clearsig_text): Disabled the forcing of CR,LF sequences - for DOS systems. - - * plaintext.c (handle_plaintext): Fixes for line endings on DOS. - and react on a LF in cleartext. - * armor.c (fake_packet): Restore the original line ending after - removing trailing spaces. - - * signal.c (got_fatal_signal): DOS fix. - -Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de> - - * mainproc.c (print_failed_pkenc): Fix for unknown algorithm. - Found by fygrave@epr0.org. - -Thu Dec 9 10:31:05 CET 1999 Werner Koch <wk@gnupg.de> - - * hkp.c: i18n the strings. - -Sat Dec 4 15:32:20 CET 1999 Werner Koch <wk@gnupg.de> - - * trustdb.c (verify_key): Shortcut for ultimately trusted keys. - -Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de> - - * pkclist.c (build_pk_list): Validate the trust using the namehash - if this one has been set by the key lookup. - - * g10.c: Add --delete-secret-key to the help page. - - * openfile.c (copy_options_file): Made static. - (try_make_homedir): New. - * ringedit.c (add_keyblock_resource): Use the try_make_hoemdir logic. - * tdbio.c (tdbio_set_dbname): Likewise. - - * keygen.c (generate_user_id): Use m_alloc_clear() here. We should - better use an allocation function specific to the user_id packet. - - * keygen.c (keygen_add_std_prefs): Changed symmetric preferences - to include Blowfish again. This is due to it's better speed compared - to CAST5. - - * g10.c (strusage): Print the home directory. - - * armor.c (armor_filter): Take action on the cancel control msg. - * filter.h (armor_filter_context_t): Add cancel flag. - -Mon Nov 29 21:52:11 CET 1999 Werner Koch <wk@gnupg.de> - - * g10.c: New option --fast-list-mode .. - * keylist.c (list_keyblock): .. and implemented. - * mainproc.c (list_node): Ditto. - - * import.c (mark_non_selfsigned_uids_valid): Fixed the case that there - is a uid without any packet following. - -Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de> - - * mainproc.c (proc_plaintext): Never enable the hash processing - when skip_verify is active. - - * armor.c (parse_header_line): Stop parsing on a WS line too. - Suggested by Aric Cyr. - - * tdbdump.c (HEXTOBIN): Changed the name of the argument, so that - traditional cpp don't mess up the macros. Suggested by Jos Backus. - - * mainproc.c (list_node): Print the PK algo in the --with-colon mode. - * keylist.c (list_keyblock): Ditto. - - * signal.c (got_fatal_signal): Found the reason why exit(8) did not - work - it is better to set the disposition back to default before - raising the signal. Print the notice on stderr always. - -Fri Nov 12 20:33:19 CET 1999 Werner Koch <wk@gnupg.de> - - * g10.c (make_username): Swapped the logic. - * keylist.c (public_key_list): Now takes a STRLIST as arg and moved - the creation ot this list to the caller, so that he can copy with - UTF-conversion of user IDs. Changed all callers. - (secret_key_list): Likewise. - - * getkey.c (get_user_id_string_native): New and ... - * encode.c (write_pubkey_enc_from_list): ... use it here. - - * pubring.asc: Updated. - - * packet.h (PKT_PHOTO_ID): New. - * parse-packet.c (parse_photo_id): New. - * build-packet.c (do_user_id: Handle photo IDs. - (build_packet): Change CTB for photo IDs - * free-packet.c (free_user_id): Release memory used for photo IDs - * sig-check.c (hash_uid_node): Handle photo IDs too. - * trustdb.c (print_uid_from_keyblock): Hash photo ID. - (make_uid_records): Ditto. - * getkey.c (find_by_name): Ditto. - * keyedit.c (show_prefs): Ditto. - * keylist.c (list_keyblock): Ditto. - -Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de> - - * keygen.c (ask_expire_interval): Print a warning for systems - with a signed 32 time_t if the exiration time is beyoind 2038. - -Fri Oct 8 20:40:50 CEST 1999 Werner Koch <wk@gnupg.de> - - * ringedit.c (enum_keyblocks): The last fix way really stupid; - reverted and set rt to Unknown. - -Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de> - - * ringedit.c (enum_keyblocks): Zero the entire kbpos out on open. - - * g10.c (oEntropyDLL): Removed option. - (main): Made the warning on development versions more verbose. - - * g10.c (oHonorHttpProxy): New option. - * hkp.c (hkp_ask_import,hkp_export): Implement this option. - * options.skel: Enable this option for new installations - -Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de> - - * import.c (import_keys): Changed calling interface, adjusted caller. - (import): Moved printing of stats out ... - (print_stats): New. ... to here. - (import_keys_stream): Call stats print here. - (import_keys): Print stats as totals for all files. - - * tdbio.h (DIRF_NEWKEYS): New - * tdbio.c (tdbio_dump_record): Print the new flag. - * trustdb.c (check_trust_record): New arg sigs_only. Adapted all - callers. - (do_update_trust_record): Removed recheck arg and add a new sigs_only - do we can later improve on the performance. Changed all callers too. - (check_trustdb): Evalutate the new flag and add a status output. - Do a check when the dir record has not been checked. - (build_cert_tree): Evaluate the new flag. - (check_trust): Ditto. Do a trust_record check, when the dir record - is not marked as checked. - (mark_fresh_keys): New. - (clear_lid_table): New. - (sync_trustdb): New. - * import.c (import_keys): Call sync_trustdb() after processing. - (import_keys_stream): Ditto. - * tdbdump.c (import_ownertrust): Ditto. - - * import.c (import_revoke_cert): Notify the trust DB. - (do_update_trust_record): Use |= to set the REVOKED bit and not &=; - shame on me for this bad copy+paste introduced bug. - (do_we_trust): Add trustmask to allow revoked key override to work. - Chnaged are to allow return of a mofified trustlevel. Adapted the - one caller. - - * g10.c: New options --emulate-3des-s2k-bug - * passphrase.c (hash_passphrase): Implemented above. - - * mainproc.c (proc_tree): Check for standalone signatures. - (do_check_sig): Print a notice for a standalone revocation - (check_sig_and_print): Do not print an error for unchecked standalone - revocations. - -Tue Sep 28 20:54:37 CEST 1999 Werner Koch <wk@gnupg.de> - - * encode.c (encode_simple): Use new CTB when we don't have the - length of the file. This is somewhat strange as the comment above - indicates that this part is actually fixed for PGP 5 - maybe I simply - lost the source line, tsss. - - * armor.c (armor_filter): Set a flag if no OpenPGP data has been found. - * verify.c (verify_signatures): Add an error helptext. - -Thu Sep 23 19:24:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (open_outfile): Fixed the 8dot3 handling. - - * passphrase.c (passphrase_to_dek): Print uid using utf8 func. - * delkey.c (delete_key): Ditto. - * pkclist.c (show_paths,do_edit_ownertrust,do_we_trust): Ditto - (do_we_trust_pre): Ditto. - * trustdb.c (print_user_id,check_uidsigs): Ditto. - * revoke.c (gen_revoke,ask_revoke_sig): Ditto. - -Thu Sep 23 09:52:58 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * verify.c (print_file_status): New. - (verify_one_file): Moved status print to th new fnc. Add error status. - * status.c, status.h (STATUS_FILE_ERROR): New - -Wed Sep 22 10:14:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (make_outfile_name): Use case-insenstive compare for - DOS systems. Add ".pgp" to the list of know extensions. - (open_outfile): For DOS systems try to replace the suffiy instead of - appending it. - - * status.c, status.h: Add STATUS_FILE_{START,DONE}. - * verify.c (verify_one_file): Emit these new stati. - - * sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:" - line. Those headers are now only _not_ printed when there are - only old-style keys _and_ all hashs are MD5. - -Mon Sep 20 12:24:41 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * verify.c (verify_files, ferify_one_file): New. - * g10.c: New command --verify-files - -Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: Add UK spelling as alias for armor options ;-) - - * import.c (append_uid): Fixed a SEGV when there is no selfsig and - no subkey. - (merge_sigs): Ditto. Removed the assertion. - -Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --entropy-dll-name - -Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * signal.c (got_fatal_signal): Print message using write(2) and - only for development versions. - -Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbio.c (tdbio_set_dbname): Use mkdir macro - * ringedit.c (add_keyblock_resource): Ditto. - -Fri Sep 3 10:04:45 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Skip keys set with --encrypt-to also - when asking for a key. - - * plaintext.c (handle_plaintext): Make sure that we don't read a - second EOF in the read loop for partial length packets. - - * mainproc.c (check_sig_and_print): print user ID as utf-8. - -Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (merge_blocks): First add new subkeys, then merge subkey - certificates. - (merge_sigs): Don't merge subkey signatures here. - -Wed Sep 1 15:30:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (ask_expire_interval): Fixed bug related to cpr_xx (tnx - Francis J. Lacoste). - -Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * plaintext.c (do_hash): Hash CR,LF for a single CR. - (ask_for_detached_datafile): Changed arguments to be closer to - those of hash_datafiles and cleanup the code a bit. - * mainproc.c (proc_tree): Workaround for pgp5 textmode detached - signatures. Changed behavior of asking for data file to be the same - as with provided data files. - - * keylist.c (list_keyblock): Use UTF8 print functions. - -Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (chk_self_sigs): some s/log_error/log_info/ so that gpg - does not return an error if a key has some invalid packets. - - * helptext.c: Fixed some typos and changed the way the - translation works. The english text is now the keyword for gettext - and not anymore the keyword supplied to the function. Done after - some discussion with Walter who thinks this is much easier for the - translators. - - * misc.c (disable_core_dumps): Don't do it for DOSish systems. - - * signal.c (signal_name): Bounds check on signum. - -Wed Aug 4 10:34:18 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pubring.asc: Updated. - - * pkclist.c (do_we_trust_pre,check_signatures_trust): Do not print - the warning about --always_trust when --quiet is used. - - * pkclist.c (fpr_info): New and called at several places. - - * parse-packet.c (dump_sig_subpkt): List revocation key contents. - -Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Fixed typo in format string. - - * trustdb.c (create_shadow_dir): Don't translate the error string. - - * g10.c (main): Fixed spelling of user-id. - * getkey.c (find_by_name_pk,find_by_name_sk, - find_by_keyid,find_by_keyid_sk): Ditto and translate it. - * import.c (mark_non_selfsigned_uids_valid,delete_inv_parts): Ditto. - - -Mon Jul 26 01:01:39 CEST 1999 Michael Roth <mroth@nessie.de> - - * g10.c, options.h: New options --no-literal and --set-filesize - - * encode.c (encode_simple, encode_crypt): Support for the options - --no-literal and --set-filesize. - - * sign.c (sign_file): ditto. - -Fri Jul 23 13:53:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * ringedit.c (enum_keyblocks): Removed annoying error message in cases - when we have no keyring at all to enum. - - * getkey.c (classify_user_id): Rewrote to relax the recognition of - keyIDs and fingerprints (Michael). - - * mainproc.c (check_sig_and_print): Print status NO_PUBKEY. - (print_failed_pkenc): Print status NO_SECKEY. - - * import.c (mark_non_selfsigned_uids_valid): New. - * g10.c: New option --allow-non-selfsigned-uid. - - * pkclist.c (print_fpr): New. - (do_we_trust_pre): Print the fpr before asking whether to use the key - anyway. - (do_edit_ownertrust): Likewise. - -Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * ringedit.c (enum_keyblocks): Removed annoying error message in cases - when we have no keyring at all to enum. - - * getkey.c (classify_user_id): Rewrote to relax the recognition of - keyIDs and fingerprints (Michael). - - * mainproc.c (check_sig_and_print): Print status NO_PUBKEY. - (print_failed_pkenc): Print status NO_SECKEY. - - * import.c (mark_non_selfsigned_uids_valid): New. - * g10.c: New option --allow-non-selfsigned-uid. - -Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New options --disable-{cipher,pubkey}-algo. - -Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.h (STATUS_IMPORTED): New. - * import.c (import): Print some status information (Holger Schurig). - - * g10.c (main): Make --no-greeting work again. Add a warning when - --force-mds is used. - -Tue Jul 13 17:39:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (do_edit_ownertrust): Changed the way help works. - (build_pk_list): Implemented default recipient stuff. - * g10.c: New options --default-recipient[-self] - (main): Suppress greeting in most cases, entering a passphrase or - a missing value is not considered to be interactive use. - Merged --print-md and --print-mds; the latter is now obsolete. - Changed the way --gen-random works and documented it. - Changed the way --gen-prime works and add a man entry. - * g10.c (MAINTAINER_OPTIONS): Removed. - -Mon Jul 12 18:45:57 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keyedit.c (keyedit_menu): Add arg sign_mode and changed callers - * g10.c (main): New command --lsign-key. - -Mon Jul 12 14:55:34 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (kidlist_item): New. - (release_list): Release failed pk-enc-list. - (print_failed_pkenc): New - (proc_encrypted): Print info about failed PK enc. - - * openfile.c (make_outfile_name): s/error/info/ - - * passphrase.c (passphrase_to_dek): Return an empty passphrase when - in batch mode and don't make the warning message fatal - * seckey-cert.c (check_secret_key): Try only once when in batch mode. - - * g10.c (make_username): New. - -Thu Jul 8 16:21:27 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * packet.h (PKT_ring_trust): New - * parse-packet.c (parse_trust): Store trust value - * build-packet (build_packet): Ignore ring trust packets. - * mainproc.c (add_ring_trust): New. - (list_node): Print "rtv" records. - * g10.c: New option --with-fingerprint. - - * trustdb.c (verify_own_keys): Don't insert if we are dry running - (check_trust): Ditto. - -Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * Makefile.am: Support for libtool. - - * keygen.c (ask_expire_interval): Hack to allow for an expire date. - - * trustdb.c (do_update_trust_record,update_trust_record): Splitted. - (check_trust_record): New. - (check_trust,build_cert_tree): Check the dir record as needed. - (upd_pref_record): Removed. - (make_pref_record): New. - (propagate_validity): Stop as soon as we have enough validity. - - * tbdio.c (MAX_CACHE_ENTRIES_HARD): Increased the limit. - - -Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (g10_exit): Dump random stats. - - * sig-check.c (check_key_signature,check_key_signature2): Enhanced - version and wrapper for old function. - (do_signature_check,signature_check): Ditto. - -Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * keyedit.c (show_key_with_all_names): Print a notice for disabled keys. - (enable_disable_keys): Add functionality - * pkclist.c (edit_ownertrust): preserve disabled state. - (build_pk_list): Skip disabled keys. - * trustdb.c (upd_one_ownertrust): Ditto. - (build_cert_tree): Mask the ownertrust. - (trust_letter): Mask the value. - (do_check): Take disabled flag into account. - - * passphrase.c (passphrase_to_dek): Add a pubkey_algo arg and changed - all callers. - - * g10.c (utf8_strings): 2 new options. - - * trustdb.c (insert_trust_record_by_pk): New, replaces the next one. - (insert_trust_record): Now takes a keyblock as arg. Changed all - callers to use the appropritae function. - - * openfile.c (ask_outfile_name): New. - * plaintext.c (handle_plaintext): Ask for filename if there is - no valid syntax. Don't use fname varbatim but filter it. - -Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * trustdb.h (TRUST_FLAG_DISABLED): New. - - * status.c (USE_CAPABILITIES): Capabilities support (Remi). - - * tdbio.c : Added new fields to the DIR record. - (tdbio_write_record): Fixed the update of the hash tables. - (tdbio_delete_record): Drop the record from the hash tables. - (drop_from_hashtbl): New. - - * status.c (cpr_get): Special online help mode. - * helptext.c ("keyedit.cmd"): Removed. - * keyedit.c (keyedit_menu): Use only help system. - (enable_disable_key): New bit doies not yet work. - -Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * dearmor.c (enarmor_file): Fixed comment string. - * tdbdump.c (export_ownertrust): Text fix. - * tbio.c (tdbio_invalid): Ditto. - - * parse-packet.c (parse_key): Made temp buffer larger. - - * Makefile.am (install-data-local): Add missing backslashes - -Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Made iterated+salted the default S2K method. - - * Makefile.am (install-data-local): Use DESTDIR. - - * passphrase.c (passphrase_to_dek): Emit missing-passphrase while in - batchmode. - - * parse-packet.c (parse_pubkeyenc): Fixed a SEGV. - -Mon Jun 14 21:18:54 CEST 1999 Michael Roth <mroth@nessie.de> - - * g10.c: New options --openpgp, --no-tty, --emit-version, - --default-comment and --lock-multiple - -Thu Jun 10 14:18:23 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * free-packet.c (free_encrypted): Fixed EOF case (Remi). - (free_plaintext): Ditto. - - * helptext.c (keyedit.delsig.unknown): New (Remi). - * keyedit.c (print_and_check_one_sig): Add arg print_without_key and - changed all callers to make use of it (Remi): - -Tue Jun 8 13:36:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (print_key_data): New and called elsewhere. - * g10.c: New option --with-key-data - -Wed Jun 2 14:17:19 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (proc_tree): Yet another bad hack to cope with - broken pgp2 created detached messages in textmode. - -Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * openfile.c (make_outfile_name): New. - * plaintext.c (handle_plaintext): Outputfile is now the inputfile - without the suffix. - * g10.c: New option --use-embedded-filename - -Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Fix for SHM init (Michael). - - * compress.c, encr-data.c, mdfilter.c, - plaintext.c, free-packet.c: Speed patches (Rémi). - -Thu May 27 09:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.c (cpr_get_answer_yes_no_quit): New. - * keyedit.c (menu_delsig): New. - (check_all_keysigs): Splitted. - (print_and_check_one_sig): New. - -Wed May 26 14:36:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * build-packet.c (build_sig_subpkt): Support large packets. - * parse-packet.c (enum_sig_subpkt): Replaces parse_sig_subpkt. - * mainproc.c (print_notation_data): Print all notation packets. - * g10.c (add_notation_data): Add a way to specify the critical flag. - (main): Add option --set-policy-url. - (check_policy_url): Basic checks. - * sign.c (mk_notation_and_policy): Replaces mk_notation. - - * parse-packet.c (can_handle_critical): Moved decision whether we can - handle critical subpacket to an extra function. - -Tue May 25 19:50:32 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sign.c (sign_file): Always use compression algo 1 for signed - onyl file becuase we can´ be sure the the verifier supports other - algorithms. - - * build-packet.c (build_sig_subpkt): Support for notation data. - * sign.c (sign_file,clearsign_file,make_keysig_packet): Ditto. - (mk_notation): New. - * g10.c (add_notation_data): New and add option -N - * mainproc.c (print_notation_data): New. - (check_sig_and_print): Print any notation data of the signed text. - -Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (check_signatures_trust): Print a warning and return - immediateley if opt.always_trust is true. - - * g10.c (main): Corrected handling of no-default-keyring - - * pkclist.c (algo_available): Disable Twofish until we have settled - how to do the MDC. - - * hkp.c: Disable everything for mingw32 - -Sat May 22 22:47:26 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (check_sig_and_print): Add sig creation time to the - VALIDSIG status output. Add more info to the ERRSIG output. - * sig-check.c (signature_check): Add sig time after epoch to SIG_ID. - - * import.c (import_one): Merge duplicate user IDs. - (collapse_uids): New. - * kbnode.c (move_kbnode): New. - (remove_kbnode): New. - * keyedit.c (keyedit_menu): Call collapse_uids. - - * g10.c: new option --logger-fd. - - * import.c: s/log_*_f/log_*/ - -Thu May 20 14:04:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (pull_in_libs): do the volatile only for gcc - - * sig-check (signature_check): Emit SIG_iD only for classes 0 and 1. - - * armor.c (armor_filter): Add detection of PGP2 created clearsigs. - (fake_packet): A tab is not a WS for pgp2 - handle this. - * textfilter.c (len_without_trailing_chars): New. - (copy_clearsig_text): Add pgp2mode arg. - * sign.c (clearsign_file): pass old_style to the above fnc. - - -Wed May 19 16:04:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --interactive. - - * mainproc.c (proc_plaintext): Add workaround for pgp2 bug - (do_check_sig): Ditto. - (proc_tree): Ditto. - * plaintext.c (do_hash): Ditto. - (hash_datafiles): Ditto, add an arg, changed all callers. - * mdfilter.c (md_filter): Add support for the alternate hash context. - -Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_encrypted): Support for PKT_ENCRYPTED_MDC. - * build-packet.c (do_encrypted_mdc): Ditto. - * cipher.c (write_header): Add mdc hashing. - (cipher_filter): write out the hash. - * mainproc.c (do_proc_packets): Add PKT_ENCRYPTED_MDC. - * encr-data.c (decrypt_data): Add mdc hashing. - (mdc_decode_filter): New. - - * parse-packet.c (parse_sig_subpkt): Fixed stupid bug for subpkt - length calculation - (parse_signature): Fixed even more stupid bug. - -Sat May 8 19:28:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * build-packet.c (do_signature): Removed MDC hack. - * encode.c (encode_crypt_mdc): Removed. - * mainproc.c (do_check_sig): Removed MDC hack. - (check_sig_and_print): Ditto. - * parse-packet.c (parse_signature): Ditto. - * sig-check.c (mdc_kludge_check): Ditto. - * free-packte.c (copy_signature, free_seckey_enc): Ditto. - - * parse-packet.c (parse_signature,parse_key): Store data of - unknown algorithms with mpi_set_opaque inseatd of the old - faked data stuff. - (read_rest): Removed. - (read_rest2): Renamed to read_rest - * build-packet.c (write_fake_data): Use mpi_get_opaque. - * free-packet.c (cp_fake_data): Removed and cahnged all callers - to use mpi_copy. - (free_pubkey_enc,free_seckey_enc,release_public_key_parts, - release_secret_key_parts): Use mpi_free for opaque data. - -Thu May 6 14:18:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (check_trust): Check for revoked subkeys. - * pkclist.c (do_we_trust): Handled revoked subkeys. - (do_we_trust_pre): Ditto. - (check_signatures_trust): Ditto. - - * build-packet.c (hash_public_key): Fix for ancient g10 keys. - - * mainproc.c (do_proc_packets): Return EOF if no data has been read. - * g10.c (main): Catch errors for default operation. - -Thu Apr 29 12:29:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sign.c (sign_file): Fixed hashing in case of no subpackets. - (clearsign_file): Ditto. - (make_keysig_packet): Ditto. - -Wed Apr 28 13:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keyedit.c (keyedit_menu): Add new command revkey. - * (menu_revkey): New. - - -Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_signature): Add the MDC hack. - * build-packet.c (do_signature): Ditto. - * free-packet.c (free_seckey_enc,copy_signature,cmp_signatures): Ditto. - * mainproc.c (do_check_sig): Ditto. - * sig-check.c (mdc_kludge_check): New. - * encode.c (encrypt_mdc_file): New. - - * keyedit.c (check_all_keysigs): List revocations. - * (menu_revsig): New. - * sign (make_keysig_packet): Support for class 0x30. - -Sun Apr 18 20:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (select_algo_from_prefs): Fixed the case that one key - has no preferences (Remi Guyomarch). - - keylist.c (list_keyblock): ulti_hack to propagate trust to all uids. - -Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * seckey-cert.c (do_check): Use real IV instead of a 0 one, so that - it works even if the length of the IV doesn't match the blocksize. - Removed the save_iv stuff. - (protect_secret_key): Likewise. Create the IV here. - * packet.h (PKT_secret_key): Increased size of IV field and add a - ivlen field. - * parse-packet.c (parse_key): Use the len protect.ivlen. - * build-packet.c (do_secret_key). Ditto. - - * getkey.c (key_byname): Close keyblocks. - - * Makefile.am (gpgm): Removed this - * g10.c: Merged gpg and gpgm - - * import.c (import): Utilize option quiet. - * tdbio.c (tdbio_set_dbname): Ditto. - * ringedit.c (add_keyblock_resource,keyring_copy): Ditto. - - * keyedit.c (sign_uids): Add some batch support. - - * g10.c (main): add call to tty_batchmode. - -Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * status.c (write_status_text): Some more status codes. - * passphrase_to_dek (passphrase_to_dek): add a status code. - * seckey_cert.c (check_secret_key): Likewise. - - * encr-data.c (decrypt_data): Reverse the last changes - * cipher.c (write_header): Ditto. - - * parse-packet.c (parse_key): Dropped kludge for ancient blowfish mode. - -Thu Apr 8 09:35:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * mainproc.c (proc_encrypted): Add a new status output - * passphrase.c (passphrase_to_dek): Ditto. - * status.h status.c: Add new status tokens. - -Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * encr-data.c (decrypt_data): Fixes for 128 bit blocksize - * cipher.c (write_header): Ditto. - * seckey-cert.c (do_check): Ditto. - (protect_secret_key). Ditto. - * misc.c (print_cipher_algo_note): Twofish is now a standard algo. - - * keygen.c (do_create): Fixed spelling (Gaël Quéri) - (ask_keysize): Only allow keysizes up to 4096 - - * ringedit.c (add_keyblock_resource): chmod newly created secrings. - - * import.c (delete_inv_parts): Fixed accidently deleted subkeys. - -Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c: Removed duped include (John Bley) - * mainproc.c: Ditto. - - * build-packet.c (hash_public_key): Fixed hashing of the header. - - * import.c (delete_inv_parts): Allow import of own non-exportable sigs. - -Sat Mar 20 13:59:47 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (fake_packet): Fix for not not-dash-escaped - -Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): Added command --recv-keys - * hkp.c (hkp_import): New. - -Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (check_trust): add new arg add_fnc and changed all callers. - (do_check): Ditto. - (verify_key): Ditto. - (propagate_validity): Use the new add_fnc arg. - (print_user_id): Add the FILE arg. - (propagate_ownertrust): New. - * pkclist.c (add_ownertrust_cb): New and changed the add_ownertrust - logic. - - * getkey.c (get_keyblock_bylid): New. - * trustdb.c (print_uid_from_keyblock): New. - (dump_tn_tree_with_colons): New. - (list_trust_path): Add colon print mode. - - * trustdb.c (insert_trust_record): Always use the primary key. - - * encode.c (encode_simple): Added text_mode filter (Rémi Guyomarch) - (encode_crypt): Ditto. - - * mainproc.c (proc_pubkey_enc): Added status ENC_TO. - * armor.c (armor_filter): Added status NODATA. - * passphrase.c (passphrase_to_dek): Always print NEED_PASSPHRASE - * seckey_cert.c (check_secret_key): Added BAD_PASS status. - - * g10.c (main): Set g10_opt_homedir. - -Sun Mar 14 19:34:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (do_create): Changed wording of the note (Hugh Daniel) - -Thu Mar 11 16:39:46 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbdump.c: New - - * trustdb.c (walk_sigrecs,do_list_sigs,list_sigs, - list_records,list_trustdb,export_ownertrust,import_ownertrust): Moved - to tdbdump.c - (init_trustdb): renamed to setup_trustdb. Changed all callers. - (do_init_trustdb): renamed to init_trustdb(). - * trustdb.c (die_invalid_db): replaced by tdbio_invalid. - * tdbio.c (tdbio_invalid): New. - - * import.c (delete_inv_parts): Skip non exportable signatures. - * keyedit.c (sign_uid_mk_attrib): New. - (sign_uids): Add the local argument. - (keyedit_menu): New "lsign" command. - * trustdb.c (register_trusted_key): Removed this and all related stuff. - * g10.c (oTrustedKey): Removed option. - - * tdbio.h (dir.valcheck): New trustdb field. - * tdbio.c: Add support for this field - (tdbio_read_modify_stamp): New. - (tdbio_write_modify_stamp): New. - * trustdb.c (do_check): Check against this field. Removed cache update. - (verify_key): Add cache update. - (upd_uid_record): Some functional changes. - (upd_cert_record): Ditto - -Wed Mar 10 11:26:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (list_keyblock): Fixed segv in uid. Print 'u' as - validity of sks. - -Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c (classify_user_id): Add new mode 12 (#<lid>). - - * seckey-cert.c (check_secret_key): replaced error by info. - - * trustdb.c (query_trust_info): Add another arg, changed all callers. - (check_trust): Ditto. - (do_check): Ditto. - (verify_key): Handle namehash. - * keylist.c (list_keyblock): print trust info for user ids. - - * sig-check.c (signature_check): Add sig-created to status output. - -Tue Mar 2 16:44:57 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c (copy_clearsig_text): New. - (clearsign): Removed. - * sign.c (clearsign_file): does not use textfiler anymore. - - * keygen.c (ask_user_id): print a note about the used charset. - -Tue Mar 2 10:38:42 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sig-check.c (signature_check): sig-id now works for all algos. - - * armor.c (armor_filter): Fixed armor bypassing. - -Sun Feb 28 19:11:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keygen.c (ask_user_id): Don't change the case of email addresses. - (has_invalid_email_chars): Adjusted. - - * keylist.c (list_one): Really list serect keys (Remi Guyomarch) - - * keyedit.c (menu_select_uid): Add some braces to make egcs happy. - (menu_select_key): Ditto. - - * mainproc.c (do_proc_packets): List sym-enc packets (Remi Guyomarch) - -Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (build_pk_list): Return error if there are no recipients. - - * sig-check.c (signature_check): New signature id feature. - * armor.c (make_radic64_string): New. - - * mainproc.c (proc_pubkey_enc): early check for seckey availability. - - * pkclist.c (do_we_trust_pre): print user id before asking. - - * ringedit.c (add_keyblock_resource,get_keyblock_handle): Cleaner - handling of default resource. - - -Thu Feb 25 18:47:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (algo_available): New. - (select_algo_from_prefs): Check whether algo is available. - - * ringedit.c (keyring_copy): Take care of opt.dry_run. - (do_gdbm_store): Ditto. - * openfile.c (open_outfile). Ditto. - (copy_options_file): Ditto. - * trustdb.c (update_trustdb): Ditto. - (clear_trust_checked_flag): Ditto. - (update_trust_record): Ditto. - (insert_trust_record): Ditto. - -Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * keylist.c (secret_key_list): Now really list the secret key. - - * trustdb.c (do_init_trustdb): New. Init is now deferred. - -Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c (lookup_sk): Return G10ERR_NO_SECKEY and not x_PUBKEY. - -Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (select_algo_from_prefs): retrieve LID if not there. - - * armor.c (fake_packet): Replaced ugly lineending handling. - - * g10.c (oNoEncryptTo): New. - * pkclist.c (build_pk_list): Implemented this option. - - * g10.c (main): Greeting is now printed to stderr and not to tty. - Use add_to_strlist() instead of direct coding. - - * import.c (import): Use iobuf_push_filter2. - - * mainproc.c (check_sig_and_print): Print all user ids - for good signatures. - * getkey.c (get_pubkeyblock): New. - - * import.c (chk_self_sigs): Fixed SEGV for unbounded class 0x18 keys. - (delete_inv_parts): Delete special marked packets. - -Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): New option --encrypt-to - - * pkclist.c (build_pk_list): Implemented encrypt-to. - - * parse-packet.c (parse_user_id): Removed the hack to work with - utf-8 strings. - - * g10.c (main): Install lockfile cleanup handler. - * tdbio.c (cleanup): Removed: this is now handled by dotlock. - -Sat Feb 13 14:13:04 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * tdbio.c (tdbio_set_dbname): Init lockhandle for a new trustdb - -Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c (main): check for development version now in configure - - * tdbio.c (tdbio_write_record): Add uid.validity - (tdbio_read_record) : Ditto. - (tdbio_dump_record) : Ditto. - - * keygen.c (keygen_add_std_prefs): Replaced Blowfish by Twofish, - removed MD5 and Tiger. - * pubkey-enc.c (get_it): Suppress warning about missing Blowfish - in preferences in certain cases. - - * ringedit.c (lock_rentry,unlock_rentry): New. - - * getkey.c (key_byname): Pass ret_kb down to lookup_xx. - - * armor.c (armor_filter): No output of of empty comment lines. - Add option --no-version to suppress the output of the version string. - - * getkey.c: Release the getkey context for auto context variables. - -Sun Jan 24 18:16:26 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * getkey.c: Changed the internal design to allow simultaneous - lookup of multible user ids - (get_pubkey_bynames): New. - (get_seckey_bynames): New. - (get_seckey_next): New. - (get_seckey_end): New. - * keylist.c (list_one): Use the new functions. - - * keylist.c (list_keyblock): add a newline for normal listings. - - * g10.c (--recipient): New option name to replace --remote-user - - -Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c: Mostly rewritten - * plaintext.c (handle_plaintext): Use now text_filter semantics. - -Tue Jan 19 19:34:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * export.c (export_pubkeys_stream): New. - (do_export_stream): New. - * g10.c (aSendKeys): New command. - * hkp.c (hkp_export): New. - - * compress.c (do_uncompress): Hack for algo 1 and 1.1.3 - -Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * textfilter.c (text_filter): Now uses iobuf_read_line(). - (read_line): Removed. - - * armor.c (trim_trailing_spaces): Removed and replaced - by trim_trailing_ws from libutil - -Sat Jan 16 12:03:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * hkp.c (hkp_ask_import): Use only the short keyid - -Sat Jan 16 09:27:30 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * import.c (import_key_stream): New - (import): New, moved most of import_keys here. - * g10.c: New option --keyserver - * mainproc.c (check_sig_and_print): Hook to import a pubkey. - - * pref.c pref.h : Removed - - * hkp.c hkp.h: New - -Wed Jan 13 14:10:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (radix64_read): Print an error if a bad armor was detected. - -Wed Jan 13 12:49:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (radix64_read): Now handles malformed armors produced - by some buggy MUAs. - -Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * ringedit.c (find_keyblock_bysk): New. - - * skc_list.c (is_insecure): New. - (build_sk_list): usage check for insecure keys. - - * import.c (chk_self_sigs): Add handling for subkeys. - (delete_inv_parts): Skip unsigned subkeys - - * sig-check.c (do_check): Print info if the signature is older - than the key. - * keygen.c (generate_subkeypair): Fail on time warp. - * sign.c (do_sign): Ditto. - -Sun Jan 10 15:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (fake_packet): Fixed not-dash-escaped bug. - -Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * sig-check.c (do_check): Output time diff on error - - * status.c (STATUS_VALIDSIG): New. - (is_status_enabled): New. - * mainproc.c (check_sig_and_print): Issue that status message. - - * plaintext.c (special_md_putc): Removed - - * armor.c (armor_filter): print error for truncated lines. - - * free-packet.c (free_encrypted): Revomed call to set_block_mode. - (free_plaintext): Ditto. - -Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (add_ownertrust): Fixed return value. - - * encr-data.c (decrypt_data): Disabled iobuf_set_limit and - iobuf_pop_filter stuff. - * compress.c (handle_compressed): Disabled iobuf_pop_filter. - - * packet.h (PKT_secret_key): Add is_primary flag. - * parse-packet.c (parse_key): Set this flag. - * passphrase.c (passphrase_to_dek): Kludge to print the primary - keyid - changed the API: keyid must now hold 2 keyids. - * getkey.c (get_primary_seckey): New. - * seckey-cert.c (do_check): pass primary keyid to passphrase query - - * tbdio.c (open_db): removed the atexit - (tdbio_set_dbname): and moved it to here. - - * armor.c: Rewrote large parts. - -Tue Dec 29 19:55:38 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * revoke.c (gen_revoke): Removed compression. - - * pkclist.c (do_we_trust_pre): special check for revoked keys - - * trustdb.c (update_trust_record): Fixed revoke flag. - -Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (disable_core_dumps): Check for EINVAL (Atari) - - * getkey (merge_one_pk_and_selfsig): Fixed search of expiredate. - (merge_keys_and_selfsig): Ditto. - - * free-packet.c (cmp_public_keys): cmp expire only for v3 packets - (cmp_secret_keys): Ditto. - (cmp_public_secret_key): Ditto. - -Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (find_header): Reset not_dashed at every header - -Wed Dec 23 13:18:14 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * pkclist.c (add_ownertrust): Refresh validity values. - - * trustdb.c (enum_cert_paths_print): New arg refresh. - - * ringedit.c: Fixed problems fix keyrings - * parse-packet.c (dbg_parse_packet): New debug functions. - - * getkey.c (getkey_disable_caches): New. - * import.c (import_keys): Disable caches. - -Thu Dec 17 18:31:15 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (trap_unaligned): Only for glibc 1 - - * sign.c (write_dash_escaped): Now escapes "From " lines - * g10.c: New option --escape-from-lines - - * trustdb.c (sort_tsl_list): New - (list_trust_path): Now prints sorted list. - (enum_cert_paths): Likewise. - (enum_cert_paths_print): New. - (print_paths): New printing format. - * pkclist.c (add_ownertrust): New arg quit. - (edit_ownertrust): New quit selection and does not query - the recipients ownertrust anymore. - (add_ownertrust): Print the ceritficate path. - - -Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * parse-packet.c (parse_signature): Now checks for critical bit - (parse_sig_subpkt): Splitted. - (parse_one_sig_subpkt): New. - * sig-check.c (do_check): handle critical bit. - -Sun Dec 13 14:10:56 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * pcklist.c (select_algo_from_prefs): Preferences should - now work (lost the != ? ) - -Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * ringedit.c (gdbm_store): Fix for inserts - - * g10.c (main): New option --export-all - * export.c (export_pubkeys): New arg. - (do_export): Now may skip old keys. - - * status.c: Minor patches for Sun's cc - - * keygen.c (ask_algo): Disabled v3 ElGamal choice, rearranged - the numbers. Add a warning question when a sign+encrypt key - is selected. - - * g10.c (do_not_use_RSA): Removed. - * misc.c (print_pubkey_algo_note): New as replacement for the - do_not_use_RSA() and chnaged all callers. - (print_cipher_algo_note): New. - (print_hash_algo_note): New. - - * cipher.c (write_header): Add a call to print_cipher_algo_note. - * seckey-cert.c (protect_secret_key): Ditto - * sign.c (do_sign): Add a call to print_digest_algo_note. - - * getkey.c (get_long_user_id_string): New. - * mainproc.c (check_sig_and_print): Changed the format of the - status output. - - * encrypt.c (write_pubkey_enc_from_list): print used symmetric cipher. - - * pkclist.c (do_we_trust): Changed a message. - -Wed Dec 9 13:41:06 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * misc.c (trap_unaligned) [ALPHA]: Only if UAC_SIGBUS is defined. - - * sign.c (write_dash_escaped): Add the forgotten patch by Brian Moore. - - * compress.c (do_uncompress): Fixed the inflating bug. - - -Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * trustdb.c (upd_uid_record): Now uses the newest self-signature - (insert_trust_record): Now calls update with recheck set to true. - (register_trusted_key): New. - (verify_own_keys): Enhanced by list of trusted keys. - - * g10.c (main): Print a warning when a devel version is used. - (main): New option --trusted-key - - * import.c (merge_blocks): Fixed merging of new user ids and - added merging of subkeys. - (append_uid): Ditto. - (merge_keysig): New. - (append_key): New. - * getkey.c (merge_one_pk_and_selfsig): Get the expiration time - from the newest self-signature. - (merge_keys_and_selfsig): Ditto. - - * free-packet.c (cmp_secret_key): New. - - -Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * g10.c: New option --lock-once - * tdbio.c (open_db): Add an atexit - (cleanup): New. - (tdbio_sync): Add locking. - (tdbio_end_transaction): Ditto. - (put_record_into_cache): Ditto. - * ringedit.c (keyring_copy): Ditto. - (cleanup): New. - (add_keyblock_resource): Add an atexit. - -Fri Nov 27 15:30:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * armor.c (find_header): Another fix for clearsigs. - -Fri Nov 27 12:39:29 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - - * status.c (display_help): Removed. - * helptext.c: New and removed the N_() from all cpr_gets. - - -Fri Nov 20 16:54:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New option --not-dash-escaped - * sign.c (write_dashed_escaped): Ditto. - * armor.c (find_header): Support for NotDashEscaped header. - - * getkey.c: print "disabled cache.." only if verbose is used. - -Thu Nov 19 07:17:31 1998 Werner Koch <werner.koch@guug.de> - - * parse-packet.c (dump_sig_subpkt): Fixed expire listing - * getkey.c (merge_keys_and_selfsig): Fixed expire calculation. - (merge_one_pk_and_selfsig): Ditto. - * keyedit.c (menu_expire). Ditto. - * keygen.c (keygen_add_key_expire): Ditto. - (ask_expire_interval): New and changed all local function to use - this instead. - (keygen_add_key_expire): Opaque should now be a public key; - changed all callers. - - * parse.packet.c (parse): use skip_rest to skip packets. - - * keyedit.c (keyedit_menu): New arg for cmdline cmds. - -Wed Nov 18 20:33:50 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (check_trustdb): Now rechecks all gived userids. - (collect_paths): Some fixes. - (upd_pref_records): Skips empty items, evaluate all items. - - * parse-packet.c (dump_sig_subpkt): Better listing of prefs. - (skip_packet): Now knows about marker packet - - * g10.c: removed cmd "--edit-sig". - - * pubring.asc: Updated. - -Sat Nov 14 14:01:29 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed syntax of --list-trust-path - * trustdb.c (list_trust_path): Replaced max_depth by - opt.max_cert_depth - -Fri Nov 13 07:39:58 1998 Werner Koch <werner.koch@guug.de> - - * trustdb.c (collect_paths): Removed a warning message. - (enum_trust_web): Removed. - (enum_cert_paths): New. - * pkclist.c (add_ownertrust): Changed to use enum_cert_paths. - (edit_ownertrust): Now list ceritficates on request. - (show_paths): New. - -Wed Nov 11 18:05:44 1998 Werner Koch <werner.koch@guug.de> - - * g10.c (main): New option --max-cert-depth - * tdbio.h: add new fields to ver and dir record. - * tdbio.c: read/write/dump of these fields. - (tdbio_db_matches_options): New. - * trustdb.c: replaced MAC_CERT_DEPTH by opt.max_cert_depth. - (do_check): cache validity and changed other functions - to reset the cached value. - - * keylist.c (list_one): Now lists the ownertrust. - * mainproc.c (list_node): Ditto. - -Tue Nov 10 10:08:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (g10_exit): Now looks at the new g10_errors_seen. - * mainproc.c (check_sig_and_print): Sets g10_errors_seen. - - * *.c : i18n many more strings. - - * ringedit.c (locate_keyblock_by_keyid): Add HAVE_LIBGDBM - (locate_keyblock_by_fpr): Ditto. - - * g10.c (main): removed unsused "int errors". - (main): Add new option --charset. - - * g10.c (main): special message for the unix newbie. - -Mon Nov 9 07:17:42 1998 Werner Koch <werner.koch@guug.de> - - * getkey.c (finish_lookup): Kludge to prefere algo 16. - - * trustdb.c (new_lid_table): Clear cached item. - - * status.c (cpr_get_utf8): New. - * pkclist.c (build_pk_list): Uses this. - -Sun Nov 8 17:20:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (check_sig_and_print): Why did I use strlen()-1 - in the printf? - This truncated the TZ. - -Sat Nov 7 15:57:28 1998 me,,, (wk@tobold) - - * getkey.c (lookup): Changes to support a read_next. - (get_pubkey): Fixed a memory leak. - - * keylist.c (list_one): Now lists all matching user IDs. - -Tue Nov 3 16:19:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (ask_user_id): Now converted to UTF-8 - - * g10.c (main): Kludge for pgp clearsigs and textmode. - -Fri Oct 30 16:40:39 1998 me,,, (wk@tobold) - - * signal.c (block_all_signals): New. - (unblock_all_signals): New - * tdbio.c (tdbio_end_transaction): Now blocks all signals. - - * trustdb.c (new_lid_table): Changed the representation of the - former local_lid_info stuff. - - * trustdb.c (update_trust_record): Reorganized the whole thing. - * sig-check.c (check_key_signature): Now handles class 0x28 - - -Wed Oct 28 18:56:33 1998 me,,, (wk@tobold) - - * export.c (do_export): Takes care of the exportable sig flag. - -Tue Oct 27 14:53:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trust_record): New "fast" parameter. - -Sun Oct 25 19:32:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile.c (copy_options_File): New. - * ringedit.c (add_keyblock_resource): Creates options file - * tdbio.c (tdbio_set_dbname): Ditto. - -Sat Oct 24 14:10:53 1998 brian moore <bem@cmc.net> - - * mainproc.c (proc_pubkey_enc): Don't release the DEK - (do_proc_packets): Ditto. - -Fri Oct 23 06:49:38 1998 me,,, (wk@tobold) - - * keyedit.c (keyedit_menu): Comments are now allowed - - * trustdb.c: Rewrote large parts. - - -Thu Oct 22 15:56:45 1998 Michael Roth (mroth@nessie.de) - - * encode.c: (encode_simple): Only the plain filename without - a given directory is stored in generated packets. - (encode_crypt): Ditto. - - * sign.c: (sign_file) Ditto. - - -Thu Oct 22 10:53:41 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trust_record): Add new optional arg. - - * import.c (import_keys): Add statistics output - * trustdb.c (update_trustdb): Ditto. - (insert_trustdb): Ditto. - - * tdbio.c (tdbio_begin_transaction): New. - (tdbio_end_transaction): New. - (tdbio_cancel_transaction): New. - - * g10.c (main): New option --quit. - - * trustdb.c (check_hint_sig): No tests for user-id w/o sig. - This caused an assert while checking the sigs. - - * trustdb.c (upd_sig_record): Splitted into several functions. - - * import.c (import_keys): New arg "fast". - * g10.c (main): New command --fast-import. - -Wed Oct 21 18:19:36 1998 Michael Roth <mroth@nessie.de> - - * ringedit.c (add_keyblock_resource): Directory is now created. - * tdbio.c (tdbio_set_dbname): New info message. - -Wed Oct 21 11:52:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (update_trustdb): released keyblock in loop. - - * keylist.c (list_block): New. - (list_all): Changed to use list_block. - - * trustdb.c: Completed support for GDBM - - * sign.c (only_old_style): Changed the way force_v3 is handled - (sign_file): Ditto. - (clearsign_file): Ditto. - - * keygen.c (has_invalid_email_chars): Splitted into mailbox and - host part. - - * keylist.c (list_one): Add a merge_keys_and_selfsig. - * mainproc.c (proc_tree): Ditto. - -Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (only_old_style): Add option force_v3_sigs - (sign_file): Fixed a bug in sig->version - (clearsign_file): Ditto. - - * parse-packet.c (dump_sig_subpkt): New - - * keyedit.c (menu_expire): New. - * free-packet.c (cmp_signatures): New - - -Sat Oct 17 10:22:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c: changed output line length from 72 to 64. - - * keyedit.c (fix_keyblock): New. - -Fri Oct 16 10:24:47 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c: Rewrote most. - * tdbio.c: Add cache and generalized hash tables. - - * options.h (ENABLE_COMMENT_PACKETS): New but undef'ed. - * encode.c, sign.c, keygen.c: Disabled comment packets. - * export.c (do_export): Comment packets are never exported, - except for those in the secret keyring. - - * g10.c (main): Removed option do-no-export-rsa; should be - be replaced by a secpial tool. - * export.c (do_export): Removed the code for the above option. - - * armor.c (find_header): Support for new only_keyblocks. - * import.c (import_keys): Only looks for keyblock armors. - - * packet.h: replaced valid_days by expiredate and changed all users. - * build-packet.c (do_public_key): calculates valid-days - (do_secret_key): Ditto. - * parse-packet.c (parse_key): expiredate is calucated from the - valid_period in v3 packets. - * keyid.c (do_fingerprint_md): calculates valid_dates. - - * keygen.c (add_key_expire): fixed key expiration time for v4 packets. - - * armor.c (find_header): A LF in the first 28 bytes - was skipped for non-armored data. - -Thu Oct 8 11:35:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (is_armored): Add test on old comment packets. - - * tdbio.c (tdbio_search_dir_bypk): fixed memory leak. - - * getkey.c: Changed the caching algorithms. - -Wed Oct 7 19:33:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnodes.c (unused_nodes): New. - -Wed Oct 7 11:15:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyedit.c (sign_uids): Fixed a problem with SK which could caused - a save of an unprotected key. - (menu_adduid): Ditto. - - * keyedit.c (keyedit_menu): Prefs are now correctly listed for - new user ids. - - * trustdb.c (update_trust_record): New. - (insert_trust_record): Now makes use of update_trust_record. - -Tue Oct 6 16:18:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (read_record): replaces most of the tdbio_read_records. - (write_record): Ditto. - -Sat Oct 3 11:01:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (ask_alogo): enable ElGamal enc-only only for addmode. - -Wed Sep 30 10:15:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_one): Fixed update of wrong keyblock. - -Tue Sep 29 08:32:08 1998 me,,, (wk@tobold) - - * mainproc.c (proc_plaintext): Display note for special filename. - * plaintext.c (handle_plaintext): Suppress output of special file. - -Mon Sep 28 12:57:12 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (verify_own_keys): Add warning if a key is not protected. - - * passphrase (hash_passphrase): Fixed iterated+salted mode and - setup for keysizes > hashsize. - - * g10.c (main): New options: --s2k-{cipher,digest,mode}. - -Fri Sep 25 09:34:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c: Chnaged some help texts. - -Tue Sep 22 19:34:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * passphrase.c (read_passphrase_from_fd): fixed bug for long - passphrases. - -Mon Sep 21 11:28:05 1998 Werner Koch (wk@(none)) - - * getkey.c (lookup): Add code to use the sub key if the primary one - does not match the usage. - - * armor.c (armor_filter): New error message: no valid data found. - (radix64_read): Changes to support multiple messages. - (i18n.h): New. - * mainproc.c (add_onepass_sig): bug fix. - -Mon Sep 21 08:03:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (do_we_trust): Add keyid to most messages. - - * passphrase.c (read_passphrase_from_fd): New. - (have_static_passphrase): New - (get_passphrase_fd): Removed. - (set_passphrase_fd): Removed. - * g10.c (main): passphrase is now read here. - - * keyedit.c (keyedit_menu): "help" texts should now translate fine. - -Mon Sep 21 06:40:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * encode.c (encode_simple): Now disables compression - when --rfc1991 is used. - (encode_crypt): Ditto. - -Fri Sep 18 16:50:32 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (merge_key_and_selfsig): New. - -Fri Sep 18 10:20:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (select_algo_from_prefs): Removed 3DES kludge. - - * seskey.c (make_session_key): Fixed SERIOUS bug introduced - by adding the weak key detection code. - - * sign.c (sign_file): Changed aremor header in certain cases. - -Tue Sep 15 17:52:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (check_sig_and_print): Replaced ascime by asctimestamp. - -Mon Sep 14 11:40:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seskey.c (make_session_key): Now detects weak keys. - - * trustdb (clear_trust_checked_flag): New. - - * plaintext.c (handle_plaintext): Does no anymore suppress CR from - cleartext signed messages. - -Sun Sep 13 12:54:29 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (insert_trust_record): Fixed a stupid bug in the free - liunked list loops. - -Sat Sep 12 15:49:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (remove_shmid): New. - (init_shm_comprocess): Now sets permission to the real uid. - -Wed Sep 9 11:15:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to - implement it. - * g10.c (main): New Option --throw-keyid - - * getkey.c (enum_secret_keys): Add new ar and changed all callers. - -Tue Sep 8 20:04:09 1998 Werner Koch (wk@isil.d.shuttle.de) - - * delkey.c (delete_key): Moved from keyedit.c. - -Mon Sep 7 16:37:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (calc_length_header): New arg new_ctb to correctly - calculate the length of new style packets. - - * armor.c (is_armored): Checks for symkey_enc packets. - - * pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5. - -Tue Aug 11 17:54:50 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (do_secret_key): Fixed handling of old keys. - - * getkey.c (compare_name): Fixed exact and email matching - - * openfile.c (open_outfile): Changed arguments and all callers. - -Tue Aug 11 09:14:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * encode.c (encode_simple): Applied option set-filename and comment. - (encode_crypt): Ditto. - * sign.c (sign_file): Ditto. - * armor.c (armor_filter): Applied option comment. - - * encode.c (encode_crypt): Moved init_packet to the begin. - (encode_simple): add an init_packet(). - - * comment (write_comment): Now enforces a hash sign as the 1st byte. - - * import.c (import_one): Add explanation for "no user ids". - - * compress.c (do_uncompress): Applied Brian Warner's patch to support - zlib 1.1.3 etc. - - * trustdb.c (check_trust): Fixed a problem after inserting new keys. - - * getkey (lookup): do not return the primary key if usage is given - (lookup_sk): Ditto and take usage into account. - - * status.c (cpr_get_answer_is_yes): add display_help. - -Mon Aug 10 10:11:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (lookup_sk): Now always returns the primary if arg - primary is true. - (lookup): Likewise. - (get_pubkey_byname): Now returns the primary key - (get_seckey_byname): Ditto. - - -Mon Aug 10 08:34:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (pubkey_letter): ELG_E is now a small g. - -Sat Aug 8 17:26:12 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile (overwrite_filep): Changed semantics and all callers. - -Sat Aug 8 12:17:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (display_help): New. - -Thu Aug 6 16:30:41 1998 Werner Koch,mobil,,, (wk@tobold) - - * seskey.c (encode_session_key): Now uses get_random_bits(). - -Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold) - - * ringedit.c (keyring_copy): No more backupfiles for - secret keyrings and add additional warning in case of - a failed secret keyring operation. - -Wed Aug 5 11:54:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (check_opts): Moved to main. Changed def_cipher_algo - semantics and chnaged all users. - - * pubkey-enc.c (get_sssion_key): New informational output - about preferences. - - * parse-packet.c (parse_symkeyenc): Fixed salted+iterated S2K - (parse_key): Ditto. - * build-packet.c (do_secret_key): Ditto. - (do_symkey_enc): Ditto. - -Tue Aug 4 08:59:10 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (enum_secret_keys): Now returns only primary keys. - - * getkey (lookup): Now sets the new namehash field. - - * parse-packet.c (parse_sig_subpkt2): New. - - * sign.c (sign_file): one-pass sigs are now emiited reverse. - Preference data is considered when selecting the compress algo. - -Wed Jul 29 12:53:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * free-packet.c (copy_signature): New. - - * keygen.c (generate_subkeypair): rewritten - * g10.c (aKeyadd): Removed option --add-key - -Mon Jul 27 10:37:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): Additional check on cipher blocksize. - (protect_secret_key): Ditto. - * encr-data.c: Support for other blocksizes. - * cipher.c (write_header): Ditto. - -Fri Jul 24 16:47:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (insert_kbnode): Changed semantics and all callers. - * keyedit.c : More or less a complete rewrite - -Wed Jul 22 17:10:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (write_sign_packet_header): New. - -Tue Jul 21 14:37:09 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_one): Now creates a trustdb record. - - * g10.c (main): New command --check-trustdb - -Mon Jul 20 11:15:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * genkey.c (generate_keypair): Default key is now DSA with - encryption only ElGamal subkey. - -Thu Jul 16 10:58:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (keyid_from_fingerprint): New. - * getkey.c (get_pubkey_byfprint): New. - -Tue Jul 14 18:09:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keyid.c (fingerprint_from_pk): Add argument and changed all callers. - (fingerprint_from_sk): Ditto. - -Tue Jul 14 10:10:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (handle_plaintext): Now returns create error if - the file could not be created or the user responded not to overwrite - the file. - * mainproc.c (proc_plaintext): Tries again if the file could not - be created to check the signature without output. - - * misc.c (disable_core_dumps): New. - * g10.c (main): disable coredumps for gpg - - * g10.c (MAINTAINER_OPTIONS): New to disable some options - -Mon Jul 13 16:47:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (hash_datafiles): New arg for better support of - detached sigs. Changed all callers. - * mainproc.c (proc_signature_packets): Ditto. - - * g10.c (main): New option "compress-sigs" - * sig.c (sign_file): detached signatures are not anymore compressed - unless the option --compress-sigs is used. - -Thu Jul 9 19:54:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c: Fixes to allow zero length cleartext signatures - -Thu Jul 9 14:52:47 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (build_list): Now drops setuid. - (main): Changed the way keyrings and algorithms are registered . - -Wed Jul 8 14:17:30 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_public_key): Add field keyid. - * parse-packet.c (parse_key): Reset the above field. - * keyid.c (keyid_from_pk): Use above field as cache. - - * tdbio.c, tdbio.h: New - * trustdb.c: Moved some functions to tdbio.c. - (print_keyid): New. - - * pkclist.c (check_signatures_trust): New. - -Wed Jul 8 10:45:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (special_md_putc): New. - (handle_plaintext): add clearsig argument - * mainproc.c (proc_plaintext): detection of clearsig - * sign.c (write_dased_escaped): Changed clearsig format - -Tue Jul 7 18:56:19 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Now makes sure that there is only one - empty line for clearsigs, as this is what OP now says. - -Mon Jul 6 13:09:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New option default-secret-key - * getkey.c (get_seckey_byname): support for this option. - -Mon Jul 6 09:03:49 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (add_keyring): Keyrings are now added to end of the - list of keyrings. The first added keyringwill be created. - (add_secret_keyring): Likewise. - - * ringedit.c (add_keyblock_resource): Files are created here. - - * g10.c (aNOP): Removed - - * getkey.c (lookup): Add checking of usage for name lookups - * packet.h (pubkey_usage): Add a field which may be used to store - usage capabilities. - * pkclist.c (build_pk_list): getkey now called with usage arg. - * skclist.c (build_sk_list): Ditto. - - * sign.c (clearsign_file): Fixed "Hash:" headers - -Sat Jul 4 13:33:31 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (list_ownertrust): New. - * g10.c (aListOwnerTrust): New. - - * g10.c (def_pubkey_algo): Removed. - - * trustdb.c (verify_private_data): Removed and also the call to it. - (sign_private_data): Removed. - -Fri Jul 3 13:26:10 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aEditKey): was aEditSig. Changed usage msg. - - * keyedit.c: Done some i18n stuff. - - * g10.c (do_not_use_RSA): New. - * sign.c (do_sign): Add call to above function. - * encode.c (write_pubkey_enc_from_list): Ditto. - -Thu Jul 2 21:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c: Now is able sto store data of unknown - algorithms. - * free-packet.c: Support for this. - * build-packet.c: Can write data of packet with unknown algos. - -Thu Jul 2 11:46:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse): fixed 4 byte length header - -Wed Jul 1 12:36:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (new_ctb): New field for some packets - * build-packet.c (build_packet): Support for new_ctb - * parse-packet.c (parse): Ditto. - -Mon Jun 29 12:54:45 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: changed all "_cert" to "_key", "subcert" to "subkey". - - * free-packet.c (free_packet): Removed memory leak for subkeys. - -Sun Jun 28 18:32:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (import_keys): Renamed from import_pubkeys. - (import_secret_one): New. - - * g10.c (aExportSecret): New. - - * export.c (export_seckeys): New. - - * parse-packet.c (parse_certificate): Cleaned up. - (parse_packet): Trust packets are now considered as unknown. - (parse_pubkey_warning): New. - -Fri Jun 26 10:37:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (has_invalid_email_chars): New. - -Wed Jun 24 16:40:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Now creates valid onepass_sig packets - with all detected hash algorithms. - * mainproc.c (proc_plaintext): Now uses the hash algos as specified - in the onepass_sig packets (if there are any) - -Mon Jun 22 11:54:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (handle_plaintext): add arg to disable outout - * mainproc.c (proc_plaintext): disable output when in sigs_only mode. - -Thu Jun 18 13:17:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c: Removed all rsa packet stuff, chnaged defaults - for key generation. - -Sun Jun 14 21:28:31 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c (checksum_u16): Fixed a stupid bug which caused a - wrong checksum calculation for the secret key protection and - add a backward compatibility option. - * g10.c (main): Add option --emulate-checksum-bug. - -Thu Jun 11 13:26:44 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: Major changes to the structure of public key material - which is now stored in an array and not anaymore in a union of - algorithm specific structures. These is needed to make the system - more extendable and makes a lot of stuff much simpler. Changed - all over the system. - - * dsa.c, rsa.c, elg.c: Removed. - -Wed Jun 10 07:22:02 1998 Werner Koch,mobil,,, (wk@tobold) - - * g10.c ("load-extension"): New option. - -Mon Jun 8 22:23:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): Removed cipher constants - (protect_secret_key): Ditto. - -Fri May 29 10:00:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (query_trust_info): New. - * keylist.c (list_one): Add output of trust info - * mainproc (list_node): ditto. - * g10.c (main): full trustdb init if -with-colons and any of the - key list modes. - -Thu May 28 10:34:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * status.c (STATUS_RSA_OR_IDEA): New. - * sig-check.c (check_signature): Output special status message. - * pubkey-enc.c (get_session_key): Ditto. - - * mainproc.c (check_sig_and_print): Changed format of output. - * passpharse.c (passphrase_to_dek): Likewise. - -Wed May 27 13:46:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aListSecretKeys): New option --list-secret-keys - * keylist.c (std_key_list): Renamed to public_key_list. - (secret_key_list): New - (list_one, list_all): Add support for secret keys. - * getkey.c (get_secret_keyring): New. - * mainproc.c (list_node): Add option --with-colons for secret keys - - * sig-check.c (check_key_signature): detection of selfsigs - * mainproc.c (list_node): fixed listing. - - * g10.c (aListSecretKeys): New option --always-trust - * pkclist.c (do_we_trust): Override per option added - - * status.c (write_status_text): Add a prefix to every output line. - -Wed May 27 07:49:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10 (--compress-keys): New. - * options.h (compress_keys): New. - * export.c (export_pubkeys): Only compresses with the new option. - -Tue May 26 11:24:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * passphrase.c (get_last_passphrase): New - (set_next_passphrase): New. - (passphrase_to_dek): add support for the above functions. - * keyedit.c (make_keysig_packet): Add sigclass 0x18, - changed all callers due to a new argument. - * keygen.c (write_keybinding): New - (generate_subkeypair): Add functionality - (ask_algo, ask_keysize, ask_valid_days): Broke out of generate_keypair - (ask_user_id, ask_passphrase): Ditto. - -Thu May 21 11:26:13 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c,gpgd.c (main): Does now return an int, so that egcs does - not complain. - - * armor.c (fake_packet): Removed erro message and add a noticed - that this part should be fixed. - - * sign.c (sign_file): Compression now comes in front of encryption. - * encode.c (encode_simple): Ditto. - (encode_crypt): Ditto. - -Tue May 19 16:18:19 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (fake_packet): Changed assertion to log_error - -Sat May 16 16:02:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (build_packet): Add SUBKEY packets. - -Fri May 15 17:57:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (hash_for): New and used in all places here. - * main.h (DEFAULT_): new macros. - * g10.c (opt.def_digest_algo): Now set to 0 - - * compress.c (init_compress): Add support for algo 1 - * options.h (def_compress_algo): New - * g10.c (main): New option --compress-algo - -Fri May 15 13:23:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (print_mds): New feature to print only one hash, - chnaged formatting. - -Thu May 14 15:36:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c (trap_unaligned) [__alpha__]: New - * g10.c (trap_unaligned): Add call to this to track down SIGBUS - on Alphas (to avoid the slow emulation code). - -Wed May 13 11:48:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (do_signature): Support for v4 pakets. - * keyedit.c (make_keysig_packet): Ditto. - * build-packet.c (build_sig_subpkt_from_sig): New. - (build_sig_subpkt): New. - - * elg.c (g10_elg_sign): removed keyid_from_skc. - * dsa.c (g10_dsa_sign): Ditto. - * rsa.c (g10_rsa_sign): Ditto. - * keyedit.c (make_keysig_packet): Add call to keyid_from_skc - - * sign.c (clearsign_file): Support for v4 signatures. - (sign_file): Ditto. - -Wed May 6 09:31:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (do_parse): add support for 5 byte length leader. - (parse_subpkt): Ditto. - * build-packet.c (write_new_header): Ditto. - - * packet.h (SIGSUBPKT_): New constants. - * parse-packet.c (parse_sig_subpkt): Changed name, made global, - and arg to return packet length, chnaged all callers - - -Tue May 5 22:11:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (gen_dsa): New. - * build_packet.c (do_secret_cert): Support for DSA - -Mon May 4 19:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) - - * compress.c: doubled buffer sizes - * parse-packet.c (do_plaintext): now uses iobuf_read/write. - -Mon May 4 09:35:53 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seskey.c (encode_md_value): Add optional argument hash_algo, - changed all callers. - - * passphrase.c (make_dek_from_passphrase): Removed - * (get_passhrase_hash): Changed name to passphrase_to_dek, add arg, - changed all callers. - - * all: Introduced the new ELG identifier and added support for the - encryption only one (which is okay to use by GNUPG for signatures). - -Sun May 3 17:50:26 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h (PKT_OLD_COMMENT): New name for type 16. - * parse-packet.c (parse_comment): Now uses type 61 - -Fri May 1 12:44:39 1998 Werner Koch,mobil,,, (wk@tobold) - - * packet.h (count): Chnaged s2k count from byte to u32. - * seckey-cert.c (do_check): Changed s2k algo 3 to 4, changed - reading of count. - * build-packet.c (do_secret_cert): ditto. - * parse-packet.c (parse_certificate): ditto. - - * parse-packet.c (parse_symkeyenc): New. - * build-packet.c (do_symkey_enc): New. - -Thu Apr 30 16:33:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sign.c (clearsign_file): Fixed "Hash: " armor line. - -Tue Apr 28 14:27:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_subpkt): Some new types. - -Mon Apr 27 12:53:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add option --skip-verify. - * mainproc.c (check_sig_and_print): Ditto. - - * g10.c (print_mds): Add output for Tiger. - - * sign.c (sign_file): Now uses partial length headers if used - in canonical textmode (kludge to fix a bug). - - * parse-packet.c (parse_certificate): Changed BLOWFISH id. - * pubkey-enc.c (get_session_key): Ditto. - * seskey.c (make_session_key): Ditto. - * seckey-cert.c (protect_secret_key,do_check): Add BLOWFISH160. - -Fri Apr 24 17:38:48 1998 Werner Koch,mobil,,, (wk@tobold) - - * sig-check.c (check_key_signature): Add sig-class 0x14..0x17 - * keyedit.c (sign-key): Some changes to start with support of - the above new sig-classes. - -Wed Apr 22 09:01:57 1998 Werner Koch,mobil,,, (wk@tobold) - - * getkey.c (compare_name): add email matching - -Tue Apr 21 16:17:12 1998 Werner Koch,mobil,,, (wk@tobold) - - * armor.c (armor_filter): fixed missing last LF before CSUM. - -Thu Apr 9 11:35:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (do_check): New; combines all the check functions - into one. - - * sign.c: removed all key management functions - * keyedit.c: New. - -Thu Apr 9 09:49:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * import.c (chk_self_sigs): Changed an error message. - -Wed Apr 8 16:19:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * packet.h: packet structs now uses structs from the pubkey, - removed all copy operations from packet to pubkey structs. - -Wed Apr 8 13:40:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (verify_own_certs): Fixed "public key not found". - - * getkey.c (key_byname): New, combines public and secret key search. - - * pkclist.c (build_pkc_list): Add new arg usage, changed all callers. - * skclist.c (build_skc_list): Likewise. - - * ringedit.c (find_keyblock, keyring_search2): Removed. - -Wed Apr 8 09:47:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.c (do_check): Applied small fix from Ulf Möller. - -Tue Apr 7 19:28:07 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.c, encr-data.c, seckey-cert.c: Now uses cipher_xxxx - functions instead of blowfish_xxx or cast_xxx - -Tue Apr 7 11:04:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (g10maint.o): Changed the way it is created. - -Mon Apr 6 11:17:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * misc.c: New. - * keygen.c (checksum,checksum_u16,checksum_mpi): Moved to misc.c - * seckey-cert.c: Kludge for wrong ELG checksum implementation. - -Sat Apr 4 20:07:01 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.c (cipher_filter): Support for CAST5 - * encr-data.c (decode_filter): Ditto. - (decrypt_data): Ditto. - * seskey.c (make_session_key): Ditto. - * seckey-cert.c (check_elg, check_dsa): Ditto, - (protect_secret_key): Ditto. - * pubkey-enc.c (get_session_key): Ditto. - * passphrase.c (hash_passphrase): Ditto. - -Thu Apr 2 20:22:35 1998 Werner Koch (wk@isil.d.shuttle.de) - - * gpgd.c: New - -Thu Apr 2 10:38:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Add valid_days stuff. - * trustdb.c (check_trust): Add check for valid_days. - -Wed Apr 1 16:15:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Addional question whether the - selected large keysize is really needed. - -Wed Apr 1 15:56:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * seckey-cert.c (protect_secret_key): merged protect_xxx to here. - -Wed Apr 1 10:34:46 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (g10maint.c): Changed creation rule, so that it works - on FreeBSD (missing CFLAGS). - - * parse-packet.c (parse_subkey): Removed. - -Thu Mar 19 15:22:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (keyring_enum): Fixed problem with reading too - many packets. Add support to read secret keyrings. - - * getkey.c (scan_keyring): Removed - (lookup): New to replace scan_keyring. - (scan_secret_keyring): Removed. - (lookup_skc): New. - -Wed Mar 18 11:47:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (enum_keyblocks): New read mode 11. - - * keyid.c (elg_fingerprint_md): New and changed all other functions - to call this if the packet version is 4 or above. - -Tue Mar 17 20:46:16 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_certificate): Add listing support for subkeys. - -Tue Mar 17 20:32:22 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (is_armored): Allow marker packet. - -Thu Mar 12 13:36:49 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (check_trust): Checks timestamp of pubkey. - * sig-check. (do_check): Compares timestamps. - -Tue Mar 10 17:01:56 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add call to init_signals. - * signal.c: New. - -Mon Mar 9 12:43:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * dsa.c: New - * packet.h, free-packet.c, parse-packet.c : Add support for DSA - * sig-check.c, getkey.c, keyid.c, ringedit.c: Ditto. - * seckey-cert.c: Ditto. - - * packet.h : Moved .digest_algo of signature packets to outer - structure. Changed all references - -Sun Mar 8 13:06:42 1998 Werner Koch (wk@isil.d.shuttle.de) - - * openfile.c : Support for stdout filename "-". - - * mainproc.c (check_sig_and_print): Enhanced status output: - * status.c (write_status_text): New. - -Fri Mar 6 16:10:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (clone_kbnode): Fixed private_flag. - - * mainproc.c (list_node): Output of string "Revoked" as user-id. - -Fri Mar 6 14:26:39 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Add userids to "-kv" and cleaned up this stuff. - -Fri Mar 6 12:45:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed semantics of the list-... commands - and added a new one. Removed option "-d" - - * decrypt.c: New. - - * trustdb.c (init_trustdb): Autocreate directory only if it ends - in "/.gnupg". - -Thu Mar 5 12:12:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (do_proc_packets): New. Common part of proc_packet. - (proc_signature_packets): special version to handle signature data. - * verify.c: New. - * g10.c (aVerify): New. - * plaintext.c (hash_datafiles): New. - * compress.c (handle_compressed): Add callback arg, changed caller. - -Thu Mar 5 10:20:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c: Is nom the common source for gpg and gpgm - * g10maint.c: Removed - * Makefile.am: Add rule to build g10maint.c - -Thu Mar 5 08:43:59 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Changed the way clear text sigs are faked. - -Wed Mar 4 19:47:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10maint.c (aMuttKeyList): New - * keylist.c: New. - -Wed Mar 4 17:20:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (get_pubkey_byname): Kludge to allow 0x prefix. - -Tue Mar 3 13:46:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10maint.c (main): New option --gen-random. - -Tue Mar 3 09:50:08 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aDeleteSecretKey): New. - (aEditSig): Add option "--edit-key" as synonym for "--edit-sig". - (aDeleteSecretKey): New. - * getkey.c (seckey_available): New. - * sign.c (delete_key): Enhanced to delete secret keys, changed all - callers. - -Mon Mar 2 21:23:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkc_list.c (build_pkc_list): Add interactive input of user ID. - -Mon Mar 2 20:54:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * pkclist.c (do_we_trust_pre): New. - (add_ownertrust): Add message. - * trustdb.c (enum_trust_web): Quick fix. - -Mon Mar 2 13:50:53 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): New action aDeleteKey - * sign.c (delete_key): New. - -Sun Mar 1 16:38:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (do_check): No returns TRUST_UNDEFINED instead of - eof error. - -Fri Feb 27 18:14:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Removed trailing CR on headers. - -Fri Feb 27 18:02:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (keyring_search) [MINGW32]: Open and close file here - because rename does not work on open files. Chnaged callers. - -Fri Feb 27 16:43:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.c (do_check): Add an md_enable. - * mainproc.c (do_check_sig): Use md_open in case of detached sig - (proc_tree): Take detached sigs into account. - -Fri Feb 27 15:22:46 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): Make use of GNUPGHOME envvar. - * g10main.c (main): Ditto. - -Wed Feb 25 11:40:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * plaintext.c (ask_for_detached_datafile): add opt.verbose to - info output. - - * openfile.c (open_sigfile): Try also name ending in ".asc" - -Wed Feb 25 08:41:00 1998 Werner Koch (wk@isil.d.shuttle.de) - - * keygen.c (generate_keypair): Fixed memory overflow. - -Tue Feb 24 15:51:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_certificate): Support for S2K. - * build-packet.c (do_secret_cert): Ditto. - * keygen.c (gen_elg): Ditto. - * seckey-cert.c (check_elg): Ditto - (protect_elg): Ditto. - * sign.c (chnage_passphrase): Ditto. - * passphrase.c (get_passphrase_hash): Support for a salt and - changed all callers. - (make_dek_from_passphrase): Ditto. - -Tue Feb 24 12:30:56 1998 Werner Koch (wk@isil.d.shuttle.de) - - * build-packet.c (hash_public_cert): Disabled debug output. - -Fri Feb 20 17:22:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (init_trustdb) [MINGW32]: Removed 2nd mkdir arg. - (keyring_copy) [MINGW32]: Add a remove prior to the renames. - -Wed Feb 18 18:39:02 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (OMIT_DEPENDENCIES): New. - - * rsa.c: Replaced log_bug by BUG. - -Wed Feb 18 13:35:58 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (do_check_sig): Now uses hash_public_cert. - * parse-packet.c (parse_certificate): Removed hashing. - * packet.h (public_cert): Removed hash variable. - * free-packet.c (copy_public_cert, free_public_cert): Likewise. - - * sig-check.c (check_key_signatures): Changed semantics. - -Wed Feb 18 12:11:28 1998 Werner Koch (wk@isil.d.shuttle.de) - - * trustdb.c (do_check): Add handling for revocation certificates. - (build_sigrecs): Ditto. - (check_sigs): Ditto. - -Wed Feb 18 09:31:04 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Add afx->hdrlines. - * revoke.c (gen_revoke): Add comment line. - * dearmor.c (enarmor_file): Ditto. - - * sig-check.c (check_key_signature): Add handling for class 0x20. - * mainproc.c : Ditto. - -Tue Feb 17 21:24:17 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c : Add header lines "...ARMORED FILE .." - * dearmor.c (enarmor_file): New. - * g10maint.c (main): New option "--enarmor" - -Tue Feb 17 19:03:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c : Changed a lot, because the packets are now stored - a simple linlked list and not anymore in a complicatd tree structure. - -Tue Feb 17 10:14:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * free_packet.c (cmp_public_certs): New. - (cmp_user_ids): New. - - * kbnode.c (clone_kbnode): New. - (release_kbnode): Add clone support. - - * ringedit.c (find_keyblock_bypkc): New. - - * sign.c (remove_keysigs): Self signatures are now skipped, - changed arguments and all callers. - - * import.c : Add functionality. - -Tue Feb 17 09:31:40 1998 Werner Koch (wk@isil.d.shuttle.de) - - * options.h (homedir): New option. - * g10.c, g10maint.c, getkey.c, keygen.c, trustdb.c (opt.homedir): New. - - * trustdb.c (init_trustdb): mkdir for hoem directory - (sign_private_data): Renamed "sig" to "g10.sig" - -Mon Feb 16 20:02:03 1998 Werner Koch (wk@isil.d.shuttle.de) - - * kbnode.c (commit_kbnode): New. - (delete_kbnode): removed unused first arg. Changed all Callers. - - * ringedit.c (keyblock_resource_name): New. - (get_keyblock_handle): NULL for filename returns default resource. - -Mon Feb 16 19:38:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * sig-check.s (check_key_signature): Now uses the supplied - public key to check the signature and not any more the one - from the getkey.c - (do_check): New. - (check_signature): Most work moved to do_check. - -Mon Feb 16 14:48:57 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (find_header): Fixed another bug. - -Mon Feb 16 12:18:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * getkey.c (scan_keyring): Add handling of compressed keyrings. - -Mon Feb 16 10:44:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c, g10maint.c (strusage): Rewrote. - (build_list): New - -Mon Feb 16 08:58:41 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (use_armor): New. - -Sat Feb 14 14:30:57 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mainproc.c (proc_tree): Sigclass fix. - -Sat Feb 14 14:16:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * armor.c (armor_filter): Changed version and comment string. - * encode.c, sign.c, keygen.c: Changed all comment packet strings. - -Sat Feb 14 12:39:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (aGenRevoke): New command. - * revoke.c: New. - * sign.c (make_keysig_packet): Add support for sigclass 0x20. - -Fri Feb 13 20:18:14 1998 Werner Koch (wk@isil.d.shuttle.de) - - * ringedit.c (enum_keyblocks, keyring_enum): New. - -Fri Feb 13 19:33:40 1998 Werner Koch (wk@isil.d.shuttle.de) - - * export.c: Add functionality. - - * keygen.c (generate_keypair): Moved the leading comment behind the - key packet. - * kbnode.c (walk_kbnode): Fixed. - - * g10.c (main): listing armored keys now work. - -Fri Feb 13 16:17:43 1998 Werner Koch (wk@isil.d.shuttle.de) - - * parse-packet.c (parse_publickey, parse_signature): Fixed calls - to mpi_read used for ELG b. - -Fri Feb 13 15:13:23 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10.c (main): changed formatting of help output. - -Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo) - - * pubkey-enc.c (get_session_key): rewritten - - - Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/g10/Makefile.am b/g10/Makefile.am deleted file mode 100644 index fc33acf73..000000000 --- a/g10/Makefile.am +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (C) 1998, 1999, 2000, 2001, 2002, -# 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = options.skel - -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/include \ - -I$(top_srcdir)/intl - -include $(top_srcdir)/am/cmacros.am - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) - -needed_libs = ../common/libcommon.a ../jnlib/libjnlib.a - -bin_PROGRAMS = gpg2 gpgv2 - -common_source = \ - global.h gpg.h \ - build-packet.c \ - compress.c \ - filter.h \ - free-packet.c \ - getkey.c \ - keydb.c keydb.h \ - keyring.c keyring.h \ - seskey.c \ - kbnode.c \ - main.h \ - mainproc.c \ - armor.c \ - mdfilter.c \ - textfilter.c \ - progress.c \ - misc.c \ - options.h \ - openfile.c \ - keyid.c \ - packet.h \ - parse-packet.c \ - comment.c \ - status.c \ - status.h \ - plaintext.c \ - sig-check.c \ - keylist.c \ - pkglue.c pkglue.h - -gpg2_SOURCES = g10.c \ - $(common_source) \ - pkclist.c \ - skclist.c \ - pubkey-enc.c \ - passphrase.c \ - seckey-cert.c \ - encr-data.c \ - cipher.c \ - encode.c \ - sign.c \ - verify.c \ - revoke.c \ - decrypt.c \ - keyedit.c \ - dearmor.c \ - import.c \ - export.c \ - trustdb.c \ - trustdb.h \ - tdbdump.c \ - tdbio.c \ - tdbio.h \ - delkey.c \ - keygen.c \ - pipemode.c \ - helptext.c \ - keyserver.c \ - keyserver-internal.h \ - photoid.c photoid.h \ - call-agent.c call-agent.h \ - card-util.c \ - exec.c exec.h - -gpgv2_SOURCES = gpgv.c \ - $(common_source) \ - verify.c - -#gpgd_SOURCES = gpgd.c \ -# ks-proto.h \ -# ks-proto.c \ -# ks-db.c \ -# ks-db.h \ -# $(common_source) - -LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@ -gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error -gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error - -$(PROGRAMS): $(needed_libs) - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) - $(INSTALL_DATA) $(srcdir)/options.skel \ - $(DESTDIR)$(pkgdatadir)/options.skel - diff --git a/g10/OPTIONS b/g10/OPTIONS deleted file mode 100644 index b1a49e254..000000000 --- a/g10/OPTIONS +++ /dev/null @@ -1,24 +0,0 @@ -# Some notes used by the maintainers - - -store -# simply packs the input data into a rfc1991 packet format - -check-trustdb - - -compress-keys -# compress exported key, compress level is still set with "-z" and -# algorithm with --compress-algo" - Default is to not compress keys, as -# this is better for interoperability. - -compress-sigs -# Normally, compressing of signatures does not make sense; so this -# is disabled for detached signatures unless this option is used. - -run-as-shm-coprocess [request-locked-shm-size] -# very special :-) -# You will have to use "--status-fd" too -# Note: This option does only work if given on the command line. - - diff --git a/g10/armor.c b/g10/armor.c deleted file mode 100644 index 121ec3a09..000000000 --- a/g10/armor.c +++ /dev/null @@ -1,1334 +0,0 @@ -/* armor.c - Armor flter - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -#else -#define LF "\n" -#endif - -#define MAX_LINELEN 20000 - -#define CRCINIT 0xB704CE -#define CRCPOLY 0X864CFB -#define CRCUPDATE(a,c) do { \ - a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \ - a &= 0x00ffffff; \ - } while(0) -static u32 crc_table[256]; -static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -static byte asctobin[256]; /* runtime initialized */ -static int is_initialized; - - -typedef enum { - fhdrHASArmor = 0, - fhdrNOArmor, - fhdrINIT, - fhdrINITCont, - fhdrINITSkip, - fhdrCHECKBegin, - fhdrWAITHeader, - fhdrWAITClearsig, - fhdrSKIPHeader, - fhdrCLEARSIG, - fhdrREADClearsig, - fhdrNullClearsig, - fhdrEMPTYClearsig, - fhdrCHECKClearsig, - fhdrCHECKClearsig2, - fhdrCHECKDashEscaped, - fhdrCHECKDashEscaped2, - fhdrCHECKDashEscaped3, - fhdrREADClearsigNext, - fhdrENDClearsig, - fhdrENDClearsigHelp, - fhdrTESTSpaces, - fhdrCLEARSIGSimple, - fhdrCLEARSIGSimpleNext, - fhdrTEXT, - fhdrTEXTSimple, - fhdrERROR, - fhdrERRORShow, - fhdrEOF -} fhdr_state_t; - - -/* if we encounter this armor string with this index, go - * into a mode which fakes packets and wait for the next armor */ -#define BEGIN_SIGNATURE 2 -#define BEGIN_SIGNED_MSG_IDX 3 -static char *head_strings[] = { - "BEGIN PGP MESSAGE", - "BEGIN PGP PUBLIC KEY BLOCK", - "BEGIN PGP SIGNATURE", - "BEGIN PGP SIGNED MESSAGE", - "BEGIN PGP ARMORED FILE", /* gnupg extension */ - "BEGIN PGP PRIVATE KEY BLOCK", - "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */ - NULL -}; -static char *tail_strings[] = { - "END PGP MESSAGE", - "END PGP PUBLIC KEY BLOCK", - "END PGP SIGNATURE", - "END dummy", - "END PGP ARMORED FILE", - "END PGP PRIVATE KEY BLOCK", - "END PGP SECRET KEY BLOCK", - NULL -}; - - - -static void -initialize(void) -{ - int i, j; - u32 t; - byte *s; - - /* init the crc lookup table */ - crc_table[0] = 0; - for(i=j=0; j < 128; j++ ) { - t = crc_table[j]; - if( t & 0x00800000 ) { - t <<= 1; - crc_table[i++] = t ^ CRCPOLY; - crc_table[i++] = t; - } - else { - t <<= 1; - crc_table[i++] = t; - crc_table[i++] = t ^ CRCPOLY; - } - } - /* build the helptable for radix64 to bin conversion */ - for(i=0; i < 256; i++ ) - asctobin[i] = 255; /* used to detect invalid characters */ - for(s=bintoasc,i=0; *s; s++,i++ ) - asctobin[*s] = i; - - is_initialized=1; -} - -/**************** - * Check whether this is an armored file or not See also - * parse-packet.c for details on this code For unknown historic - * reasons we use a string here but only the first byte will be used. - * Returns: True if it seems to be armored - */ -static int -is_armored( const byte *buf ) -{ - int ctb, pkttype; - - ctb = *buf; - if( !(ctb & 0x80) ) - return 1; /* invalid packet: assume it is armored */ - pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf); - switch( pkttype ) { - case PKT_MARKER: - case PKT_SYMKEY_ENC: - case PKT_ONEPASS_SIG: - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBKEY_ENC: - case PKT_SIGNATURE: - case PKT_COMMENT: - case PKT_OLD_COMMENT: - case PKT_PLAINTEXT: - case PKT_COMPRESSED: - case PKT_ENCRYPTED: - return 0; /* seems to be a regular packet: not armored */ - } - - return 1; -} - - -/**************** - * Try to check whether the iobuf is armored - * Returns true if this may be the case; the caller should use the - * filter to do further processing. - */ -int -use_armor_filter( iobuf_t a ) -{ - byte buf[1]; - int n; - - /* fixme: there might be a problem with iobuf_peek */ - n = iobuf_peek(a, buf, 1 ); - if( n == -1 ) - return 0; /* EOF, doesn't matter whether armored or not */ - if( !n ) - return 1; /* can't check it: try armored */ - return is_armored(buf); -} - - - - -static void -invalid_armor(void) -{ - write_status(STATUS_BADARMOR); - g10_exit(1); /* stop here */ -} - - -/**************** - * check whether the armor header is valid on a signed message. - * this is for security reasons: the header lines are not included in the - * hash and by using some creative formatting rules, Mallory could fake - * any text at the beginning of a document; assuming it is read with - * a simple viewer. We only allow the Hash Header. - */ -static int -parse_hash_header( const char *line ) -{ - const char *s, *s2; - unsigned found = 0; - - if( strlen(line) < 6 || strlen(line) > 60 ) - return 0; /* too short or too long */ - if( memcmp( line, "Hash:", 5 ) ) - return 0; /* invalid header */ - s = line+5; - for(s=line+5;;s=s2) { - for(; *s && (*s==' ' || *s == '\t'); s++ ) - ; - if( !*s ) - break; - for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ ) - ; - if( !strncmp( s, "RIPEMD160", s2-s ) ) - found |= 1; - else if( !strncmp( s, "SHA1", s2-s ) ) - found |= 2; - else if( !strncmp( s, "MD5", s2-s ) ) - found |= 4; - else if( !strncmp( s, "SHA256", s2-s ) ) - found |= 8; - else if( !strncmp( s, "SHA384", s2-s ) ) - found |= 16; - else if( !strncmp( s, "SHA512", s2-s ) ) - found |= 32; - else - return 0; - for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ ) - ; - if( *s2 && *s2 != ',' ) - return 0; - if( *s2 ) - s2++; - } - return found; -} - - - -/**************** - * Check whether this is a armor line. - * returns: -1 if it is not a armor header or the index number of the - * armor header. - */ -static int -is_armor_header( byte *line, unsigned len ) -{ - const char *s; - byte *save_p, *p; - int save_c; - int i; - - if( len < 15 ) - return -1; /* too short */ - if( memcmp( line, "-----", 5 ) ) - return -1; /* no */ - p = strstr( line+5, "-----"); - if( !p ) - return -1; - save_p = p; - p += 5; - - /* Some mail programs on Windows seem to add spaces to the end of - the line. This becomes strict if --openpgp is set. */ - - if(!RFC2440) - while(*p==' ') - p++; - - if( *p == '\r' ) - p++; - if( *p == '\n' ) - p++; - if( *p ) - return -1; /* garbage after dashes */ - save_c = *save_p; *save_p = 0; - p = line+5; - for(i=0; (s=head_strings[i]); i++ ) - if( !strcmp(s, p) ) - break; - *save_p = save_c; - if( !s ) - return -1; /* unknown armor line */ - - if( opt.verbose > 1 ) - log_info(_("armor: %s\n"), head_strings[i]); - return i; -} - - - -/**************** - * Parse a header lines - * Return 0: Empty line (end of header lines) - * -1: invalid header line - * >0: Good header line - */ -static int -parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len ) -{ - byte *p; - int hashes=0; - unsigned int len2; - - len2 = length_sans_trailing_ws( line, len ); - if( !len2 ) { - afx->buffer_pos = len2; /* (it is not the fine way to do it here) */ - return 0; /* WS only: same as empty line */ - } - len = len2; - line[len2] = 0; - - p = strchr( line, ':'); - if( !p || !p[1] ) { - log_error(_("invalid armor header: ")); - print_string( stderr, line, len, 0 ); - putc('\n', stderr); - return -1; - } - - if( opt.verbose ) { - log_info(_("armor header: ")); - print_string( stderr, line, len, 0 ); - putc('\n', stderr); - } - - if( afx->in_cleartext ) { - if( (hashes=parse_hash_header( line )) ) - afx->hashes |= hashes; - else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) ) - afx->not_dash_escaped = 1; - else { - log_error(_("invalid clearsig header\n")); - return -1; - } - } - return 1; -} - - - -/* figure out whether the data is armored or not */ -static int -check_input( armor_filter_context_t *afx, iobuf_t a ) -{ - int rc = 0; - int i; - byte *line; - unsigned len; - unsigned maxlen; - int hdr_line = -1; - - /* read the first line to see whether this is armored data */ - maxlen = MAX_LINELEN; - len = afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - if( !maxlen ) { - /* line has been truncated: assume not armored */ - afx->inp_checked = 1; - afx->inp_bypass = 1; - return 0; - } - - if( !len ) { - return -1; /* eof */ - } - - /* (the line is always a C string but maybe longer) */ - if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) ) - ; - else if( !is_armored( line ) ) { - afx->inp_checked = 1; - afx->inp_bypass = 1; - return 0; - } - - /* find the armor header */ - while(len) { - i = is_armor_header( line, len ); - if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) { - hdr_line = i; - if( hdr_line == BEGIN_SIGNED_MSG_IDX ) { - if( afx->in_cleartext ) { - log_error(_("nested clear text signatures\n")); - rc = GPG_ERR_INV_ARMOR; - } - afx->in_cleartext = 1; - } - break; - } - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - len = afx->buffer_len; - } while( !maxlen ); - } - - /* parse the header lines */ - while(len) { - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - line = afx->buffer; - len = afx->buffer_len; - } while( !maxlen ); - - i = parse_header_line( afx, line, len ); - if( i <= 0 ) { - if( i ) - rc = GPG_ERR_INV_ARMOR; - break; - } - } - - - if( rc ) - invalid_armor(); - else if( afx->in_cleartext ) - afx->faked = 1; - else { - afx->inp_checked = 1; - afx->crc = CRCINIT; - afx->idx = 0; - afx->radbuf[0] = 0; - } - - return rc; -} - - - -/**************** - * Fake a literal data packet and wait for the next armor line - * fixme: empty line handling and null length clear text signature are - * not implemented/checked. - */ -static int -fake_packet( armor_filter_context_t *afx, iobuf_t a, - size_t *retn, byte *buf, size_t size ) -{ - int rc = 0; - size_t len = 0; - int lastline = 0; - unsigned maxlen, n; - byte *p; - - len = 2; /* reserve 2 bytes for the length header */ - size -= 2; /* and 2 for the terminating header */ - while( !rc && len < size ) { - /* copy what we have in the line buffer */ - if( afx->faked == 1 ) - afx->faked++; /* skip the first (empty) line */ - else { - while( len < size && afx->buffer_pos < afx->buffer_len ) - buf[len++] = afx->buffer[afx->buffer_pos++]; - if( len >= size ) - continue; - } - - /* read the next line */ - maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !afx->buffer_len ) { - rc = -1; /* eof (should not happen) */ - continue; - } - if( !maxlen ) - afx->truncated++; - if( !afx->not_dash_escaped ) { - int crlf; - p = afx->buffer; - n = afx->buffer_len; - crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n'; - - /* PGP2 does not treat a tab as white space character */ - afx->buffer_len = trim_trailing_chars( p, n, - afx->pgp2mode ? " \r\n" : " \t\r\n"); - /* the buffer is always allocated with enough space to append - * the removed [CR], LF and a Nul - * The reason for this complicated procedure is to keep at least - * the original type of lineending - handling of the removed - * trailing spaces seems to be impossible in our method - * of faking a packet; either we have to use a temporary file - * or calculate the hash here in this module and somehow find - * a way to send the hash down the processing line (well, a special - * faked packet could do the job). - */ - if( crlf ) - afx->buffer[afx->buffer_len++] = '\r'; - afx->buffer[afx->buffer_len++] = '\n'; - afx->buffer[afx->buffer_len] = 0; - } - p = afx->buffer; - n = afx->buffer_len; - - if( n > 2 && *p == '-' ) { - /* check for dash escaped or armor header */ - if( p[1] == ' ' && !afx->not_dash_escaped ) { - /* issue a warning if it is not regular encoded */ - if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) { - log_info(_("invalid dash escaped line: ")); - print_string( stderr, p, n, 0 ); - putc('\n', stderr); - } - afx->buffer_pos = 2; /* skip */ - } - else if( n >= 15 && p[1] == '-' && p[2] == '-' && p[3] == '-' ) { - int type = is_armor_header( p, n ); - if( afx->not_dash_escaped && type != BEGIN_SIGNATURE ) - ; /* this is okay */ - else { - if( type != BEGIN_SIGNATURE ) { - log_info(_("unexpected armor:")); - print_string( stderr, p, n, 0 ); - putc('\n', stderr); - } - lastline = 1; - rc = -1; - } - } - } - } - - buf[0] = (len-2) >> 8; - buf[1] = (len-2); - if( lastline ) { /* write last (ending) length header */ - if( buf[0] || buf[1] ) { /* only if we have some text */ - buf[len++] = 0; - buf[len++] = 0; - } - rc = 0; - afx->faked = 0; - afx->in_cleartext = 0; - /* and now read the header lines */ - afx->buffer_pos = 0; - for(;;) { - int i; - - /* read the next line (skip all truncated lines) */ - do { - maxlen = MAX_LINELEN; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - } while( !maxlen ); - p = afx->buffer; - n = afx->buffer_len; - if( !n ) { - rc = -1; - break; /* eof */ - } - i = parse_header_line( afx, p , n ); - if( i <= 0 ) { - if( i ) - invalid_armor(); - break; - } - } - afx->inp_checked = 1; - afx->crc = CRCINIT; - afx->idx = 0; - afx->radbuf[0] = 0; - } - - *retn = len; - return rc; -} - - -static int -invalid_crc(void) -{ - if ( opt.ignore_crc_error ) - return 0; - log_inc_errorcount(); - return GPG_ERR_INV_ARMOR; -} - - -static int -radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn, - byte *buf, size_t size ) -{ - byte val; - int c=0, c2; /*init c because gcc is not clever enough for the continue*/ - int checkcrc=0; - int rc = 0; - size_t n = 0; - int idx, i; - u32 crc; - - crc = afx->crc; - idx = afx->idx; - val = afx->radbuf[0]; - for( n=0; n < size; ) { - - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - - again: - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' ) - continue; - else if( c == '=' ) { /* pad character: stop */ - /* some mailers leave quoted-printable encoded characters - * so we try to workaround this */ - if( afx->buffer_pos+2 < afx->buffer_len ) { - int cc1, cc2, cc3; - cc1 = afx->buffer[afx->buffer_pos]; - cc2 = afx->buffer[afx->buffer_pos+1]; - cc3 = afx->buffer[afx->buffer_pos+2]; - if( isxdigit(cc1) && isxdigit(cc2) - && strchr( "=\n\r\t ", cc3 )) { - /* well it seems to be the case - adjust */ - c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10); - c <<= 4; - c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10); - afx->buffer_pos += 2; - afx->qp_detected = 1; - goto again; - } - } - - if( idx == 1 ) - buf[n++] = val; - checkcrc++; - break; - } - else if( (c = asctobin[(c2=c)]) == 255 ) { - log_error(_("invalid radix64 character %02x skipped\n"), c2); - continue; - } - switch(idx) { - case 0: val = c << 2; break; - case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break; - case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break; - case 3: val |= c&0x3f; buf[n++] = val; break; - } - idx = (idx+1) % 4; - } - - for(i=0; i < n; i++ ) - crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]]; - crc &= 0x00ffffff; - afx->crc = crc; - afx->idx = idx; - afx->radbuf[0] = val; - - if( checkcrc ) { - afx->any_data = 1; - afx->inp_checked=0; - afx->faked = 0; - for(;;) { /* skip lf and pad characters */ - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - if( c == '\n' || c == ' ' || c == '\r' - || c == '\t' || c == '=' ) - continue; - break; - } - if( c == -1 ) - log_error(_("premature eof (no CRC)\n")); - else { - u32 mycrc = 0; - idx = 0; - do { - if( (c = asctobin[c]) == 255 ) - break; - switch(idx) { - case 0: val = c << 2; break; - case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break; - case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break; - case 3: val |= c&0x3f; mycrc |= val; break; - } - for(;;) { - if( afx->buffer_pos < afx->buffer_len ) - c = afx->buffer[afx->buffer_pos++]; - else { /* read the next line */ - unsigned maxlen = MAX_LINELEN; - afx->buffer_pos = 0; - afx->buffer_len = iobuf_read_line( a, &afx->buffer, - &afx->buffer_size, - &maxlen ); - if( !maxlen ) - afx->truncated++; - if( !afx->buffer_len ) - break; /* eof */ - continue; - } - break; - } - if( !afx->buffer_len ) - break; /* eof */ - } while( ++idx < 4 ); - if( c == -1 ) { - log_info(_("premature eof (in CRC)\n")); - rc = invalid_crc(); - } - else if( idx != 4 ) { - log_info(_("malformed CRC\n")); - rc = invalid_crc(); - } - else if( mycrc != afx->crc ) { - log_info (_("CRC error; %06lx - %06lx\n"), - (ulong)afx->crc, (ulong)mycrc); - rc = invalid_crc(); - } - else { - rc = 0; - /* FIXME: Here we should emit another control packet, - * so that we know in mainproc that we are processing - * a clearsign message */ -#if 0 - for(rc=0;!rc;) { - rc = 0 /*check_trailer( &fhdr, c )*/; - if( !rc ) { - if( (c=iobuf_get(a)) == -1 ) - rc = 2; - } - } - if( rc == -1 ) - rc = 0; - else if( rc == 2 ) { - log_error(_("premature eof (in Trailer)\n")); - rc = GPG_ERR_INV_ARMOR; - } - else { - log_error(_("error in trailer line\n")); - rc = GPG_ERR_INV_ARMOR; - } -#endif - } - } - } - - if( !n ) - rc = -1; - - *retn = n; - return rc; -} - -/**************** - * This filter is used to handle the armor stuff - */ -int -armor_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - armor_filter_context_t *afx = opaque; - int rc=0, i, c; - byte radbuf[3]; - int idx, idx2; - size_t n=0; - u32 crc; -#if 0 - static FILE *fp ; - - if( !fp ) { - fp = fopen("armor.out", "w"); - assert(fp); - } -#endif - - if( DBG_FILTER ) - log_debug("armor-filter: control: %d\n", control ); - if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) { - n = 0; - if( afx->buffer_len ) { - for(; n < size && afx->buffer_pos < afx->buffer_len; n++ ) - buf[n++] = afx->buffer[afx->buffer_pos++]; - if( afx->buffer_pos >= afx->buffer_len ) - afx->buffer_len = 0; - } - for(; n < size; n++ ) { - if( (c=iobuf_get(a)) == -1 ) - break; - buf[n] = c & 0xff; - } - if( !n ) - rc = -1; - *ret_len = n; - } - else if( control == IOBUFCTRL_UNDERFLOW ) { - /* We need some space for the faked packet. The minmum required - * size is ~18 + length of the session marker */ - if( size < 50 ) - BUG(); /* supplied buffer too short */ - - if( afx->faked ) - rc = fake_packet( afx, a, &n, buf, size ); - else if( !afx->inp_checked ) { - rc = check_input( afx, a ); - if( afx->inp_bypass ) { - for(n=0; n < size && afx->buffer_pos < afx->buffer_len; ) - buf[n++] = afx->buffer[afx->buffer_pos++]; - if( afx->buffer_pos >= afx->buffer_len ) - afx->buffer_len = 0; - if( !n ) - rc = -1; - } - else if( afx->faked ) { - unsigned int hashes = afx->hashes; - const byte *sesmark; - size_t sesmarklen; - - sesmark = get_session_marker( &sesmarklen ); - if ( sesmarklen > 20 ) - BUG(); - - /* the buffer is at least 15+n*15 bytes long, so it - * is easy to construct the packets */ - - hashes &= 1|2|4|8|16|32|64; - if( !hashes ) { - hashes |= 4; /* default to MD 5 */ - /* This is non-ideal since PGP 5-8 have the same - end-of-line bugs as PGP 2. However, we only - enable pgp2mode if there is no Hash: header. */ - if( opt.pgp2_workarounds ) - afx->pgp2mode = 1; - } - n=0; - /* first a gpg control packet */ - buf[n++] = 0xff; /* new format, type 63, 1 length byte */ - n++; /* see below */ - memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen; - buf[n++] = CTRLPKT_CLEARSIGN_START; - buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */ - if( hashes & 1 ) - buf[n++] = DIGEST_ALGO_RMD160; - if( hashes & 2 ) - buf[n++] = DIGEST_ALGO_SHA1; - if( hashes & 4 ) - buf[n++] = DIGEST_ALGO_MD5; - if( hashes & 8 ) - buf[n++] = DIGEST_ALGO_SHA256; - if( hashes & 16 ) - buf[n++] = DIGEST_ALGO_SHA384; - if( hashes & 32 ) - buf[n++] = DIGEST_ALGO_SHA512; - buf[1] = n - 2; - - /* followed by a plaintext packet */ - buf[n++] = 0xaf; /* old packet format, type 11, var length */ - buf[n++] = 0; /* set the length header */ - buf[n++] = 6; - buf[n++] = 't'; /* canonical text mode */ - buf[n++] = 0; /* namelength */ - memset(buf+n, 0, 4); /* timestamp */ - n += 4; - } - else if( !rc ) - rc = radix64_read( afx, a, &n, buf, size ); - } - else - rc = radix64_read( afx, a, &n, buf, size ); -#if 0 - if( n ) - if( fwrite(buf, n, 1, fp ) != 1 ) - BUG(); -#endif - *ret_len = n; - } - else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) { - if( !afx->status ) { /* write the header line */ - const char *s; - STRLIST comment = opt.comments; - - if( afx->what >= DIM(head_strings) ) - log_bug("afx->what=%d", afx->what); - iobuf_writestr(a, "-----"); - iobuf_writestr(a, head_strings[afx->what] ); - iobuf_writestr(a, "-----" LF ); - if( !opt.no_version ) - iobuf_writestr(a, "Version: GnuPG v" VERSION " (" - PRINTABLE_OS_NAME ")" LF ); - - /* Write the comment string. */ - for(s=comment? comment->d:NULL; comment; - comment=comment->next,s=comment->d) - { - iobuf_writestr(a, "Comment: " ); - for ( ; *s; s++ ) - { - if( *s == '\n' ) - iobuf_writestr(a, "\\n" ); - else if( *s == '\r' ) - iobuf_writestr(a, "\\r" ); - else if( *s == '\v' ) - iobuf_writestr(a, "\\v" ); - else - iobuf_put(a, *s ); - } - iobuf_writestr(a, LF ); - } - - if ( afx->hdrlines ) { - for ( s = afx->hdrlines; *s; s++ ) { -#ifdef HAVE_DOSISH_SYSTEM - if ( *s == '\n' ) - iobuf_put( a, '\r'); -#endif - iobuf_put(a, *s ); - } - } - iobuf_writestr(a, LF ); - afx->status++; - afx->idx = 0; - afx->idx2 = 0; - afx->crc = CRCINIT; - - } - crc = afx->crc; - idx = afx->idx; - idx2 = afx->idx2; - for(i=0; i < idx; i++ ) - radbuf[i] = afx->radbuf[i]; - - for(i=0; i < size; i++ ) - crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]]; - crc &= 0x00ffffff; - - for( ; size; buf++, size-- ) { - radbuf[idx++] = *buf; - if( idx > 2 ) { - idx = 0; - c = bintoasc[(*radbuf >> 2) & 077]; - iobuf_put(a, c); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - iobuf_put(a, c); - c = bintoasc[radbuf[2]&077]; - iobuf_put(a, c); - if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */ - iobuf_writestr(a, LF ); - idx2=0; - } - } - } - for(i=0; i < idx; i++ ) - afx->radbuf[i] = radbuf[i]; - afx->idx = idx; - afx->idx2 = idx2; - afx->crc = crc; - } - else if( control == IOBUFCTRL_INIT ) { - if( !is_initialized ) - initialize(); - } - else if( control == IOBUFCTRL_CANCEL ) { - afx->cancel = 1; - } - else if( control == IOBUFCTRL_FREE ) { - if( afx->cancel ) - ; - else if( afx->status ) { /* pad, write cecksum, and bottom line */ - crc = afx->crc; - idx = afx->idx; - idx2 = afx->idx2; - for(i=0; i < idx; i++ ) - radbuf[i] = afx->radbuf[i]; - if( idx ) { - c = bintoasc[(*radbuf>>2)&077]; - iobuf_put(a, c); - if( idx == 1 ) { - c = bintoasc[((*radbuf << 4) & 060) & 077]; - iobuf_put(a, c); - iobuf_put(a, '='); - iobuf_put(a, '='); - } - else { /* 2 */ - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; - iobuf_put(a, c); - iobuf_put(a, '='); - } - if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */ - iobuf_writestr(a, LF ); - idx2=0; - } - } - /* may need a linefeed */ - if( idx2 ) - iobuf_writestr(a, LF ); - /* write the CRC */ - iobuf_put(a, '='); - radbuf[0] = crc >>16; - radbuf[1] = crc >> 8; - radbuf[2] = crc; - c = bintoasc[(*radbuf >> 2) & 077]; - iobuf_put(a, c); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - iobuf_put(a, c); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - iobuf_put(a, c); - c = bintoasc[radbuf[2]&077]; - iobuf_put(a, c); - iobuf_writestr(a, LF ); - /* and the the trailer */ - if( afx->what >= DIM(tail_strings) ) - log_bug("afx->what=%d", afx->what); - iobuf_writestr(a, "-----"); - iobuf_writestr(a, tail_strings[afx->what] ); - iobuf_writestr(a, "-----" LF ); - } - else if( !afx->any_data && !afx->inp_bypass ) { - log_error(_("no valid OpenPGP data found.\n")); - afx->no_openpgp_data = 1; - write_status_text( STATUS_NODATA, "1" ); - } - if( afx->truncated ) - log_info(_("invalid armor: line longer than %d characters\n"), - MAX_LINELEN ); - /* issue an error to enforce dissemination of correct software */ - if( afx->qp_detected ) - log_error(_("quoted printable character in armor - " - "probably a buggy MTA has been used\n") ); - xfree ( afx->buffer ); - afx->buffer = NULL; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "armor_filter"; - return rc; -} - - -/**************** - * create a radix64 encoded string. - */ -char * -make_radix64_string( const byte *data, size_t len ) -{ - char *buffer, *p; - - buffer = p = xmalloc ( (len+2)/3*4 + 1 ); - for( ; len >= 3 ; len -= 3, data += 3 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077]; - *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077]; - *p++ = bintoasc[data[2]&077]; - } - if( len == 2 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077]; - *p++ = bintoasc[((data[1]<<2)&074)]; - } - else if( len == 1 ) { - *p++ = bintoasc[(data[0] >> 2) & 077]; - *p++ = bintoasc[(data[0] <<4)&060]; - } - *p = 0; - return buffer; -} - - -/*********************************************** - * For the pipemode command we can't use the armor filter for various - * reasons, so we use this new unarmor_pump stuff to remove the armor - */ - -enum unarmor_state_e { - STA_init = 0, - STA_bypass, - STA_wait_newline, - STA_wait_dash, - STA_first_dash, - STA_compare_header, - STA_found_header_wait_newline, - STA_skip_header_lines, - STA_skip_header_lines_non_ws, - STA_read_data, - STA_wait_crc, - STA_read_crc, - STA_ready -}; - -struct unarmor_pump_s { - enum unarmor_state_e state; - byte val; - int checkcrc; - int pos; /* counts from 0..3 */ - u32 crc; - u32 mycrc; /* the one store in the data */ -}; - - - -UnarmorPump -unarmor_pump_new (void) -{ - UnarmorPump x; - - if( !is_initialized ) - initialize(); - x = xcalloc (1,sizeof *x); - return x; -} - -void -unarmor_pump_release (UnarmorPump x) -{ - xfree (x); -} - -/* - * Get the next character from the ascii armor taken from the IOBUF - * created earlier by unarmor_pump_new(). - * Return: c = Character - * 256 = ignore this value - * -1 = End of current armor - * -2 = Premature EOF (not used) - * -3 = Invalid armor - */ -int -unarmor_pump (UnarmorPump x, int c) -{ - int rval = 256; /* default is to ignore the return value */ - - switch (x->state) { - case STA_init: - { - byte tmp[1]; - tmp[0] = c; - if ( is_armored (tmp) ) - x->state = c == '-'? STA_first_dash : STA_wait_newline; - else { - x->state = STA_bypass; - return c; - } - } - break; - case STA_bypass: - return c; /* return here to avoid crc calculation */ - case STA_wait_newline: - if (c == '\n') - x->state = STA_wait_dash; - break; - case STA_wait_dash: - x->state = c == '-'? STA_first_dash : STA_wait_newline; - break; - case STA_first_dash: /* just need for initalization */ - x->pos = 0; - x->state = STA_compare_header; - case STA_compare_header: - if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) { - if ( x->pos == 28 ) - x->state = STA_found_header_wait_newline; - } - else - x->state = c == '\n'? STA_wait_dash : STA_wait_newline; - break; - case STA_found_header_wait_newline: - /* to make CR,LF issues easier we simply allow for white space - behind the 5 dashes */ - if ( c == '\n' ) - x->state = STA_skip_header_lines; - else if ( c != '\r' && c != ' ' && c != '\t' ) - x->state = STA_wait_dash; /* garbage after the header line */ - break; - case STA_skip_header_lines: - /* i.e. wait for one empty line */ - if ( c == '\n' ) { - x->state = STA_read_data; - x->crc = CRCINIT; - x->val = 0; - x->pos = 0; - } - else if ( c != '\r' && c != ' ' && c != '\t' ) - x->state = STA_skip_header_lines_non_ws; - break; - case STA_skip_header_lines_non_ws: - /* like above but we already encountered non white space */ - if ( c == '\n' ) - x->state = STA_skip_header_lines; - break; - case STA_read_data: - /* fixme: we don't check for the trailing dash lines but rely - * on the armor stop characters */ - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' ) - break; /* skip all kind of white space */ - - if( c == '=' ) { /* pad character: stop */ - if( x->pos == 1 ) /* in this case val has some value */ - rval = x->val; - x->state = STA_wait_crc; - break; - } - - { - int c2; - if( (c = asctobin[(c2=c)]) == 255 ) { - log_error(_("invalid radix64 character %02x skipped\n"), c2); - break; - } - } - - switch(x->pos) { - case 0: - x->val = c << 2; - break; - case 1: - x->val |= (c>>4)&3; - rval = x->val; - x->val = (c<<4)&0xf0; - break; - case 2: - x->val |= (c>>2)&15; - rval = x->val; - x->val = (c<<6)&0xc0; - break; - case 3: - x->val |= c&0x3f; - rval = x->val; - break; - } - x->pos = (x->pos+1) % 4; - break; - case STA_wait_crc: - if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' ) - break; /* skip ws and pad characters */ - /* assume that we are at the next line */ - x->state = STA_read_crc; - x->pos = 0; - x->mycrc = 0; - case STA_read_crc: - if( (c = asctobin[c]) == 255 ) { - rval = -1; /* ready */ - if( x->crc != x->mycrc ) { - log_info (_("CRC error; %06lx - %06lx\n"), - (ulong)x->crc, (ulong)x->mycrc); - if ( invalid_crc() ) - rval = -3; - } - x->state = STA_ready; /* not sure whether this is correct */ - break; - } - - switch(x->pos) { - case 0: - x->val = c << 2; - break; - case 1: - x->val |= (c>>4)&3; - x->mycrc |= x->val << 16; - x->val = (c<<4)&0xf0; - break; - case 2: - x->val |= (c>>2)&15; - x->mycrc |= x->val << 8; - x->val = (c<<6)&0xc0; - break; - case 3: - x->val |= c&0x3f; - x->mycrc |= x->val; - break; - } - x->pos = (x->pos+1) % 4; - break; - case STA_ready: - rval = -1; - break; - } - - if ( !(rval & ~255) ) { /* compute the CRC */ - x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval]; - x->crc &= 0x00ffffff; - } - - return rval; -} diff --git a/g10/build-packet.c b/g10/build-packet.c deleted file mode 100644 index d2c538477..000000000 --- a/g10/build-packet.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* build-packet.c - assemble packets and write them - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "options.h" - - -static int do_comment( iobuf_t out, int ctb, PKT_comment *rem ); -static int do_user_id( iobuf_t out, int ctb, PKT_user_id *uid ); -static int do_public_key( iobuf_t out, int ctb, PKT_public_key *pk ); -static int do_secret_key( iobuf_t out, int ctb, PKT_secret_key *pk ); -static int do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc ); -static int do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc ); -static u32 calc_plaintext( PKT_plaintext *pt ); -static int do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt ); -static int do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed ); -static int do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed ); -static int do_compressed( iobuf_t out, int ctb, PKT_compressed *cd ); -static int do_signature( iobuf_t out, int ctb, PKT_signature *sig ); -static int do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops ); - -static int calc_header_length( u32 len, int new_ctb ); -static int write_16(iobuf_t inp, u16 a); -static int write_32(iobuf_t inp, u32 a); -static int write_header( iobuf_t out, int ctb, u32 len ); -static int write_sign_packet_header( iobuf_t out, int ctb, u32 len ); -static int write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode ); -static int write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen ); -static int write_version( iobuf_t out, int ctb ); - -/**************** - * Build a packet and write it to INP - * Returns: 0 := okay - * >0 := error - * Note: Caller must free the packet - */ -int -build_packet( iobuf_t out, PACKET *pkt ) -{ - int new_ctb=0, rc=0, ctb; - int pkttype; - - if( DBG_PACKET ) - log_debug("build_packet() type=%d\n", pkt->pkttype ); - assert( pkt->pkt.generic ); - - switch( (pkttype = pkt->pkttype) ) { - case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break; - case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break; - case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break; - case PKT_USER_ID: - if( pkt->pkt.user_id->attrib_data ) - pkttype = PKT_ATTRIBUTE; - break; - default: break; - } - - if( new_ctb || pkttype > 15 ) /* new format */ - ctb = 0xc0 | (pkttype & 0x3f); - else - ctb = 0x80 | ((pkttype & 15)<<2); - switch( pkttype ) { - case PKT_ATTRIBUTE: - case PKT_USER_ID: - rc = do_user_id( out, ctb, pkt->pkt.user_id ); - break; - case PKT_COMMENT: - rc = do_comment( out, ctb, pkt->pkt.comment ); - break; - case PKT_PUBLIC_SUBKEY: - case PKT_PUBLIC_KEY: - rc = do_public_key( out, ctb, pkt->pkt.public_key ); - break; - case PKT_SECRET_SUBKEY: - case PKT_SECRET_KEY: - rc = do_secret_key( out, ctb, pkt->pkt.secret_key ); - break; - case PKT_SYMKEY_ENC: - rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc ); - break; - case PKT_PUBKEY_ENC: - rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc ); - break; - case PKT_PLAINTEXT: - rc = do_plaintext( out, ctb, pkt->pkt.plaintext ); - break; - case PKT_ENCRYPTED: - rc = do_encrypted( out, ctb, pkt->pkt.encrypted ); - break; - case PKT_ENCRYPTED_MDC: - rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted ); - break; - case PKT_COMPRESSED: - rc = do_compressed( out, ctb, pkt->pkt.compressed ); - break; - case PKT_SIGNATURE: - rc = do_signature( out, ctb, pkt->pkt.signature ); - break; - case PKT_ONEPASS_SIG: - rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig ); - break; - case PKT_RING_TRUST: - break; /* ignore it (keyring.c does write it directly)*/ - case PKT_MDC: /* we write it directly, so we should never see it here. */ - default: - log_bug("invalid packet type in build_packet()\n"); - break; - } - - return rc; -} - -/**************** - * calculate the length of a packet described by PKT - */ -u32 -calc_packet_length( PACKET *pkt ) -{ - u32 n=0; - int new_ctb = 0; - - assert( pkt->pkt.generic ); - switch( pkt->pkttype ) { - case PKT_PLAINTEXT: - n = calc_plaintext( pkt->pkt.plaintext ); - new_ctb = pkt->pkt.plaintext->new_ctb; - break; - case PKT_ATTRIBUTE: - case PKT_USER_ID: - case PKT_COMMENT: - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_SYMKEY_ENC: - case PKT_PUBKEY_ENC: - case PKT_ENCRYPTED: - case PKT_SIGNATURE: - case PKT_ONEPASS_SIG: - case PKT_RING_TRUST: - case PKT_COMPRESSED: - default: - log_bug("invalid packet type in calc_packet_length()"); - break; - } - - n += calc_header_length(n, new_ctb); - return n; -} - -static void -write_fake_data( iobuf_t out, gcry_mpi_t a ) -{ - if( a ) { - unsigned int n; - void *p; - - assert( gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque (a, &n); - iobuf_write (out, p, (n+7)/8); - } -} - - -static int -do_comment (iobuf_t out, int ctb, PKT_comment *rem) -{ - int rc = 0; - - if (opt.sk_comments) - { - write_header(out, ctb, rem->len); - rc = iobuf_write( out, rem->data, rem->len ); - } - return rc; -} - -static int -do_user_id( iobuf_t out, int ctb, PKT_user_id *uid ) -{ - int rc; - - if (uid->attrib_data) - { - write_header (out, ctb, uid->attrib_len); - rc = iobuf_write (out, uid->attrib_data, uid->attrib_len ); - } - else - { - write_header (out, ctb, uid->len); - rc = iobuf_write (out, uid->name, uid->len ); - } - return rc; -} - -static int -do_public_key( iobuf_t out, int ctb, PKT_public_key *pk ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - if( !pk->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, pk->version ); - write_32(a, pk->timestamp ); - if( pk->version < 4 ) { - u16 ndays; - if( pk->expiredate ) - ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L); - else - ndays = 0; - write_16(a, ndays ); - } - iobuf_put(a, pk->pubkey_algo ); - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - write_fake_data( a, pk->pkey[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, pk->pkey[i] ); - - write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes, 1 ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -/**************** - * Make a hash value from the public key certificate - */ -void -hash_public_key( MD_HANDLE md, PKT_public_key *pk ) -{ - PACKET pkt; - int rc = 0; - int ctb; - ulong pktlen; - int c; - iobuf_t a = iobuf_temp(); -#if 0 - FILE *fp = fopen("dump.pk", "a"); - int i=0; - - fprintf(fp, "\nHashing PK (v%d):\n", pk->version); -#endif - - /* build the packet */ - init_packet(&pkt); - pkt.pkttype = PKT_PUBLIC_KEY; - pkt.pkt.public_key = pk; - if( (rc = build_packet( a, &pkt )) ) - log_fatal("build public_key for hashing failed: %s\n", gpg_strerror (rc)); - - if( !(pk->version == 3 && pk->pubkey_algo == 16) ) { - /* skip the constructed header but don't do this for our very old - * v3 ElG keys */ - ctb = iobuf_get_noeof(a); - pktlen = 0; - if( (ctb & 0x40) ) { - c = iobuf_get_noeof(a); - if( c < 192 ) - pktlen = c; - else if( c < 224 ) { - pktlen = (c - 192) * 256; - c = iobuf_get_noeof(a); - pktlen += c + 192; - } - else if( c == 255 ) { - pktlen = iobuf_get_noeof(a) << 24; - pktlen |= iobuf_get_noeof(a) << 16; - pktlen |= iobuf_get_noeof(a) << 8; - pktlen |= iobuf_get_noeof(a); - } - } - else { - int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - for( ; lenbytes; lenbytes-- ) { - pktlen <<= 8; - pktlen |= iobuf_get_noeof(a); - } - } - /* hash a header */ - gcry_md_putc ( md, 0x99 ); - pktlen &= 0xffff; /* can't handle longer packets */ - gcry_md_putc ( md, pktlen >> 8 ); - gcry_md_putc ( md, pktlen & 0xff ); - } - /* hash the packet body */ - while( (c=iobuf_get(a)) != -1 ) { -#if 0 - fprintf( fp," %02x", c ); - if( (++i == 24) ) { - putc('\n', fp); - i=0; - } -#endif - gcry_md_putc ( md, c ); - } -#if 0 - putc('\n', fp); - fclose(fp); -#endif - iobuf_cancel(a); -} - - -static int -do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk ) -{ - int rc = 0; - int i, nskey, npkey; - iobuf_t a = iobuf_temp(); /* build in a self-enlarging buffer */ - - /* Write the version number - if none is specified, use 3 */ - if( !sk->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, sk->version ); - write_32(a, sk->timestamp ); - - /* v3 needs the expiration time */ - if( sk->version < 4 ) { - u16 ndays; - if( sk->expiredate ) - ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L); - else - ndays = 0; - write_16(a, ndays); - } - - iobuf_put(a, sk->pubkey_algo ); - - /* get number of secret and public parameters. They are held in - one array first the public ones, then the secret ones */ - nskey = pubkey_get_nskey( sk->pubkey_algo ); - npkey = pubkey_get_npkey( sk->pubkey_algo ); - - /* If we don't have any public parameters - which is the case if - we don't know the algorithm used - the parameters are stored as - one blob in a faked (opaque) gcry_mpi_t */ - if( !npkey ) { - write_fake_data( a, sk->skey[0] ); - goto leave; - } - assert( npkey < nskey ); - - /* Writing the public parameters is easy */ - for(i=0; i < npkey; i++ ) - mpi_write(a, sk->skey[i] ); - - /* build the header for protected (encrypted) secret parameters */ - if( sk->is_protected ) { - if( is_RSA(sk->pubkey_algo) && sk->version < 4 - && !sk->protect.s2k.mode ) { - /* the simple rfc1991 (v3) way */ - iobuf_put(a, sk->protect.algo ); - iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); - } - else { - /* OpenPGP protection according to rfc2440 */ - iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff ); - iobuf_put(a, sk->protect.algo ); - if( sk->protect.s2k.mode >= 1000 ) { - /* These modes are not possible in OpenPGP, we use them - to implement our extensions, 101 can be seen as a - private/experimental extension (this is not - specified in rfc2440 but the same scheme is used - for all other algorithm identifiers) */ - iobuf_put(a, 101 ); - iobuf_put(a, sk->protect.s2k.hash_algo ); - iobuf_write(a, "GNU", 3 ); - iobuf_put(a, sk->protect.s2k.mode - 1000 ); - } - else { - iobuf_put(a, sk->protect.s2k.mode ); - iobuf_put(a, sk->protect.s2k.hash_algo ); - } - if( sk->protect.s2k.mode == 1 - || sk->protect.s2k.mode == 3 ) - iobuf_write(a, sk->protect.s2k.salt, 8 ); - if( sk->protect.s2k.mode == 3 ) - iobuf_put(a, sk->protect.s2k.count ); - - /* For our special modes 1001 and 1002 we do not need an IV */ - if( sk->protect.s2k.mode != 1001 - && sk->protect.s2k.mode != 1002 ) - iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); - } - } - else - iobuf_put(a, 0 ); - - if( sk->protect.s2k.mode == 1001 ) - ; /* GnuPG extension - don't write a secret key at all */ - else if( sk->protect.s2k.mode == 1002 ) - { /* GnuPG extension - divert to OpenPGP smartcard. */ - iobuf_put(a, sk->protect.ivlen ); /* length of the serial - number or 0 for no serial - number. */ - /* The serial number gets stored in the IV field. */ - iobuf_write(a, sk->protect.iv, sk->protect.ivlen); - } - else if( sk->is_protected && sk->version >= 4 ) { - /* The secret key is protected - write it out as it is */ - byte *p; - assert( gcry_mpi_get_flag( sk->skey[npkey], GCRYMPI_FLAG_OPAQUE ) ); - p = gcry_mpi_get_opaque( sk->skey[npkey], &i ); - iobuf_write(a, p, (i+7)/8 ); - } - else if( sk->is_protected ) { - /* The secret key is protected the old v4 way. */ - for( ; i < nskey; i++ ) { - byte *p; - size_t n; - - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque( sk->skey[i], &n ); - iobuf_write (a, p, (n+7)/8); - } - write_16(a, sk->csum ); - } - else { - /* non-protected key */ - for( ; i < nskey; i++ ) - mpi_write(a, sk->skey[i] ); - write_16(a, sk->csum ); - } - - leave: - /* Build the header of the packet - which we must do after writing all - the other stuff, so that we know the length of the packet */ - write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 ); - /* And finally write it out the real stream */ - rc = iobuf_write_temp (out, a ); - - iobuf_close(a); /* close the remporary buffer */ - return rc; -} - -static int -do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc ) -{ - int rc = 0; - iobuf_t a = iobuf_temp(); - - assert( enc->version == 4 ); - switch( enc->s2k.mode ) { - case 0: case 1: case 3: break; - default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode ); - } - iobuf_put( a, enc->version ); - iobuf_put( a, enc->cipher_algo ); - iobuf_put( a, enc->s2k.mode ); - iobuf_put( a, enc->s2k.hash_algo ); - if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) { - iobuf_write(a, enc->s2k.salt, 8 ); - if( enc->s2k.mode == 3 ) - iobuf_put(a, enc->s2k.count); - } - if( enc->seskeylen ) - iobuf_write(a, enc->seskey, enc->seskeylen ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - - - -static int -do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - write_version( a, ctb ); - if( enc->throw_keyid ) { - write_32(a, 0 ); /* don't tell Eve who can decrypt the message */ - write_32(a, 0 ); - } - else { - write_32(a, enc->keyid[0] ); - write_32(a, enc->keyid[1] ); - } - iobuf_put(a,enc->pubkey_algo ); - n = pubkey_get_nenc( enc->pubkey_algo ); - if( !n ) - write_fake_data( a, enc->data[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, enc->data[i] ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - - - -static u32 -calc_plaintext( PKT_plaintext *pt ) -{ - return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0; -} - -static int -do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt ) -{ - int i, rc = 0; - u32 n; - byte buf[1000]; /* this buffer has the plaintext! */ - int nbytes; - - /* Truncate namelen to the maximum 255 characters. This does mean - that a function that calls build_packet with an illegal literal - packet will get it back legalized. */ - if(pt->namelen>255) - pt->namelen=255; - - write_header(out, ctb, calc_plaintext( pt ) ); - iobuf_put(out, pt->mode ); - iobuf_put(out, pt->namelen ); - for(i=0; i < pt->namelen; i++ ) - iobuf_put(out, pt->name[i] ); - rc = write_32 (out, pt->timestamp); - - n = 0; - while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) { - rc = iobuf_write(out, buf, nbytes); - if (rc) - break; - n += nbytes; - } - wipememory(buf,1000); /* burn the buffer */ - if( !pt->len ) - iobuf_set_block_mode(out, 0 ); /* write end marker */ - else if( n != pt->len ) - log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", - (ulong)n, (ulong)pt->len ); - - return rc; -} - - - -static int -do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed ) -{ - int rc = 0; - u32 n; - - n = ed->len ? (ed->len + ed->extralen) : 0; - write_header(out, ctb, n ); - - /* This is all. The caller has to write the real data */ - - return rc; -} - -static int -do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed ) -{ - int rc = 0; - u32 n; - - assert( ed->mdc_method ); - - /* Take version number and the following MDC packet in account. */ - n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0; - write_header(out, ctb, n ); - iobuf_put(out, 1 ); /* version */ - - /* This is all. The caller has to write the real data */ - - return rc; -} - - -static int -do_compressed( iobuf_t out, int ctb, PKT_compressed *cd ) -{ - int rc = 0; - - /* We must use the old convention and don't use blockmode for tyhe - sake of PGP 2 compatibility. However if the new_ctb flag was - set, CTB is already formatted as new style and write_header2 - does create a partial length encoding using new the new - style. */ - write_header2(out, ctb, 0, 0, 0 ); - iobuf_put(out, cd->algorithm ); - - /* This is all. The caller has to write the real data */ - - return rc; -} - - -/**************** - * Delete all subpackets of type REQTYPE and return a bool whether a packet - * was deleted. - */ -int -delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) -{ - int buflen; - sigsubpkttype_t type; - byte *buffer, *bufstart; - size_t n; - size_t unused = 0; - int okay = 0; - - if( !area ) - return 0; - buflen = area->len; - buffer = area->data; - for(;;) { - if( !buflen ) { - okay = 1; - break; - } - bufstart = buffer; - n = *buffer++; buflen--; - if( n == 255 ) { - if( buflen < 4 ) - break; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { - if( buflen < 2 ) - break; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - break; - - type = *buffer & 0x7f; - if( type == reqtype ) { - buffer++; - buflen--; - n--; - if( n > buflen ) - break; - buffer += n; /* point to next subpkt */ - buflen -= n; - memmove (bufstart, buffer, buflen); /* shift */ - unused += buffer - bufstart; - buffer = bufstart; - } - else { - buffer += n; buflen -=n; - } - } - - if (!okay) - log_error ("delete_subpkt: buffer shorter than subpacket\n"); - assert (unused <= area->len); - area->len -= unused; - return !!unused; -} - - -/**************** - * Create or update a signature subpacket for SIG of TYPE. This - * functions knows where to put the data (hashed or unhashed). The - * function may move data from the unhashed part to the hashed one. - * Note: All pointers into sig->[un]hashed (e.g. returned by - * parse_sig_subpkt) are not valid after a call to this function. The - * data to put into the subpaket should be in a buffer with a length - * of buflen. - */ -void -build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, - const byte *buffer, size_t buflen ) -{ - byte *p; - int critical, hashed; - subpktarea_t *oldarea, *newarea; - size_t nlen, n, n0; - - critical = (type & SIGSUBPKT_FLAG_CRITICAL); - type &= ~SIGSUBPKT_FLAG_CRITICAL; - - /* Sanity check buffer sizes */ - if(parse_one_sig_subpkt(buffer,buflen,type)<0) - BUG(); - - switch(type) - { - case SIGSUBPKT_NOTATION: - case SIGSUBPKT_POLICY: - case SIGSUBPKT_REV_KEY: - /* we do allow multiple subpackets */ - break; - - default: - /* we don't allow multiple subpackets */ - delete_sig_subpkt(sig->hashed,type); - delete_sig_subpkt(sig->unhashed,type); - break; - } - - /* Any special magic that needs to be done for this type so the - packet doesn't need to be reparsed? */ - switch(type) - { - case SIGSUBPKT_NOTATION: - sig->flags.notation=1; - break; - - case SIGSUBPKT_POLICY: - sig->flags.policy_url=1; - break; - - case SIGSUBPKT_PREF_KS: - sig->flags.pref_ks=1; - break; - - case SIGSUBPKT_EXPORTABLE: - if(buffer[0]) - sig->flags.exportable=1; - else - sig->flags.exportable=0; - break; - - case SIGSUBPKT_REVOCABLE: - if(buffer[0]) - sig->flags.revocable=1; - else - sig->flags.revocable=0; - break; - - case SIGSUBPKT_TRUST: - sig->trust_depth=buffer[0]; - sig->trust_value=buffer[1]; - break; - - case SIGSUBPKT_REGEXP: - sig->trust_regexp=buffer; - break; - - /* This should never happen since we don't currently allow - creating such a subpacket, but just in case... */ - case SIGSUBPKT_SIG_EXPIRE: - if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp()) - sig->flags.expired=1; - else - sig->flags.expired=0; - break; - - default: - break; - } - - if( (buflen+1) >= 8384 ) - nlen = 5; /* write 5 byte length header */ - else if( (buflen+1) >= 192 ) - nlen = 2; /* write 2 byte length header */ - else - nlen = 1; /* just a 1 byte length header */ - - switch( type ) { - /* The issuer being unhashed is a historical oddity. It - should work equally as well hashed. Of course, if even an - unhashed issuer is tampered with, it makes it awfully hard - to verify the sig... */ - case SIGSUBPKT_ISSUER: - hashed = 0; - break; - default: - hashed = 1; - break; - } - - if( critical ) - type |= SIGSUBPKT_FLAG_CRITICAL; - - oldarea = hashed? sig->hashed : sig->unhashed; - - /* Calculate new size of the area and allocate */ - n0 = oldarea? oldarea->len : 0; - n = n0 + nlen + 1 + buflen; /* length, type, buffer */ - if (oldarea && n <= oldarea->size) { /* fits into the unused space */ - newarea = oldarea; - /*log_debug ("updating area for type %d\n", type );*/ - } - else if (oldarea) { - newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1); - newarea->size = n; - /*log_debug ("reallocating area for type %d\n", type );*/ - } - else { - newarea = xmalloc (sizeof (*newarea) + n - 1); - newarea->size = n; - /*log_debug ("allocating area for type %d\n", type );*/ - } - newarea->len = n; - - p = newarea->data + n0; - if (nlen == 5) { - *p++ = 255; - *p++ = (buflen+1) >> 24; - *p++ = (buflen+1) >> 16; - *p++ = (buflen+1) >> 8; - *p++ = (buflen+1); - *p++ = type; - memcpy (p, buffer, buflen); - } - else if (nlen == 2) { - *p++ = (buflen+1-192) / 256 + 192; - *p++ = (buflen+1-192) % 256; - *p++ = type; - memcpy (p, buffer, buflen); - } - else { - *p++ = buflen+1; - *p++ = type; - memcpy (p, buffer, buflen); - } - - if (hashed) - sig->hashed = newarea; - else - sig->unhashed = newarea; -} - -/**************** - * Put all the required stuff from SIG into subpackets of sig. - * Hmmm, should we delete those subpackets which are in a wrong area? - */ -void -build_sig_subpkt_from_sig( PKT_signature *sig ) -{ - u32 u; - byte buf[8]; - - u = sig->keyid[0]; - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - u = sig->keyid[1]; - buf[4] = (u >> 24) & 0xff; - buf[5] = (u >> 16) & 0xff; - buf[6] = (u >> 8) & 0xff; - buf[7] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 ); - - u = sig->timestamp; - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 ); - - if(sig->expiredate) - { - if(sig->expiredate>sig->timestamp) - u=sig->expiredate-sig->timestamp; - else - u=0; - - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - - /* Mark this CRITICAL, so if any implementation doesn't - understand sigs that can expire, it'll just disregard this - sig altogether. */ - - build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL, - buf, 4 ); - } -} - -void -build_attribute_subpkt(PKT_user_id *uid,byte type, - const void *buf,u32 buflen, - const void *header,u32 headerlen) -{ - byte *attrib; - int idx; - - if(1+headerlen+buflen>8383) - idx=5; - else if(1+headerlen+buflen>191) - idx=2; - else - idx=1; - - /* realloc uid->attrib_data to the right size */ - - uid->attrib_data=xrealloc(uid->attrib_data, - uid->attrib_len+idx+1+headerlen+buflen); - - attrib=&uid->attrib_data[uid->attrib_len]; - - if(idx==5) - { - attrib[0]=255; - attrib[1]=(1+headerlen+buflen) >> 24; - attrib[2]=(1+headerlen+buflen) >> 16; - attrib[3]=(1+headerlen+buflen) >> 8; - attrib[4]=1+headerlen+buflen; - } - else if(idx==2) - { - attrib[0]=(1+headerlen+buflen-192) / 256 + 192; - attrib[1]=(1+headerlen+buflen-192) % 256; - } - else - attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */ - - attrib[idx++]=type; - - /* Tack on our data at the end */ - - if(headerlen>0) - memcpy(&attrib[idx],header,headerlen); - memcpy(&attrib[idx+headerlen],buf,buflen); - uid->attrib_len+=idx+headerlen+buflen; -} - -static int -do_signature( iobuf_t out, int ctb, PKT_signature *sig ) -{ - int rc = 0; - int n, i; - iobuf_t a = iobuf_temp(); - - if( !sig->version ) - iobuf_put( a, 3 ); - else - iobuf_put( a, sig->version ); - if( sig->version < 4 ) - iobuf_put(a, 5 ); /* constant */ - iobuf_put(a, sig->sig_class ); - if( sig->version < 4 ) { - write_32(a, sig->timestamp ); - write_32(a, sig->keyid[0] ); - write_32(a, sig->keyid[1] ); - } - iobuf_put(a, sig->pubkey_algo ); - iobuf_put(a, sig->digest_algo ); - if( sig->version >= 4 ) { - size_t nn; - /* timestamp and keyid must have been packed into the - * subpackets prior to the call of this function, because - * these subpackets are hashed */ - nn = sig->hashed? sig->hashed->len : 0; - write_16(a, nn); - if( nn ) - iobuf_write( a, sig->hashed->data, nn ); - nn = sig->unhashed? sig->unhashed->len : 0; - write_16(a, nn); - if( nn ) - iobuf_write( a, sig->unhashed->data, nn ); - } - iobuf_put(a, sig->digest_start[0] ); - iobuf_put(a, sig->digest_start[1] ); - n = pubkey_get_nsig( sig->pubkey_algo ); - if( !n ) - write_fake_data( a, sig->data[0] ); - for(i=0; i < n; i++ ) - mpi_write(a, sig->data[i] ); - - if( is_RSA(sig->pubkey_algo) && sig->version < 4 ) - write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) ); - else - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -static int -do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops ) -{ - int rc = 0; - iobuf_t a = iobuf_temp(); - - write_version( a, ctb ); - iobuf_put(a, ops->sig_class ); - iobuf_put(a, ops->digest_algo ); - iobuf_put(a, ops->pubkey_algo ); - write_32(a, ops->keyid[0] ); - write_32(a, ops->keyid[1] ); - iobuf_put(a, ops->last ); - - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp (out, a); - - iobuf_close(a); - return rc; -} - - -static int -write_16(iobuf_t out, u16 a) -{ - iobuf_put(out, a>>8); - return iobuf_put(out,a); -} - -static int -write_32(iobuf_t out, u32 a) -{ - iobuf_put(out, a>> 24); - iobuf_put(out, a>> 16); - iobuf_put(out, a>> 8); - return iobuf_put (out, a); -} - - -/**************** - * calculate the length of a header - */ -static int -calc_header_length( u32 len, int new_ctb ) -{ - if( !len ) - return 1; /* only the ctb */ - - if( new_ctb ) { - if( len < 192 ) - return 2; - if( len < 8384 ) - return 3; - else - return 6; - } - if( len < 256 ) - return 2; - if( len < 65536 ) - return 3; - - return 5; -} - -/**************** - * Write the CTB and the packet length - */ -static int -write_header( iobuf_t out, int ctb, u32 len ) -{ - return write_header2( out, ctb, len, 0, 1 ); -} - - -static int -write_sign_packet_header( iobuf_t out, int ctb, u32 len ) -{ - /* work around a bug in the pgp read function for signature packets, - * which are not correctly coded and silently assume at some - * point 2 byte length headers.*/ - iobuf_put(out, 0x89 ); - iobuf_put(out, len >> 8 ); - return iobuf_put(out, len ) == -1 ? -1:0; -} - -/**************** - * if HDRLEN is > 0, try to build a header of this length. - * we need this, so that we can hash packets without reading them again. - */ -static int -write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode ) -{ - if( ctb & 0x40 ) - return write_new_header( out, ctb, len, hdrlen ); - - if( hdrlen ) { - if( !len ) - ctb |= 3; - else if( hdrlen == 2 && len < 256 ) - ; - else if( hdrlen == 3 && len < 65536 ) - ctb |= 1; - else - ctb |= 2; - } - else { - if( !len ) - ctb |= 3; - else if( len < 256 ) - ; - else if( len < 65536 ) - ctb |= 1; - else - ctb |= 2; - } - if( iobuf_put(out, ctb ) ) - return -1; - if( !len ) { - if( blkmode ) - iobuf_set_block_mode(out, 8196 ); - } - else { - if( ctb & 2 ) { - iobuf_put(out, len >> 24 ); - iobuf_put(out, len >> 16 ); - } - if( ctb & 3 ) - iobuf_put(out, len >> 8 ); - if( iobuf_put(out, len ) ) - return -1; - } - return 0; -} - - -static int -write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen ) -{ - if( hdrlen ) - log_bug("can't cope with hdrlen yet\n"); - - if( iobuf_put(out, ctb ) ) - return -1; - if( !len ) { - iobuf_set_partial_block_mode(out, 512 ); - } - else { - if( len < 192 ) { - if( iobuf_put(out, len ) ) - return -1; - } - else if( len < 8384 ) { - len -= 192; - if( iobuf_put( out, (len / 256) + 192) ) - return -1; - if( iobuf_put( out, (len % 256) ) ) - return -1; - } - else { - if( iobuf_put( out, 0xff ) ) - return -1; - if( iobuf_put( out, (len >> 24)&0xff ) ) - return -1; - if( iobuf_put( out, (len >> 16)&0xff ) ) - return -1; - if( iobuf_put( out, (len >> 8)&0xff ) ) - return -1; - if( iobuf_put( out, len & 0xff ) ) - return -1; - } - } - return 0; -} - -static int -write_version( iobuf_t out, int ctb ) -{ - if( iobuf_put( out, 3 ) ) - return -1; - return 0; -} diff --git a/g10/call-agent.c b/g10/call-agent.c deleted file mode 100644 index de157d491..000000000 --- a/g10/call-agent.c +++ /dev/null @@ -1,893 +0,0 @@ -/* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if 0 /* lety Emacs display a red warning */ -#error fixme: this shares a lof of code with the file in ../sm -#endif - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#include <assuan.h> - -#include "gpg.h" -#include "util.h" -#include "membuf.h" -#include "options.h" -#include "i18n.h" -#include "call-agent.h" - -#ifndef DBG_ASSUAN -# define DBG_ASSUAN 1 -#endif - -static ASSUAN_CONTEXT agent_ctx = NULL; -static int force_pipe_server = 1; /* FIXME: set this back to 0. */ - -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; - size_t ciphertextlen; -}; - -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; - size_t sexplen; -}; - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_agent (void) -{ - int rc = 0; - char *infostr, *p; - ASSUAN_CONTEXT ctx; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the agent. */ - - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error_from_errno (errno); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - dft_display = getenv ("DISPLAY"); - if (opt.display || dft_display) - { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt.display ? opt.display : dft_display) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt.ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt.ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt.ttyname ? opt.ttyname : dft_ttyname) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - dft_ttytype = getenv ("TERM"); - if (opt.ttytype || (dft_ttyname && dft_ttytype)) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt.ttyname ? opt.ttytype : dft_ttytype) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - - } - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt.lc_ctype || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt.lc_ctype ? opt.lc_ctype : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - free (old_lc); - } -#endif - if (rc) - return rc; -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return gpg_error_from_errno (errno); - } - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt.lc_messages || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt.lc_messages ? opt.lc_messages : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - free (old_lc); - } -#endif - - return rc; -} - - -/* Return a new malloced string by unescaping the string S. Escaping - is percent escaping and '+'/space mapping. A binary nul will - silently be replaced by a 0xFF. Function returns NULL to indicate - an out of memory status. */ -static char * -unescape_status_string (const unsigned char *s) -{ - char *buffer, *d; - - buffer = d = xtrymalloc (strlen (s)+1); - if (!buffer) - return NULL; - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d = xtoi_2 (s); - if (!*d) - *d = '\xff'; - d++; - s += 2; - } - else if (*s == '+') - { - *d++ = ' '; - s++; - } - else - *d++ = *s++; - } - *d = 0; - return buffer; -} - -/* Take a 20 byte hexencoded string and put it into the the provided - 20 byte buffer FPR in binary format. */ -static int -unhexify_fpr (const char *hexstr, unsigned char *fpr) -{ - const char *s; - int n; - - for (s=hexstr, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n != 40)) - return 0; /* no fingerprint (invalid or wrong length). */ - n /= 2; - for (s=hexstr, n=0; *s; s += 2, n++) - fpr[n] = xtoi_2 (s); - return 1; /* okay */ -} - -/* Take the serial number from LINE and return it verbatim in a newly - allocated string. We make sure that only hex characters are - returned. */ -static char * -store_serialno (const char *line) -{ - const char *s; - char *p; - - for (s=line; hexdigitp (s); s++) - ; - p = xtrymalloc (s + 1 - line); - if (p) - { - memcpy (p, line, s-line); - p[s-line] = 0; - } - return p; -} - - - -#if 0 -/* Handle a KEYPARMS inquiry. Note, we only send the data, - assuan_transact takes care of flushing and writing the end */ -static AssuanError -inq_genkey_parms (void *opaque, const char *keyword) -{ - struct genkey_parm_s *parm = opaque; - AssuanError rc; - - rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen); - return rc; -} - - - -/* Call the agent to generate a new key */ -int -agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - membuf_t data; - size_t len; - char *buf; - - *r_pubkey = NULL; - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, - NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - gk_parm.ctx = agent_ctx; - gk_parm.sexp = keyparms; - gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); - if (!gk_parm.sexplen) - return gpg_error (GPG_ERR_INV_VALUE); - rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, - inq_genkey_parms, &gk_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_SEXP); - } - *r_pubkey = buf; - return 0; -} -#endif /*0*/ - - - -/* Ask the agent whether the corresponding secret key is available for - the given keygrip. */ -int -agent_havekey (const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Release the card info structure INFO. */ -void -agent_release_card_info (struct agent_card_info_s *info) -{ - if (!info) - return; - - xfree (info->serialno); info->serialno = NULL; - xfree (info->disp_name); info->disp_name = NULL; - xfree (info->disp_lang); info->disp_lang = NULL; - xfree (info->pubkey_url); info->pubkey_url = NULL; - xfree (info->login_data); info->login_data = NULL; - info->fpr1valid = info->fpr2valid = info->fpr3valid = 0; -} - -static AssuanError -learn_status_cb (void *opaque, const char *line) -{ - struct agent_card_info_s *parm = opaque; - const char *keyword = line; - int keywordlen; - int i; - - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - - if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) - { - xfree (parm->serialno); - parm->serialno = store_serialno (line); - } - else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen)) - { - xfree (parm->disp_name); - parm->disp_name = unescape_status_string (line); - } - else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen)) - { - xfree (parm->disp_lang); - parm->disp_lang = unescape_status_string (line); - } - else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen)) - { - parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0; - } - else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen)) - { - xfree (parm->pubkey_url); - parm->pubkey_url = unescape_status_string (line); - } - else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen)) - { - xfree (parm->login_data); - parm->login_data = unescape_status_string (line); - } - else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen)) - { - parm->sig_counter = strtoul (line, NULL, 0); - } - else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen)) - { - char *p, *buf; - - buf = p = unescape_status_string (line); - if (buf) - { - while (spacep (p)) - p++; - parm->chv1_cached = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - for (i=0; *p && i < 3; i++) - { - parm->chvmaxlen[i] = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - } - for (i=0; *p && i < 3; i++) - { - parm->chvretry[i] = atoi (p); - while (*p && !spacep (p)) - p++; - while (spacep (p)) - p++; - } - xfree (buf); - } - } - else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) - { - int no = atoi (line); - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - if (no == 1) - parm->fpr1valid = unhexify_fpr (line, parm->fpr1); - else if (no == 2) - parm->fpr2valid = unhexify_fpr (line, parm->fpr2); - else if (no == 3) - parm->fpr3valid = unhexify_fpr (line, parm->fpr3); - } - - return 0; -} - -/* Call the agent to learn about a smartcard */ -int -agent_learn (struct agent_card_info_s *info) -{ - int rc; - - rc = start_agent (); - if (rc) - return rc; - - memset (info, 0, sizeof *info); - rc = assuan_transact (agent_ctx, "LEARN --send", - NULL, NULL, NULL, NULL, - learn_status_cb, info); - - return map_assuan_err (rc); -} - -/* Call the agent to retrieve a data object. This function returns - the data in the same structure as used by the learn command. It is - allowed to update such a structure using this commmand. */ -int -agent_scd_getattr (const char *name, struct agent_card_info_s *info) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - if (!*name) - return gpg_error (GPG_ERR_INV_VALUE); - - /* We assume that NAME does not need escaping. */ - if (12 + strlen (name) > DIM(line)-1) - return gpg_error (GPG_ERR_TOO_LARGE); - stpcpy (stpcpy (line, "SCD GETATTR "), name); - - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, - learn_status_cb, info); - - return map_assuan_err (rc); -} - - -/* Send an setattr command to the SCdaemon. */ -int -agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - char *p; - - if (!*name || !valuelen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* We assume that NAME does not need escaping. */ - if (12 + strlen (name) > DIM(line)-1) - return gpg_error (GPG_ERR_TOO_LARGE); - - p = stpcpy (stpcpy (line, "SCD SETATTR "), name); - *p++ = ' '; - for (; valuelen; value++, valuelen--) - { - if (p >= line + DIM(line)-5 ) - return gpg_error (GPG_ERR_TOO_LARGE); - if (*value < ' ' || *value == '+' || *value == '%') - { - sprintf (p, "%%%02X", *value); - p += 3; - } - else if (*value == ' ') - *p++ = '+'; - else - *p++ = *value; - } - *p = 0; - - rc = start_agent (); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Status callback for the SCD GENKEY command. */ -static AssuanError -scd_genkey_cb (void *opaque, const char *line) -{ - struct agent_card_genkey_s *parm = opaque; - const char *keyword = line; - int keywordlen; - gpg_error_t rc; - - log_debug ("got status line `%s'\n", line); - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - - if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) - { - parm->fprvalid = unhexify_fpr (line, parm->fpr); - } - if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen)) - { - gcry_mpi_t a; - const char *name = line; - - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - - rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL); - if (rc) - log_error ("error parsing received key data: %s\n", gpg_strerror (rc)); - else if (*name == 'n' && spacep (name+1)) - parm->n = a; - else if (*name == 'e' && spacep (name+1)) - parm->e = a; - else - { - log_info ("unknown parameter name in received key data\n"); - gcry_mpi_release (a); - } - } - else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen)) - { - parm->created_at = (u32)strtoul (line, NULL, 10); - } - - return 0; -} - -/* Send a GENKEY command to the SCdaemon. */ -int -agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - memset (info, 0, sizeof *info); - snprintf (line, DIM(line)-1, "SCD GENKEY %s%d", - force? "--force ":"", keyno); - line[DIM(line)-1] = 0; - - memset (info, 0, sizeof *info); - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, - scd_genkey_cb, info); - - return map_assuan_err (rc); -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - -/* Send a sign command to the scdaemon via gpg-agent's pass thru - mechanism. */ -int -agent_scd_pksign (const char *serialno, int hashalgo, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */ - - *r_buf = NULL; - *r_buflen = 0; - - rc = start_agent (); - if (rc) - return rc; - - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - sprintf (line, "SCD SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); -#if 0 - if (!hashalgo) /* Temporary test hack. */ - snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); - else -#endif - snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, - NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - - return 0; -} - - -/* Decrypt INDATA of length INDATALEN using the card identified by - SERIALNO. Return the plaintext in a nwly allocated buffer stored - at the address of R_BUF. - - Note, we currently support only RSA or more exactly algorithms - taking one input data element. */ -int -agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - *r_buf = NULL; - rc = start_agent (); - if (rc) - return rc; - - /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - sprintf (line, "SCD SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, - NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - return gpg_error (GPG_ERR_ENOMEM); - - return 0; -} - - -/* Change the PIN of an OpenPGP card or reset the retry counter. - CHVNO 1: Change the PIN - 2: Same as 1 - 3: Change the admin PIN - 101: Set a new PIN and reset the retry counter - 102: Same as 101 - */ -int -agent_scd_change_pin (int chvno) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - const char *reset = ""; - - if (chvno >= 100) - reset = "--reset"; - chvno %= 100; - - rc = start_agent (); - if (rc) - return rc; - - snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, - NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -/* Perform a CHECKPIN operation. SERIALNO should be the serial - number of the card - optioanlly followed by the fingerprint; - however the fingerprint is ignored here. */ -int -agent_scd_checkpin (const char *serialno) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno); - line[DIM(line)-1] = 0; - return assuan_transact (agent_ctx, line, - NULL, NULL, - NULL, NULL, NULL, NULL); -} - - diff --git a/g10/call-agent.h b/g10/call-agent.h deleted file mode 100644 index 875110118..000000000 --- a/g10/call-agent.h +++ /dev/null @@ -1,94 +0,0 @@ -/* call-agent.h - Divert operations to the agent - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_G10_CALL_AGENT_H -#define GNUPG_G10_CALL_AGENT_H - - -struct agent_card_info_s { - int error; /* private. */ - char *serialno; /* malloced hex string. */ - char *disp_name; /* malloced. */ - char *disp_lang; /* malloced. */ - int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ - char *pubkey_url; /* malloced. */ - char *login_data; /* malloced. */ - char fpr1valid; - char fpr2valid; - char fpr3valid; - char fpr1[20]; - char fpr2[20]; - char fpr3[20]; - unsigned long sig_counter; - int chv1_cached; /* True if a PIN is not required for each - signing. Note that the gpg-agent might cache - it anyway. */ - int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ - int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ -}; - -struct agent_card_genkey_s { - char fprvalid; - char fpr[20]; - u32 created_at; - gcry_mpi_t n; - gcry_mpi_t e; -}; - - -/* Release the card info structure. */ -void agent_release_card_info (struct agent_card_info_s *info); - -/* Return card info. */ -int agent_learn (struct agent_card_info_s *info); - -/* Update INFO with the attribute NAME. */ -int agent_scd_getattr (const char *name, struct agent_card_info_s *info); - -/* Check whether the secret key for the key identified by HEXKEYGRIP - is available. Return 0 for yes or an error code. */ -int agent_havekey (const char *hexkeygrip); - -/* Send a SETATTR command to the SCdaemon. */ -int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen); - -/* Send a GENKEY command to the SCdaemon. */ -int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); - -/* Send a PKSIGN command to the SCdaemon. */ -int agent_scd_pksign (const char *keyid, int hashalgo, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); - -/* Send a PKDECRYPT command to the SCdaemon. */ -int agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); - -/* Change the PIN of an OpenPGP card or reset the retry counter. */ -int agent_scd_change_pin (int chvno); - -/* Send the CHECKPIN command to the SCdaemon. */ -int agent_scd_checkpin (const char *serialno); - - - -#endif /*GNUPG_G10_CALL_AGENT_H*/ - diff --git a/g10/card-util.c b/g10/card-util.c deleted file mode 100644 index c93d028bd..000000000 --- a/g10/card-util.c +++ /dev/null @@ -1,884 +0,0 @@ -/* card-util.c - Utility functions for the OpenPGP card. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#if GNUPG_MAJOR_VERSION != 1 -#include "gpg.h" -#endif -#include "util.h" -#include "i18n.h" -#include "ttyio.h" -#include "status.h" -#include "options.h" -#include "main.h" -#if GNUPG_MAJOR_VERSION == 1 -#include "cardglue.h" -#else -#include "call-agent.h" -#endif - -#define CONTROL_D ('D' - 'A' + 1) - - -/* Change the PIN of a an OpenPGP card. This is an interactive - function. */ -void -change_pin (int chvno) -{ - struct agent_card_info_s info; - int rc; - - rc = agent_learn (&info); - if (rc) - { - log_error (_("OpenPGP card not available: %s\n"), - gpg_strerror (rc)); - return; - } - - log_info (_("OpenPGP card no. %s detected\n"), - info.serialno? info.serialno : "[none]"); - - agent_release_card_info (&info); - - if (opt.batch) - { - log_error (_("sorry, can't do this in batch mode\n")); - return; - } - - for (;;) - { - char *answer; - - tty_printf ("\n"); - tty_printf ("1 - change PIN\n" - "2 - unblock PIN\n" - "3 - change Admin PIN\n" - "Q - quit\n"); - tty_printf ("\n"); - - answer = cpr_get("cardutil.change_pin.menu",_("Your selection? ")); - cpr_kill_prompt(); - if (strlen (answer) != 1) - continue; - - rc = 0; - if (*answer == '1') - { - rc = agent_scd_change_pin (1); - if (rc) - tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN changed.\n"); - } - else if (*answer == '2') - { - rc = agent_scd_change_pin (101); - if (rc) - tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN unblocked and new PIN set.\n"); - } - else if (*answer == '3') - { - rc = agent_scd_change_pin (3); - if (rc) - tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); - else - tty_printf ("PIN changed.\n"); - } - else if (*answer == 'q' || *answer == 'Q') - { - break; - } - } -} - -static const char * -get_manufacturer (unsigned int no) -{ - /* Note: Make sure that there is no colon or linefeed in the string. */ - switch (no) - { - case 0: - case 0xffff: return "test card"; - case 0x0001: return "PPC Card Systems"; - default: return "unknown"; - } -} - - -static void -print_sha1_fpr (FILE *fp, const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i+=2, fpr += 2 ) - { - if (i == 10 ) - tty_fprintf (fp, " "); - tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]); - } - } - else - tty_fprintf (fp, " [none]"); - tty_fprintf (fp, "\n"); -} - - -static void -print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i++, fpr++) - fprintf (fp, "%02X", *fpr); - } - putc (':', fp); -} - - -static void -print_name (FILE *fp, const char *text, const char *name) -{ - tty_fprintf (fp, "%s", text); - - /* FIXME: tty_printf_utf8_string2 eats everything after and - including an @ - e.g. when printing an url. */ - if (name && *name) - { - if (fp) - print_utf8_string2 (fp, name, strlen (name), '\n'); - else - tty_print_utf8_string2 (name, strlen (name), 0); - } - else - tty_fprintf (fp, _("[not set]")); - tty_fprintf (fp, "\n"); -} - -static void -print_isoname (FILE *fp, const char *text, const char *tag, const char *name) -{ - if (opt.with_colons) - fprintf (fp, "%s:", tag); - else - tty_fprintf (fp, "%s", text); - - if (name && *name) - { - char *p, *given, *buf = xstrdup (name); - - given = strstr (buf, "<<"); - for (p=buf; *p; p++) - if (*p == '<') - *p = ' '; - if (given && given[2]) - { - *given = 0; - given += 2; - if (opt.with_colons) - print_string (fp, given, strlen (given), ':'); - else if (fp) - print_utf8_string2 (fp, given, strlen (given), '\n'); - else - tty_print_utf8_string2 (given, strlen (given), 0); - - if (opt.with_colons) - putc (':', fp); - else if (*buf) - tty_fprintf (fp, " "); - } - - if (opt.with_colons) - print_string (fp, buf, strlen (buf), ':'); - else if (fp) - print_utf8_string2 (fp, buf, strlen (buf), '\n'); - else - tty_print_utf8_string2 (buf, strlen (buf), 0); - xfree (buf); - } - else - { - if (opt.with_colons) - putc (':', fp); - else - tty_fprintf (fp, _("[not set]")); - } - - if (opt.with_colons) - fputs (":\n", fp); - else - tty_fprintf (fp, "\n"); -} - -/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */ -static int -fpr_is_zero (const char *fpr) -{ - int i; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - return (i == 20); -} - - -/* Print all available information about the current card. */ -void -card_status (FILE *fp, char *serialno, size_t serialnobuflen) -{ - struct agent_card_info_s info; - PKT_public_key *pk = xcalloc (1, sizeof *pk); - int rc; - unsigned int uval; - - if (serialno && serialnobuflen) - *serialno = 0; - - rc = agent_learn (&info); - if (rc) - { - if (opt.with_colons) - fputs ("AID:::\n", fp); - log_error (_("OpenPGP card not available: %s\n"), - gpg_strerror (rc)); - xfree (pk); - return; - } - - if (opt.with_colons) - fprintf (fp, "AID:%s:", info.serialno? info.serialno : ""); - else - tty_fprintf (fp, "Application ID ...: %s\n", - info.serialno? info.serialno : "[none]"); - if (!info.serialno || strncmp (info.serialno, "D27600012401", 12) - || strlen (info.serialno) != 32 ) - { - if (opt.with_colons) - fputs ("unknown:\n", fp); - log_info ("not an OpenPGP card\n"); - agent_release_card_info (&info); - xfree (pk); - return; - } - - if (!serialno) - ; - else if (strlen (serialno)+1 > serialnobuflen) - log_error ("serial number longer than expected\n"); - else - strcpy (serialno, info.serialno); - - if (opt.with_colons) - fputs ("openpgp-card:\n", fp); - - - if (opt.with_colons) - { - fprintf (fp, "version:%.4s:\n", info.serialno+12); - uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18); - fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval)); - fprintf (fp, "serial:%.8s:\n", info.serialno+20); - - print_isoname (fp, "Name of cardholder: ", "name", info.disp_name); - - fputs ("lang:", fp); - if (info.disp_lang) - print_string (fp, info.disp_lang, strlen (info.disp_lang), ':'); - fputs (":\n", fp); - - fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm': - info.disp_sex == 2? 'f' : 'u')); - - fputs ("url:", fp); - if (info.pubkey_url) - print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':'); - fputs (":\n", fp); - - fputs ("login:", fp); - if (info.login_data) - print_string (fp, info.login_data, strlen (info.login_data), ':'); - fputs (":\n", fp); - - fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached); - fprintf (fp, "maxpinlen:%d:%d:%d:\n", - info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); - fprintf (fp, "pinretry:%d:%d:%d:\n", - info.chvretry[0], info.chvretry[1], info.chvretry[2]); - fprintf (fp, "sigcount:%lu:::\n", info.sig_counter); - - fputs ("fpr:", fp); - print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL); - print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL); - print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL); - putc ('\n', fp); - - } - else - { - tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n", - info.serialno[12] == '0'?"":info.serialno+12, - info.serialno[13], - info.serialno[14] == '0'?"":info.serialno+14, - info.serialno[15]); - tty_fprintf (fp, "Manufacturer .....: %s\n", - get_manufacturer (xtoi_2(info.serialno+16)*256 - + xtoi_2 (info.serialno+18))); - tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20); - - print_isoname (fp, "Name of cardholder: ", "name", info.disp_name); - print_name (fp, "Language prefs ...: ", info.disp_lang); - tty_fprintf (fp, "Sex ..............: %s\n", - info.disp_sex == 1? _("male"): - info.disp_sex == 2? _("female") : _("unspecified")); - print_name (fp, "URL of public key : ", info.pubkey_url); - print_name (fp, "Login data .......: ", info.login_data); - tty_fprintf (fp, "Signature PIN ....: %s\n", - info.chv1_cached? _("not forced"): _("forced")); - tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", - info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); - tty_fprintf (fp, "PIN retry counter : %d %d %d\n", - info.chvretry[0], info.chvretry[1], info.chvretry[2]); - tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter); - tty_fprintf (fp, "Signature key ....:"); - print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL); - tty_fprintf (fp, "Encryption key....:"); - print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); - tty_fprintf (fp, "Authentication key:"); - print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); - tty_fprintf (fp, "General key info..: "); - if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20)) - print_pubkey_info (fp, pk); - else - tty_fprintf (fp, "[none]\n"); - } - - free_public_key (pk); - agent_release_card_info (&info); -} - - -static char * -get_one_name (const char *prompt1, const char *prompt2) -{ - char *name; - int i; - - for (;;) - { - name = cpr_get (prompt1, prompt2); - if (!name) - return NULL; - trim_spaces (name); - cpr_kill_prompt (); - for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++) - ; - - /* The name must be in Latin-1 and not UTF-8 - lacking the code - to ensure this we restrict it to ASCII. */ - if (name[i]) - tty_printf (_("Error: Only plain ASCII is currently allowed.\n")); - else if (strchr (name, '<')) - tty_printf (_("Error: The \"<\" character may not be used.\n")); - else if (strstr (name, " ")) - tty_printf (_("Error: Double spaces are not allowed.\n")); - else - return name; - xfree (name); - } -} - - - -static int -change_name (void) -{ - char *surname = NULL, *givenname = NULL; - char *isoname, *p; - int rc; - - surname = get_one_name ("keygen.smartcard.surname", - _("Cardholder's surname: ")); - givenname = get_one_name ("keygen.smartcard.givenname", - _("Cardholder's given name: ")); - if (!surname || !givenname || (!*surname && !*givenname)) - { - xfree (surname); - xfree (givenname); - return -1; /*canceled*/ - } - - isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1); - strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname); - xfree (surname); - xfree (givenname); - for (p=isoname; *p; p++) - if (*p == ' ') - *p = '<'; - - if (strlen (isoname) > 39 ) - { - tty_printf (_("Error: Combined name too long " - "(limit is %d characters).\n"), 39); - xfree (isoname); - return -1; - } - - log_debug ("setting Name to `%s'\n", isoname); - rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) ); - if (rc) - log_error ("error setting Name: %s\n", gpg_strerror (rc)); - - xfree (isoname); - return rc; -} - - -static int -change_url (void) -{ - char *url; - int rc; - - url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: ")); - if (!url) - return -1; - trim_spaces (url); - cpr_kill_prompt (); - - if (strlen (url) > 254 ) - { - tty_printf (_("Error: URL too long " - "(limit is %d characters).\n"), 254); - xfree (url); - return -1; - } - - rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) ); - if (rc) - log_error ("error setting URL: %s\n", gpg_strerror (rc)); - xfree (url); - return rc; -} - -static int -change_login (void) -{ - char *data; - int rc; - - data = cpr_get ("cardedit.change_login", - _("Login data (account name): ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (strlen (data) > 254 ) - { - tty_printf (_("Error: Login data too long " - "(limit is %d characters).\n"), 254); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) ); - if (rc) - log_error ("error setting login data: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - -static int -change_lang (void) -{ - char *data, *p; - int rc; - - data = cpr_get ("cardedit.change_lang", - _("Language preferences: ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (strlen (data) > 8 || (strlen (data) & 1)) - { - tty_printf (_("Error: invalid length of preference string.\n")); - xfree (data); - return -1; - } - - for (p=data; *p && *p >= 'a' && *p <= 'z'; p++) - ; - if (*p) - { - tty_printf (_("Error: invalid characters in preference string.\n")); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) ); - if (rc) - log_error ("error setting lang: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - - -static int -change_sex (void) -{ - char *data; - const char *str; - int rc; - - data = cpr_get ("cardedit.change_sex", - _("Sex ((M)ale, (F)emale or space): ")); - if (!data) - return -1; - trim_spaces (data); - cpr_kill_prompt (); - - if (!*data) - str = "9"; - else if ((*data == 'M' || *data == 'm') && !data[1]) - str = "1"; - else if ((*data == 'F' || *data == 'f') && !data[1]) - str = "2"; - else - { - tty_printf (_("Error: invalid response.\n")); - xfree (data); - return -1; - } - - rc = agent_scd_setattr ("DISP-SEX", str, 1 ); - if (rc) - log_error ("error setting sex: %s\n", gpg_strerror (rc)); - xfree (data); - return rc; -} - - -static void -toggle_forcesig (void) -{ - struct agent_card_info_s info; - int rc; - int newstate; - - memset (&info, 0, sizeof info); - rc = agent_scd_getattr ("CHV-STATUS", &info); - if (rc) - { - log_error ("error getting current status: %s\n", gpg_strerror (rc)); - return; - } - newstate = !info.chv1_cached; - agent_release_card_info (&info); - - rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1); - if (rc) - log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc)); -} - - -static void -generate_card_keys (const char *serialno) -{ - struct agent_card_info_s info; - int rc; - int forced_chv1; - - memset (&info, 0, sizeof info); - rc = agent_scd_getattr ("KEY-FPR", &info); - if (!rc) - rc = agent_scd_getattr ("SERIALNO", &info); - if (!rc) - rc = agent_scd_getattr ("CHV-STATUS", &info); - if (!rc) - rc = agent_scd_getattr ("DISP-NAME", &info); - if (rc) - { - log_error ("error getting current key info: %s\n", gpg_strerror (rc)); - return; - } - if ( (info.fpr1valid && !fpr_is_zero (info.fpr1)) - || (info.fpr2valid && !fpr_is_zero (info.fpr2)) - || (info.fpr3valid && !fpr_is_zero (info.fpr3))) - { - tty_printf ("\n"); - log_info ("NOTE: keys are already stored on the card!\n"); - tty_printf ("\n"); - if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys", - _("Replace existing keys? "))) - { - agent_release_card_info (&info); - return; - } - } - else if (!info.disp_name || !*info.disp_name) - { - tty_printf ("\n"); - tty_printf (_("Please note that the factory settings of the PINs are\n" - " PIN = \"%s\" Admin PIN = \"%s\"\n" - "You should change them using the command --change-pin\n"), - "123456", "12345678"); - tty_printf ("\n"); - } - - forced_chv1 = !info.chv1_cached; - if (forced_chv1) - { /* Switch of the forced mode so that during key generation we - don't get bothered with PIN queries for each - self-signature. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1); - if (rc) - { - log_error ("error clearing forced signature PIN flag: %s\n", - gpg_strerror (rc)); - return; - } - } - - /* Check the PIN now, so that we won't get asked later for each - binding signature. */ - rc = agent_scd_checkpin (serialno); - if (rc) - log_error ("error checking the PIN: %s\n", gpg_strerror (rc)); - else - generate_keypair (NULL, info.serialno); - - agent_release_card_info (&info); - if (forced_chv1) - { /* Switch back to forced state. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "", 1); - if (rc) - { - log_error ("error setting forced signature PIN flag: %s\n", - gpg_strerror (rc)); - return; - } - } -} - -/* Menu to edit all user changeable values on an OpenPGP card. Only - Key creation is not handled here. */ -void -card_edit (STRLIST commands) -{ - enum cmdids { - cmdNOP = 0, - cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG, - cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, - cmdFORCESIG, cmdGENERATE, cmdPASSWD, - cmdINVCMD - }; - - static struct { - const char *name; - enum cmdids id; - const char *desc; - } cmds[] = { - { N_("quit") , cmdQUIT , N_("quit this menu") }, - { N_("q") , cmdQUIT , NULL }, - { N_("help") , cmdHELP , N_("show this help") }, - { "?" , cmdHELP , NULL }, - { N_("list") , cmdLIST , N_("list all available data") }, - { N_("l") , cmdLIST , NULL }, - { N_("debug") , cmdDEBUG , NULL }, - { N_("name") , cmdNAME , N_("change card holder's name") }, - { N_("url") , cmdURL , N_("change URL to retrieve key") }, - { N_("login") , cmdLOGIN , N_("change the login name") }, - { N_("lang") , cmdLANG , N_("change the language preferences") }, - { N_("sex") , cmdSEX , N_("change card holder's sex") }, - { N_("forcesig"), - cmdFORCESIG, N_("toggle the signature force PIN flag") }, - { N_("generate"), - cmdGENERATE, N_("generate new keys") }, - { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") }, - { NULL, cmdINVCMD } - }; - - enum cmdids cmd = cmdNOP; - int have_commands = !!commands; - int redisplay = 1; - char *answer = NULL; - int did_checkpin = 0; - char serialnobuf[50]; - - - if (opt.command_fd != -1) - ; - else if (opt.batch && !have_commands) - { - log_error(_("can't do that in batchmode\n")); - goto leave; - } - - for (;;) - { - int arg_number; - const char *arg_string = ""; - char *p; - int i; - - tty_printf("\n"); - if (redisplay ) - { - if (opt.with_colons) - { - card_status (stdout, serialnobuf, DIM (serialnobuf)); - fflush (stdout); - } - else - { - card_status (NULL, serialnobuf, DIM (serialnobuf)); - tty_printf("\n"); - } - redisplay = 0; - } - - do - { - xfree (answer); - if (have_commands) - { - if (commands) - { - answer = xstrdup (commands->d); - commands = commands->next; - } - else if (opt.batch) - { - answer = xstrdup ("quit"); - } - else - have_commands = 0; - } - - if (!have_commands) - { - answer = cpr_get_no_help("cardedit.prompt", _("Command> ")); - cpr_kill_prompt(); - } - trim_spaces(answer); - } - while( *answer == '#' ); - - arg_number = 0; /* Yes, here is the init which egcc complains about */ - if (!*answer) - cmd = cmdLIST; /* Default to the list command */ - else if (*answer == CONTROL_D) - cmd = cmdQUIT; - else { - if ((p=strchr (answer,' '))) - { - *p++ = 0; - trim_spaces (answer); - trim_spaces (p); - arg_number = atoi(p); - arg_string = p; - } - - for (i=0; cmds[i].name; i++ ) - if (!ascii_strcasecmp (answer, cmds[i].name )) - break; - - cmd = cmds[i].id; - } - - - switch (cmd) - { - case cmdHELP: - for (i=0; cmds[i].name; i++ ) - if (cmds[i].desc) - tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - break; - - case cmdLIST: - redisplay = 1; - break; - - case cmdNAME: - change_name (); - break; - - case cmdURL: - change_url (); - break; - - case cmdLOGIN: - change_login (); - break; - - case cmdLANG: - change_lang (); - break; - - case cmdSEX: - change_sex (); - break; - - case cmdFORCESIG: - toggle_forcesig (); - break; - - case cmdGENERATE: - generate_card_keys (serialnobuf); - break; - - case cmdPASSWD: - change_pin (0); - did_checkpin = 0; /* Need to reset it of course. */ - break; - - case cmdQUIT: - goto leave; - - case cmdNOP: - break; - - case cmdINVCMD: - default: - tty_printf ("\n"); - tty_printf (_("Invalid command (try \"help\")\n")); - break; - } /* End command switch. */ - } /* End of main menu loop. */ - - leave: - xfree (answer); -} - diff --git a/g10/cipher.c b/g10/cipher.c deleted file mode 100644 index 3d51a874a..000000000 --- a/g10/cipher.c +++ /dev/null @@ -1,165 +0,0 @@ -/* cipher.c - En-/De-ciphering filter - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" -#include "status.h" - - -#define MIN_PARTIAL_SIZE 512 - - -static void -write_header( cipher_filter_context_t *cfx, iobuf_t a ) -{ - PACKET pkt; - PKT_encrypted ed; - byte temp[18]; - unsigned int blocksize; - unsigned int nprefix; - gpg_error_t rc; - - blocksize = gcry_cipher_get_algo_blklen ( cfx->dek->algo ); - if( blocksize < 8 || blocksize > 16 ) - log_fatal("unsupported blocksize %u\n", blocksize ); - - memset( &ed, 0, sizeof ed ); - ed.len = cfx->datalen; - ed.extralen = blocksize+2; - ed.new_ctb = !ed.len && !RFC1991; - if( cfx->dek->use_mdc ) { - ed.mdc_method = DIGEST_ALGO_SHA1; - gcry_md_open (&cfx->mdc_hash, GCRY_MD_SHA1, 0 ); - if ( DBG_HASHING ) - gcry_md_start_debug ( cfx->mdc_hash, "creatmdc" ); - } - - { - char buf[20]; - - sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo); - write_status_text (STATUS_BEGIN_ENCRYPTION, buf); - } - - init_packet( &pkt ); - pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; - pkt.pkt.encrypted = &ed; - if( build_packet( a, &pkt )) - log_bug("build_packet(ENCR_DATA) failed\n"); - nprefix = blocksize; - gcry_randomize ( temp, nprefix, GCRY_STRONG_RANDOM); - temp[nprefix] = temp[nprefix-2]; - temp[nprefix+1] = temp[nprefix-1]; - print_cipher_algo_note( cfx->dek->algo ); - rc = gcry_cipher_open (&cfx->cipher_hd, cfx->dek->algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | ((cfx->dek->use_mdc || cfx->dek->algo >= 100) ? - 0 : GCRY_CIPHER_ENABLE_SYNC)); - if (rc) { - /* we should never get an error here cause we already checked, that - * the algorithm is available. */ - BUG(); - } -/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/ - gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen ); - gcry_cipher_setiv( cfx->cipher_hd, NULL, 0 ); -/* log_hexdump( "prefix", temp, nprefix+2 ); */ - if( cfx->mdc_hash ) /* hash the "IV" */ - gcry_md_write( cfx->mdc_hash, temp, nprefix+2 ); - gcry_cipher_encrypt( cfx->cipher_hd, temp, nprefix+2, NULL, 0); - gcry_cipher_sync( cfx->cipher_hd ); - iobuf_write(a, temp, nprefix+2); - cfx->header=1; -} - - - -/**************** - * This filter is used to en/de-cipher data with a conventional algorithm - */ -int -cipher_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - cipher_filter_context_t *cfx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ - rc = -1; /* not yet used */ - } - else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ - assert(a); - if( !cfx->header ) { - write_header( cfx, a ); - } - if( cfx->mdc_hash ) - gcry_md_write( cfx->mdc_hash, buf, size ); - gcry_cipher_encrypt( cfx->cipher_hd, buf, size, NULL, 0); - rc = iobuf_write( a, buf, size ); - } - else if( control == IOBUFCTRL_FREE ) { - if( cfx->mdc_hash ) { - byte *hash; - int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo ( - cfx->mdc_hash)); - byte temp[22]; - - assert( hashlen == 20 ); - /* we must hash the prefix of the MDC packet here */ - temp[0] = 0xd3; - temp[1] = 0x14; - gcry_md_putc ( cfx->mdc_hash, temp[0] ); - gcry_md_putc ( cfx->mdc_hash, temp[1] ); - - gcry_md_final ( cfx->mdc_hash ); - hash = gcry_md_read ( cfx->mdc_hash, 0 ); - memcpy(temp+2, hash, 20); - gcry_cipher_encrypt( cfx->cipher_hd, temp, 22, NULL, 0 ); - gcry_md_close ( cfx->mdc_hash ); cfx->mdc_hash = NULL; - rc = iobuf_write( a, temp, 22 ); - if (rc) - log_error("writing MDC packet failed\n" ); - } - gcry_cipher_close (cfx->cipher_hd); - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "cipher_filter"; - } - return rc; -} - - - diff --git a/g10/comment.c b/g10/comment.c deleted file mode 100644 index b52104cd7..000000000 --- a/g10/comment.c +++ /dev/null @@ -1,112 +0,0 @@ -/* comment.c - write comment stuff - * Copyright (C) 1998, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "keydb.h" - - - -int -write_comment( iobuf_t out, const char *s ) -{ - PACKET pkt; - size_t n = strlen(s); - int rc=0; - - pkt.pkttype = PKT_COMMENT; - if( *s != '#' ) { - pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n ); - pkt.pkt.comment->len = n+1; - *pkt.pkt.comment->data = '#'; - strcpy(pkt.pkt.comment->data+1, s); - } - else { - pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n - 1 ); - pkt.pkt.comment->len = n; - strcpy(pkt.pkt.comment->data, s); - } - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet(comment) failed: %s\n", gpg_strerror (rc) ); - free_packet( &pkt ); - return rc; -} - - -KBNODE -make_comment_node_from_buffer (const char *s, size_t n) -{ - PACKET *pkt; - - pkt = gcry_xcalloc( 1, sizeof *pkt ); - pkt->pkttype = PKT_COMMENT; - pkt->pkt.comment = gcry_xmalloc( sizeof *pkt->pkt.comment + n - 1 ); - pkt->pkt.comment->len = n; - strcpy(pkt->pkt.comment->data, s); - return new_kbnode( pkt ); -} - -KBNODE -make_comment_node( const char *s ) -{ - return make_comment_node_from_buffer (s, strlen (s)); -} - - -KBNODE -make_mpi_comment_node( const char *s, gcry_mpi_t a ) -{ - PACKET *pkt; - byte *buf, *pp; - size_t n1, nb1; - size_t n = strlen(s); - - nb1 = mpi_get_nbits( a ); - if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &n1, a)) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc (n1); - if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, n1, &n1, a)) - BUG (); - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_COMMENT; - pkt->pkt.comment = xmalloc ( sizeof *pkt->pkt.comment + n + 2 + n1 ); - pkt->pkt.comment->len = n+1+2+n1; - pp = pkt->pkt.comment->data; - memcpy(pp, s, n+1); - memcpy(pp+n+1, buf, n1 ); - xfree (buf); - return new_kbnode( pkt ); -} - - diff --git a/g10/compress.c b/g10/compress.c deleted file mode 100644 index 7dce1790a..000000000 --- a/g10/compress.c +++ /dev/null @@ -1,329 +0,0 @@ -/* compress.c - compress filter - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <zlib.h> -#ifdef __riscos__ -# include "zlib-riscos.h" -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "filter.h" -#include "main.h" -#include "options.h" - -static void -init_compress( compress_filter_context_t *zfx, z_stream *zs ) -{ - int rc; - int level; - -#ifdef __riscos__ - static int zlib_initialized = 0; - - if (!zlib_initialized) - zlib_initialized = riscos_load_module("ZLib", zlib_path, 1); -#endif - - if( opt.compress >= 0 && opt.compress <= 9 ) - level = opt.compress; - else if( opt.compress == -1 ) - level = Z_DEFAULT_COMPRESSION; - else if( opt.compress == 10 ) /* remove this ! */ - level = 0; - else { - log_error("invalid compression level; using default level\n"); - level = Z_DEFAULT_COMPRESSION; - } - - - if( (rc = zfx->algo == 1? deflateInit2( zs, level, Z_DEFLATED, - -13, 8, Z_DEFAULT_STRATEGY) - : deflateInit( zs, level ) - ) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : - rc == Z_MEM_ERROR ? "out of core" : - rc == Z_VERSION_ERROR ? "invalid lib version" : - "unknown error" ); - } - - zfx->outbufsize = 8192; - zfx->outbuf = xmalloc ( zfx->outbufsize ); -} - -static int -do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, iobuf_t a ) -{ - gpg_error_t rc; - int zrc; - unsigned n; - - do { -#ifndef __riscos__ - zs->next_out = zfx->outbuf; -#else /* __riscos__ */ - zs->next_out = (Bytef *) zfx->outbuf; -#endif /* __riscos__ */ - zs->avail_out = zfx->outbufsize; - if( DBG_FILTER ) - log_debug("enter deflate: avail_in=%u, avail_out=%u, flush=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, flush ); - zrc = deflate( zs, flush ); - if( zrc == Z_STREAM_END && flush == Z_FINISH ) - ; - else if( zrc != Z_OK ) { - if( zs->msg ) - log_fatal("zlib deflate problem: %s\n", zs->msg ); - else - log_fatal("zlib deflate problem: rc=%d\n", zrc ); - } - n = zfx->outbufsize - zs->avail_out; - if( DBG_FILTER ) - log_debug("leave deflate: " - "avail_in=%u, avail_out=%u, n=%u, zrc=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, - (unsigned)n, zrc ); - - rc = iobuf_write (a, zfx->outbuf, n); - if (rc) - { - log_debug("deflate: iobuf_write failed\n"); - return rc; - } - } while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) ); - return 0; -} - -static void -init_uncompress( compress_filter_context_t *zfx, z_stream *zs ) -{ - int rc; - - /**************** - * PGP uses a windowsize of 13 bits. Using a negative value for - * it forces zlib not to expect a zlib header. This is a - * undocumented feature Peter Gutmann told me about. - * - * We must use 15 bits for the inflator because CryptoEx uses 15 - * bits thus the output would get scrambled w/o error indication - * if we would use 13 bits. For the uncompressing this does not - * matter at all. - */ - if( (rc = zfx->algo == 1? inflateInit2( zs, -15) - : inflateInit( zs )) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : - rc == Z_MEM_ERROR ? "out of core" : - rc == Z_VERSION_ERROR ? "invalid lib version" : - "unknown error" ); - } - - zfx->inbufsize = 2048; - zfx->inbuf = xmalloc ( zfx->inbufsize ); - zs->avail_in = 0; -} - -static int -do_uncompress( compress_filter_context_t *zfx, z_stream *zs, - iobuf_t a, size_t *ret_len ) -{ - int zrc; - int rc=0; - size_t n; - int nread, count; - int refill = !zs->avail_in; - - if( DBG_FILTER ) - log_debug("begin inflate: avail_in=%u, avail_out=%u, inbuf=%u\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, - (unsigned)zfx->inbufsize ); - do { - if( zs->avail_in < zfx->inbufsize && refill ) { - n = zs->avail_in; - if( !n ) -#ifndef __riscos__ - zs->next_in = zfx->inbuf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) zfx->inbuf; -#endif /* __riscos__ */ - count = zfx->inbufsize - n; - nread = iobuf_read( a, zfx->inbuf + n, count ); - if( nread == -1 ) nread = 0; - n += nread; - /* If we use the undocumented feature to suppress - * the zlib header, we have to give inflate an - * extra dummy byte to read */ - if( nread < count && zfx->algo == 1 ) { - *(zfx->inbuf + n) = 0xFF; /* is it really needed ? */ - zfx->algo1hack = 1; - n++; - } - zs->avail_in = n; - } - refill = 1; - if( DBG_FILTER ) - log_debug("enter inflate: avail_in=%u, avail_out=%u\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out); -#ifdef Z_SYNC_FLUSH - zrc = inflate( zs, Z_SYNC_FLUSH ); -#else - zrc = inflate( zs, Z_PARTIAL_FLUSH ); -#endif - if( DBG_FILTER ) - log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n", - (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc); - if( zrc == Z_STREAM_END ) - rc = -1; /* eof */ - else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) { - if( zs->msg ) - log_fatal("zlib inflate problem: %s\n", zs->msg ); - else - log_fatal("zlib inflate problem: rc=%d\n", zrc ); - } - } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR ); - *ret_len = zfx->outbufsize - zs->avail_out; - if( DBG_FILTER ) - log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len ); - return rc; -} - -int -compress_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - compress_filter_context_t *zfx = opaque; - z_stream *zs = zfx->opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - if( !zfx->status ) { - zs = zfx->opaque = xcalloc (1, sizeof *zs ); - init_uncompress( zfx, zs ); - zfx->status = 1; - } - -#ifndef __riscos__ - zs->next_out = buf; -#else /* __riscos__ */ - zs->next_out = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_out = size; - zfx->outbufsize = size; /* needed only for calculation */ - rc = do_uncompress( zfx, zs, a, ret_len ); - } - else if( control == IOBUFCTRL_FLUSH ) { - if( !zfx->status ) { - PACKET pkt; - PKT_compressed cd; - - if( !zfx->algo ) - zfx->algo = DEFAULT_COMPRESS_ALGO; - if( zfx->algo != 1 && zfx->algo != 2 ) - BUG(); - memset( &cd, 0, sizeof cd ); - cd.len = 0; - cd.algorithm = zfx->algo; - init_packet( &pkt ); - pkt.pkttype = PKT_COMPRESSED; - pkt.pkt.compressed = &cd; - if( build_packet( a, &pkt )) - log_bug("build_packet(PKT_COMPRESSED) failed\n"); - zs = zfx->opaque = xcalloc (1, sizeof *zs ); - init_compress( zfx, zs ); - zfx->status = 2; - } - -#ifndef __riscos__ - zs->next_in = buf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_in = size; - rc = do_compress( zfx, zs, Z_NO_FLUSH, a ); - } - else if( control == IOBUFCTRL_FREE ) { - if( zfx->status == 1 ) { - inflateEnd(zs); - xfree (zs); - zfx->opaque = NULL; - xfree (zfx->outbuf); zfx->outbuf = NULL; - } - else if( zfx->status == 2 ) { -#ifndef __riscos__ - zs->next_in = buf; -#else /* __riscos__ */ - zs->next_in = (Bytef *) buf; -#endif /* __riscos__ */ - zs->avail_in = 0; - do_compress( zfx, zs, Z_FINISH, a ); - deflateEnd(zs); - xfree (zs); - zfx->opaque = NULL; - xfree (zfx->outbuf); zfx->outbuf = NULL; - } - if (zfx->release) - zfx->release (zfx); - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "compress_filter"; - return rc; -} - - -static void -release_context (compress_filter_context_t *ctx) -{ - xfree (ctx); -} - -/**************** - * Handle a compressed packet - */ -int -handle_compressed( void *procctx, PKT_compressed *cd, - int (*callback)(iobuf_t, void *), void *passthru ) -{ - compress_filter_context_t *cfx; - int rc; - - if( cd->algorithm < 1 || cd->algorithm > 2 ) - return GPG_ERR_COMPR_ALGO; - cfx = xcalloc (1,sizeof *cfx); - cfx->algo = cd->algorithm; - cfx->release = release_context; - iobuf_push_filter( cd->buf, compress_filter, cfx ); - if( callback ) - rc = callback(cd->buf, passthru ); - else - rc = proc_packets(procctx, cd->buf); - cd->buf = NULL; - return rc; -} - diff --git a/g10/dearmor.c b/g10/dearmor.c deleted file mode 100644 index 4f9fa2db7..000000000 --- a/g10/dearmor.c +++ /dev/null @@ -1,123 +0,0 @@ -/* dearmor.c - Armor utility - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "packet.h" -#include "options.h" -#include "main.h" - - -/**************** - * Take an armor file and write it out without armor - */ -int -dearmor_file( const char *fname ) -{ - armor_filter_context_t afx; - iobuf_t inp = NULL, out = NULL; - int rc = 0; - int c; - - memset( &afx, 0, sizeof afx); - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - iobuf_push_filter( inp, armor_filter, &afx ); - - if( (rc = open_outfile( fname, 0, &out )) ) - goto leave; - - - - while( (c = iobuf_get(inp)) != -1 ) - iobuf_put( out, c ); - - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - return rc; -} - - -/**************** - * Take file and write it out with armor - */ -int -enarmor_file( const char *fname ) -{ - armor_filter_context_t afx; - iobuf_t inp = NULL, out = NULL; - int rc = 0; - int c; - - memset( &afx, 0, sizeof afx); - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - - if( (rc = open_outfile( fname, 1, &out )) ) - goto leave; - - afx.what = 4; - afx.hdrlines = "Comment: Use \"gpg --dearmor\" for unpacking\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - while( (c = iobuf_get(inp)) != -1 ) - iobuf_put( out, c ); - - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - return rc; -} - - diff --git a/g10/decrypt.c b/g10/decrypt.c deleted file mode 100644 index 98a270cfb..000000000 --- a/g10/decrypt.c +++ /dev/null @@ -1,142 +0,0 @@ -/* decrypt.c - verify signed data - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - - - -/**************** - * Assume that the input is an encrypted message and decrypt - * (and if signed, verify the signature on) it. - * This command differs from the default operation, as it never - * writes to the filename which is included in the file and it - * rejects files which don't begin with an encrypted message. - */ - -int -decrypt_message( const char *filename ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - int rc; - int no_out=0; - - /* open the message file */ - fp = iobuf_open(filename); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s'\n"), print_fname_stdin(filename)); - return rc; - } - - handle_progress (&pfx, fp, filename); - - if( !opt.no_armor ) { - if( use_armor_filter( fp ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( fp, armor_filter, &afx ); - } - } - - if( !opt.outfile ) { - no_out = 1; - opt.outfile = "-"; - } - rc = proc_encryption_packets( NULL, fp ); - if( no_out ) - opt.outfile = NULL; - iobuf_close(fp); - return rc; -} - -void -decrypt_messages(int nfiles, char **files) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - char *p, *output = NULL; - int rc = 0; - - if (opt.outfile) - { - log_error(_("--output doesn't work for this command\n")); - return; - - } - - while (nfiles--) - { - print_file_status(STATUS_FILE_START, *files, 3); - output = make_outfile_name(*files); - if (!output) - goto next_file; - fp = iobuf_open(*files); - if (!fp) - { - log_error(_("can't open `%s'\n"), print_fname_stdin(*files)); - goto next_file; - } - - handle_progress (&pfx, fp, *files); - - if (!opt.no_armor) - { - if (use_armor_filter(fp)) - { - memset(&afx, 0, sizeof afx); - iobuf_push_filter(fp, armor_filter, &afx); - } - } - rc = proc_packets(NULL, fp); - iobuf_close(fp); - if (rc) - log_error("%s: decryption failed: %s\n", print_fname_stdin(*files), - gpg_strerror (rc)); - p = get_last_passphrase(); - set_next_passphrase(p); - xfree (p); - - next_file: - /* Note that we emit file_done even after an error. */ - write_status( STATUS_FILE_DONE ); - xfree (output); - files++; - } - set_next_passphrase(NULL); -} - diff --git a/g10/delkey.c b/g10/delkey.c deleted file mode 100644 index 6263dec47..000000000 --- a/g10/delkey.c +++ /dev/null @@ -1,209 +0,0 @@ -/* delkey.c - delete keys - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "filter.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - - -/**************** - * Delete a public or secret key from a keyring. - * r_sec_avail will be set if a secret key is available and the public - * key can't be deleted for that reason. - */ -static int -do_delete_key( const char *username, int secret, int *r_sec_avail ) -{ - int rc = 0; - KBNODE keyblock = NULL; - KBNODE node; - KEYDB_HANDLE hd = keydb_new (secret); - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - u32 keyid[2]; - int okay=0; - int yes; - KEYDB_SEARCH_DESC desc; - int exactmatch; - - *r_sec_avail = 0; - - /* search the userid */ - classify_user_id (username, &desc); - exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR - || desc.mode == KEYDB_SEARCH_MODE_FPR16 - || desc.mode == KEYDB_SEARCH_MODE_FPR20); - rc = desc.mode? keydb_search (hd, &desc, 1):GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("key `%s' not found: %s\n"), username, gpg_strerror (rc)); - write_status_text( STATUS_DELETE_PROBLEM, "1" ); - goto leave; - } - - /* read the keyblock */ - rc = keydb_get_keyblock (hd, &keyblock ); - if (rc) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key not found anymore!\n"); - rc = GPG_ERR_GENERAL; - goto leave; - } - - if( secret ) { - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - } - else { - pk = node->pkt->pkt.public_key; - keyid_from_pk( pk, keyid ); - rc = seckey_available( keyid ); - if( !rc ) { - *r_sec_avail = 1; - rc = -1; - goto leave; - } - else if( rc != GPG_ERR_NO_SECKEY ) { - log_error("%s: get secret key: %s\n", username, gpg_strerror (rc) ); - } - else - rc = 0; - } - - if( rc ) - rc = 0; - else if (opt.batch && exactmatch) - okay++; - else if( opt.batch && secret ) - { - log_error(_("can't do that in batchmode\n")); - log_info (_("(unless you specify the key by fingerprint)\n")); - } - else if( opt.batch && opt.answer_yes ) - okay++; - else if( opt.batch ) - { - log_error(_("can't do that in batchmode without \"--yes\"\n")); - log_info (_("(unless you specify the key by fingerprint)\n")); - } - else { - if( secret ) - print_seckey_info( sk ); - else - print_pubkey_info (NULL, pk ); - tty_printf( "\n" ); - - yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay" - : "delete_key.okay", - _("Delete this key from the keyring? ")); - if( !cpr_enabled() && secret && yes ) { - /* I think it is not required to check a passphrase; if - * the user is so stupid as to let others access his secret keyring - * (and has no backup) - it is up him to read some very - * basic texts about security. - */ - yes = cpr_get_answer_is_yes("delete_key.secret.okay", - _("This is a secret key! - really delete? ")); - } - if( yes ) - okay++; - } - - - if( okay ) { - rc = keydb_delete_keyblock (hd); - if (rc) { - log_error (_("deleting keyblock failed: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* Note that the ownertrust being cleared will trigger a - revalidation_mark(). This makes sense - only deleting keys - that have ownertrust set should trigger this. */ - - if (!secret && pk && clear_ownertrusts (pk)) { - if (opt.verbose) - log_info (_("ownertrust information cleared\n")); - } - } - - leave: - keydb_release (hd); - release_kbnode (keyblock); - return rc; -} - -/**************** - * Delete a public or secret key from a keyring. - */ -int -delete_keys( STRLIST names, int secret, int allow_both ) -{ - int rc, avail; - - for(;names;names=names->next) { - rc = do_delete_key (names->d, secret, &avail ); - if ( rc && avail ) { - if ( allow_both ) { - rc = do_delete_key (names->d, 1, &avail ); - if ( !rc ) - rc = do_delete_key (names->d, 0, &avail ); - } - else { - log_error(_( - "there is a secret key for public key \"%s\"!\n"),names->d); - log_info(_( - "use option \"--delete-secret-keys\" to delete it first.\n")); - write_status_text( STATUS_DELETE_PROBLEM, "2" ); - return rc; - } - } - - if(rc) { - log_error("%s: delete key failed: %s\n", names->d, gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} diff --git a/g10/encode.c b/g10/encode.c deleted file mode 100644 index 7794bdb7c..000000000 --- a/g10/encode.c +++ /dev/null @@ -1,821 +0,0 @@ -/* encode.c - encode data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "filter.h" -#include "trustdb.h" -#include "i18n.h" -#include "status.h" -#include "pkglue.h" - - -static int encode_simple( const char *filename, int mode, int compat ); -static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out ); - - - -/**************** - * Encode FILENAME with only the symmetric cipher. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_symmetric( const char *filename ) -{ - int compat = 1; - -#if 0 - /* We don't want to use it because older gnupg version can't - handle it and we can presume that a lot of scripts are running - with the expert mode set. Some time in the future we might - want to allow for it. */ - if ( opt.expert ) - compat = 0; /* PGP knows how to handle this mode. */ -#endif - return encode_simple( filename, 1, compat ); -} - -/**************** - * Encode FILENAME as a literal data packet only. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_store( const char *filename ) -{ - return encode_simple( filename, 0, 1 ); -} - -static void -encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey) -{ - CIPHER_HANDLE hd; - DEK * c; - byte buf[33]; - - assert (dek->keylen < 32); - - c = xcalloc (1, sizeof *c); - c->keylen = dek->keylen; - c->algo = dek->algo; - make_session_key (c); - /*log_hexdump ("thekey", c->key, c->keylen);*/ - - /* the encrypted session key is prefixed with a one-octet algorithm id */ - buf[0] = c->algo; - memcpy (buf + 1, c->key, c->keylen); - - /* due to the fact that we use only checked values, consider each - failure as fatal. */ - if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG(); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG(); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_encrypt (hd, buf, c->keylen + 1, NULL, 0); - gcry_cipher_close (hd); - - memcpy (enckey, buf, c->keylen + 1); - wipememory (buf, sizeof buf); /* burn key */ - *ret_dek = c; -} - -/* We try very hard to use a MDC */ -static int -use_mdc (PK_LIST pk_list,int algo) -{ - byte cipher_algid[4] = { - CIPHER_ALGO_AES, - CIPHER_ALGO_AES192, - CIPHER_ALGO_AES256, - CIPHER_ALGO_TWOFISH - }; - int i; - - /* RFC-1991 and 2440 don't have MDC */ - if(RFC1991 || RFC2440) - return 0; - - /* --force-mdc overrides --disable-mdc */ - if (opt.force_mdc) - return 1; - - if (opt.disable_mdc) - return 0; - - /* Do the keys really support MDC? */ - - if (select_mdc_from_pklist (pk_list)) - return 1; - - /* The keys don't support MDC, so now we do a bit of a hack - if any - of the AESes or TWOFISH are in the prefs, we assume that the user - can handle a MDC. This is valid for PGP 7, which can handle MDCs - though it will not generate them. 2440bis allows this, by the - way. */ - for (i=0; i < DIM (cipher_algid); i++) - { - if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i], - NULL) == cipher_algid[i]) - return 1; - } - - /* Last try. Use MDC for the modern ciphers. */ - if (gcry_cipher_get_algo_blklen (algo) != 8) - return 1; - - return 0; /* No MDC */ -} - -static int -encode_simple( const char *filename, int mode, int compat ) -{ - iobuf_t inp, out; - PACKET pkt; - DEK *dek = NULL; - PKT_plaintext *pt = NULL; - STRING2KEY *s2k = NULL; - byte enckey[33]; - int rc = 0; - int seskeylen = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t afx; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - int do_compress = opt.compress && !RFC1991; - - memset( &cfx, 0, sizeof cfx); - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]", - strerror(errno) ); - return rc; - } - - handle_progress (&pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - /* Due the the fact that we use don't use an IV to encrypt the - session key we can't use the new mode with RFC1991 because - it has no S2K salt. RFC1991 always uses simple S2K. */ - if ( RFC1991 && !compat ) - compat = 1; - - cfx.dek = NULL; - if( mode ) { - s2k = xcalloc (1, sizeof *s2k ); - s2k->mode = RFC1991? 0:opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - cfx.dek = passphrase_to_dek( NULL, 0, - default_cipher_algo(), s2k, 2, - NULL, NULL); - if( !cfx.dek || !cfx.dek->keylen ) { - rc = gpg_error (GPG_ERR_INV_PASSPHRASE); - xfree (cfx.dek); - xfree (s2k); - iobuf_close(inp); - log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) ); - return rc; - } - if (!compat && s2k->mode != 1 && s2k->mode != 3) { - compat = 1; - log_info (_("can't use a symmetric ESK packet " - "due to the S2K mode\n")); - } - - if ( !compat ) { - seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo()); - encode_sesskey( cfx.dek, &dek, enckey ); - xfree (cfx.dek); cfx.dek = dek; - } - - cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); - } - - if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc && - is_file_compressed(filename, &rc)) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - - if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) { - iobuf_cancel(inp); - xfree (cfx.dek); - xfree (s2k); - return rc; - } - - if( opt.armor ) - iobuf_push_filter( out, armor_filter, &afx ); -#ifdef ENABLE_COMMENT_PACKETS - else { - write_comment( out, "#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")"); - if( opt.comment_string ) - write_comment( out, opt.comment_string ); - } -#endif - if( s2k && !RFC1991 ) { - PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 ); - enc->version = 4; - enc->cipher_algo = cfx.dek->algo; - enc->s2k = *s2k; - if ( !compat && seskeylen ) { - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy( enc->seskey, enckey, seskeylen + 1 ); - } - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - if( (rc = build_packet( out, &pkt )) ) - log_error("build symkey packet failed: %s\n", gpg_strerror (rc) ); - xfree (enc); - } - - if (!opt.no_literal) { - /* setup the inner packet */ - if( filename || opt.set_filename ) { - char *s = make_basename ( opt.set_filename ? opt.set_filename - : filename - /* for riscos? - .iobuf_get_real_fname( inp ) */ - ); - pt = xmalloc ( sizeof *pt + strlen(s) - 1 ); - pt->namelen = strlen(s); - memcpy(pt->name, s, pt->namelen ); - xfree (s); - } - else { /* no filename */ - pt = xmalloc ( sizeof *pt - 1 ); - pt->namelen = 0; - } - } - - /* Note that PGP 5 has problems decrypting symmetrically encrypted - data if the file length is in the inner packet. It works when - only partial length headers are use. In the past, we always - used partial body length here, but since PGP 2, PGP 6, and PGP - 7 need the file length, and nobody should be using PGP 5 - nowadays anyway, this is now set to the file length. Note also - that this only applies to the RFC-1991 style symmetric - messages, and not the RFC-2440 style. PGP 6 and 7 work with - either partial length or fixed length with the new style - messages. */ - - if (filename && *filename && !(*filename == '-' && !filename[1]) - && !opt.textmode ) { - off_t tmpsize; - - if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); - /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the - size of a file is larger than 2^32 minus some bytes for - packet headers, we switch to partial length encoding. */ - if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0; - } - else - { - cfx.datalen = filesize && !do_compress ? filesize : 0; - pkt.pkttype = 0; - pkt.pkt.generic = NULL; - } - - /* register the cipher filter */ - if( mode ) - iobuf_push_filter( out, cipher_filter, &cfx ); - /* register the compress filter */ - if( do_compress ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - zfx.algo=default_compress_algo(); - iobuf_push_filter( out, compress_filter, &zfx ); - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", gpg_strerror (rc) ); - } - else { - /* user requested not to create a literal packet, - * so we copy the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied))) { - log_error("copying input to output failed: %s\n", gpg_strerror (rc) ); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - iobuf_close(inp); - if (rc) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - if (mode) - write_status( STATUS_END_ENCRYPTION ); - } - if (pt) - pt->buf = NULL; - free_packet(&pkt); - xfree (cfx.dek); - xfree (s2k); - return rc; -} - -/**************** - * Encrypt the file with the given userids (or ask if none - * is supplied). - */ -int -encode_crypt( const char *filename, STRLIST remusr ) -{ - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - PKT_plaintext *pt = NULL; - int rc = 0, rc2 = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t afx; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - PK_LIST pk_list,work_list; - int do_compress = opt.compress && !RFC1991; - - - memset( &cfx, 0, sizeof cfx); - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) - return rc; - - if(PGP2) { - for(work_list=pk_list; work_list; work_list=work_list->next) - if(!(is_RSA(work_list->pk->pubkey_algo) && - nbits_from_pk(work_list->pk)<=2048)) - { - log_info(_("you can only encrypt to RSA keys of 2048 bits or " - "less in --pgp2 mode\n")); - compliance_failure(); - break; - } - } - - /* prepare iobufs */ - if( !(inp = iobuf_open(filename)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]", - strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("reading from `%s'\n"), filename? filename: "[stdin]"); - - handle_progress (&pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) - goto leave; - - - if( opt.armor ) - iobuf_push_filter( out, armor_filter, &afx ); -#ifdef ENABLE_COMMENT_PACKETS - else { - write_comment( out, "#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")"); - if( opt.comment_string ) - write_comment( out, opt.comment_string ); - } -#endif - /* create a session key */ - cfx.dek = xcalloc_secure (1, sizeof *cfx.dek); - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL); - /* The only way select_algo_from_prefs can fail here is when - mixing v3 and v4 keys, as v4 keys have an implicit - preference entry for 3DES, and the pk_list cannot be empty. - In this case, use 3DES anyway as it's the safest choice - - perhaps the v3 key is being used in an OpenPGP - implementation and we know that the implementation behind - any v4 key can handle 3DES. */ - if( cfx.dek->algo == -1 ) { - cfx.dek->algo = CIPHER_ALGO_3DES; - - if( PGP2 ) { - log_info(_("unable to use the IDEA cipher for all of the keys " - "you are encrypting to.\n")); - compliance_failure(); - } - } - } - else { - if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_SYM, - opt.def_cipher_algo,NULL)!=opt.def_cipher_algo) - log_info(_("forcing symmetric cipher %s (%d) " - "violates recipient preferences\n"), - gcry_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - cfx.dek->algo = opt.def_cipher_algo; - } - - cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo); - - /* Only do the is-file-already-compressed check if we are using a - MDC. This forces compressed files to be re-compressed if we do - not have a MDC to give some protection against chosen - ciphertext attacks. */ - - if (opt.compress == -1 && cfx.dek->use_mdc && - is_file_compressed(filename, &rc2) ) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - if (rc2) - { - rc = rc2; - goto leave; - } - - make_session_key( cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out ); - if( rc ) - goto leave; - - if (!opt.no_literal) { - /* setup the inner packet */ - if( filename || opt.set_filename ) { - char *s = make_basename( opt.set_filename ? opt.set_filename - : filename - /* ,iobuf_get_real_fname( inp )*/ ); - pt = xmalloc ( sizeof *pt + strlen(s) - 1 ); - pt->namelen = strlen(s); - memcpy(pt->name, s, pt->namelen ); - xfree (s); - } - else { /* no filename */ - pt = xmalloc ( sizeof *pt - 1 ); - pt->namelen = 0; - } - } - - if (filename && *filename && !(*filename == '-' && !filename[1]) - && !opt.textmode ) { - off_t tmpsize; - - if ( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info(_("%s: WARNING: empty file\n"), filename ); - /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the - size of a file is larger than 2^32 minus some bytes for - packet headers, we switch to partial length encoding. */ - if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode ? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0; - } - else - cfx.datalen = filesize && !do_compress ? filesize : 0; - - /* register the cipher filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); - - /* register the compress filter */ - if( do_compress ) { - int compr_algo = opt.def_compress_algo; - - if(compr_algo==-1) - { - if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) - compr_algo=DEFAULT_COMPRESS_ALGO; - /* Theoretically impossible to get here since uncompressed - is implicit. */ - } - else if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_ZIP, - compr_algo,NULL)!=compr_algo) - log_info(_("forcing compression algorithm %s (%d) " - "violates recipient preferences\n"), - compress_algo_to_string(compr_algo),compr_algo); - - /* algo 0 means no compression */ - if( compr_algo ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - zfx.algo = compr_algo; - iobuf_push_filter( out, compress_filter, &zfx ); - } - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", gpg_strerror (rc) ); - } - else { - /* user requested not to create a literal packet, so we copy - the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) { - log_error("copying input to output failed: %s\n", - gpg_strerror (rc) ); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - leave: - iobuf_close(inp); - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - write_status( STATUS_END_ENCRYPTION ); - } - if( pt ) - pt->buf = NULL; - free_packet(&pkt); - xfree (cfx.dek); - release_pk_list( pk_list ); - return rc; -} - - - - -/**************** - * Filter to do a complete public key encryption. - */ -int -encrypt_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - encrypt_filter_context_t *efx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ - BUG(); /* not used */ - } - else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ - if( !efx->header_okay ) { - efx->cfx.dek = xcalloc_secure (1, sizeof *efx->cfx.dek ); - - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - efx->cfx.dek->algo = - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL); - if( efx->cfx.dek->algo == -1 ) { - /* because 3DES is implicitly in the prefs, this can only - * happen if we do not have any public keys in the list */ - efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; - } - } - else { - if(!opt.expert && - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM, - opt.def_cipher_algo, - NULL)!=opt.def_cipher_algo) - log_info(_("forcing symmetric cipher %s (%d) " - "violates recipient preferences\n"), - gcry_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - efx->cfx.dek->algo = opt.def_cipher_algo; - } - - efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo); - - make_session_key( efx->cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", - efx->cfx.dek->key, efx->cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a ); - if( rc ) - return rc; - - iobuf_push_filter( a, cipher_filter, &efx->cfx ); - - efx->header_okay = 1; - } - rc = iobuf_write( a, buf, size ); - - } - else if( control == IOBUFCTRL_FREE ) { - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "encrypt_filter"; - } - return rc; -} - - -/**************** - * Write pubkey-enc packets from the list of PKs to OUT. - */ -static int -write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out ) -{ - PACKET pkt; - PKT_public_key *pk; - PKT_pubkey_enc *enc; - int rc; - - for( ; pk_list; pk_list = pk_list->next ) { - gcry_mpi_t frame; - - pk = pk_list->pk; - - print_pubkey_algo_note( pk->pubkey_algo ); - enc = xcalloc (1, sizeof *enc ); - enc->pubkey_algo = pk->pubkey_algo; - keyid_from_pk( pk, enc->keyid ); - enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1)); - - if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--throw-keyid",compliance_option_string()); - compliance_failure(); - } - - /* Okay, what's going on: We have the session key somewhere in - * the structure DEK and want to encode this session key in - * an integer value of n bits. pubkey_nbits gives us the - * number of bits we have to use. We then encode the session - * key in some way and we get it back in the big intger value - * FRAME. Then we use FRAME, the public key PK->PKEY and the - * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt - * which returns the encrypted value in the array ENC->DATA. - * This array has a size which depends on the used algorithm - * (e.g. 2 for ElGamal). We don't need frame anymore because we - * have everything now in enc->data which is the passed to - * build_packet() - */ - frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo, - pk->pkey ) ); - rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey ); - gcry_mpi_release ( frame ); - if( rc ) - log_error("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); - else { - if( opt.verbose ) { - char *ustr = get_user_id_string_printable (enc->keyid); - log_info(_("%s/%s encrypted for: \"%s\"\n"), - gcry_pk_algo_name (enc->pubkey_algo), - gcry_cipher_algo_name (dek->algo), ustr ); - xfree (ustr); - } - /* and write it */ - init_packet(&pkt); - pkt.pkttype = PKT_PUBKEY_ENC; - pkt.pkt.pubkey_enc = enc; - rc = build_packet( out, &pkt ); - if( rc ) - log_error("build_packet(pubkey_enc) failed: %s\n", gpg_strerror (rc)); - } - free_pubkey_enc(enc); - if( rc ) - return rc; - } - return 0; -} - -void -encode_crypt_files(int nfiles, char **files, STRLIST remusr) -{ - int rc = 0; - - if (opt.outfile) - { - log_error(_("--output doesn't work for this command\n")); - return; - } - - if (!nfiles) - { - char line[2048]; - unsigned int lno = 0; - while ( fgets(line, DIM(line), stdin) ) - { - lno++; - if (!*line || line[strlen(line)-1] != '\n') - { - log_error("input line %u too long or missing LF\n", lno); - return; - } - line[strlen(line)-1] = '\0'; - print_file_status(STATUS_FILE_START, line, 2); - if ( (rc = encode_crypt(line, remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(line), gpg_strerror (rc) ); - write_status( STATUS_FILE_DONE ); - } - } - else - { - while (nfiles--) - { - print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encode_crypt(*files, remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(*files), gpg_strerror (rc) ); - write_status( STATUS_FILE_DONE ); - files++; - } - } -} diff --git a/g10/encr-data.c b/g10/encr-data.c deleted file mode 100644 index 074408404..000000000 --- a/g10/encr-data.c +++ /dev/null @@ -1,269 +0,0 @@ -/* encr-data.c - process an encrypted data packet - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "cipher.h" -#include "options.h" -#include "i18n.h" - - -static int mdc_decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len); -static int decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len); - -typedef struct { - CIPHER_HANDLE cipher_hd; - MD_HANDLE mdc_hash; - char defer[20]; - int defer_filled; - int eof_seen; -} decode_filter_ctx_t; - - -/**************** - * Decrypt the data, specified by ED with the key DEK. - */ -int -decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) -{ - decode_filter_ctx_t dfx; - byte *p; - int rc=0, c, i; - byte temp[32]; - unsigned blocksize; - unsigned nprefix; - - memset( &dfx, 0, sizeof dfx ); - if( opt.verbose && !dek->algo_info_printed ) { - const char *s = gcry_cipher_algo_name (dek->algo); - if (s && *s) - log_info(_("%s encrypted data\n"), s ); - else - log_info(_("encrypted with unknown algorithm %d\n"), dek->algo ); - dek->algo_info_printed = 1; - } - if( (rc=openpgp_cipher_test_algo(dek->algo)) ) - goto leave; - blocksize = gcry_cipher_get_algo_blklen (dek->algo); - if( !blocksize || blocksize > 16 ) - log_fatal("unsupported blocksize %u\n", blocksize ); - nprefix = blocksize; - if( ed->len && ed->len < (nprefix+2) ) - BUG(); - - if( ed->mdc_method ) { - gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ); - if ( DBG_HASHING ) - gcry_md_start_debug (dfx.mdc_hash, "checkmdc"); - } - rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | ((ed->mdc_method || dek->algo >= 100)? - 0 : GCRY_CIPHER_ENABLE_SYNC) ); - if (rc) - { - /* we should never get an error here cause we already - * checked, that the algorithm is available. What about a - * flag to let the function die in this case? */ - BUG(); - } - /* log_hexdump( "thekey", dek->key, dek->keylen );*/ - rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen); - if( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) - log_info(_("WARNING: message was encrypted with " - "a weak key in the symmetric cipher.\n")); - else if( rc ) { - log_error("key setup failed: %s\n", gpg_strerror (rc) ); - goto leave; - } - if (!ed->buf) { - log_error(_("problem handling encrypted packet\n")); - goto leave; - } - - gcry_cipher_setiv (dfx.cipher_hd, NULL, 0); - - if (ed->len) { - for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) { - if( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; - } - } - else { - for(i=0; i < (nprefix+2); i++ ) - if( (c=iobuf_get(ed->buf)) == -1 ) - break; - else - temp[i] = c; - } - gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0); - gcry_cipher_sync( dfx.cipher_hd ); - p = temp; -/* log_hexdump( "prefix", temp, nprefix+2 ); */ - if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) { - rc = GPG_ERR_BAD_KEY; - goto leave; - } - - if( dfx.mdc_hash ) - gcry_md_write( dfx.mdc_hash, temp, nprefix+2 ); - - if( ed->mdc_method ) - iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx ); - else - iobuf_push_filter( ed->buf, decode_filter, &dfx ); - - proc_packets( procctx, ed->buf ); - ed->buf = NULL; - if( ed->mdc_method && dfx.eof_seen == 2 ) - rc = gpg_error (GPG_ERR_INV_PACKET); - else if( ed->mdc_method ) { /* check the mdc */ - int datalen = gcry_md_get_algo_dlen (ed->mdc_method); - - gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0); - gcry_md_final ( dfx.mdc_hash ); - if( datalen != 20 - || memcmp(gcry_md_read ( dfx.mdc_hash, 0 ), dfx.defer, datalen) ) - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - /*log_hexdump("MDC calculated:", gcry_md_read ( dfx.mdc_hash, 0), datalen);*/ - /*log_hexdump("MDC message :", dfx.defer, 20);*/ - } - - - leave: - gcry_cipher_close(dfx.cipher_hd); - gcry_md_close ( dfx.mdc_hash ); - return rc; -} - - - -/* I think we should merge this with cipher_filter */ -static int -mdc_decode_filter( void *opaque, int control, iobuf_t a, - byte *buf, size_t *ret_len) -{ - decode_filter_ctx_t *dfx = opaque; - size_t n, size = *ret_len; - int rc = 0; - int c; - - if( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) { - *ret_len = 0; - rc = -1; - } - else if( control == IOBUFCTRL_UNDERFLOW ) { - assert(a); - assert( size > 40 ); - - /* get at least 20 bytes and put it somewhere ahead in the buffer */ - for(n=20; n < 40 ; n++ ) { - if( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - if( n == 40 ) { - /* we have enough stuff - flush the deferred stuff */ - /* (we have asserted that the buffer is large enough) */ - if( !dfx->defer_filled ) { /* the first time */ - memcpy(buf, buf+20, 20 ); - n = 20; - } - else { - memcpy(buf, dfx->defer, 20 ); - } - /* now fill up */ - for(; n < size; n++ ) { - if( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - /* move the last 20 bytes back to the defer buffer */ - /* (okay, we are wasting 20 bytes of supplied buffer) */ - n -= 20; - memcpy( dfx->defer, buf+n, 20 ); - dfx->defer_filled = 1; - } - else if( !dfx->defer_filled ) { /* eof seen buf empty defer */ - /* this is bad because there is an incomplete hash */ - n -= 20; - memcpy(buf, buf+20, n ); - dfx->eof_seen = 2; /* eof with incomplete hash */ - } - else { /* eof seen */ - memcpy(buf, dfx->defer, 20 ); - n -= 20; - memcpy( dfx->defer, buf+n, 20 ); - dfx->eof_seen = 1; /* normal eof */ - } - - if( n ) { - gcry_cipher_decrypt( dfx->cipher_hd, buf, n, NULL, 0); - gcry_md_write( dfx->mdc_hash, buf, n ); - } - else { - assert( dfx->eof_seen ); - rc = -1; /* eof */ - } - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "mdc_decode_filter"; - } - return rc; -} - -static int -decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len) -{ - decode_filter_ctx_t *fc = opaque; - size_t n, size = *ret_len; - int rc = 0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - assert(a); - n = iobuf_read( a, buf, size ); - if( n == -1 ) n = 0; - if( n ) - gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0); - else - rc = -1; /* eof */ - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "decode_filter"; - } - return rc; -} - diff --git a/g10/exec.c b/g10/exec.c deleted file mode 100644 index a49fe15d2..000000000 --- a/g10/exec.c +++ /dev/null @@ -1,619 +0,0 @@ -/* exec.c - generic call-a-program code - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <sys/stat.h> -#include <sys/types.h> -#ifndef EXEC_TEMPFILE_ONLY -#include <sys/wait.h> -#endif -#ifdef HAVE_DOSISH_SYSTEM -#include <windows.h> -#endif -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include "options.h" -#include "memory.h" -#include "i18n.h" -#include "iobuf.h" -#include "util.h" -#include "exec.h" - -#ifdef NO_EXEC -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary) -{ - log_error(_("no remote program execution supported\n")); - return GPG_ERR_GENERAL; -} - -int exec_read(struct exec_info *info) { return GPG_ERR_GENERAL; } -int exec_finish(struct exec_info *info) { return GPG_ERR_GENERAL; } -int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; } - -#else /* ! NO_EXEC */ - -#ifndef HAVE_MKDTEMP -char *mkdtemp(char *template); -#endif - -#if defined (_WIN32) -/* This is a nicer system() for windows that waits for programs to - return before returning control to the caller. I hate helpful - computers. */ -static int win_system(const char *command) -{ - PROCESS_INFORMATION pi; - STARTUPINFO si; - char *string; - - /* We must use a copy of the command as CreateProcess modifies this - argument. */ - string=xstrdup (command); - - memset(&pi,0,sizeof(pi)); - memset(&si,0,sizeof(si)); - si.cb=sizeof(si); - - if(!CreateProcess(NULL,string,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) - return -1; - - /* Wait for the child to exit */ - WaitForSingleObject(pi.hProcess,INFINITE); - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - xfree (string); - - return 0; -} -#endif - -/* method==0 to replace current $PATH, and 1 to append to current - $PATH. */ -int set_exec_path(const char *path,int method) -{ - char *p,*curpath=NULL; - size_t curlen=0; - - if(method==1 && (curpath=getenv("PATH"))) - curlen=strlen(curpath)+1; - - p=xmalloc (5+curlen+strlen(path)+1); - strcpy(p,"PATH="); - - if(curpath) - { - strcat(p,curpath); - strcat(p,":"); - } - - strcat(p,path); - - if(DBG_EXTPROG) - log_debug("set_exec_path method %d: %s\n",method,p); - - /* Notice that path is never freed. That is intentional due to the - way putenv() works. This leaks a few bytes if we call - set_exec_path multiple times. */ - - if(putenv(p)!=0) - return GPG_ERR_GENERAL; - else - return 0; -} - -/* Makes a temp directory and filenames */ -static int make_tempdir(struct exec_info *info) -{ - char *tmp=opt.temp_dir,*namein=info->name,*nameout; - - if(!namein) - namein=info->binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt"; - - nameout=info->binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt"; - - /* Make up the temp dir and files in case we need them */ - - if(tmp==NULL) - { -#if defined (_WIN32) - tmp=xmalloc (256); - if(GetTempPath(256,tmp)==0) - strcpy(tmp,"c:\\windows\\temp"); - else - { - int len=strlen(tmp); - - /* GetTempPath may return with \ on the end */ - while(len>0 && tmp[len-1]=='\\') - { - tmp[len-1]='\0'; - len--; - } - } -#else /* More unixish systems */ - tmp=getenv("TMPDIR"); - if(tmp==NULL) - { - tmp=getenv("TMP"); - if(tmp==NULL) - { -#ifdef __riscos__ - tmp="<Wimp$ScrapDir>.GnuPG"; - mkdir(tmp,0700); /* Error checks occur later on */ -#else - tmp="/tmp"; -#endif - } - } -#endif - } - - info->tempdir=xmalloc (strlen(tmp)+strlen(DIRSEP_S)+10+1); - - sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp); - -#if defined (_WIN32) - xfree (tmp); -#endif - - if(mkdtemp(info->tempdir)==NULL) - log_error(_("can't create directory `%s': %s\n"), - info->tempdir,strerror(errno)); - else - { - info->madedir=1; - - info->tempfile_in=xmalloc (strlen(info->tempdir)+ - strlen(DIRSEP_S)+strlen(namein)+1); - sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein); - - if(!info->writeonly) - { - info->tempfile_out=xmalloc (strlen(info->tempdir)+ - strlen(DIRSEP_S)+strlen(nameout)+1); - sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout); - } - } - - return info->madedir?0:GPG_ERR_GENERAL; -} - -/* Expands %i and %o in the args to the full temp files within the - temp directory. */ -static int expand_args(struct exec_info *info,const char *args_in) -{ - const char *ch=args_in; - unsigned int size,len; - - info->use_temp_files=0; - info->keep_temp_files=0; - - if(DBG_EXTPROG) - log_debug("expanding string \"%s\"\n",args_in); - - size=100; - info->command=xmalloc (size); - len=0; - info->command[0]='\0'; - - while(*ch!='\0') - { - if(*ch=='%') - { - char *append=NULL; - - ch++; - - switch(*ch) - { - case 'O': - info->keep_temp_files=1; - /* fall through */ - - case 'o': /* out */ - if(!info->madedir) - { - if(make_tempdir(info)) - goto fail; - } - append=info->tempfile_out; - info->use_temp_files=1; - break; - - case 'I': - info->keep_temp_files=1; - /* fall through */ - - case 'i': /* in */ - if(!info->madedir) - { - if(make_tempdir(info)) - goto fail; - } - append=info->tempfile_in; - info->use_temp_files=1; - break; - - case '%': - append="%"; - break; - } - - if(append) - { - size_t applen=strlen(append); - - if(applen+len>size-1) - { - if(applen<100) - applen=100; - - size+=applen; - info->command=xrealloc(info->command,size); - } - - strcat(info->command,append); - len+=strlen(append); - } - } - else - { - if(len==size-1) /* leave room for the \0 */ - { - size+=100; - info->command=xrealloc(info->command,size); - } - - info->command[len++]=*ch; - info->command[len]='\0'; - } - - ch++; - } - - if(DBG_EXTPROG) - log_debug("args expanded to \"%s\", use %d, keep %d\n", - info->command,info->use_temp_files,info->keep_temp_files); - - return 0; - - fail: - - xfree (info->command); - info->command=NULL; - - return GPG_ERR_GENERAL; -} - -/* Either handles the tempfile creation, or the fork/exec. If it - returns ok, then info->tochild is a FILE * that can be written to. - The rules are: if there are no args, then it's a fork/exec/pipe. - If there are args, but no tempfiles, then it's a fork/exec/pipe via - shell -c. If there are tempfiles, then it's a system. */ - -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary) -{ - int ret=GPG_ERR_GENERAL; - - if(opt.exec_disable && !opt.no_perm_warn) - { - log_info(_("external program calls are disabled due to unsafe " - "options file permissions\n")); - - return ret; - } - -#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) - /* There should be no way to get to this spot while still carrying - setuid privs. Just in case, bomb out if we are. */ - if(getuid()!=geteuid()) - BUG(); -#endif - - if(program==NULL && args_in==NULL) - BUG(); - - *info=xcalloc (1,sizeof(struct exec_info)); - - if(name) - (*info)->name=xstrdup (name); - (*info)->binary=binary; - (*info)->writeonly=writeonly; - - /* Expand the args, if any */ - if(args_in && expand_args(*info,args_in)) - goto fail; - -#ifdef EXEC_TEMPFILE_ONLY - if(!(*info)->use_temp_files) - { - log_error(_("this platform requires temp files when calling external " - "programs\n")); - goto fail; - } - -#else /* !EXEC_TEMPFILE_ONLY */ - - /* If there are no args, or there are args, but no temp files, we - can use fork/exec/pipe */ - if(args_in==NULL || (*info)->use_temp_files==0) - { - int to[2],from[2]; - - if(pipe(to)==-1) - goto fail; - - if(pipe(from)==-1) - { - close(to[0]); - close(to[1]); - goto fail; - } - - if(((*info)->child=fork())==-1) - { - close(to[0]); - close(to[1]); - close(from[0]); - close(from[1]); - goto fail; - } - - if((*info)->child==0) - { - char *shell=getenv("SHELL"); - - if(shell==NULL) - shell="/bin/sh"; - - /* I'm the child */ - - /* If the program isn't going to respond back, they get to - keep their stdout/stderr */ - if(!(*info)->writeonly) - { - /* implied close of STDERR */ - if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1) - _exit(1); - - /* implied close of STDOUT */ - close(from[0]); - if(dup2(from[1],STDOUT_FILENO)==-1) - _exit(1); - } - - /* implied close of STDIN */ - close(to[1]); - if(dup2(to[0],STDIN_FILENO)==-1) - _exit(1); - - if(args_in==NULL) - { - if(DBG_EXTPROG) - log_debug("execlp: %s\n",program); - - execlp(program,program,(void *)NULL); - } - else - { - if(DBG_EXTPROG) - log_debug("execlp: %s -c %s\n",shell,(*info)->command); - - execlp(shell,shell,"-c",(*info)->command,(void *)NULL); - } - - /* If we get this far the exec failed. Clean up and return. */ - - log_error(_("unable to execute %s \"%s\": %s\n"), - args_in==NULL?"program":"shell", - args_in==NULL?program:shell, - strerror(errno)); - - /* This mimics the POSIX sh behavior - 127 means "not found" - from the shell. */ - if(errno==ENOENT) - _exit(127); - - _exit(1); - } - - /* I'm the parent */ - - close(to[0]); - - (*info)->tochild=fdopen(to[1],binary?"wb":"w"); - if((*info)->tochild==NULL) - { - ret = gpg_error_from_errno (errno); - close(to[1]); - goto fail; - } - - close(from[1]); - - (*info)->fromchild=iobuf_fdopen(from[0],"r"); - if((*info)->fromchild==NULL) - { - ret = gpg_error_from_errno (errno); - close(from[0]); - goto fail; - } - - /* fd iobufs are cached?! */ - iobuf_ioctl((*info)->fromchild,3,1,NULL); - - return 0; - } -#endif /* !EXEC_TEMPFILE_ONLY */ - - if(DBG_EXTPROG) - log_debug("using temp file `%s'\n",(*info)->tempfile_in); - - /* It's not fork/exec/pipe, so create a temp file */ - (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w"); - if((*info)->tochild==NULL) - { - ret = gpg_error_from_errno (errno); - log_error(_("can't create `%s': %s\n"), - (*info)->tempfile_in,strerror(errno)); - goto fail; - } - - ret=0; - - fail: - return ret; -} - -int exec_read(struct exec_info *info) -{ - int ret=GPG_ERR_GENERAL; - - fclose(info->tochild); - info->tochild=NULL; - - if(info->use_temp_files) - { - if(DBG_EXTPROG) - log_debug("system() command is %s\n",info->command); - -#if defined (_WIN32) - info->progreturn=win_system(info->command); -#else - info->progreturn=system(info->command); -#endif - - if(info->progreturn==-1) - { - log_error(_("system error while calling external program: %s\n"), - strerror(errno)); - info->progreturn=127; - goto fail; - } - -#if defined(WIFEXITED) && defined(WEXITSTATUS) - if(WIFEXITED(info->progreturn)) - info->progreturn=WEXITSTATUS(info->progreturn); - else - { - log_error(_("unnatural exit of external program\n")); - info->progreturn=127; - goto fail; - } -#else - /* If we don't have the macros, do the best we can. */ - info->progreturn = (info->progreturn & 0xff00) >> 8; -#endif - - /* 127 is the magic value returned from system() to indicate - that the shell could not be executed, or from /bin/sh to - indicate that the program could not be executed. */ - - if(info->progreturn==127) - { - log_error(_("unable to execute external program\n")); - goto fail; - } - - if(!info->writeonly) - { - info->fromchild=iobuf_open(info->tempfile_out); - if(info->fromchild==NULL) - { - ret = gpg_error_from_errno (errno); - log_error(_("unable to read external program response: %s\n"), - strerror(errno)); - goto fail; - } - - /* Do not cache this iobuf on close */ - iobuf_ioctl(info->fromchild,3,1,NULL); - } - } - - ret=0; - - fail: - return ret; -} - -int exec_finish(struct exec_info *info) -{ - int ret=info->progreturn; - - if(info->fromchild) - iobuf_close(info->fromchild); - - if(info->tochild) - fclose(info->tochild); - -#ifndef EXEC_TEMPFILE_ONLY - if(info->child>0) - { - if(waitpid(info->child,&info->progreturn,0)!=0 && - WIFEXITED(info->progreturn)) - ret=WEXITSTATUS(info->progreturn); - else - { - log_error(_("unnatural exit of external program\n")); - ret=127; - } - } -#endif - - if(info->madedir && !info->keep_temp_files) - { - if(info->tempfile_in) - { - if(unlink(info->tempfile_in)==-1) - log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"), - "in",info->tempfile_in,strerror(errno)); - } - - if(info->tempfile_out) - { - if(unlink(info->tempfile_out)==-1) - log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"), - "out",info->tempfile_out,strerror(errno)); - } - - if(rmdir(info->tempdir)==-1) - log_info(_("WARNING: unable to remove temp directory `%s': %s\n"), - info->tempdir,strerror(errno)); - } - - xfree (info->command); - xfree (info->name); - xfree (info->tempdir); - xfree (info->tempfile_in); - xfree (info->tempfile_out); - xfree (info); - - return ret; -} -#endif /* ! NO_EXEC */ diff --git a/g10/exec.h b/g10/exec.h deleted file mode 100644 index eda406894..000000000 --- a/g10/exec.h +++ /dev/null @@ -1,43 +0,0 @@ -/* exec.h - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _EXEC_H_ -#define _EXEC_H_ - -#include <unistd.h> -#include <stdio.h> -#include "../common/iobuf.h" - -struct exec_info -{ - int progreturn,binary,writeonly,madedir,use_temp_files,keep_temp_files; - pid_t child; - FILE *tochild; - iobuf_t fromchild; - char *command,*name,*tempdir,*tempfile_in,*tempfile_out; -}; - -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary); -int exec_read(struct exec_info *info); -int exec_finish(struct exec_info *info); -int set_exec_path(const char *path,int method); - -#endif /* !_EXEC_H_ */ diff --git a/g10/export.c b/g10/export.c deleted file mode 100644 index 43d1b21ed..000000000 --- a/g10/export.c +++ /dev/null @@ -1,546 +0,0 @@ -/* export.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "i18n.h" - -static int do_export( STRLIST users, int secret, unsigned int options ); -static int do_export_stream( iobuf_t out, STRLIST users, int secret, - KBNODE *keyblock_out, unsigned int options, - int *any ); -static int build_sexp (iobuf_t out, PACKET *pkt, int *indent); - -int -parse_export_options(char *str,unsigned int *options) -{ - struct parse_options export_opts[]= - { - {"include-non-rfc",EXPORT_INCLUDE_NON_RFC}, - {"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS}, - {"include-attributes",EXPORT_INCLUDE_ATTRIBUTES}, - {"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS}, - {"sexp-format",EXPORT_SEXP_FORMAT}, - {NULL,0} - /* add tags for include revoked and disabled? */ - }; - - return parse_options(str,options,export_opts); -} - -/**************** - * Export the public keys (to standard out or --output). - * Depending on opt.armor the output is armored. - * options are defined in main.h. - * If USERS is NULL, the complete ring will be exported. */ -int -export_pubkeys( STRLIST users, unsigned int options ) -{ - return do_export( users, 0, options ); -} - -/**************** - * Export to an already opened stream; return -1 if no keys have - * been exported - */ -int -export_pubkeys_stream( iobuf_t out, STRLIST users, - KBNODE *keyblock_out, unsigned int options ) -{ - int any, rc; - - rc = do_export_stream( out, users, 0, keyblock_out, options, &any ); - if( !rc && !any ) - rc = -1; - return rc; -} - -int -export_seckeys( STRLIST users ) -{ - /* Use only relevant options for the secret key. */ - unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export (users, 1, options); -} - -int -export_secsubkeys( STRLIST users ) -{ - /* Use only relevant options for the secret key. */ - unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export( users, 2, options); -} - -static int -do_export (STRLIST users, int secret, unsigned int options) -{ - iobuf_t out = NULL; - int any, rc; - armor_filter_context_t afx; - compress_filter_context_t zfx; - - memset (&afx, 0, sizeof afx); - memset (&zfx, 0, sizeof zfx); - - rc = open_outfile (NULL, 0, &out); - if (rc) - return rc; - - if (!(options & EXPORT_SEXP_FORMAT)) - { - if (opt.armor) - { - afx.what = secret?5:1; - iobuf_push_filter( out, armor_filter, &afx ); - } - if (opt.compress_keys && opt.compress) - iobuf_push_filter( out, compress_filter, &zfx ); - } - rc = do_export_stream (out, users, secret, NULL, options, &any ); - - if (rc || !any) - iobuf_cancel (out); - else - iobuf_close (out); - return rc; -} - - -/* If keyblock_out is non-NULL, AND the exit code is zero, then it - contains a pointer to the first keyblock found and exported. No - other keyblocks are exported. The caller must free it. */ -static int -do_export_stream( iobuf_t out, STRLIST users, int secret, - KBNODE *keyblock_out, unsigned int options, int *any ) -{ - int rc = 0; - PACKET pkt; - KBNODE keyblock = NULL; - KBNODE kbctx, node; - size_t ndesc, descindex; - KEYDB_SEARCH_DESC *desc = NULL; - KEYDB_HANDLE kdbhd; - STRLIST sl; - int indent = 0; - - *any = 0; - init_packet( &pkt ); - kdbhd = keydb_new (secret); - - if (!users) { - ndesc = 1; - desc = xcalloc (1, ndesc * sizeof *desc); - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - } - else { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) - ; - desc = xmalloc ( ndesc * sizeof *desc); - - for (ndesc=0, sl=users; sl; sl = sl->next) { - if (classify_user_id (sl->d, desc+ndesc)) - ndesc++; - else - log_error (_("key `%s' not found: %s\n"), - sl->d, gpg_strerror (GPG_ERR_INV_USER_ID)); - } - - /* it would be nice to see which of the given users did - actually match one in the keyring. To implement this we - need to have a found flag for each entry in desc and to set - this we must check all those entries after a match to mark - all matched one - currently we stop at the first match. To - do this we need an extra flag to enable this feature so */ - } - - while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) { - int sha1_warned=0,skip_until_subkey=0; - u32 sk_keyid[2]; - - if (!users) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - /* read the keyblock */ - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* do not export keys which are incompatible with rfc2440 */ - if( !(options&EXPORT_INCLUDE_NON_RFC) && - (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - if( pk->version == 3 && pk->pubkey_algo > 3 ) { - log_info(_("key %08lX: not a rfc2440 key - skipped\n"), - (ulong)keyid_from_pk( pk, NULL) ); - continue; - } - } - - node=find_kbnode( keyblock, PKT_SECRET_KEY ); - if(node) - { - PKT_secret_key *sk=node->pkt->pkt.secret_key; - - keyid_from_sk(sk,sk_keyid); - - /* we can't apply GNU mode 1001 on an unprotected key */ - if( secret == 2 && !sk->is_protected ) - { - log_info(_("key %08lX: not protected - skipped\n"), - (ulong)sk_keyid[1]); - continue; - } - - /* no v3 keys with GNU mode 1001 */ - if( secret == 2 && sk->version == 3 ) - { - log_info(_("key %08lX: PGP 2.x style key - skipped\n"), - (ulong)sk_keyid[1]); - continue; - } - } - - /* and write it */ - for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { - if( skip_until_subkey ) - { - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY - || node->pkt->pkttype==PKT_SECRET_SUBKEY) - skip_until_subkey=0; - else - continue; - } - - /* don't export any comment packets but those in the - * secret keyring */ - if( !secret && node->pkt->pkttype == PKT_COMMENT ) - continue; - - /* make sure that ring_trust packets never get exported */ - if (node->pkt->pkttype == PKT_RING_TRUST) - continue; - - /* If exact is set, then we only export what was requested - (plus the primary key, if the user didn't specifically - request it) */ - if(desc[descindex].exact - && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY - || node->pkt->pkttype==PKT_SECRET_SUBKEY)) - { - u32 kid[2]; - byte fpr[MAX_FINGERPRINT_LEN]; - size_t fprlen; - - switch(desc[descindex].mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - case KEYDB_SEARCH_MODE_LONG_KID: - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - keyid_from_pk(node->pkt->pkt.public_key,kid); - else - keyid_from_sk(node->pkt->pkt.secret_key,kid); - break; - - case KEYDB_SEARCH_MODE_FPR16: - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - fingerprint_from_pk(node->pkt->pkt.public_key, - fpr,&fprlen); - else - fingerprint_from_sk(node->pkt->pkt.secret_key, - fpr,&fprlen); - break; - - default: - break; - } - - switch(desc[descindex].mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - if (desc[descindex].u.kid[1] != kid[1]) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if (desc[descindex].u.kid[0] != kid[0] - || desc[descindex].u.kid[1] != kid[1]) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_FPR16: - if (memcmp (desc[descindex].u.fpr, fpr, 16)) - skip_until_subkey=1; - break; - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if (memcmp (desc[descindex].u.fpr, fpr, 20)) - skip_until_subkey=1; - break; - default: - break; - } - - if(skip_until_subkey) - continue; - } - - if( node->pkt->pkttype == PKT_SIGNATURE ) { - /* do not export packets which are marked as not exportable */ - if( !(options&EXPORT_INCLUDE_LOCAL_SIGS) && - !node->pkt->pkt.signature->flags.exportable ) - continue; /* not exportable */ - - /* Do not export packets with a "sensitive" revocation - key unless the user wants us to. Note that we do - export these when issuing the actual revocation (see - revoke.c). */ - if( !(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) && - node->pkt->pkt.signature->revkey ) { - int i; - - for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++) - if(node->pkt->pkt.signature->revkey[i]->class & 0x40) - break; - - if(i<node->pkt->pkt.signature->numrevkeys) - continue; - } - } - - /* Don't export attribs? */ - if( !(options&EXPORT_INCLUDE_ATTRIBUTES) && - node->pkt->pkttype == PKT_USER_ID && - node->pkt->pkt.user_id->attrib_data ) { - /* Skip until we get to something that is not an attrib - or a signature on an attrib */ - while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) { - kbctx=kbctx->next; - } - - continue; - } - - if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) { - /* we don't want to export the secret parts of the - * primary key, this is done by using GNU protection mode 1001 - */ - int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode; - node->pkt->pkt.secret_key->protect.s2k.mode = 1001; - if ((options&EXPORT_SEXP_FORMAT)) - rc = build_sexp (out, node->pkt, &indent); - else - rc = build_packet (out, node->pkt); - node->pkt->pkt.secret_key->protect.s2k.mode = save_mode; - } - else { - /* Warn the user if the secret key or any of the secret - subkeys are protected with SHA1 and we have - simple_sk_checksum set. */ - if(!sha1_warned && opt.simple_sk_checksum && - (node->pkt->pkttype==PKT_SECRET_KEY || - node->pkt->pkttype==PKT_SECRET_SUBKEY) && - node->pkt->pkt.secret_key->protect.sha1chk) - { - /* I hope this warning doesn't confuse people. */ - log_info(_("WARNING: secret key %08lX does not have a " - "simple SK checksum\n"),(ulong)sk_keyid[1]); - - sha1_warned=1; - } - - if ((options&EXPORT_SEXP_FORMAT)) - rc = build_sexp (out, node->pkt, &indent); - else - rc = build_packet (out, node->pkt); - } - - if( rc ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - goto leave; - } - } - if ((options&EXPORT_SEXP_FORMAT) && indent) - { - for (; indent; indent--) - iobuf_put (out, ')'); - iobuf_put (out, '\n'); - } - - ++*any; - if(keyblock_out) - { - *keyblock_out=keyblock; - break; - } - } - if ((options&EXPORT_SEXP_FORMAT) && indent) - { - for (; indent; indent--) - iobuf_put (out, ')'); - iobuf_put (out, '\n'); - } - if( rc == -1 ) - rc = 0; - - leave: - xfree (desc); - keydb_release (kdbhd); - if(rc || keyblock_out==NULL) - release_kbnode( keyblock ); - if( !*any ) - log_info(_("WARNING: nothing exported\n")); - return rc; -} - - -static int -write_sexp_line (iobuf_t out, int *indent, const char *text) -{ - int i; - - for (i=0; i < *indent; i++) - iobuf_put (out, ' '); - iobuf_writestr (out, text); - return 0; -} - -static int -write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) -{ - int rc; - unsigned char *buffer; - - write_sexp_line (out, indent, "("); - iobuf_writestr (out, name); - iobuf_writestr (out, " #"); - - rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); - assert (!rc); - iobuf_writestr (out, buffer); - iobuf_writestr (out, "#)"); - gcry_free (buffer); - return 0; -} - -static int -build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) -{ - PKT_secret_key *sk = pkt->pkt.secret_key; - char tmpbuf[100]; - - if (pkt->pkttype == PKT_SECRET_KEY) - { - iobuf_writestr (out, "(openpgp-key\n"); - (*indent)++; - } - else - { - iobuf_writestr (out, " (subkey\n"); - (*indent)++; - } - (*indent)++; - write_sexp_line (out, indent, "(private-key\n"); - (*indent)++; - if (is_RSA (sk->pubkey_algo) && !sk->is_protected) - { - write_sexp_line (out, indent, "(rsa\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "u", sk->skey[5]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) - { - write_sexp_line (out, indent, "(dsa\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "x", sk->skey[4]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) - { - write_sexp_line (out, indent, "(elg\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "x", sk->skey[4]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } - write_sexp_line (out, indent, "(attrib\n"); (*indent)++; - sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); - write_sexp_line (out, indent, tmpbuf); - iobuf_put (out,')'); (*indent)--; /* close created */ - iobuf_put (out,')'); (*indent)--; /* close attrib */ - iobuf_put (out,')'); (*indent)--; /* close private-key */ - if (pkt->pkttype != PKT_SECRET_KEY) - iobuf_put (out,')'), (*indent)--; /* close subkey */ - iobuf_put (out,'\n'); - - return 0; -} - - -/* For some packet types we write them in a S-Exp like format. This is - still EXPERIMENTAL and subject to change. */ -static int -build_sexp (iobuf_t out, PACKET *pkt, int *indent) -{ - int rc; - - switch (pkt->pkttype) - { - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - rc = build_sexp_seckey (out, pkt, indent); - break; - default: - rc = 0; - break; - } - return rc; -} - diff --git a/g10/filter.h b/g10/filter.h deleted file mode 100644 index 12c5cebed..000000000 --- a/g10/filter.h +++ /dev/null @@ -1,155 +0,0 @@ -/* filter.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_FILTER_H -#define G10_FILTER_H - -#include "types.h" -#include "cipher.h" -#include "iobuf.h" - -typedef struct { - MD_HANDLE md; /* catch all */ - MD_HANDLE md2; /* if we want to calculate an alternate hash */ - size_t maxbuf_size; -} md_filter_context_t; - -typedef struct { - /* these fields may be initialized */ - int what; /* what kind of armor headers to write */ - int only_keyblocks; /* skip all headers but ".... key block" */ - const char *hdrlines; /* write these headerlines */ - - /* these fileds must be initialized to zero */ - int no_openpgp_data; /* output flag: "No valid OpenPGP data found" */ - - /* the following fields must be initialized to zero */ - int inp_checked; /* set if the input has been checked */ - int inp_bypass; /* set if the input is not armored */ - int in_cleartext; /* clear text message */ - int not_dash_escaped; /* clear text is not dash escaped */ - int hashes; /* detected hash algorithms */ - int faked; /* we are faking a literal data packet */ - int truncated; /* number of truncated lines */ - int qp_detected; - int pgp2mode; - - byte *buffer; /* malloced buffer */ - unsigned buffer_size; /* and size of this buffer */ - unsigned buffer_len; /* used length of the buffer */ - unsigned buffer_pos; /* read position */ - - byte radbuf[4]; - int idx, idx2; - u32 crc; - - int status; /* an internal state flag */ - int cancel; - int any_data; /* any valid armored data seen */ - int pending_lf; /* used together with faked */ -} armor_filter_context_t; - -struct unarmor_pump_s; -typedef struct unarmor_pump_s *UnarmorPump; - - -struct compress_filter_context_s { - int status; - void *opaque; /* (used for z_stream) */ - byte *inbuf; - unsigned inbufsize; - byte *outbuf; - unsigned outbufsize; - int algo; /* compress algo */ - int algo1hack; - int new_ctb; - void (*release)(struct compress_filter_context_s*); -}; -typedef struct compress_filter_context_s compress_filter_context_t; - - -typedef struct { - DEK *dek; - u32 datalen; - CIPHER_HANDLE cipher_hd; - int header; - MD_HANDLE mdc_hash; - byte enchash[20]; - int create_mdc; /* flag will be set by the cipher filter */ -} cipher_filter_context_t; - - - -typedef struct { - byte *buffer; /* malloced buffer */ - unsigned buffer_size; /* and size of this buffer */ - unsigned buffer_len; /* used length of the buffer */ - unsigned buffer_pos; /* read position */ - int truncated; /* number of truncated lines */ - int not_dash_escaped; - int escape_from; - MD_HANDLE md; - int pending_lf; - int pending_esc; -} text_filter_context_t; - - -typedef struct { - char *what; /* description */ - u32 last_time; /* last time reported */ - unsigned long last; /* last amount reported */ - unsigned long offset; /* current amount */ - unsigned long total; /* total amount */ -} progress_filter_context_t; - -/* encrypt_filter_context_t defined in main.h */ - -/*-- mdfilter.c --*/ -int md_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); -void free_md_filter_context( md_filter_context_t *mfx ); - -/*-- armor.c --*/ -int use_armor_filter( iobuf_t a ); -int armor_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); -UnarmorPump unarmor_pump_new (void); -void unarmor_pump_release (UnarmorPump x); -int unarmor_pump (UnarmorPump x, int c); - -/*-- compress.c --*/ -int compress_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); - -/*-- cipher.c --*/ -int cipher_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); - -/*-- textfilter.c --*/ -int text_filter( void *opaque, int control, - iobuf_t chain, byte *buf, size_t *ret_len); -int copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md, - int escape_dash, int escape_from, int pgp2mode ); - -/*-- progress.c --*/ -int progress_filter (void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len); -void handle_progress (progress_filter_context_t *pfx, - iobuf_t inp, const char *name); - -#endif /*G10_FILTER_H*/ diff --git a/g10/free-packet.c b/g10/free-packet.c deleted file mode 100644 index 7ced327f5..000000000 --- a/g10/free-packet.c +++ /dev/null @@ -1,542 +0,0 @@ -/* free-packet.c - cleanup stuff for packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "packet.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "options.h" - -void -free_symkey_enc( PKT_symkey_enc *enc ) -{ - xfree (enc); -} - -void -free_pubkey_enc( PKT_pubkey_enc *enc ) -{ - int n, i; - n = pubkey_get_nenc( enc->pubkey_algo ); - if( !n ) - mpi_release (enc->data[0]); - for(i=0; i < n; i++ ) - mpi_release ( enc->data[i] ); - xfree (enc); -} - -void -free_seckey_enc( PKT_signature *sig ) -{ - int n, i; - - n = pubkey_get_nsig( sig->pubkey_algo ); - if( !n ) - mpi_release (sig->data[0]); - for(i=0; i < n; i++ ) - mpi_release ( sig->data[i] ); - - xfree (sig->revkey); - xfree (sig->hashed); - xfree (sig->unhashed); - xfree (sig); -} - - -void -release_public_key_parts( PKT_public_key *pk ) -{ - int n, i; - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - mpi_release (pk->pkey[0]); - for(i=0; i < n; i++ ) { - mpi_release ( pk->pkey[i] ); - pk->pkey[i] = NULL; - } - if (pk->prefs) { - xfree (pk->prefs); - pk->prefs = NULL; - } - if (pk->user_id) { - free_user_id (pk->user_id); - pk->user_id = NULL; - } - if (pk->revkey) { - xfree (pk->revkey); - pk->revkey=NULL; - pk->numrevkeys=0; - } -} - - -void -free_public_key( PKT_public_key *pk ) -{ - release_public_key_parts( pk ); - xfree (pk); -} - - -static subpktarea_t * -cp_subpktarea (subpktarea_t *s ) -{ - subpktarea_t *d; - - if( !s ) - return NULL; - d = xmalloc (sizeof (*d) + s->size - 1 ); - d->size = s->size; - d->len = s->len; - memcpy (d->data, s->data, s->len); - return d; -} - -/* - * Return a copy of the preferences - */ -prefitem_t * -copy_prefs (const prefitem_t *prefs) -{ - size_t n; - prefitem_t *new; - - if (!prefs) - return NULL; - - for (n=0; prefs[n].type; n++) - ; - new = xmalloc ( sizeof (*new) * (n+1)); - for (n=0; prefs[n].type; n++) { - new[n].type = prefs[n].type; - new[n].value = prefs[n].value; - } - new[n].type = PREFTYPE_NONE; - new[n].value = 0; - - return new; -} - - -PKT_public_key * -copy_public_key ( PKT_public_key *d, PKT_public_key *s) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - d->user_id = scopy_user_id (s->user_id); - d->prefs = copy_prefs (s->prefs); - n = pubkey_get_npkey( s->pubkey_algo ); - if( !n ) - d->pkey[0] = mpi_copy(s->pkey[0]); - else { - for(i=0; i < n; i++ ) - d->pkey[i] = mpi_copy( s->pkey[i] ); - } - if( !s->revkey && s->numrevkeys ) - BUG(); - if( s->numrevkeys ) { - d->revkey = xmalloc (sizeof(struct revocation_key)*s->numrevkeys); - memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys); - } - else - d->revkey = NULL; - return d; -} - -/**************** - * Replace all common parts of a sk by the one from the public key. - * This is a hack and a better solution will be to just store the real secret - * parts somewhere and don't duplicate all the other stuff. - */ -void -copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk ) -{ - sk->expiredate = pk->expiredate; - sk->pubkey_algo = pk->pubkey_algo; - sk->pubkey_usage= pk->pubkey_usage; - sk->req_usage = pk->req_usage; - sk->req_algo = pk->req_algo; - sk->has_expired = pk->has_expired; - sk->is_revoked = pk->is_revoked; - sk->is_valid = pk->is_valid; - sk->main_keyid[0]= pk->main_keyid[0]; - sk->main_keyid[1]= pk->main_keyid[1]; - sk->keyid[0] = pk->keyid[0]; - sk->keyid[1] = pk->keyid[1]; -} - -PKT_signature * -copy_signature( PKT_signature *d, PKT_signature *s ) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - n = pubkey_get_nsig( s->pubkey_algo ); - if( !n ) - d->data[0] = mpi_copy(s->data[0]); - else { - for(i=0; i < n; i++ ) - d->data[i] = mpi_copy( s->data[i] ); - } - d->hashed = cp_subpktarea (s->hashed); - d->unhashed = cp_subpktarea (s->unhashed); - if(s->numrevkeys) - { - d->revkey=NULL; - d->numrevkeys=0; - parse_revkeys(d); - } - return d; -} - - -/* - * shallow copy of the user ID - */ -PKT_user_id * -scopy_user_id (PKT_user_id *s) -{ - if (s) - s->ref++; - return s; -} - - - -void -release_secret_key_parts( PKT_secret_key *sk ) -{ - int n, i; - - n = pubkey_get_nskey( sk->pubkey_algo ); - if( !n ) - mpi_release (sk->skey[0]); - for(i=0; i < n; i++ ) { - mpi_release ( sk->skey[i] ); - sk->skey[i] = NULL; - } -} - -void -free_secret_key( PKT_secret_key *sk ) -{ - release_secret_key_parts( sk ); - xfree (sk); -} - -PKT_secret_key * -copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ) -{ - int n, i; - - if( !d ) - d = xmalloc (sizeof *d); - memcpy( d, s, sizeof *d ); - n = pubkey_get_nskey( s->pubkey_algo ); - if( !n ) - d->skey[0] = mpi_copy(s->skey[0]); - else { - for(i=0; i < n; i++ ) - d->skey[i] = mpi_copy( s->skey[i] ); - } - return d; -} - -void -free_comment( PKT_comment *rem ) -{ - xfree (rem); -} - -void -free_attributes(PKT_user_id *uid) -{ - xfree (uid->attribs); - xfree (uid->attrib_data); - - uid->attribs=NULL; - uid->attrib_data=NULL; - uid->attrib_len=0; -} - -void -free_user_id (PKT_user_id *uid) -{ - assert (uid->ref > 0); - if (--uid->ref) - return; - - free_attributes(uid); - xfree (uid->prefs); - xfree (uid->namehash); - xfree (uid); -} - -void -free_compressed( PKT_compressed *zd ) -{ - if( zd->buf ) { /* have to skip some bytes */ - /* don't have any information about the length, so - * we assume this is the last packet */ - while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 ) - ; - } - xfree (zd); -} - -void -free_encrypted( PKT_encrypted *ed ) -{ - if( ed->buf ) { /* have to skip some bytes */ - if( iobuf_in_block_mode(ed->buf) ) { - while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 ) - ; - } - else { - while( ed->len ) { /* skip the packet */ - int n = iobuf_read( ed->buf, NULL, ed->len ); - if( n == -1 ) - ed->len = 0; - else - ed->len -= n; - } - } - } - xfree (ed); -} - - -void -free_plaintext( PKT_plaintext *pt ) -{ - if( pt->buf ) { /* have to skip some bytes */ - if( iobuf_in_block_mode(pt->buf) ) { - while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 ) - ; - } - else { - while( pt->len ) { /* skip the packet */ - int n = iobuf_read( pt->buf, NULL, pt->len ); - if( n == -1 ) - pt->len = 0; - else - pt->len -= n; - } - } - } - xfree (pt); -} - -/**************** - * Free the packet in pkt. - */ -void -free_packet( PACKET *pkt ) -{ - if( !pkt || !pkt->pkt.generic ) - return; - - if( DBG_MEMORY ) - log_debug("free_packet() type=%d\n", pkt->pkttype ); - - switch( pkt->pkttype ) { - case PKT_SIGNATURE: - free_seckey_enc( pkt->pkt.signature ); - break; - case PKT_PUBKEY_ENC: - free_pubkey_enc( pkt->pkt.pubkey_enc ); - break; - case PKT_SYMKEY_ENC: - free_symkey_enc( pkt->pkt.symkey_enc ); - break; - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - free_public_key( pkt->pkt.public_key ); - break; - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - free_secret_key( pkt->pkt.secret_key ); - break; - case PKT_COMMENT: - free_comment( pkt->pkt.comment ); - break; - case PKT_USER_ID: - free_user_id( pkt->pkt.user_id ); - break; - case PKT_COMPRESSED: - free_compressed( pkt->pkt.compressed); - break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - free_encrypted( pkt->pkt.encrypted ); - break; - case PKT_PLAINTEXT: - free_plaintext( pkt->pkt.plaintext ); - break; - default: - xfree ( pkt->pkt.generic ); - break; - } - pkt->pkt.generic = NULL; -} - -/**************** - * returns 0 if they match. - */ -int -cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) -{ - int n, i; - - if( a->timestamp != b->timestamp ) - return -1; - if( a->version < 4 && a->expiredate != b->expiredate ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( b->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->pkey[i], b->pkey[i] ) ) - return -1; - } - - return 0; -} - -/**************** - * Returns 0 if they match. - * We only compare the public parts. - */ -int -cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b ) -{ - int n, i; - - if( a->timestamp != b->timestamp ) - return -1; - if( a->version < 4 && a->expiredate != b->expiredate ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( b->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->skey[i], b->skey[i] ) ) - return -1; - } - - return 0; -} - -/**************** - * Returns 0 if they match. - */ -int -cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ) -{ - int n, i; - - if( pk->timestamp != sk->timestamp ) - return -1; - if( pk->version < 4 && pk->expiredate != sk->expiredate ) - return -1; - if( pk->pubkey_algo != sk->pubkey_algo ) - return -1; - - n = pubkey_get_npkey( pk->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) ) - return -1; - } - return 0; -} - - - -int -cmp_signatures( PKT_signature *a, PKT_signature *b ) -{ - int n, i; - - if( a->keyid[0] != b->keyid[0] ) - return -1; - if( a->keyid[1] != b->keyid[1] ) - return -1; - if( a->pubkey_algo != b->pubkey_algo ) - return -1; - - n = pubkey_get_nsig( a->pubkey_algo ); - if( !n ) - return -1; /* can't compare due to unknown algorithm */ - for(i=0; i < n; i++ ) { - if( mpi_cmp( a->data[i] , b->data[i] ) ) - return -1; - } - return 0; -} - - -/**************** - * Returns: true if the user ids do not match - */ -int -cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) -{ - int res=1; - - if( a == b ) - return 0; - - if( a->attrib_data && b->attrib_data ) - { - res = a->attrib_len - b->attrib_len; - if( !res ) - res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len ); - } - else if( !a->attrib_data && !b->attrib_data ) - { - res = a->len - b->len; - if( !res ) - res = memcmp( a->name, b->name, a->len ); - } - - return res; -} diff --git a/g10/g10.c b/g10/g10.c deleted file mode 100644 index 915011026..000000000 --- a/g10/g10.c +++ /dev/null @@ -1,3367 +0,0 @@ -/* g10.c - The GnuPG utility (main for gpg) - * Copyright (C) 1998,1999,2000,2001,2002,2003 - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <assert.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif -#ifdef HAVE_STAT -#include <sys/stat.h> /* for stat() */ -#endif -#include <assuan.h> - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "gpg.h" -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "mpi.h" -#include "cipher.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" -#include "status.h" -#include "keyserver-internal.h" -#include "exec.h" - -enum cmd_and_opt_values { aNull = 0, - oArmor = 'a', - aDetachedSign = 'b', - aSym = 'c', - aDecrypt = 'd', - aEncr = 'e', - oInteractive = 'i', - aListKeys = 'k', - aListSecretKeys = 'K', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oRecipient = 'r', - oHiddenRecipient = 'R', - aSign = 's', - oTextmodeShort= 't', - oUser = 'u', - oVerbose = 'v', - oCompress = 'z', - oSetNotation = 'N', - oBatch = 500, - aGPGConfList, - oSigNotation, - oCertNotation, - oShowNotation, - oNoShowNotation, - aEncrFiles, - aDecryptFiles, - aClearsign, - aStore, - aKeygen, - aSignEncr, - aSignSym, - aSignKey, - aLSignKey, - aNRSignKey, - aNRLSignKey, - aListPackets, - aEditKey, - aDeleteKeys, - aDeleteSecretKeys, - aDeleteSecretAndPublicKeys, - aImport, - aFastImport, - aVerify, - aVerifyFiles, - aListSigs, - aSendKeys, - aRecvKeys, - aSearchKeys, - aExport, - aExportAll, - aExportSecret, - aExportSecretSub, - aCheckKeys, - aGenRevoke, - aDesigRevoke, - aPrimegen, - aPrintMD, - aPrintMDs, - aCheckTrustDB, - aUpdateTrustDB, - aFixTrustDB, - aListTrustDB, - aListTrustPath, - aExportOwnerTrust, - aListOwnerTrust, - aImportOwnerTrust, - aDeArmor, - aEnArmor, - aGenRandom, - aPipeMode, - aRebuildKeydbCaches, - aRefreshKeys, - aCardStatus, - aCardEdit, - aChangePIN, - - oTextmode, - oNoTextmode, - oExpert, - oNoExpert, - oAskSigExpire, - oNoAskSigExpire, - oAskCertExpire, - oNoAskCertExpire, - oFingerprint, - oWithFingerprint, - oAnswerYes, - oAnswerNo, - oDefCertCheckLevel, - oKeyring, - oPrimaryKeyring, - oSecretKeyring, - oShowKeyring, - oDefaultKey, - oDefRecipient, - oDefRecipientSelf, - oNoDefRecipient, - oOptions, - oDebug, - oDebugLevel, - oDebugAll, - oStatusFD, -#ifdef __riscos__ - oStatusFile, -#endif /* __riscos__ */ - oAttributeFD, -#ifdef __riscos__ - oAttributeFile, -#endif /* __riscos__ */ - oSKComments, - oNoSKComments, - oEmitVersion, - oNoEmitVersion, - oCompletesNeeded, - oMarginalsNeeded, - oMaxCertDepth, - oLoadExtension, - oGnuPG, - oRFC1991, - oRFC2440, - oOpenPGP, - oPGP2, - oPGP6, - oPGP7, - oPGP8, - oCipherAlgo, - oDigestAlgo, - oCertDigestAlgo, - oCompressAlgo, - oPasswdFD, -#ifdef __riscos__ - oPasswdFile, -#endif /* __riscos__ */ - oCommandFD, -#ifdef __riscos__ - oCommandFile, -#endif /* __riscos__ */ - oQuickRandom, - oNoVerbose, - oTrustDBName, - oNoSecmemWarn, - oNoPermissionWarn, - oNoMDCWarn, - oNoArmor, - oNoDefKeyring, - oNoGreeting, - oNoTTY, - oNoOptions, - oNoBatch, - oHomedir, - oWithColons, - oWithKeyData, - oSkipVerify, - oCompressKeys, - oCompressSigs, - oAlwaysTrust, - oTrustModel, - oForceOwnertrust, - oEmuChecksumBug, - oSetFilename, - oForYourEyesOnly, - oNoForYourEyesOnly, - oSetPolicyURL, - oSigPolicyURL, - oCertPolicyURL, - oShowPolicyURL, - oNoShowPolicyURL, - oSigKeyserverURL, - oUseEmbeddedFilename, - oComment, - oDefaultComment, - oNoComments, - oThrowKeyid, - oNoThrowKeyid, - oShowPhotos, - oNoShowPhotos, - oPhotoViewer, - oForceV3Sigs, - oNoForceV3Sigs, - oForceV4Certs, - oNoForceV4Certs, - oForceMDC, - oNoForceMDC, - oDisableMDC, - oNoDisableMDC, - oS2KMode, - oS2KDigest, - oS2KCipher, - oSimpleSKChecksum, - oCharset, - oNotDashEscaped, - oEscapeFrom, - oNoEscapeFrom, - oLockOnce, - oLockMultiple, - oLockNever, - oKeyServer, - oKeyServerOptions, - oImportOptions, - oExportOptions, - oListOptions, - oVerifyOptions, - oTempDir, - oExecPath, - oEncryptTo, - oHiddenEncryptTo, - oNoEncryptTo, - oLogFile, - oLoggerFD, -#ifdef __riscos__ - oLoggerFile, -#endif /* __riscos__ */ - oUtf8Strings, - oNoUtf8Strings, - oDisableCipherAlgo, - oDisablePubkeyAlgo, - oAllowNonSelfsignedUID, - oNoAllowNonSelfsignedUID, - oAllowFreeformUID, - oNoAllowFreeformUID, - oAllowSecretKeyImport, - oEnableSpecialFilenames, - oNoLiteral, - oSetFilesize, - oHonorHttpProxy, - oFastListMode, - oListOnly, - oIgnoreTimeConflict, - oIgnoreValidFrom, - oIgnoreCrcError, - oIgnoreMDCError, - oShowSessionKey, - oOverrideSessionKey, - oNoRandomSeedFile, - oAutoKeyRetrieve, - oNoAutoKeyRetrieve, - oUseAgent, - oNoUseAgent, - oGpgAgentInfo, - oMergeOnly, - oTryAllSecrets, - oTrustedKey, - oNoExpensiveTrustChecks, - oFixedListMode, - oNoSigCache, - oNoSigCreateCheck, - oAutoCheckTrustDB, - oNoAutoCheckTrustDB, - oPreservePermissions, - oDefaultPreferenceList, - oPersonalCipherPreferences, - oPersonalDigestPreferences, - oPersonalCompressPreferences, - oEmuMDEncodeBug, - oAgentProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - oGroup, - oStrict, - oNoStrict, - oMangleDosFilenames, - oNoMangleDosFilenames, - oEnableProgressFilter, - oMultifile, -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aSign, "sign", 256, N_("|[file]|make a signature")}, - { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") }, - { aDetachedSign, "detach-sign", 256, N_("make a detached signature")}, - { aEncr, "encrypt", 256, N_("encrypt data")}, - { aEncrFiles, "encrypt-files", 256, "@"}, - { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { aStore, "store", 256, "@"}, - { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { aDecryptFiles, "decrypt-files", 256, "@"}, - { aVerify, "verify" , 256, N_("verify a signature")}, - { aVerifyFiles, "verify-files" , 256, "@" }, - { aListKeys, "list-keys", 256, N_("list keys")}, - { aListKeys, "list-public-keys", 256, "@" }, - { aListSigs, "list-sigs", 256, N_("list keys and signatures")}, - { aCheckKeys, "check-sigs",256, N_("list and check key signatures")}, - { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")}, - { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, - { aKeygen, "gen-key", 256, N_("generate a new key pair")}, - { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")}, - { aDeleteSecretKeys, "delete-secret-keys",256, - N_("remove keys from the secret keyring")}, - { aSignKey, "sign-key" ,256, N_("sign a key")}, - { aLSignKey, "lsign-key" ,256, N_("sign a key locally")}, - { aNRSignKey, "nrsign-key" ,256, "@"}, - { aNRLSignKey, "nrlsign-key" ,256, "@"}, - { aEditKey, "edit-key" ,256, N_("sign or edit a key")}, - { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")}, - { aDesigRevoke, "desig-revoke",256, "@" }, - { aExport, "export" , 256, N_("export keys") }, - { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, - { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, - { aSearchKeys, "search-keys" , 256, - N_("search for keys on a key server") }, - { aRefreshKeys, "refresh-keys", 256, - N_("update all keys from a keyserver")}, - { aExportAll, "export-all" , 256, "@" }, - { aExportSecret, "export-secret-keys" , 256, "@" }, - { aExportSecretSub, "export-secret-subkeys" , 256, "@" }, - { aImport, "import", 256 , N_("import/merge keys")}, - { aFastImport, "fast-import", 256 , "@"}, - { aCardStatus, "card-status", 256, N_("print the card status")}, - { aCardEdit, "card-edit", 256, N_("change data on a card")}, - { aChangePIN, "change-pin", 256, N_("change a card's PIN")}, - - { aListPackets, "list-packets",256, "@"}, - { aExportOwnerTrust, "export-ownertrust", 256, "@"}, - { aImportOwnerTrust, "import-ownertrust", 256, "@"}, - { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")}, - { aCheckTrustDB, "check-trustdb",0 , "@"}, - { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")}, - { aDeArmor, "dearmor", 256, "@" }, - { aDeArmor, "dearmour", 256, "@" }, - { aEnArmor, "enarmor", 256, "@" }, - { aEnArmor, "enarmour", 256, "@" }, - { aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")}, - { aPrimegen, "gen-prime" , 256, "@" }, - { aGenRandom, "gen-random" , 256, "@" }, - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - { oHiddenRecipient, "hidden-recipient", 2, "@" }, - { oRecipient, "remote-user", 2, "@"}, /* old option name */ - { oDefRecipient, "default-recipient" ,2, "@" }, - { oDefRecipientSelf, "default-recipient-self" ,0, "@" }, - { oNoDefRecipient, "no-default-recipient", 0, "@" }, - { oTempDir, "temp-directory", 2, "@" }, - { oExecPath, "exec-path", 2, "@" }, - { oEncryptTo, "encrypt-to", 2, "@" }, - { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" }, - { oNoEncryptTo, "no-encrypt-to", 0, "@" }, - { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, - { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, - { oTextmodeShort, NULL, 0, "@"}, - { oTextmode, "textmode", 0, N_("use canonical text mode")}, - { oNoTextmode, "no-textmode", 0, "@"}, - { oExpert, "expert", 0, "@"}, - { oNoExpert, "no-expert", 0, "@"}, - { oAskSigExpire, "ask-sig-expire", 0, "@"}, - { oNoAskSigExpire, "no-ask-sig-expire", 0, "@"}, - { oAskCertExpire, "ask-cert-expire", 0, "@"}, - { oNoAskCertExpire, "no-ask-cert-expire", 0, "@"}, - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, "@" }, - { oNoTTY, "no-tty", 0, "@" }, - { oLogFile, "log-file" ,2, "@" }, - { oForceV3Sigs, "force-v3-sigs", 0, "@" }, - { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" }, - { oForceV4Certs, "force-v4-certs", 0, "@" }, - { oNoForceV4Certs, "no-force-v4-certs", 0, "@" }, - { oForceMDC, "force-mdc", 0, "@" }, - { oNoForceMDC, "no-force-mdc", 0, "@" }, - { oDisableMDC, "disable-mdc", 0, "@" }, - { oNoDisableMDC, "no-disable-mdc", 0, "@" }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oInteractive, "interactive", 0, N_("prompt before overwriting") }, - { oUseAgent, "use-agent",0, "@"}, - { oNoUseAgent, "no-use-agent",0, "@"}, - { oGpgAgentInfo, "gpg-agent-info",2, "@"}, - { oBatch, "batch", 0, "@"}, - { oAnswerYes, "yes", 0, "@"}, - { oAnswerNo, "no", 0, "@"}, - { oKeyring, "keyring" , 2, "@"}, - { oPrimaryKeyring, "primary-keyring",2, "@" }, - { oSecretKeyring, "secret-keyring" ,2, "@"}, - { oShowKeyring, "show-keyring", 0, "@"}, - { oDefaultKey, "default-key" , 2, "@"}, - { oKeyServer, "keyserver", 2, "@"}, - { oKeyServerOptions, "keyserver-options",2,"@"}, - { oImportOptions, "import-options",2,"@"}, - { oExportOptions, "export-options",2,"@"}, - { oListOptions, "list-options",2,"@"}, - { oVerifyOptions, "verify-options",2,"@"}, - { oCharset, "charset" , 2, "@" }, - { oOptions, "options" , 2, "@"}, - - { oDebug, "debug" ,4|16, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oStatusFD, "status-fd" ,1, "@" }, -#ifdef __riscos__ - { oStatusFile, "status-file" ,2, "@" }, -#endif /* __riscos__ */ - { oAttributeFD, "attribute-fd" ,1, "@" }, -#ifdef __riscos__ - { oAttributeFile, "attribute-file" ,2, "@" }, -#endif /* __riscos__ */ - { oNoSKComments, "no-sk-comments", 0, "@"}, - { oSKComments, "sk-comments", 0, "@"}, - { oCompletesNeeded, "completes-needed", 1, "@"}, - { oMarginalsNeeded, "marginals-needed", 1, "@"}, - { oMaxCertDepth, "max-cert-depth", 1, "@" }, - { oTrustedKey, "trusted-key", 2, "@"}, - { oLoadExtension, "load-extension" ,2, "@"}, - { oGnuPG, "gnupg", 0, "@"}, - { oGnuPG, "no-pgp2", 0, "@"}, - { oGnuPG, "no-pgp6", 0, "@"}, - { oGnuPG, "no-pgp7", 0, "@"}, - { oGnuPG, "no-pgp8", 0, "@"}, - { oRFC1991, "rfc1991", 0, "@"}, - { oRFC2440, "rfc2440", 0, "@"}, - { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")}, - { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")}, - { oPGP6, "pgp6", 0, "@"}, - { oPGP7, "pgp7", 0, "@"}, - { oPGP8, "pgp8", 0, "@"}, - { oS2KMode, "s2k-mode", 1, "@"}, - { oS2KDigest, "s2k-digest-algo",2, "@"}, - { oS2KCipher, "s2k-cipher-algo",2, "@"}, - { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"}, - { oCipherAlgo, "cipher-algo", 2 , "@"}, - { oDigestAlgo, "digest-algo", 2 , "@"}, - { oCertDigestAlgo, "cert-digest-algo", 2 , "@" }, - { oCompressAlgo,"compress-algo",2, "@"}, - { oThrowKeyid, "throw-keyid", 0, "@"}, - { oNoThrowKeyid, "no-throw-keyid", 0, "@" }, - { oShowPhotos, "show-photos", 0, "@" }, - { oNoShowPhotos, "no-show-photos", 0, "@" }, - { oPhotoViewer, "photo-viewer", 2, "@" }, - { oSetNotation, "set-notation", 2, "@" }, - { oSetNotation, "notation-data", 2, "@" }, /* Alias */ - { oSigNotation, "sig-notation", 2, "@" }, - { oCertNotation, "cert-notation", 2, "@" }, - - { 302, NULL, 0, N_( - "@\n(See the man page for a complete listing of all commands and options)\n" - )}, - - { 303, NULL, 0, N_("@\nExamples:\n\n" - " -se -r Bob [file] sign and encrypt for user Bob\n" - " --clearsign [file] make a clear text signature\n" - " --detach-sign [file] make a detached signature\n" - " --list-keys [names] show keys\n" - " --fingerprint [names] show fingerprints\n" ) }, - - /* hidden options */ - { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */ - { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */ - { aPrintMDs, "print-mds" , 256, "@"}, /* old */ - { aListTrustDB, "list-trustdb",0 , "@"}, - /* Not yet used */ - /* { aListTrustPath, "list-trust-path",0, "@"}, */ - { aPipeMode, "pipemode", 0, "@" }, - { oPasswdFD, "passphrase-fd",1, "@" }, -#ifdef __riscos__ - { oPasswdFile, "passphrase-file",2, "@" }, -#endif /* __riscos__ */ - { oCommandFD, "command-fd",1, "@" }, -#ifdef __riscos__ - { oCommandFile, "command-file",2, "@" }, -#endif /* __riscos__ */ - { oQuickRandom, "quick-random", 0, "@"}, - { oNoVerbose, "no-verbose", 0, "@"}, - { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ - { oNoPermissionWarn, "no-permission-warning", 0, "@" }, - { oNoMDCWarn, "no-mdc-warning", 0, "@" }, - { oNoArmor, "no-armor", 0, "@"}, - { oNoArmor, "no-armour", 0, "@"}, - { oNoDefKeyring, "no-default-keyring", 0, "@" }, - { oNoGreeting, "no-greeting", 0, "@" }, - { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - { oNoBatch, "no-batch", 0, "@" }, - { oWithColons, "with-colons", 0, "@"}, - { oWithKeyData,"with-key-data", 0, "@"}, - { aListKeys, "list-key", 0, "@" }, /* alias */ - { aListSigs, "list-sig", 0, "@" }, /* alias */ - { aCheckKeys, "check-sig",0, "@" }, /* alias */ - { oSkipVerify, "skip-verify",0, "@" }, - { oCompressKeys, "compress-keys",0, "@"}, - { oCompressSigs, "compress-sigs",0, "@"}, - { oDefCertCheckLevel, "default-cert-check-level", 1, "@"}, - { oAlwaysTrust, "always-trust", 0, "@"}, - { oTrustModel, "trust-model", 2, "@"}, - { oForceOwnertrust, "force-ownertrust", 2, "@"}, - { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"}, - { oSetFilename, "set-filename", 2, "@" }, - { oForYourEyesOnly, "for-your-eyes-only", 0, "@" }, - { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" }, - { oSetPolicyURL, "set-policy-url", 2, "@" }, - { oSigPolicyURL, "sig-policy-url", 2, "@" }, - { oCertPolicyURL, "cert-policy-url", 2, "@" }, - { oShowPolicyURL, "show-policy-url", 0, "@" }, - { oNoShowPolicyURL, "no-show-policy-url", 0, "@" }, - { oShowNotation, "show-notation", 0, "@" }, - { oNoShowNotation, "no-show-notation", 0, "@" }, - { oSigKeyserverURL, "sig-keyserver-url", 2, "@" }, - { oComment, "comment", 2, "@" }, - { oDefaultComment, "default-comment", 0, "@" }, - { oNoComments, "no-comments", 0, "@" }, - { oEmitVersion, "emit-version", 0, "@"}, - { oNoEmitVersion, "no-emit-version", 0, "@"}, - { oNoEmitVersion, "no-version", 0, "@"}, /* alias */ - { oNotDashEscaped, "not-dash-escaped", 0, "@" }, - { oEscapeFrom, "escape-from-lines", 0, "@" }, - { oNoEscapeFrom, "no-escape-from-lines", 0, "@" }, - { oLockOnce, "lock-once", 0, "@" }, - { oLockMultiple, "lock-multiple", 0, "@" }, - { oLockNever, "lock-never", 0, "@" }, - { oLoggerFD, "logger-fd",1, "@" }, -#ifdef __riscos__ - { oLoggerFile, "logger-file",2, "@" }, -#endif /* __riscos__ */ - { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" }, - { oUtf8Strings, "utf8-strings", 0, "@" }, - { oNoUtf8Strings, "no-utf8-strings", 0, "@" }, - { oWithFingerprint, "with-fingerprint", 0, "@" }, - { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" }, - { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" }, - { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" }, - { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" }, - { oAllowFreeformUID, "allow-freeform-uid", 0, "@" }, - { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" }, - { oNoLiteral, "no-literal", 0, "@" }, - { oSetFilesize, "set-filesize", 20, "@" }, - { oHonorHttpProxy,"honor-http-proxy", 0, "@" }, - { oFastListMode,"fast-list-mode", 0, "@" }, - { oFixedListMode,"fixed-list-mode", 0, "@" }, - { oListOnly, "list-only", 0, "@"}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, - { oIgnoreValidFrom, "ignore-valid-from", 0, "@" }, - { oIgnoreCrcError, "ignore-crc-error", 0,"@" }, - { oIgnoreMDCError, "ignore-mdc-error", 0,"@" }, - { oShowSessionKey, "show-session-key", 0, "@" }, - { oOverrideSessionKey, "override-session-key", 2, "@" }, - { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, - { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" }, - { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" }, - { oNoSigCache, "no-sig-cache", 0, "@" }, - { oNoSigCreateCheck, "no-sig-create-check", 0, "@" }, - { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"}, - { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"}, - { oMergeOnly, "merge-only", 0, "@" }, - { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" }, - { oTryAllSecrets, "try-all-secrets", 0, "@" }, - { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, - { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" }, - { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, - { oPreservePermissions, "preserve-permissions", 0, "@"}, - { oDefaultPreferenceList, "default-preference-list", 2, "@"}, - { oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"}, - { oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"}, - { oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"}, - { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"}, - { oAgentProgram, "agent-program", 2 , "@" }, - { oDisplay, "display", 2, "@" }, - { oTTYname, "ttyname", 2, "@" }, - { oTTYtype, "ttytype", 2, "@" }, - { oLCctype, "lc-ctype", 2, "@" }, - { oLCmessages, "lc-messages", 2, "@" }, - { oGroup, "group", 2, "@" }, - { oStrict, "strict", 0, "@" }, - { oNoStrict, "no-strict", 0, "@" }, - { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" }, - { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" }, - { oEnableProgressFilter, "enable-progress-filter", 0, "@" }, - { oMultifile, "multifile", 0, "@" }, -{0} }; - - - -int g10_errors_seen = 0; - -static int utf8_strings = 0; -static int maybe_setuid = 1; - -static char *build_list( const char *text, char letter, - const char *(*mapf)(int), int (*chkf)(int) ); -static void set_cmd( enum cmd_and_opt_values *ret_cmd, - enum cmd_and_opt_values new_cmd ); -static void print_mds( const char *fname, int algo ); -static void add_notation_data( const char *string, int which ); -static void add_policy_url( const char *string, int which ); -static void add_keyserver_url( const char *string, int which ); -static void emergency_cleanup (void); - -#ifdef __riscos__ -RISCOS_GLOBAL_STATICS("GnuPG Heap") -#endif /* __riscos__ */ - -static int -pk_test_algo (int algo) -{ - return openpgp_pk_test_algo (algo, 0); -} - - -static const char * -my_strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers, *zips; - const char *p; - switch( level ) { - case 11: p = "gpg (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to <gnupg-bugs@gnu.org>.\n"); - break; - case 1: - case 40: p = - _("Usage: gpg [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: gpg [options] [files]\n" - "sign, check, encrypt or decrypt\n" - "default operation depends on the input data\n"); - break; - - case 31: p = "\nHome: "; break; -#ifndef __riscos__ - case 32: p = opt.homedir; break; -#else /* __riscos__ */ - case 32: p = make_filename(opt.homedir, NULL); break; -#endif /* __riscos__ */ - case 33: p = _("\nSupported algorithms:\n"); break; - case 34: - if( !pubkeys ) - pubkeys = build_list(_("Pubkey: "), 0, gcry_pk_algo_name, - pk_test_algo ); - p = pubkeys; - break; - case 35: - if( !ciphers ) - ciphers = build_list(_("Cipher: "), 'S', gcry_cipher_algo_name, - openpgp_cipher_test_algo ); - p = ciphers; - break; - case 36: - if( !digests ) - digests = build_list(_("Hash: "), 'H', gcry_md_algo_name, - openpgp_md_test_algo ); - p = digests; - break; - case 37: - if( !zips ) - zips = build_list(_("Compression: "),'Z',compress_algo_to_string, - check_compress_algo); - p = zips; - break; - - default: p = NULL; - } - return p; -} - - -static char * -build_list( const char *text, char letter, - const char * (*mapf)(int), int (*chkf)(int) ) -{ - int i; - const char *s; - size_t n=strlen(text)+2; - char *list, *p, *line=NULL; - - if( maybe_setuid ) - gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* drop setuid */ - - for(i=0; i <= 110; i++ ) - if( !chkf(i) && (s=mapf(i)) ) - n += strlen(s) + 7 + 2; - list = xmalloc ( 21 + n ); *list = 0; - for(p=NULL, i=0; i <= 110; i++ ) { - if( !chkf(i) && (s=mapf(i)) ) { - if( !p ) { - p = stpcpy( list, text ); - line=p; - } - else - p = stpcpy( p, ", "); - - if(strlen(line)>60) { - int spaces=strlen(text); - - list = xrealloc(list,n+spaces+1); - /* realloc could move the block, so find the end again */ - p=list; - while(*p) - p++; - - p=stpcpy(p, "\n"); - line=p; - for(;spaces;spaces--) - p=stpcpy(p, " "); - } - - p = stpcpy(p, s ); - if(opt.verbose && letter) - { - char num[8]; - sprintf(num," (%c%d)",letter,i); - p = stpcpy(p,num); - } - } - } - if( p ) - p = stpcpy(p, "\n" ); - return list; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - setlocale( LC_ALL, "" ); - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - -static void -wrong_args( const char *text) -{ - fputs(_("usage: gpg [options] "),stderr); - fputs(text,stderr); - putc('\n',stderr); - g10_exit(2); -} - - -static void -log_set_strict (int yesno) -{ - /* FIXME-XXX*/ -} - -static char * -make_username( const char *string ) -{ - char *p; - if( utf8_strings ) - p = xstrdup (string); - else - p = native_to_utf8( string ); - return p; -} - - -/* - * same as add_to_strlist() but if is_utf8 is *not* set a conversion - * to UTF8 is done - */ -static STRLIST -add_to_strlist2 ( STRLIST *list, const char *string, int is_utf8) -{ - STRLIST sl; - - if (is_utf8) - sl = add_to_strlist( list, string ); - else - { - char *p = native_to_utf8( string ); - sl = add_to_strlist( list, p ); - xfree( p ); - } - return sl; -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_MEMSTAT_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE - |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - g10_exit (2); - } - - if (opt.debug & DBG_MEMORY_VALUE ) - memory_debug_mode = 1; - if (opt.debug & DBG_MEMSTAT_VALUE ) - memory_stat_debug_mode = 1; - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CIPHER_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); - if (opt.debug & DBG_IOBUF_VALUE ) - iobuf_debug_mode = 1; -} - - -/* We need the home directory also in some other directories, so make - sure that both variables are always in sync. */ -static void -set_homedir (char *dir) -{ - if (!dir) - dir = ""; - g10_opt_homedir = opt.homedir = dir; -} - - -static void -set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ) -{ - enum cmd_and_opt_values cmd = *ret_cmd; - - if( !cmd || cmd == new_cmd ) - cmd = new_cmd; - else if( cmd == aSign && new_cmd == aEncr ) - cmd = aSignEncr; - else if( cmd == aEncr && new_cmd == aSign ) - cmd = aSignEncr; - else if( cmd == aSign && new_cmd == aSym ) - cmd = aSignSym; - else if( cmd == aSym && new_cmd == aSign ) - cmd = aSignSym; - else if( ( cmd == aSign && new_cmd == aClearsign ) - || ( cmd == aClearsign && new_cmd == aSign ) ) - cmd = aClearsign; - else { - log_error(_("conflicting commands\n")); - g10_exit(2); - } - - *ret_cmd = cmd; -} - - -static void add_group(char *string) -{ - char *name,*value; - struct groupitem *item; - STRLIST values=NULL; - - /* Break off the group name */ - name=strsep(&string,"="); - if(string==NULL) - { - log_error(_("no = sign found in group definition \"%s\"\n"),name); - return; - } - - trim_trailing_ws(name,strlen(name)); - - /* Break apart the values */ - while ((value= strsep(&string," \t"))) - { - if (*value) - add_to_strlist2 (&values,value,utf8_strings); - } - - item=xmalloc (sizeof(struct groupitem)); - item->name=name; - item->values=values; - item->next=opt.grouplist; - - opt.grouplist=item; -} - -/* We need to check three things. - - 0) The homedir. It must be x00, a directory, and owned by the - user. - - 1) The options file. Okay unless it or its containing directory is - group or other writable or not owned by us. disable exec in this - case. - - 2) Extensions. Same as #2. - - Returns true if the item is unsafe. */ -static int -check_permissions(const char *path,int item) -{ -#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - static int homedir_cache=-1; - char *tmppath,*dir; - struct stat statbuf,dirbuf; - int homedir=0,ret=0,checkonly=0; - int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0; - - if(opt.no_perm_warn) - return 0; - - assert(item==0 || item==1 || item==2); - - /* extensions may attach a path */ - if(item==2 && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=xstrdup (path); - - /* If the item is located in the homedir, but isn't the homedir, - don't continue if we already checked the homedir itself. This is - to avoid user confusion with an extra options file warning which - could be rectified if the homedir itself had proper - permissions. */ - if(item!=0 && homedir_cache>-1 - && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0) - { - ret=homedir_cache; - goto end; - } - - /* It's okay if the file or directory doesn't exist */ - if(stat(tmppath,&statbuf)!=0) - { - ret=0; - goto end; - } - - /* Now check the enclosing directory. Theoretically, we could walk - this test up to the root directory /, but for the sake of sanity, - I'm stopping at one level down. */ - dir=make_dirname(tmppath); - - if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode)) - { - /* Weird error */ - ret=1; - goto end; - } - - xfree (dir); - - /* Assume failure */ - ret=1; - - if(item==0) - { - /* The homedir must be x00, a directory, and owned by the user. */ - - if(S_ISDIR(statbuf.st_mode)) - { - if(statbuf.st_uid==getuid()) - { - if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - ret=0; - else - perm=1; - } - else - own=1; - - homedir_cache=ret; - } - } - else if(item==1 || item==2) - { - /* The options or extension file. Okay unless it or its - containing directory is group or other writable or not owned - by us or root. */ - - if(S_ISREG(statbuf.st_mode)) - { - if(statbuf.st_uid==getuid() || statbuf.st_uid==0) - { - if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0) - { - /* it's not writable, so make sure the enclosing - directory is also not writable */ - if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0) - { - if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0) - ret=0; - else - enc_dir_perm=1; - } - else - enc_dir_own=1; - } - else - { - /* it's writable, so the enclosing directory had - better not let people get to it. */ - if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0) - { - if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - ret=0; - else - perm=enc_dir_perm=1; /* unclear which one to fix! */ - } - else - enc_dir_own=1; - } - } - else - own=1; - } - } - else - BUG(); - - if(!checkonly) - { - if(own) - { - if(item==0) - log_info(_("WARNING: unsafe ownership on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe ownership on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe ownership on " - "extension \"%s\"\n"),tmppath); - } - if(perm) - { - if(item==0) - log_info(_("WARNING: unsafe permissions on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe permissions on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe permissions on " - "extension \"%s\"\n"),tmppath); - } - if(enc_dir_own) - { - if(item==0) - log_info(_("WARNING: unsafe enclosing directory ownership on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory ownership on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe enclosing directory ownership on " - "extension \"%s\"\n"),tmppath); - } - if(enc_dir_perm) - { - if(item==0) - log_info(_("WARNING: unsafe enclosing directory permissions on " - "homedir \"%s\"\n"),tmppath); - else if(item==1) - log_info(_("WARNING: unsafe enclosing directory permissions on " - "configuration file \"%s\"\n"),tmppath); - else - log_info(_("WARNING: unsafe enclosing directory permissions on " - "extension \"%s\"\n"),tmppath); - } - } - - end: - xfree (tmppath); - - if(homedir) - homedir_cache=ret; - - return ret; - -#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ - - return 0; -} - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - iobuf_t a; - int rc=0; - int orig_argc; - char **orig_argv; - const char *fname; - char *username; - int may_coredump; - STRLIST sl, remusr= NULL, locusr=NULL; - STRLIST nrings=NULL, sec_nrings=NULL; - armor_filter_context_t afx; - int detached_sig = 0; - FILE *configfp = NULL; - char *configname = NULL; - const char *config_filename = NULL; - unsigned configlineno; - int parse_debug = 0; - int default_config = 1; - int default_keyring = 1; - int greeting = 0; - int nogreeting = 0; - char *logfile = NULL; - int use_random_seed = 1; - enum cmd_and_opt_values cmd = 0; - const char *debug_level = NULL; - const char *trustdb_name = NULL; - char *def_cipher_string = NULL; - char *def_digest_string = NULL; - char *def_compress_string = NULL; - char *cert_digest_string = NULL; - char *s2k_cipher_string = NULL; - char *s2k_digest_string = NULL; - char *pers_cipher_list = NULL; - char *pers_digest_list = NULL; - char *pers_compress_list = NULL; - int eyes_only=0; - int multifile=0; - int pwfd = -1; - int with_fpr = 0; /* make an option out of --fingerprint */ - int any_explicit_recipient = 0; - -#ifdef __riscos__ - riscos_global_defaults(); - opt.lock_once = 1; -#endif /* __riscos__ */ - - trap_unaligned(); - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* We don't need any locking in libgcrypt unless we use any kind of - threading. */ - gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - * when adding any stuff between here and the call to - * secmem_init() somewhere after the option parsing - */ - log_set_prefix ("gpg", 1); - /* check that the libraries are suitable. Do it here because the - option parse may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps(); - gnupg_init_signals (0, emergency_cleanup); - create_dotlock (NULL); /* register locking cleanup */ - i18n_init(); - - opt.command_fd = -1; /* no command fd */ - opt.compress = -1; /* defaults to standard compress level */ - /* note: if you change these lines, look at oOpenPGP */ - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.def_compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; -#ifdef USE_CAST5 - opt.s2k_cipher_algo = CIPHER_ALGO_CAST5; -#else - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; -#endif - opt.completes_needed = 1; - opt.marginals_needed = 3; - opt.max_cert_depth = 5; - opt.pgp2_workarounds = 1; - opt.force_v3_sigs = 1; - opt.escape_from = 1; - opt.import_options=IMPORT_SK2PK; - opt.export_options= - EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES; - opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG; - opt.keyserver_options.export_options= - EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES; - opt.keyserver_options.include_subkeys=1; - opt.keyserver_options.include_revoked=1; - opt.keyserver_options.try_dns_srv=1; - opt.verify_options= - VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER; - opt.trust_model=TM_AUTO; - opt.mangle_dos_filenames = 1; - opt.use_agent = 1; - -#if defined (_WIN32) - set_homedir ( read_w32_registry_string( NULL, - "Software\\GNU\\GnuPG", "HomeDir" )); -#else - set_homedir ( getenv("GNUPGHOME") ); -#endif - if( !*opt.homedir ) - set_homedir ( GNUPG_DEFAULT_HOMEDIR ); - - /* check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while( arg_parse( &pargs, opts) ) { - if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll ) - parse_debug++; - else if( pargs.r_opt == oOptions ) { - /* yes there is one, so we do not try the default one, but - * read the option file when it is encountered at the commandline - */ - default_config = 0; - } - else if( pargs.r_opt == oNoOptions ) - default_config = 0; /* --no-options */ - else if( pargs.r_opt == oHomedir ) - set_homedir ( pargs.r.ret_str ); - else if( pargs.r_opt == oNoPermissionWarn ) - opt.no_perm_warn=1; - else if (pargs.r_opt == oStrict ) - { - opt.strict=1; - log_set_strict(1); - } - else if (pargs.r_opt == oNoStrict ) - { - opt.strict=0; - log_set_strict(0); - } - } - -#ifdef HAVE_DOSISH_SYSTEM - if ( strchr (opt.homedir,'\\') ) { - char *d, *buf = xmalloc (strlen (opt.homedir)+1); - const char *s = opt.homedir; - for (d=buf,s=opt.homedir; *s; s++) - *d++ = *s == '\\'? '/': *s; - *d = 0; - set_homedir (buf); - } -#endif - - /* Initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0); - maybe_setuid = 0; - /* Okay, we are now working under our real uid */ - - /* malloc hooks go here ... */ - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - set_native_charset (NULL); /* Try to auto set the character set */ - - /* Try for a version specific config file first */ - if( default_config ) - { - char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION); - char *ver = name + strlen("gpg" EXTSEP_S "conf-"); - - do - { - if(configname) - { - char *tok; - - xfree (configname); - configname=NULL; - - if((tok=strrchr (ver,SAFE_VERSION_DASH))) - *tok='\0'; - else if((tok=strrchr (ver,SAFE_VERSION_DOT))) - *tok='\0'; - else - break; - } - - configname = make_filename (opt.homedir, name, NULL); - } - while ( access(configname,R_OK) ); - xfree(name); - - if (!access (configname, R_OK)) - { /* Print a warning when both config files are present. */ - char *p = make_filename(opt.homedir, "options", NULL ); - if (!access (p, R_OK)) - log_info (_("NOTE: old default options file `%s' ignored\n"), p); - xfree (p); - } - else - { /* Keep on using the old default one. */ - xfree (configname); - configname = make_filename(opt.homedir, "options", NULL ); - } - } - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - - /* By this point we have a homedir, and cannot change it. */ - check_permissions(opt.homedir,0); - - next_pass: - if( configname ) { - if(check_permissions(configname,1)) - { - /* If any options file is unsafe, then disable any external - programs for keyserver calls or photo IDs. Since the - external program to call is set in the options file, a - unsafe options file can lead to an arbitrary program - being run. */ - - opt.exec_disable=1; - } - - configlineno = 0; - configfp = fopen( configname, "r" ); - if( !configfp ) { - if( default_config ) { - if( parse_debug ) - log_info(_("NOTE: no default option file `%s'\n"), - configname ); - } - else { - log_error(_("option file `%s': %s\n"), - configname, strerror(errno) ); - g10_exit(2); - } - xfree (configname); configname = NULL; - } - if( parse_debug && configname ) - log_info(_("reading options from `%s'\n"), configname ); - default_config = 0; - } - - while( optfile_parse( configfp, configname, &configlineno, - &pargs, opts) ) { - switch( pargs.r_opt ) { - case aCheckKeys: set_cmd( &cmd, aCheckKeys); break; - case aListPackets: set_cmd( &cmd, aListPackets); break; - case aImport: set_cmd( &cmd, aImport); break; - case aFastImport: set_cmd( &cmd, aFastImport); break; - case aSendKeys: set_cmd( &cmd, aSendKeys); break; - case aRecvKeys: set_cmd( &cmd, aRecvKeys); break; - case aSearchKeys: set_cmd( &cmd, aSearchKeys); break; - case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break; - case aExport: set_cmd( &cmd, aExport); break; - case aExportAll: set_cmd( &cmd, aExportAll); break; - case aListKeys: set_cmd( &cmd, aListKeys); break; - case aListSigs: set_cmd( &cmd, aListSigs); break; - case aExportSecret: set_cmd( &cmd, aExportSecret); break; - case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break; - case aDeleteSecretKeys: set_cmd( &cmd, aDeleteSecretKeys); - greeting=1; break; - case aDeleteSecretAndPublicKeys: - set_cmd( &cmd, aDeleteSecretAndPublicKeys); - greeting=1; - break; - case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break; - - case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; - case aSym: set_cmd( &cmd, aSym); break; - - case aDecryptFiles: multifile=1; /* fall through */ - case aDecrypt: set_cmd( &cmd, aDecrypt); break; - - case aEncrFiles: multifile=1; /* fall through */ - case aEncr: set_cmd( &cmd, aEncr); break; - - case aVerifyFiles: multifile=1; /* fall through */ - case aVerify: set_cmd( &cmd, aVerify); break; - - case aSign: set_cmd( &cmd, aSign ); break; - case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break; - case aSignKey: set_cmd( &cmd, aSignKey); break; - case aLSignKey: set_cmd( &cmd, aLSignKey); break; - case aNRSignKey: set_cmd( &cmd, aNRSignKey); break; - case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break; - case aStore: set_cmd( &cmd, aStore); break; - case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break; - case aClearsign: set_cmd( &cmd, aClearsign); break; - case aGenRevoke: set_cmd( &cmd, aGenRevoke); break; - case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break; - - case aPrimegen: set_cmd( &cmd, aPrimegen); break; - case aGenRandom: set_cmd( &cmd, aGenRandom); break; - case aPrintMD: set_cmd( &cmd, aPrintMD); break; - case aPrintMDs: set_cmd( &cmd, aPrintMDs); break; - case aListTrustDB: set_cmd( &cmd, aListTrustDB); break; - case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break; - case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break; - case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break; - case aListTrustPath: set_cmd( &cmd, aListTrustPath); break; - case aDeArmor: set_cmd( &cmd, aDeArmor); break; - case aEnArmor: set_cmd( &cmd, aEnArmor); break; - case aListOwnerTrust: - deprecated_warning(configname,configlineno, - "--list-ownertrust","--export-ownertrust",""); - case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break; - case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break; - case aPipeMode: set_cmd( &cmd, aPipeMode); break; - case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break; - - case aCardStatus: set_cmd (&cmd, aCardStatus); break; - case aCardEdit: set_cmd (&cmd, aCardEdit); break; - case aChangePIN: set_cmd (&cmd, aChangePIN); break; - case aGPGConfList: - set_cmd (&cmd, aGPGConfList); - nogreeting = 1; - break; - - case oArmor: opt.armor = 1; opt.no_armor=0; break; - case oOutput: opt.outfile = pargs.r.ret_str; break; - case oQuiet: opt.quiet = 1; break; - case oNoTTY: tty_no_terminal(1); break; - case oDryRun: opt.dry_run = 1; break; - case oInteractive: opt.interactive = 1; break; - case oVerbose: g10_opt_verbose++; - opt.verbose++; opt.list_sigs=1; break; - - case oLogFile: logfile = pargs.r.ret_str; break; - - case oBatch: opt.batch = 1; nogreeting = 1; break; - case oUseAgent: -#ifndef __riscos__ - opt.use_agent = 1; -#else /* __riscos__ */ - opt.use_agent = 0; - riscos_not_implemented("use-agent"); -#endif /* __riscos__ */ - break; - case oNoUseAgent: opt.use_agent = 0; break; - case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break; - case oAnswerYes: opt.answer_yes = 1; break; - case oAnswerNo: opt.answer_no = 1; break; - case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; - case oPrimaryKeyring: - sl=append_to_strlist( &nrings, pargs.r.ret_str); - sl->flags=2; - break; - case oShowKeyring: opt.list_options|=LIST_SHOW_KEYRING; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oStatusFD: - set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) ); - break; -#ifdef __riscos__ - case oStatusFile: - set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oAttributeFD: - set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; -#ifdef __riscos__ - case oAttributeFile: - set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; -#ifdef __riscos__ - case oLoggerFile: - log_set_logfile( NULL, - iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); - break; -#endif /* __riscos__ */ - case oWithFingerprint: - opt.with_fingerprint = 1; - with_fpr=1; /*fall thru*/ - case oFingerprint: opt.fingerprint++; break; - case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; - case oOptions: - /* config files may not be nested (silently ignore them) */ - if( !configfp ) { - xfree (configname); - configname = xstrdup (pargs.r.ret_str); - goto next_pass; - } - break; - case oNoArmor: opt.no_armor=1; opt.armor=0; break; - case oNoDefKeyring: default_keyring = 0; break; - case oDefCertCheckLevel: opt.def_cert_check_level=pargs.r.ret_int; break; - case oNoGreeting: nogreeting = 1; break; - case oNoVerbose: g10_opt_verbose = 0; - opt.verbose = 0; opt.list_sigs=0; break; - /* disabled for now: - case oQuickRandom: quick_random_gen(1); break; */ - case oSKComments: opt.sk_comments=1; break; - case oNoSKComments: opt.sk_comments=0; break; - case oEmitVersion: opt.no_version=0; break; - case oNoEmitVersion: opt.no_version=1; break; - case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break; - case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break; - case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break; - case oTrustDBName: trustdb_name = pargs.r.ret_str; break; - case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break; - case oDefRecipient: - if( *pargs.r.ret_str ) - opt.def_recipient = make_username(pargs.r.ret_str); - break; - case oDefRecipientSelf: - xfree (opt.def_recipient); opt.def_recipient = NULL; - opt.def_recipient_self = 1; - break; - case oNoDefRecipient: - xfree (opt.def_recipient); opt.def_recipient = NULL; - opt.def_recipient_self = 0; - break; - case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */ - case oHomedir: break; - case oNoBatch: opt.batch = 0; break; - case oWithKeyData: opt.with_key_data=1; /* fall thru */ - case oWithColons: opt.with_colons=':'; break; - - case oSkipVerify: opt.skip_verify=1; break; - case oCompressKeys: opt.compress_keys = 1; break; - case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break; - /* There are many programs (like mutt) that call gpg with - --always-trust so keep this option around for a long - time. */ - case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break; - case oTrustModel: - if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0) - opt.trust_model=TM_PGP; - else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0) - opt.trust_model=TM_CLASSIC; - else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0) - opt.trust_model=TM_ALWAYS; - else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0) - opt.trust_model=TM_AUTO; - else - log_error("unknown trust model \"%s\"\n",pargs.r.ret_str); - break; - case oForceOwnertrust: - log_info(_("NOTE: %s is not for normal use!\n"), - "--force-ownertrust"); - opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str); - if(opt.force_ownertrust==-1) - { - log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str); - opt.force_ownertrust=0; - } - break; - case oLoadExtension: -#ifndef __riscos__ -#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32) - if(check_permissions(pargs.r.ret_str,2)) - log_info(_("cipher extension \"%s\" not loaded due to " - "unsafe permissions\n"),pargs.r.ret_str); - else - register_cipher_extension(orig_argc? *orig_argv:NULL, - pargs.r.ret_str); -#endif -#else /* __riscos__ */ - riscos_not_implemented("load-extension"); -#endif /* __riscos__ */ - break; - case oRFC1991: - opt.compliance = CO_RFC1991; - opt.force_v4_certs = 0; - opt.escape_from = 1; - break; - case oRFC2440: - case oOpenPGP: - /* TODO: When 2440bis becomes a RFC, these may need - changing. */ - opt.compliance = CO_RFC2440; - opt.allow_non_selfsigned_uid = 1; - opt.allow_freeform_uid = 1; - opt.pgp2_workarounds = 0; - opt.escape_from = 0; - opt.force_v3_sigs = 0; - opt.compress_keys = 0; /* not mandated but we do it */ - opt.compress_sigs = 0; /* ditto. */ - opt.not_dash_escaped = 0; - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.def_compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; - break; - case oPGP2: opt.compliance = CO_PGP2; break; - case oPGP6: opt.compliance = CO_PGP6; break; - case oPGP7: opt.compliance = CO_PGP7; break; - case oPGP8: opt.compliance = CO_PGP8; break; - case oGnuPG: opt.compliance = CO_GNUPG; break; - case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break; - case oCompressSigs: opt.compress_sigs = 1; break; - case oSetFilename: opt.set_filename = pargs.r.ret_str; break; - case oForYourEyesOnly: eyes_only = 1; break; - case oNoForYourEyesOnly: eyes_only = 0; break; - case oSetPolicyURL: - add_policy_url(pargs.r.ret_str,0); - add_policy_url(pargs.r.ret_str,1); - break; - case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break; - case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break; - case oShowPolicyURL: - opt.list_options|=LIST_SHOW_POLICY; - opt.verify_options|=VERIFY_SHOW_POLICY; - break; - case oNoShowPolicyURL: - opt.list_options&=~LIST_SHOW_POLICY; - opt.verify_options&=~VERIFY_SHOW_POLICY; - break; - case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break; - case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break; - - case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break; - case oDefaultComment: - deprecated_warning(configname,configlineno, - "--default-comment","--no-comments",""); - /* fall through */ - case oNoComments: - free_strlist(opt.comments); - opt.comments=NULL; - break; - - case oThrowKeyid: opt.throw_keyid = 1; break; - case oNoThrowKeyid: opt.throw_keyid = 0; break; - case oShowPhotos: - opt.list_options|=LIST_SHOW_PHOTOS; - opt.verify_options|=VERIFY_SHOW_PHOTOS; - break; - case oNoShowPhotos: - opt.list_options&=~LIST_SHOW_PHOTOS; - opt.verify_options&=~VERIFY_SHOW_PHOTOS; - break; - case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break; - case oForceV3Sigs: opt.force_v3_sigs = 1; break; - case oNoForceV3Sigs: opt.force_v3_sigs = 0; break; - case oForceV4Certs: opt.force_v4_certs = 1; break; - case oNoForceV4Certs: opt.force_v4_certs = 0; break; - case oForceMDC: opt.force_mdc = 1; break; - case oNoForceMDC: opt.force_mdc = 0; break; - case oDisableMDC: opt.disable_mdc = 1; break; - case oNoDisableMDC: opt.disable_mdc = 0; break; - case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; - case oS2KDigest: s2k_digest_string = xstrdup (pargs.r.ret_str); break; - case oS2KCipher: s2k_cipher_string = xstrdup (pargs.r.ret_str); break; - case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break; - case oNoEncryptTo: opt.no_encrypt_to = 1; break; - case oEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 1; - break; - case oHiddenEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 1|2; - break; - case oRecipient: /* store the recipient */ - add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - any_explicit_recipient = 1; - break; - case oHiddenRecipient: /* store the recipient with a flag */ - sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = 2; - any_explicit_recipient = 1; - break; - case oTextmodeShort: opt.textmode = 2; break; - case oTextmode: opt.textmode=1; break; - case oNoTextmode: opt.textmode=0; break; - case oExpert: opt.expert = 1; break; - case oNoExpert: opt.expert = 0; break; - case oAskSigExpire: opt.ask_sig_expire = 1; break; - case oNoAskSigExpire: opt.ask_sig_expire = 0; break; - case oAskCertExpire: opt.ask_cert_expire = 1; break; - case oNoAskCertExpire: opt.ask_cert_expire = 0; break; - case oUser: /* store the local users */ - add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings ); - break; - case oCompress: opt.compress = pargs.r.ret_int; break; - case oPasswdFD: - pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0); - opt.use_agent = 0; - break; -#ifdef __riscos__ - case oPasswdFile: - pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); - break; -#endif /* __riscos__ */ - case oCommandFD: - opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0); - break; -#ifdef __riscos__ - case oCommandFile: - opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); - break; -#endif /* __riscos__ */ - case oCipherAlgo: def_cipher_string = xstrdup (pargs.r.ret_str); break; - case oDigestAlgo: def_digest_string = xstrdup (pargs.r.ret_str); break; - case oCompressAlgo: - /* If it is all digits, stick a Z in front of it for - later. This is for backwards compatibility with - versions that took the compress algorithm number. */ - { - char *pt=pargs.r.ret_str; - while(*pt) - { - if(!isdigit(*pt)) - break; - - pt++; - } - - if(*pt=='\0') - { - def_compress_string=xmalloc (strlen(pargs.r.ret_str)+2); - strcpy(def_compress_string,"Z"); - strcat(def_compress_string,pargs.r.ret_str); - } - else - def_compress_string = xstrdup (pargs.r.ret_str); - } - break; - case oCertDigestAlgo: cert_digest_string = xstrdup (pargs.r.ret_str); break; - case oNoSecmemWarn: - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - break; - case oNoPermissionWarn: opt.no_perm_warn=1; break; - case oNoMDCWarn: opt.no_mdc_warn=1; break; - case oCharset: - if( set_native_charset( pargs.r.ret_str ) ) - log_error(_("%s is not a valid character set\n"), - pargs.r.ret_str); - break; - case oNotDashEscaped: opt.not_dash_escaped = 1; break; - case oEscapeFrom: opt.escape_from = 1; break; - case oNoEscapeFrom: opt.escape_from = 0; break; - case oLockOnce: opt.lock_once = 1; break; - case oLockNever: disable_dotlock(); break; - case oLockMultiple: -#ifndef __riscos__ - opt.lock_once = 0; -#else /* __riscos__ */ - riscos_not_implemented("lock-multiple"); -#endif /* __riscos__ */ - break; - case oKeyServer: - opt.keyserver_uri=xstrdup (pargs.r.ret_str); - if(parse_keyserver_uri(pargs.r.ret_str,configname,configlineno)) - log_error(_("could not parse keyserver URI\n")); - break; - case oKeyServerOptions: - parse_keyserver_options(pargs.r.ret_str); - break; - case oImportOptions: - if(!parse_import_options(pargs.r.ret_str,&opt.import_options)) - { - if(configname) - log_error(_("%s:%d: invalid import options\n"), - configname,configlineno); - else - log_error(_("invalid import options\n")); - } - break; - case oExportOptions: - if(!parse_export_options(pargs.r.ret_str,&opt.export_options)) - { - if(configname) - log_error(_("%s:%d: invalid export options\n"), - configname,configlineno); - else - log_error(_("invalid export options\n")); - } - break; - case oListOptions: - { - struct parse_options lopts[]= - { - {"show-photos",LIST_SHOW_PHOTOS}, - {"show-policy-url",LIST_SHOW_POLICY}, - {"show-notation",LIST_SHOW_NOTATION}, - {"show-keyserver-url",LIST_SHOW_KEYSERVER}, - {"show-validity",LIST_SHOW_VALIDITY}, - {"show-long-keyid",LIST_SHOW_LONG_KEYID}, - {"show-keyring",LIST_SHOW_KEYRING}, - {"show-sig-expire",LIST_SHOW_SIG_EXPIRE}, - {NULL,0} - }; - - if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts)) - { - if(configname) - log_error(_("%s:%d: invalid list options\n"), - configname,configlineno); - else - log_error(_("invalid list options\n")); - } - } - break; - case oVerifyOptions: - { - struct parse_options vopts[]= - { - {"show-photos",VERIFY_SHOW_PHOTOS}, - {"show-policy-url",VERIFY_SHOW_POLICY}, - {"show-notation",VERIFY_SHOW_NOTATION}, - {"show-keyserver-url",VERIFY_SHOW_KEYSERVER}, - {"show-validity",VERIFY_SHOW_VALIDITY}, - {"show-long-keyid",VERIFY_SHOW_LONG_KEYID}, - {NULL,0} - }; - - if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts)) - { - if(configname) - log_error(_("%s:%d: invalid verify options\n"), - configname,configlineno); - else - log_error(_("invalid verify options\n")); - } - } - break; - case oTempDir: opt.temp_dir=pargs.r.ret_str; break; - case oExecPath: - if(set_exec_path(pargs.r.ret_str,0)) - log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str); - else - opt.exec_path_set=1; - break; - case oSetNotation: - add_notation_data( pargs.r.ret_str, 0 ); - add_notation_data( pargs.r.ret_str, 1 ); - break; - case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break; - case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break; - case oShowNotation: - opt.list_options|=LIST_SHOW_NOTATION; - opt.verify_options|=VERIFY_SHOW_NOTATION; - break; - case oNoShowNotation: - opt.list_options&=~LIST_SHOW_NOTATION; - opt.verify_options&=~VERIFY_SHOW_NOTATION; - break; - case oUtf8Strings: utf8_strings = 1; break; - case oNoUtf8Strings: utf8_strings = 0; break; - case oDisableCipherAlgo: - { - int algo = gcry_cipher_map_name (pargs.r.ret_str); - gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, - &algo, sizeof algo); - } - break; - case oDisablePubkeyAlgo: - { - int algo = gcry_pk_map_name (pargs.r.ret_str); - gcry_pk_ctl (GCRYCTL_DISABLE_ALGO, - &algo, sizeof algo ); - } - break; - case oNoSigCache: opt.no_sig_cache = 1; break; - case oNoSigCreateCheck: opt.no_sig_create_check = 1; break; - case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break; - case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break; - case oAllowFreeformUID: opt.allow_freeform_uid = 1; break; - case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break; - case oNoLiteral: opt.no_literal = 1; break; - case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break; - case oHonorHttpProxy: - opt.keyserver_options.honor_http_proxy = 1; - deprecated_warning(configname,configlineno, - "--honor-http-proxy", - "--keyserver-options ", - "honor-http-proxy"); - break; - case oFastListMode: opt.fast_list_mode = 1; break; - case oFixedListMode: opt.fixed_list_mode = 1; break; - case oListOnly: opt.list_only=1; break; - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; - case oIgnoreCrcError: opt.ignore_crc_error = 1; break; - case oIgnoreMDCError: opt.ignore_mdc_error = 1; break; - case oNoRandomSeedFile: use_random_seed = 0; break; - case oAutoKeyRetrieve: - case oNoAutoKeyRetrieve: - opt.keyserver_options.auto_key_retrieve= - (pargs.r_opt==oAutoKeyRetrieve); - deprecated_warning(configname,configlineno, - pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve": - "--no-auto-key-retrieve","--keyserver-options ", - pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve": - "no-auto-key-retrieve"); - break; - case oShowSessionKey: opt.show_session_key = 1; break; - case oOverrideSessionKey: - opt.override_session_key = pargs.r.ret_str; - break; - case oMergeOnly: opt.merge_only = 1; break; - case oAllowSecretKeyImport: /* obsolete */ break; - case oTryAllSecrets: opt.try_all_secrets = 1; break; - case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break; - case oEnableSpecialFilenames: - iobuf_enable_special_filenames (1); - break; - case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; - case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break; - case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break; - case oPreservePermissions: opt.preserve_permissions=1; break; - case oDefaultPreferenceList: - opt.def_preference_list = pargs.r.ret_str; - break; - case oPersonalCipherPreferences: - pers_cipher_list=pargs.r.ret_str; - break; - case oPersonalDigestPreferences: - pers_digest_list=pargs.r.ret_str; - break; - case oPersonalCompressPreferences: - pers_compress_list=pargs.r.ret_str; - break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDisplay: opt.display = pargs.r.ret_str; break; - case oTTYname: opt.ttyname = pargs.r.ret_str; break; - case oTTYtype: opt.ttytype = pargs.r.ret_str; break; - case oLCctype: opt.lc_ctype = pargs.r.ret_str; break; - case oLCmessages: opt.lc_messages = pargs.r.ret_str; break; - case oGroup: add_group(pargs.r.ret_str); break; - case oStrict: opt.strict=1; log_set_strict(1); break; - case oNoStrict: opt.strict=0; log_set_strict(0); break; - - case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break; - case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break; - - case oEnableProgressFilter: opt.enable_progress_filter = 1; break; - case oMultifile: multifile=1; break; - - default : pargs.err = configfp? 1:2; break; - } - } - - if( configfp ) { - fclose( configfp ); - configfp = NULL; - config_filename = configname; /* Keep a copy of the config - file name. */ - configname = NULL; - goto next_pass; - } - xfree ( configname ); configname = NULL; - if( log_get_errorcount(0) ) - g10_exit(2); - if( nogreeting ) - greeting = 0; - - if( greeting ) { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); - } -#ifdef IS_DEVELOPMENT_VERSION - if( !opt.batch ) { - log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n"); - log_info("It is only intended for test purposes and should NOT be\n"); - log_info("used in a production environment or with production keys!\n"); - } -#endif - - /* FIXME: We should use the lggging to a file only in server mode; - however we have not yet implemetyed that thus we try to get - away with --batch as indication for logging to file required. */ - if (logfile && opt.batch) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - if (opt.verbose > 2) - log_info ("using character set `%s'\n", get_native_charset ()); - - if( may_coredump && !opt.quiet ) - log_info(_("WARNING: program may create a core file!\n")); - - if (eyes_only) { - if (opt.set_filename) - log_info(_("WARNING: %s overrides %s\n"), - "--for-your-eyes-only","--set-filename"); - - opt.set_filename="_CONSOLE"; - } - - if (opt.no_literal) { - log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal"); - if (opt.textmode) - log_error(_("%s not allowed with %s!\n"), - "--textmode", "--no-literal" ); - if (opt.set_filename) - log_error(_("%s makes no sense with %s!\n"), - eyes_only?"--for-your-eyes-only":"--set-filename", - "--no-literal" ); - } - - if (opt.set_filesize) - log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize"); - if( opt.batch ) - tty_batchmode( 1 ); - - gcry_control (GCRYCTL_RESUME_SECMEM_WARN); - set_debug (debug_level); - - /* Do these after the switch(), so they can override settings. */ - if(PGP2) - { - int unusable=0; - - if(cmd==aSign && !detached_sig) - { - log_info(_("you can only make detached or clear signatures " - "while in --pgp2 mode\n")); - unusable=1; - } - else if(cmd==aSignEncr || cmd==aSignSym) - { - log_info(_("you can't sign and encrypt at the " - "same time while in --pgp2 mode\n")); - unusable=1; - } - else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym)) - { - log_info(_("you must use files (and not a pipe) when " - "working with --pgp2 enabled.\n")); - unusable=1; - } - else if(cmd==aEncr || cmd==aSym) - { - /* Everything else should work without IDEA (except using - a secret key encrypted with IDEA and setting an IDEA - preference, but those have their own error - messages). */ - - if(openpgp_cipher_test_algo (CIPHER_ALGO_IDEA)) - { - log_info(_("encrypting a message in --pgp2 mode requires " - "the IDEA cipher\n")); - idea_cipher_warn(1); - unusable=1; - } - else if(cmd==aSym) - { - /* This only sets IDEA for symmetric encryption - since it is set via select_algo_from_prefs for - pk encryption. */ - xfree (def_cipher_string); - def_cipher_string = xstrdup ("idea"); - } - - /* PGP2 can't handle the output from the textmode - filter, so we disable it for anything that could - create a literal packet (only encryption and - symmetric encryption, since we disable signing - above). */ - if(!unusable) - opt.textmode=0; - } - - if(unusable) - compliance_failure(); - else - { - opt.force_v4_certs = 0; - opt.sk_comments = 0; - opt.escape_from = 1; - opt.force_v3_sigs = 1; - opt.pgp2_workarounds = 1; - opt.ask_sig_expire = 0; - opt.ask_cert_expire = 0; - xfree (def_digest_string); - def_digest_string = xstrdup ("md5"); - opt.def_compress_algo = 1; - } - } - else if(PGP6) - { - opt.sk_comments=0; - opt.escape_from=1; - opt.force_v3_sigs=1; - opt.ask_sig_expire=0; - } - else if(PGP7) - { - opt.sk_comments=0; - opt.escape_from=1; - opt.force_v3_sigs=1; - opt.ask_sig_expire=0; - } - else if(PGP8) - { - opt.escape_from=1; - } - - /* must do this after dropping setuid, because string_to... - * may try to load an module */ - if( def_cipher_string ) { - opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string); - if(opt.def_cipher_algo==0 && - (ascii_strcasecmp(def_cipher_string,"idea")==0 - || ascii_strcasecmp(def_cipher_string,"s1")==0)) - idea_cipher_warn(1); - xfree (def_cipher_string); def_cipher_string = NULL; - if( openpgp_cipher_test_algo (opt.def_cipher_algo) ) - log_error(_("selected cipher algorithm is invalid\n")); - } - if( def_digest_string ) { - opt.def_digest_algo = gcry_md_map_name (def_digest_string); - xfree (def_digest_string); def_digest_string = NULL; - if( openpgp_md_test_algo (opt.def_digest_algo) ) - log_error(_("selected digest algorithm is invalid\n")); - } - if( def_compress_string ) { - opt.def_compress_algo = string_to_compress_algo(def_compress_string); - xfree (def_compress_string); def_compress_string = NULL; - if( check_compress_algo(opt.def_compress_algo) ) - log_error(_("selected compression algorithm is invalid\n")); - } - if( cert_digest_string ) { - opt.cert_digest_algo = gcry_md_map_name (cert_digest_string); - xfree (cert_digest_string); cert_digest_string = NULL; - if( openpgp_md_test_algo(opt.cert_digest_algo) ) - log_error(_("selected certification digest algorithm is invalid\n")); - } - if( s2k_cipher_string ) { - opt.s2k_cipher_algo = gcry_cipher_map_name (s2k_cipher_string); - xfree (s2k_cipher_string); s2k_cipher_string = NULL; - if( openpgp_cipher_test_algo (opt.s2k_cipher_algo) ) - log_error(_("selected cipher algorithm is invalid\n")); - } - if( s2k_digest_string ) { - opt.s2k_digest_algo = gcry_md_map_name (s2k_digest_string); - xfree (s2k_digest_string); s2k_digest_string = NULL; - if( openpgp_md_test_algo (opt.s2k_digest_algo) ) - log_error(_("selected digest algorithm is invalid\n")); - } - if( opt.completes_needed < 1 ) - log_error(_("completes-needed must be greater than 0\n")); - if( opt.marginals_needed < 2 ) - log_error(_("marginals-needed must be greater than 1\n")); - if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 ) - log_error(_("max-cert-depth must be in range 1 to 255\n")); - switch( opt.s2k_mode ) { - case 0: - log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n")); - break; - case 1: case 3: break; - default: - log_error(_("invalid S2K mode; must be 0, 1 or 3\n")); - } - - if(opt.def_cert_check_level<0 || opt.def_cert_check_level>3) - log_error(_("invalid default-check-level; must be 0, 1, 2, or 3\n")); - - /* This isn't actually needed, but does serve to error out if the - string is invalid. */ - if(opt.def_preference_list && - keygen_set_std_prefs(opt.def_preference_list,0)) - log_error(_("invalid default preferences\n")); - - /* We provide defaults for the personal digest list */ - if(!pers_digest_list) - pers_digest_list="h2"; - - if(pers_cipher_list && - keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM)) - log_error(_("invalid personal cipher preferences\n")); - - if(pers_digest_list && - keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH)) - log_error(_("invalid personal digest preferences\n")); - - if(pers_compress_list && - keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP)) - log_error(_("invalid personal compress preferences\n")); - - /* We don't support all possible commands with multifile yet */ - if(multifile) - { - char *cmdname; - - switch(cmd) - { - case aSign: - cmdname="--sign"; - break; - case aClearsign: - cmdname="--clearsign"; - break; - case aDetachedSign: - cmdname="--detach-sign"; - break; - case aSym: - cmdname="--symmetric"; - break; - case aStore: - cmdname="--store"; - break; - default: - cmdname=NULL; - break; - } - - if(cmdname) - log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile"); - } - - if( log_get_errorcount(0) ) - g10_exit(2); - - /* Check our chosen algorithms against the list of legal - algorithms. */ - - if(!GNUPG) - { - const char *badalg=NULL; - preftype_t badtype=PREFTYPE_NONE; - - if (opt.def_cipher_algo - && !algo_available (PREFTYPE_SYM,opt.def_cipher_algo,NULL)) - { - badalg = gcry_cipher_algo_name (opt.def_cipher_algo); - badtype = PREFTYPE_SYM; - } - else if (opt.def_digest_algo - && !algo_available (PREFTYPE_HASH,opt.def_digest_algo,NULL)) - { - badalg = gcry_md_algo_name (opt.def_digest_algo); - badtype = PREFTYPE_HASH; - } - else if (opt.cert_digest_algo - && !algo_available (PREFTYPE_HASH,opt.cert_digest_algo,NULL)) - { - badalg = gcry_md_algo_name (opt.cert_digest_algo); - badtype = PREFTYPE_HASH; - } - else if (opt.def_compress_algo!=-1 - && !algo_available (PREFTYPE_ZIP,opt.def_compress_algo,NULL)) - { - badalg = compress_algo_to_string (opt.def_compress_algo); - badtype = PREFTYPE_ZIP; - } - - if (badalg) - { - switch(badtype) - { - case PREFTYPE_SYM: - log_info(_("you may not use cipher algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - case PREFTYPE_HASH: - log_info(_("you may not use digest algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - case PREFTYPE_ZIP: - log_info(_("you may not use compression algorithm \"%s\" " - "while in %s mode\n"), - badalg,compliance_option_string()); - break; - default: - BUG(); - } - - compliance_failure(); - } - } - - /* set the random seed file */ - if( use_random_seed ) { - char *p = make_filename(opt.homedir, "random_seed", NULL ); - gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); - xfree (p); - } - - if( !cmd && opt.fingerprint && !with_fpr ) { - set_cmd( &cmd, aListKeys); - } - - /* Compression algorithm 0 means no compression at all */ - if( opt.def_compress_algo == 0) - opt.compress = 0; - - /* kludge to let -sat generate a clear text signature */ - if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign ) - cmd = aClearsign; - - if( opt.verbose > 1 ) - set_packet_list_mode(1); - - /* Add the keyrings, but not for some special commands. Also - avoid adding the secret keyring for a couple of commands to - avoid unneeded access in case the secrings are stored on a - floppy */ - if( cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfList ) - { - if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys - && cmd != aVerify && cmd != aSym) - { - if (!sec_nrings || default_keyring) /* add default secret rings */ - keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1); - for (sl = sec_nrings; sl; sl = sl->next) - keydb_add_resource ( sl->d, 0, 1 ); - } - if( !nrings || default_keyring ) /* add default ring */ - keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0); - for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource ( sl->d, sl->flags, 0 ); - } - FREE_STRLIST(nrings); - FREE_STRLIST(sec_nrings); - - - if( pwfd != -1 ) /* read the passphrase now. */ - read_passphrase_from_fd( pwfd ); - - fname = argc? *argv : NULL; - - switch( cmd ) { - case aPrimegen: - case aPrintMD: - case aPrintMDs: - case aGenRandom: - case aDeArmor: - case aEnArmor: - case aFixTrustDB: - case aCardStatus: - case aCardEdit: - case aChangePIN: - case aGPGConfList: - break; - case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; - case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; - default: rc = setup_trustdb(1, trustdb_name ); break; - } - if( rc ) - log_error(_("failed to initialize the TrustDB: %s\n"), gpg_strerror (rc)); - - - switch (cmd) { - case aStore: - case aSym: - case aSign: - case aSignSym: - case aClearsign: - if (!opt.quiet && any_explicit_recipient) - log_info (_("WARNING: recipients (-r) given " - "without using public key encryption\n")); - break; - default: - break; - } - - switch( cmd ) { - case aStore: /* only store the file */ - if( argc > 1 ) - wrong_args(_("--store [filename]")); - if( (rc = encode_store(fname)) ) - log_error ("\b%s: store failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - case aSym: /* encrypt the given file only with the symmetric cipher */ - if( argc > 1 ) - wrong_args(_("--symmetric [filename]")); - if( (rc = encode_symmetric(fname)) ) - log_error ("\b%s: symmetric encryption failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aEncr: /* encrypt the given file */ - if(multifile) - encode_crypt_files(argc, argv, remusr); - else - { - if( argc > 1 ) - wrong_args(_("--encrypt [filename]")); - if( (rc = encode_crypt(fname,remusr)) ) - log_error("%s: encryption failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - } - break; - - case aSign: /* sign the given file */ - sl = NULL; - if( detached_sig ) { /* sign all files */ - for( ; argc; argc--, argv++ ) - add_to_strlist( &sl, *argv ); - } - else { - if( argc > 1 ) - wrong_args(_("--sign [filename]")); - if( argc ) { - sl = xcalloc (1, sizeof *sl + strlen(fname)); - strcpy(sl->d, fname); - } - } - if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) ) - log_error("signing failed: %s\n", gpg_strerror (rc) ); - free_strlist(sl); - break; - - case aSignEncr: /* sign and encrypt the given file */ - if( argc > 1 ) - wrong_args(_("--sign --encrypt [filename]")); - if( argc ) { - sl = xcalloc (1, sizeof *sl + strlen(fname)); - strcpy(sl->d, fname); - } - else - sl = NULL; - if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) ) - log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), gpg_strerror (rc) ); - free_strlist(sl); - break; - - case aSignSym: /* sign and conventionally encrypt the given file */ - if (argc > 1) - wrong_args(_("--sign --symmetric [filename]")); - rc = sign_symencrypt_file (fname, locusr); - if (rc) - log_error("%s: sign+symmetric failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aClearsign: /* make a clearsig */ - if( argc > 1 ) - wrong_args(_("--clearsign [filename]")); - if( (rc = clearsign_file(fname, locusr, NULL)) ) - log_error("%s: clearsign failed: %s\n", - print_fname_stdin(fname), gpg_strerror (rc) ); - break; - - case aVerify: - if(multifile) - { - if( (rc = verify_files( argc, argv ) )) - log_error("verify files failed: %s\n", gpg_strerror (rc) ); - } - else - { - if( (rc = verify_signatures( argc, argv ) )) - log_error("verify signatures failed: %s\n", gpg_strerror (rc) ); - } - break; - - case aDecrypt: - if(multifile) - decrypt_messages(argc, argv); - else - { - if( argc > 1 ) - wrong_args(_("--decrypt [filename]")); - if( (rc = decrypt_message( fname ) )) - log_error("decrypt_message failed: %s\n", gpg_strerror (rc) ); - } - break; - - case aSignKey: /* sign the key given as argument */ - if( argc != 1 ) - wrong_args(_("--sign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 1 ); - xfree (username); - break; - - case aLSignKey: - if( argc != 1 ) - wrong_args(_("--lsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 2 ); - xfree (username); - break; - - case aNRSignKey: - if( argc != 1 ) - wrong_args(_("--nrsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 3 ); - xfree (username); - break; - - case aNRLSignKey: - if( argc != 1 ) - wrong_args(_("--nrlsign-key user-id")); - username = make_username( fname ); - keyedit_menu(fname, locusr, NULL, 4 ); - xfree (username); - break; - - case aEditKey: /* Edit a key signature */ - if( !argc ) - wrong_args(_("--edit-key user-id [commands]")); - username = make_username( fname ); - if( argc > 1 ) { - sl = NULL; - for( argc--, argv++ ; argc; argc--, argv++ ) - append_to_strlist( &sl, *argv ); - keyedit_menu( username, locusr, sl, 0 ); - free_strlist(sl); - } - else - keyedit_menu(username, locusr, NULL, 0 ); - xfree (username); - break; - - case aDeleteKeys: - case aDeleteSecretKeys: - case aDeleteSecretAndPublicKeys: - sl = NULL; - /* I'm adding these in reverse order as add_to_strlist2 - reverses them again, and it's easier to understand in the - proper order :) */ - for( ; argc; argc-- ) - add_to_strlist2( &sl, argv[argc-1], utf8_strings ); - delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys); - free_strlist(sl); - break; - - case aCheckKeys: - opt.check_sigs = 1; - case aListSigs: - opt.list_sigs = 1; - case aListKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - public_key_list( sl ); - free_strlist(sl); - break; - case aListSecretKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - secret_key_list( sl ); - free_strlist(sl); - break; - - case aKeygen: /* generate a key */ - if( opt.batch ) { - if( argc > 1 ) - wrong_args("--gen-key [parameterfile]"); - generate_keypair( argc? *argv : NULL, NULL ); - } - else { - if( argc ) - wrong_args("--gen-key"); - generate_keypair(NULL, NULL); - } - break; - - case aFastImport: - opt.import_options |= IMPORT_FAST_IMPORT; - case aImport: - import_keys( argc? argv:NULL, argc, NULL, opt.import_options ); - break; - - case aExport: - case aExportAll: - case aSendKeys: - case aRecvKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - if( cmd == aSendKeys ) - rc=keyserver_export( sl ); - else if( cmd == aRecvKeys ) - rc=keyserver_import( sl ); - else - rc=export_pubkeys( sl, opt.export_options ); - if(rc) - { - if(cmd==aSendKeys) - log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc)); - else if(cmd==aRecvKeys) - log_error(_("keyserver receive failed: %s\n"),gpg_strerror (rc)); - else - log_error(_("key export failed: %s\n"),gpg_strerror (rc)); - } - free_strlist(sl); - break; - - case aSearchKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - { - if (utf8_strings) - sl = append_to_strlist ( &sl, *argv ); - else - { - char *p = native_to_utf8 ( *argv ); - sl = append_to_strlist( &sl, p ); - xfree( p ); - } - } - - rc=keyserver_search( sl ); - if(rc) - log_error(_("keyserver search failed: %s\n"),gpg_strerror (rc)); - free_strlist(sl); - break; - - case aRefreshKeys: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - rc=keyserver_refresh(sl); - if(rc) - log_error(_("keyserver refresh failed: %s\n"),gpg_strerror (rc)); - free_strlist(sl); - break; - - case aExportSecret: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - export_seckeys( sl ); - free_strlist(sl); - break; - - case aExportSecretSub: - sl = NULL; - for( ; argc; argc--, argv++ ) - add_to_strlist2( &sl, *argv, utf8_strings ); - export_secsubkeys( sl ); - free_strlist(sl); - break; - - case aGenRevoke: - if( argc != 1 ) - wrong_args("--gen-revoke user-id"); - username = make_username(*argv); - gen_revoke( username ); - xfree ( username ); - break; - - case aDesigRevoke: - if( argc != 1 ) - wrong_args("--desig-revoke user-id"); - username = make_username(*argv); - gen_desig_revoke( username ); - xfree ( username ); - break; - - case aDeArmor: - if( argc > 1 ) - wrong_args("--dearmor [file]"); - rc = dearmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("dearmoring failed: %s\n"), gpg_strerror (rc)); - break; - - case aEnArmor: - if( argc > 1 ) - wrong_args("--enarmor [file]"); - rc = enarmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("enarmoring failed: %s\n"), gpg_strerror (rc)); - break; - - - case aPrimegen: -#if 0 /*FIXME-XXX*/ - { int mode = argc < 2 ? 0 : atoi(*argv); - - if( mode == 1 && argc == 2 ) { - mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1); - } - else if( mode == 2 && argc == 3 ) { - mpi_print( stdout, generate_elg_prime( - 0, atoi(argv[1]), - atoi(argv[2]), NULL,NULL ), 1); - } - else if( mode == 3 && argc == 3 ) { - gcry_mpi_t *factors; - mpi_print( stdout, generate_elg_prime( - 1, atoi(argv[1]), - atoi(argv[2]), NULL,&factors ), 1); - putchar('\n'); - mpi_print( stdout, factors[0], 1 ); /* print q */ - } - else if( mode == 4 && argc == 3 ) { - gcry_mpi_t g = mpi_alloc(1); - mpi_print( stdout, generate_elg_prime( - 0, atoi(argv[1]), - atoi(argv[2]), g, NULL ), 1); - putchar('\n'); - mpi_print( stdout, g, 1 ); - mpi_free(g); - } - else - wrong_args("--gen-prime mode bits [qbits] "); - putchar('\n'); - } -#endif - break; - - case aGenRandom: - { - int level = argc ? atoi(*argv):0; - int count = argc > 1 ? atoi(argv[1]): 0; - int endless = !count; - - if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 ) - wrong_args("--gen-random 0|1|2 [count]"); - - while( endless || count ) { - byte *p; - /* Wee need a multiple of 3, so that in case of - armored output we get a correct string. No - linefolding is done, as it is best to levae this to - other tools */ - size_t n = !endless && count < 99? count : 99; - - p = gcry_random_bytes (n, level); -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(stdout), O_BINARY ); -#endif - if (opt.armor) { - char *tmp = make_radix64_string (p, n); - fputs (tmp, stdout); - xfree (tmp); - if (n%3 == 1) - putchar ('='); - if (n%3) - putchar ('='); - } else { - fwrite( p, n, 1, stdout ); - } - xfree (p); - if( !endless ) - count -= n; - } - if (opt.armor) - putchar ('\n'); - } - break; - - case aPrintMD: - if( argc < 1) - wrong_args("--print-md algo [files]"); - { - int all_algos = (**argv=='*' && !(*argv)[1]); - int algo = all_algos? 0 : gcry_md_map_name (*argv); - - if( !algo && !all_algos ) - log_error(_("invalid hash algorithm `%s'\n"), *argv ); - else { - argc--; argv++; - if( !argc ) - print_mds(NULL, algo); - else { - for(; argc; argc--, argv++ ) - print_mds(*argv, algo); - } - } - } - break; - - case aPrintMDs: /* old option */ - if( !argc ) - print_mds(NULL,0); - else { - for(; argc; argc--, argv++ ) - print_mds(*argv,0); - } - break; - - case aListTrustDB: - if( !argc ) - list_trustdb(NULL); - else { - for( ; argc; argc--, argv++ ) - list_trustdb( *argv ); - } - break; - - case aUpdateTrustDB: - if( argc ) - wrong_args("--update-trustdb"); - update_trustdb(); - break; - - case aCheckTrustDB: - /* Old versions allowed for arguments - ignore them */ - check_trustdb(); - break; - - case aFixTrustDB: - log_error("this command is not yet implemented.\n"); - log_error("A workaround is to use \"--export-ownertrust\", remove\n"); - log_error("the trustdb file and do an \"--import-ownertrust\".\n" ); - break; - - case aListTrustPath: - if( !argc ) - wrong_args("--list-trust-path <user-ids>"); - for( ; argc; argc--, argv++ ) { - username = make_username( *argv ); - list_trust_path( username ); - xfree (username); - } - break; - - case aExportOwnerTrust: - if( argc ) - wrong_args("--export-ownertrust"); - export_ownertrust(); - break; - - case aImportOwnerTrust: - if( argc > 1 ) - wrong_args("--import-ownertrust [file]"); - import_ownertrust( argc? *argv:NULL ); - break; - - case aPipeMode: - if ( argc ) - wrong_args ("--pipemode"); - run_in_pipemode (); - break; - - case aRebuildKeydbCaches: - if (argc) - wrong_args ("--rebuild-keydb-caches"); - keydb_rebuild_caches (); - break; - - case aCardStatus: - if (argc) - wrong_args ("--card-status"); - card_status (stdout, NULL, 0); - break; - - case aCardEdit: - if (argc) - { - sl = NULL; - for (argc--, argv++ ; argc; argc--, argv++) - append_to_strlist (&sl, *argv); - card_edit (sl); - free_strlist (sl); - } - else - card_edit (NULL); - break; - - case aChangePIN: - if (!argc) - change_pin (0); - else if (argc == 1) - change_pin ( atoi (*argv)); - else - wrong_args ("--change-pin [no]"); - break; - - case aGPGConfList: - { /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - - if (!config_filename) - config_filename = make_filename (opt.homedir, "gpg.conf", NULL); - - printf ("gpgconf-gpg.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); - - } - break; - - case aListPackets: - opt.list_packets=2; - default: - if( argc > 1 ) - wrong_args(_("[filename]")); - /* Issue some output for the unix newbie */ - if( !fname && !opt.outfile && isatty( fileno(stdin) ) - && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) ) - log_info(_("Go ahead and type your message ...\n")); - - if( !(a = iobuf_open(fname)) ) - log_error(_("can't open `%s'\n"), print_fname_stdin(fname)); - else { - - if( !opt.no_armor ) { - if( use_armor_filter( a ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( a, armor_filter, &afx ); - } - } - if( cmd == aListPackets ) { - set_packet_list_mode(1); - opt.list_packets=1; - } - rc = proc_packets(NULL, a ); - if( rc ) - log_error("processing message failed: %s\n", gpg_strerror (rc) ); - iobuf_close(a); - } - break; - } - - /* cleanup */ - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - g10_exit(0); - return 8; /*NEVER REACHED*/ -} - -/* Note: This function is used by signal handlers!. */ -static void -emergency_cleanup (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM ); -} - - -void -g10_exit( int rc ) -{ - gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); - emergency_cleanup (); - rc = rc? rc : log_get_errorcount(0)? 2 : - g10_errors_seen? 1 : 0; - exit (rc ); -} - - -/* Pretty-print hex hashes. This assumes at least an 80-character - display, but there are a few other similar assumptions in the - display code. */ -static void -print_hex( MD_HANDLE md, int algo, const char *fname ) -{ - int i,n,count,indent=0; - const byte *p; - - if(fname) - indent=printf("%s: ",fname); - - if(indent>40) - { - printf("\n"); - indent=0; - } - - if(algo==DIGEST_ALGO_RMD160) - indent+=printf("RMD160 = "); - else if(algo>0) - indent+=printf("%6s = ", gcry_md_algo_name (algo)); - else - algo=abs(algo); - - count=indent; - - p = gcry_md_read (md, algo); - n = gcry_md_get_algo_dlen (algo); - - count+=printf("%02X",*p++); - - for(i=1;i<n;i++,p++) - { - if(n==16) - { - if(count+2>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - - if(!(i%8)) - count+=printf(" "); - } - else if (n==20) - { - if(!(i%2)) - { - if(count+4>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - } - - if(!(i%10)) - count+=printf(" "); - } - else - { - if(!(i%4)) - { - if(count+8>79) - { - printf("\n%*s",indent," "); - count=indent; - } - else - count+=printf(" "); - } - } - - count+=printf("%02X",*p); - } - - printf("\n"); -} - -static void -print_hashline( MD_HANDLE md, int algo, const char *fname ) -{ - int i, n; - const byte *p; - - if ( fname ) { - for (p = fname; *p; p++ ) { - if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) - printf("%%%02X", *p ); - else - putchar( *p ); - } - } - putchar(':'); - printf("%d:", algo ); - p = gcry_md_read (md, algo ); - n = gcry_md_get_algo_dlen (algo); - for(i=0; i < n ; i++, p++ ) - printf("%02X", *p ); - putchar(':'); - putchar('\n'); -} - -static void -print_mds( const char *fname, int algo ) -{ - FILE *fp; - char buf[1024]; - size_t n; - MD_HANDLE md; - - if( !fname ) { - fp = stdin; -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); -#endif - } - else { - fp = fopen( fname, "rb" ); - } - if( !fp ) { - log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); - return; - } - - gcry_md_open (&md, 0, 0 ); - if( algo ) - gcry_md_enable ( md, algo ); - else { - gcry_md_enable (md, GCRY_MD_MD5 ); - gcry_md_enable (md, GCRY_MD_SHA1 ); - gcry_md_enable (md, GCRY_MD_RMD160 ); -#ifdef USE_SHA256 - gcry_md_enable (md, GCRY_MD_SHA256 ); -#endif -#ifdef USE_SHA512 - gcry_md_enable (md, GCRY_MD_SHA384 ); - gcry_md_enable (md, GCRY_MD_SHA512 ); -#endif - } - - while( (n=fread( buf, 1, DIM(buf), fp )) ) - gcry_md_write (md, buf, n); - if( ferror(fp) ) - log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) ); - else { - gcry_md_final (md); - if ( opt.with_colons ) { - if ( algo ) - print_hashline( md, algo, fname ); - else { - print_hashline( md, GCRY_MD_MD5, fname ); - print_hashline( md, GCRY_MD_SHA1, fname ); - print_hashline( md, GCRY_MD_RMD160, fname ); -#ifdef USE_SHA256 - print_hashline( md, GCRY_MD_SHA256, fname ); -#endif -#ifdef USE_SHA512 - print_hashline( md, GCRY_MD_SHA384, fname ); - print_hashline( md, GCRY_MD_SHA512, fname ); -#endif - } - } - else { - if( algo ) - print_hex(md,-algo,fname); - else { - print_hex( md, GCRY_MD_MD5, fname ); - print_hex( md, GCRY_MD_SHA1, fname ); - print_hex( md, GCRY_MD_RMD160, fname ); -#ifdef USE_SHA256 - print_hex( md, GCRY_MD_SHA256, fname ); -#endif -#ifdef USE_SHA512 - print_hex( md, GCRY_MD_SHA384, fname ); - print_hex( md, GCRY_MD_SHA512, fname ); -#endif - } - } - } - gcry_md_close (md); - - if( fp != stdin ) - fclose(fp); -} - - -/**************** - * Check the supplied name,value string and add it to the notation - * data to be used for signatures. which==0 for sig notations, and 1 - * for cert notations. -*/ -static void -add_notation_data( const char *string, int which ) -{ - const char *s; - STRLIST sl,*notation_data; - int critical=0; - int highbit=0; - int saw_at=0; - - if(which) - notation_data=&opt.cert_notation_data; - else - notation_data=&opt.sig_notation_data; - - if( *string == '!' ) { - critical = 1; - string++; - } - - /* If and when the IETF assigns some official name tags, we'll - have to add them here. */ - - for( s=string ; *s != '='; s++ ) - { - if( *s=='@') - saw_at=1; - - if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) ) - { - log_error(_("a notation name must have only printable characters " - "or spaces, and end with an '='\n") ); - return; - } - } - - if(!saw_at && !opt.expert) - { - log_error( - _("a user notation name must contain the '@' character\n")); - return; - } - - /* we only support printable text - therefore we enforce the use - * of only printable characters (an empty value is valid) */ - for( s++; *s ; s++ ) { - if( *s & 0x80 ) - highbit = 1; - else if( iscntrl(*s) ) { - log_error(_("a notation value must not use " - "any control characters\n") ); - return; - } - } - - if( highbit ) /* must use UTF8 encoding */ - sl = add_to_strlist2( notation_data, string, utf8_strings ); - else - sl = add_to_strlist( notation_data, string ); - - if( critical ) - sl->flags |= 1; -} - - -static void -add_policy_url( const char *string, int which ) -{ - int i,critical=0; - STRLIST sl; - - if(*string=='!') - { - string++; - critical=1; - } - - for(i=0;i<strlen(string);i++) - if(string[i]&0x80 || iscntrl(string[i])) - break; - - if(i==0 || i<strlen(string)) - { - if(which) - log_error(_("the given certification policy URL is invalid\n")); - else - log_error(_("the given signature policy URL is invalid\n")); - } - - if(which) - sl=add_to_strlist( &opt.cert_policy_url, string ); - else - sl=add_to_strlist( &opt.sig_policy_url, string ); - - if(critical) - sl->flags |= 1; -} - - -static void -add_keyserver_url( const char *string, int which ) -{ - int i,critical=0; - STRLIST sl; - - if(*string=='!') - { - string++; - critical=1; - } - - for(i=0;i<strlen(string);i++) - if(string[i]&0x80 || iscntrl(string[i])) - break; - - if(i==0 || i<strlen(string)) - { - if(which) - BUG(); - else - log_error(_("the given signature preferred" - " keyserver URL is invalid\n")); - } - - if(which) - BUG(); - else - sl=add_to_strlist( &opt.sig_keyserver_url, string ); - - if(critical) - sl->flags |= 1; -} - diff --git a/g10/getkey.c b/g10/getkey.c deleted file mode 100644 index f51b8f2df..000000000 --- a/g10/getkey.c +++ /dev/null @@ -1,2618 +0,0 @@ -/* getkey.c - Get a key from the database - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "util.h" -#include "packet.h" -#include "memory.h" -#include "iobuf.h" -#include "keydb.h" -#include "options.h" -#include "main.h" -#include "trustdb.h" -#include "i18n.h" - -#define MAX_PK_CACHE_ENTRIES 200 -#define MAX_UID_CACHE_ENTRIES 200 - -#if MAX_PK_CACHE_ENTRIES < 2 -#error We need the cache for key creation -#endif - - -struct getkey_ctx_s { - int exact; - KBNODE keyblock; - KBPOS kbpos; - KBNODE found_key; /* pointer into some keyblock */ - int last_rc; - int req_usage; - int req_algo; - KEYDB_HANDLE kr_handle; - int not_allocated; - int nitems; - KEYDB_SEARCH_DESC items[1]; -}; - -#if 0 -static struct { - int any; - int okay_count; - int nokey_count; - int error_count; -} lkup_stats[21]; -#endif - -typedef struct keyid_list { - struct keyid_list *next; - u32 keyid[2]; -} *keyid_list_t; - - -#if MAX_PK_CACHE_ENTRIES - typedef struct pk_cache_entry { - struct pk_cache_entry *next; - u32 keyid[2]; - PKT_public_key *pk; - } *pk_cache_entry_t; - static pk_cache_entry_t pk_cache; - static int pk_cache_entries; /* number of entries in pk cache */ - static int pk_cache_disabled; -#endif - -#if MAX_UID_CACHE_ENTRIES < 5 -#error we really need the userid cache -#endif -typedef struct user_id_db { - struct user_id_db *next; - keyid_list_t keyids; - int len; - char name[1]; -} *user_id_db_t; -static user_id_db_t user_id_db; -static int uid_cache_entries; /* number of entries in uid cache */ - -static void merge_selfsigs( KBNODE keyblock ); -static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ); - -#if 0 -static void -print_stats() -{ - int i; - for(i=0; i < DIM(lkup_stats); i++ ) { - if( lkup_stats[i].any ) - fprintf(stderr, - "lookup stats: mode=%-2d ok=%-6d nokey=%-6d err=%-6d\n", - i, - lkup_stats[i].okay_count, - lkup_stats[i].nokey_count, - lkup_stats[i].error_count ); - } -} -#endif - - -void -cache_public_key( PKT_public_key *pk ) -{ -#if MAX_PK_CACHE_ENTRIES - pk_cache_entry_t ce; - u32 keyid[2]; - - if( pk_cache_disabled ) - return; - - if( pk->dont_cache ) - return; - - if( is_ELGAMAL(pk->pubkey_algo) - || pk->pubkey_algo == PUBKEY_ALGO_DSA - || is_RSA(pk->pubkey_algo) ) { - keyid_from_pk( pk, keyid ); - } - else - return; /* don't know how to get the keyid */ - - for( ce = pk_cache; ce; ce = ce->next ) - if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { - if( DBG_CACHE ) - log_debug("cache_public_key: already in cache\n"); - return; - } - - if( pk_cache_entries >= MAX_PK_CACHE_ENTRIES ) { - /* fixme: use another algorithm to free some cache slots */ - pk_cache_disabled=1; - if( opt.verbose > 1 ) - log_info(_("too many entries in pk cache - disabled\n")); - return; - } - pk_cache_entries++; - ce = xmalloc ( sizeof *ce ); - ce->next = pk_cache; - pk_cache = ce; - ce->pk = copy_public_key( NULL, pk ); - ce->keyid[0] = keyid[0]; - ce->keyid[1] = keyid[1]; -#endif -} - - -/* - * Return the user ID from the given keyblock. - * We use the primary uid flag which has been set by the merge_selfsigs - * function. The returned value is only valid as long as then given - * keyblock is not changed - */ -static const char * -get_primary_uid ( KBNODE keyblock, size_t *uidlen ) -{ - KBNODE k; - const char *s; - - for (k=keyblock; k; k=k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data - && k->pkt->pkt.user_id->is_primary ) { - *uidlen = k->pkt->pkt.user_id->len; - return k->pkt->pkt.user_id->name; - } - } - /* fixme: returning translatable constants instead of a user ID is - * not good because they are probably not utf-8 encoded. */ - s = _("[User id not found]"); - *uidlen = strlen (s); - return s; -} - - -static void -release_keyid_list ( keyid_list_t k ) -{ - while ( k ) { - keyid_list_t k2 = k->next; - xfree (k); - k = k2; - } -} - -/**************** - * Store the association of keyid and userid - * Feed only public keys to this function. - */ -static void -cache_user_id( KBNODE keyblock ) -{ - user_id_db_t r; - const char *uid; - size_t uidlen; - keyid_list_t keyids = NULL; - KBNODE k; - - for (k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - keyid_list_t a = xcalloc (1, sizeof *a ); - /* Hmmm: For a long list of keyids it might be an advantage - * to append the keys */ - keyid_from_pk( k->pkt->pkt.public_key, a->keyid ); - /* first check for duplicates */ - for(r=user_id_db; r; r = r->next ) { - keyid_list_t b = r->keyids; - for ( b = r->keyids; b; b = b->next ) { - if( b->keyid[0] == a->keyid[0] - && b->keyid[1] == a->keyid[1] ) { - if( DBG_CACHE ) - log_debug("cache_user_id: already in cache\n"); - release_keyid_list ( keyids ); - xfree ( a ); - return; - } - } - } - /* now put it into the cache */ - a->next = keyids; - keyids = a; - } - } - if ( !keyids ) - BUG (); /* No key no fun */ - - - uid = get_primary_uid ( keyblock, &uidlen ); - - if( uid_cache_entries >= MAX_UID_CACHE_ENTRIES ) { - /* fixme: use another algorithm to free some cache slots */ - r = user_id_db; - user_id_db = r->next; - release_keyid_list ( r->keyids ); - xfree (r); - uid_cache_entries--; - } - r = xmalloc ( sizeof *r + uidlen-1 ); - r->keyids = keyids; - r->len = uidlen; - memcpy(r->name, uid, r->len); - r->next = user_id_db; - user_id_db = r; - uid_cache_entries++; -} - - -void -getkey_disable_caches() -{ -#if MAX_PK_CACHE_ENTRIES - { - pk_cache_entry_t ce, ce2; - - for( ce = pk_cache; ce; ce = ce2 ) { - ce2 = ce->next; - free_public_key( ce->pk ); - xfree ( ce ); - } - pk_cache_disabled=1; - pk_cache_entries = 0; - pk_cache = NULL; - } -#endif - /* fixme: disable user id cache ? */ -} - - -static void -pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock ) -{ - KBNODE a = ctx->found_key ? ctx->found_key : keyblock; - - assert ( a->pkt->pkttype == PKT_PUBLIC_KEY - || a->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - - copy_public_key ( pk, a->pkt->pkt.public_key ); -} - -static void -sk_from_block ( GETKEY_CTX ctx, - PKT_secret_key *sk, KBNODE keyblock ) -{ - KBNODE a = ctx->found_key ? ctx->found_key : keyblock; - - assert ( a->pkt->pkttype == PKT_SECRET_KEY - || a->pkt->pkttype == PKT_SECRET_SUBKEY ); - - copy_secret_key( sk, a->pkt->pkt.secret_key); -} - - -/**************** - * Get a public key and store it into the allocated pk - * can be called with PK set to NULL to just read it into some - * internal structures. - */ -int -get_pubkey( PKT_public_key *pk, u32 *keyid ) -{ - int internal = 0; - int rc = 0; - -#if MAX_PK_CACHE_ENTRIES - { /* Try to get it from the cache */ - pk_cache_entry_t ce; - for( ce = pk_cache; ce; ce = ce->next ) { - if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { - if( pk ) - copy_public_key( pk, ce->pk ); - return 0; - } - } - } -#endif - /* more init stuff */ - if( !pk ) { - pk = xcalloc (1, sizeof *pk ); - internal++; - } - - - /* do a lookup */ - { struct getkey_ctx_s ctx; - KBNODE kb = NULL; - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1; /* use the key ID exactly as given */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - ctx.req_algo = pk->req_algo; - ctx.req_usage = pk->req_usage; - rc = lookup( &ctx, &kb, 0 ); - if ( !rc ) { - pk_from_block ( &ctx, pk, kb ); - } - get_pubkey_end( &ctx ); - release_kbnode ( kb ); - } - if( !rc ) - goto leave; - - rc = GPG_ERR_NO_PUBKEY; - - leave: - if( !rc ) - cache_public_key( pk ); - if( internal ) - free_public_key(pk); - return rc; -} - - -/* Get a public key and store it into the allocated pk. This function - differs from get_pubkey() in that it does not do a check of the key - to avoid recursion. It should be used only in very certain cases. */ -int -get_pubkey_fast (PKT_public_key *pk, u32 *keyid) -{ - int rc = 0; - KEYDB_HANDLE hd; - KBNODE keyblock; - - assert (pk); -#if MAX_PK_CACHE_ENTRIES - { /* Try to get it from the cache */ - pk_cache_entry_t ce; - - for (ce = pk_cache; ce; ce = ce->next) - { - if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1]) - { - if (pk) - copy_public_key (pk, ce->pk); - return 0; - } - } - } -#endif - - hd = keydb_new (0); - rc = keydb_search_kid (hd, keyid); - if (rc == -1) - { - keydb_release (hd); - return GPG_ERR_NO_PUBKEY; - } - rc = keydb_get_keyblock (hd, &keyblock); - keydb_release (hd); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - return GPG_ERR_NO_PUBKEY; - } - - assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - copy_public_key (pk, keyblock->pkt->pkt.public_key ); - release_kbnode (keyblock); - - /* Not caching key here since it won't have all of the fields - properly set. */ - - return 0; -} - - - -KBNODE -get_pubkeyblock( u32 *keyid ) -{ - struct getkey_ctx_s ctx; - int rc = 0; - KBNODE keyblock = NULL; - - memset( &ctx, 0, sizeof ctx ); - /* no need to set exact here because we want the entire block */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - rc = lookup( &ctx, &keyblock, 0 ); - get_pubkey_end( &ctx ); - - return rc ? NULL : keyblock; -} - - - - -/**************** - * Get a secret key and store it into sk - */ -int -get_seckey( PKT_secret_key *sk, u32 *keyid ) -{ - int rc; - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1; /* use the key ID exactly as given */ - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; - ctx.items[0].u.kid[0] = keyid[0]; - ctx.items[0].u.kid[1] = keyid[1]; - ctx.req_algo = sk->req_algo; - ctx.req_usage = sk->req_usage; - rc = lookup( &ctx, &kb, 1 ); - if ( !rc ) { - sk_from_block ( &ctx, sk, kb ); - } - get_seckey_end( &ctx ); - release_kbnode ( kb ); - - if( !rc ) { - /* check the secret key (this may prompt for a passprase to - * unlock the secret key - */ - rc = check_secret_key( sk, 0 ); - } - - return rc; -} - - -/**************** - * Check whether the secret key is available. This is just a fast - * check and does not tell us whether the secret key is valid. It - * merely tells other whether there is some secret key. - * Returns: 0 := key is available - * GPG_ERR_NO_SECKEY := not availabe - */ -int -seckey_available( u32 *keyid ) -{ - int rc; - KEYDB_HANDLE hd = keydb_new (1); - - rc = keydb_search_kid (hd, keyid); - if ( rc == -1 ) - rc = GPG_ERR_NO_SECKEY; - keydb_release (hd); - return rc; -} - - -/**************** - * Return the type of the user id: - * - * Please use the constants KEYDB_SERCH_MODE_xxx - * 0 = Invalid user ID - * 1 = exact match - * 2 = match a substring - * 3 = match an email address - * 4 = match a substring of an email address - * 5 = match an email address, but compare from end - * 6 = word match mode - * 10 = it is a short KEYID (don't care about keyid[0]) - * 11 = it is a long KEYID - * 12 = it is a trustdb index (keyid is looked up) - * 16 = it is a 16 byte fingerprint - * 20 = it is a 20 byte fingerprint - * 21 = Unified fingerprint :fpr:pk_algo: - * (We don't use pk_algo yet) - * - * Rules used: - * - If the username starts with 8,9,16 or 17 hex-digits (the first one - * must be in the range 0..9), this is considered a keyid; depending - * on the length a short or complete one. - * - If the username starts with 32,33,40 or 41 hex-digits (the first one - * must be in the range 0..9), this is considered a fingerprint. - * - If the username starts with a left angle, we assume it is a complete - * email address and look only at this part. - * - If the username starts with a colon we assume it is a unified - * key specfification. - * - If the username starts with a '.', we assume it is the ending - * part of an email address - * - If the username starts with an '@', we assume it is a part of an - * email address - * - If the userid start with an '=' an exact compare is done. - * - If the userid starts with a '*' a case insensitive substring search is - * done (This is the default). - * - If the userid starts with a '+' we will compare individual words - * and a match requires that all the words are in the userid. - * Words are delimited by white space or "()<>[]{}.@-+_,;/&!" - * (note that you can't search for these characters). Compare - * is not case sensitive. - */ - -int -classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc ) -{ - const char *s; - int hexprefix = 0; - int hexlength; - int mode = 0; - KEYDB_SEARCH_DESC dummy_desc; - - if (!desc) - desc = &dummy_desc; - - /* clear the structure so that the mode field is set to zero unless - * we set it to the correct value right at the end of this function */ - memset (desc, 0, sizeof *desc); - - /* skip leading spaces. Fixme: what is with trailing spaces? */ - for(s = name; *s && spacep (s); s++ ) - ; - - switch (*s) { - case 0: /* empty string is an error */ - return 0; - - case '.': /* an email address, compare from end */ - mode = KEYDB_SEARCH_MODE_MAILEND; - s++; - desc->u.name = s; - break; - - case '<': /* an email address */ - mode = KEYDB_SEARCH_MODE_MAIL; - desc->u.name = s; - break; - - case '@': /* part of an email address */ - mode = KEYDB_SEARCH_MODE_MAILSUB; - s++; - desc->u.name = s; - break; - - case '=': /* exact compare */ - mode = KEYDB_SEARCH_MODE_EXACT; - s++; - desc->u.name = s; - break; - - case '*': /* case insensitive substring search */ - mode = KEYDB_SEARCH_MODE_SUBSTR; - s++; - desc->u.name = s; - break; - - case '+': /* compare individual words */ - mode = KEYDB_SEARCH_MODE_WORDS; - s++; - desc->u.name = s; - break; - - case '#': /* local user id */ - return 0; /* This is now obsolete and van't not be used anymore*/ - - case ':': /*Unified fingerprint */ - { - const char *se, *si; - int i; - - se = strchr( ++s,':'); - if ( !se ) - return 0; - for (i=0,si=s; si < se; si++, i++ ) { - if ( !strchr("01234567890abcdefABCDEF", *si ) ) - return 0; /* invalid digit */ - } - if (i != 32 && i != 40) - return 0; /* invalid length of fpr*/ - for (i=0,si=s; si < se; i++, si +=2) - desc->u.fpr[i] = hextobyte(si); - for ( ; i < 20; i++) - desc->u.fpr[i]= 0; - s = se + 1; - mode = KEYDB_SEARCH_MODE_FPR; - } - break; - - default: - if (s[0] == '0' && s[1] == 'x') { - hexprefix = 1; - s += 2; - } - - hexlength = strspn(s, "0123456789abcdefABCDEF"); - if (hexlength >= 8 && s[hexlength] =='!') { - desc->exact = 1; - hexlength++; /* just for the following check */ - } - - /* check if a hexadecimal number is terminated by EOS or blank */ - if (hexlength && s[hexlength] && !spacep (s+hexlength)) { - if (hexprefix) /* a "0x" prefix without correct */ - return 0; /* termination is an error */ - else /* The first chars looked like */ - hexlength = 0; /* a hex number, but really were not. */ - } - - if (desc->exact) - hexlength--; - - if (hexlength == 8 - || (!hexprefix && hexlength == 9 && *s == '0')){ - /* short keyid */ - if (hexlength == 9) - s++; - desc->u.kid[0] = 0; - desc->u.kid[1] = strtoul( s, NULL, 16 ); - mode = KEYDB_SEARCH_MODE_SHORT_KID; - } - else if (hexlength == 16 - || (!hexprefix && hexlength == 17 && *s == '0')) { - /* complete keyid */ - char buf[9]; - if (hexlength == 17) - s++; - mem2str(buf, s, 9 ); - desc->u.kid[0] = strtoul( buf, NULL, 16 ); - desc->u.kid[1] = strtoul( s+8, NULL, 16 ); - mode = KEYDB_SEARCH_MODE_LONG_KID; - } - else if (hexlength == 32 || (!hexprefix && hexlength == 33 - && *s == '0')) { - /* md5 fingerprint */ - int i; - if (hexlength == 33) - s++; - memset(desc->u.fpr+16, 0, 4); - for (i=0; i < 16; i++, s+=2) { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR16; - } - else if (hexlength == 40 || (!hexprefix && hexlength == 41 - && *s == '0')) { - /* sha1/rmd160 fingerprint */ - int i; - if (hexlength == 41) - s++; - for (i=0; i < 20; i++, s+=2) { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR20; - } - else { - if (hexprefix) /* This was a hex number with a prefix */ - return 0; /* and a wrong length */ - - desc->exact = 0; - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBSTR; /* default mode */ - } - } - - desc->mode = mode; - return mode; -} - - -static int -skip_disabled(void *dummy,u32 *keyid) -{ - int rc,disabled=0; - PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key)); - - rc = get_pubkey(pk, keyid); - if(rc) - { - log_error("error checking disabled status of %08lX: %s\n", - (ulong)keyid[1],gpg_strerror (rc)); - goto leave; - } - - disabled=pk_is_disabled(pk); - - leave: - free_public_key(pk); - return disabled; -} - -/**************** - * Try to get the pubkey by the userid. This function looks for the - * first pubkey certificate which has the given name in a user_id. - * if pk/sk has the pubkey algo set, the function will only return - * a pubkey with that algo. - * The caller should provide storage for either the pk or the sk. - * If ret_kb is not NULL the function will return the keyblock there. - */ - -static int -key_byname( GETKEY_CTX *retctx, STRLIST namelist, - PKT_public_key *pk, PKT_secret_key *sk, - int secmode, int include_disabled, - KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd ) -{ - int rc = 0; - int n; - STRLIST r; - GETKEY_CTX ctx; - KBNODE help_kb = NULL; - - if( retctx ) {/* reset the returned context in case of error */ - assert (!ret_kdbhd); /* not allowed because the handle is - stored in the context */ - *retctx = NULL; - } - if (ret_kdbhd) - *ret_kdbhd = NULL; - - /* build the search context */ - for(n=0, r=namelist; r; r = r->next ) - n++; - ctx = xcalloc (1,sizeof *ctx + (n-1)*sizeof ctx->items ); - ctx->nitems = n; - - for(n=0, r=namelist; r; r = r->next, n++ ) { - classify_user_id (r->d, &ctx->items[n]); - - if (ctx->items[n].exact) - ctx->exact = 1; - if (!ctx->items[n].mode) { - xfree (ctx); - return GPG_ERR_INV_USER_ID; - } - if(!include_disabled - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_LONG_KID - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16 - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20 - && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR) - ctx->items[n].skipfnc=skip_disabled; - } - - ctx->kr_handle = keydb_new (secmode); - if ( !ret_kb ) - ret_kb = &help_kb; - - if( secmode ) { - if (sk) { - ctx->req_algo = sk->req_algo; - ctx->req_usage = sk->req_usage; - } - rc = lookup( ctx, ret_kb, 1 ); - if ( !rc && sk ) { - sk_from_block ( ctx, sk, *ret_kb ); - } - } - else { - if (pk) { - ctx->req_algo = pk->req_algo; - ctx->req_usage = pk->req_usage; - } - rc = lookup( ctx, ret_kb, 0 ); - if ( !rc && pk ) { - pk_from_block ( ctx, pk, *ret_kb ); - } - } - - release_kbnode ( help_kb ); - - if (retctx) /* caller wants the context */ - *retctx = ctx; - else { - if (ret_kdbhd) { - *ret_kdbhd = ctx->kr_handle; - ctx->kr_handle = NULL; - } - get_pubkey_end (ctx); - } - - return rc; -} - -/* - * Find a public key from NAME and returh the keyblock or the key. - * If ret_kdb is not NULL, the KEYDB handle used to locate this keyblock is - * returned and the caller is responsible for closing it. - */ -int -get_pubkey_byname (PKT_public_key *pk, - const char *name, KBNODE *ret_keyblock, - KEYDB_HANDLE *ret_kdbhd, int include_disabled ) -{ - int rc; - STRLIST namelist = NULL; - - add_to_strlist( &namelist, name ); - rc = key_byname( NULL, namelist, pk, NULL, 0, - include_disabled, ret_keyblock, ret_kdbhd); - free_strlist( namelist ); - return rc; -} - -int -get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk, - STRLIST names, KBNODE *ret_keyblock ) -{ - return key_byname( retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL); -} - -int -get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ) -{ - int rc; - - rc = lookup( ctx, ret_keyblock, 0 ); - if ( !rc && pk && ret_keyblock ) - pk_from_block ( ctx, pk, *ret_keyblock ); - - return rc; -} - - -void -get_pubkey_end( GETKEY_CTX ctx ) -{ - if( ctx ) { - memset (&ctx->kbpos, 0, sizeof ctx->kbpos); - keydb_release (ctx->kr_handle); - if( !ctx->not_allocated ) - xfree ( ctx ); - } -} - - - - -/**************** - * Search for a key with the given fingerprint. - * FIXME: - * We should replace this with the _byname function. This can be done - * by creating a userID conforming to the unified fingerprint style. - */ -int -get_pubkey_byfprint( PKT_public_key *pk, - const byte *fprint, size_t fprint_len) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1 ; - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, &kb, 0 ); - if (!rc && pk ) - pk_from_block ( &ctx, pk, kb ); - release_kbnode ( kb ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - return rc; -} - - -/* Get a public key and store it into the allocated pk. This function - differs from get_pubkey_byfprint() in that it does not do a check - of the key to avoid recursion. It should be used only in very - certain cases. PK may be NULL to check just for the existance of - the key. */ -int -get_pubkey_byfprint_fast (PKT_public_key *pk, - const byte *fprint, size_t fprint_len) -{ - int rc = 0; - KEYDB_HANDLE hd; - KBNODE keyblock; - byte fprbuf[MAX_FINGERPRINT_LEN]; - int i; - - for (i=0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++) - fprbuf[i] = fprint[i]; - while (i < MAX_FINGERPRINT_LEN) - fprbuf[i++] = 0; - - hd = keydb_new (0); - rc = keydb_search_fpr (hd, fprbuf); - if (rc == -1) - { - keydb_release (hd); - return GPG_ERR_NO_PUBKEY; - } - rc = keydb_get_keyblock (hd, &keyblock); - keydb_release (hd); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - return GPG_ERR_NO_PUBKEY; - } - - assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY - || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - if (pk) - copy_public_key (pk, keyblock->pkt->pkt.public_key ); - release_kbnode (keyblock); - - /* Not caching key here since it won't have all of the fields - properly set. */ - - return 0; -} - -/**************** - * Search for a key with the given fingerprint and return the - * complete keyblock which may have more than only this key. - */ -int -get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, - size_t fprint_len ) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - - memset( &ctx, 0, sizeof ctx ); - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, ret_keyblock, 0 ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - - return rc; -} - - -/**************** - * Get a secret key by name and store it into sk - * If NAME is NULL use the default key - */ -static int -get_seckey_byname2( GETKEY_CTX *retctx, - PKT_secret_key *sk, const char *name, int unprotect, - KBNODE *retblock ) -{ - STRLIST namelist = NULL; - int rc; - - if( !name && opt.def_secret_key && *opt.def_secret_key ) { - add_to_strlist( &namelist, opt.def_secret_key ); - rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); - } - else if( !name ) { /* use the first one as default key */ - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - assert (!retctx ); /* do we need this at all */ - assert (!retblock); - memset( &ctx, 0, sizeof ctx ); - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = KEYDB_SEARCH_MODE_FIRST; - rc = lookup( &ctx, &kb, 1 ); - if (!rc && sk ) - sk_from_block ( &ctx, sk, kb ); - release_kbnode ( kb ); - get_seckey_end( &ctx ); - } - else { - add_to_strlist( &namelist, name ); - rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); - } - - free_strlist( namelist ); - - if( !rc && unprotect ) - rc = check_secret_key( sk, 0 ); - - return rc; -} - -int -get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ) -{ - return get_seckey_byname2 ( NULL, sk, name, unlock, NULL ); -} - - -int -get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk, - STRLIST names, KBNODE *ret_keyblock ) -{ - return key_byname( retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL ); -} - - -int -get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock ) -{ - int rc; - - rc = lookup( ctx, ret_keyblock, 1 ); - if ( !rc && sk && ret_keyblock ) - sk_from_block ( ctx, sk, *ret_keyblock ); - - return rc; -} - - -void -get_seckey_end( GETKEY_CTX ctx ) -{ - get_pubkey_end( ctx ); -} - - -/**************** - * Search for a key with the given fingerprint. - * FIXME: - * We should replace this with the _byname function. Thiscsan be done - * by creating a userID conforming to the unified fingerprint style. - */ -int -get_seckey_byfprint( PKT_secret_key *sk, - const byte *fprint, size_t fprint_len) -{ - int rc; - - if( fprint_len == 20 || fprint_len == 16 ) { - struct getkey_ctx_s ctx; - KBNODE kb = NULL; - - memset( &ctx, 0, sizeof ctx ); - ctx.exact = 1 ; - ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); - ctx.nitems = 1; - ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16 - : KEYDB_SEARCH_MODE_FPR20; - memcpy( ctx.items[0].u.fpr, fprint, fprint_len ); - rc = lookup( &ctx, &kb, 1 ); - if (!rc && sk ) - sk_from_block ( &ctx, sk, kb ); - release_kbnode ( kb ); - get_pubkey_end( &ctx ); - } - else - rc = GPG_ERR_GENERAL; /* Oops */ - return rc; -} - - -/************************************************ - ************* Merging stuff ******************** - ************************************************/ - -/**************** - * merge all selfsignatures with the keys. - * FIXME: replace this at least for the public key parts - * by merge_selfsigs. - * It is still used in keyedit.c and - * at 2 or 3 other places - check whether it is really needed. - * It might be needed by the key edit and import stuff because - * the keylock is changed. - */ -void -merge_keys_and_selfsig( KBNODE keyblock ) -{ - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - PKT_signature *sig; - KBNODE k; - u32 kid[2] = { 0, 0 }; - u32 sigdate = 0; - - if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) { - /* divert to our new function */ - merge_selfsigs (keyblock); - return; - } - /* still need the old one because the new one can't handle secret keys */ - - for(k=keyblock; k; k = k->next ) { - if( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - pk = k->pkt->pkt.public_key; sk = NULL; - if( pk->version < 4 ) - pk = NULL; /* not needed for old keys */ - else if( k->pkt->pkttype == PKT_PUBLIC_KEY ) - keyid_from_pk( pk, kid ); - else if( !pk->expiredate ) { /* and subkey */ - /* insert the expiration date here */ - /*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid );*/ - } - sigdate = 0; - } - else if( k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY ) { - pk = NULL; sk = k->pkt->pkt.secret_key; - if( sk->version < 4 ) - sk = NULL; - else if( k->pkt->pkttype == PKT_SECRET_KEY ) - keyid_from_sk( sk, kid ); - sigdate = 0; - } - else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE - && (sig=k->pkt->pkt.signature)->sig_class >= 0x10 - && sig->sig_class <= 0x30 && sig->version > 3 - && !(sig->sig_class == 0x18 || sig->sig_class == 0x28) - && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) { - /* okay this is a self-signature which can be used. - * This is not used for subkey binding signature, becuase this - * is done above. - * FIXME: We should only use this if the signature is valid - * but this is time consuming - we must provide another - * way to handle this - */ - const byte *p; - u32 ed; - - p = parse_sig_subpkt( sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL ); - if( pk ) { - ed = p? pk->timestamp + buffer_to_u32(p):0; - if( sig->timestamp > sigdate ) { - pk->expiredate = ed; - sigdate = sig->timestamp; - } - } - else { - ed = p? sk->timestamp + buffer_to_u32(p):0; - if( sig->timestamp > sigdate ) { - sk->expiredate = ed; - sigdate = sig->timestamp; - } - } - } - - if(pk && (pk->expiredate==0 || - (pk->max_expiredate && pk->expiredate>pk->max_expiredate))) - pk->expiredate=pk->max_expiredate; - - if(sk && (sk->expiredate==0 || - (sk->max_expiredate && sk->expiredate>sk->max_expiredate))) - sk->expiredate=sk->max_expiredate; - } -} - -/* - * Apply information from SIGNODE (which is the valid self-signature - * associated with that UID) to the UIDNODE: - * - wether the UID has been revoked - * - assumed creation date of the UID - * - temporary store the keyflags here - * - temporary store the key expiration time here - * - mark whether the primary user ID flag hat been set. - * - store the preferences - */ -static void -fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) -{ - PKT_user_id *uid = uidnode->pkt->pkt.user_id; - PKT_signature *sig = signode->pkt->pkt.signature; - const byte *p, *sym, *hash, *zip; - size_t n, nsym, nhash, nzip; - - uid->created = 0; /* not created == invalid */ - if ( IS_UID_REV ( sig ) ) { - uid->is_revoked = 1; - return; /* has been revoked */ - } - - uid->created = sig->timestamp; /* this one is okay */ - uid->selfsigversion = sig->version; - /* If we got this far, it's not expired :) */ - uid->is_expired = 0; - uid->expiredate = sig->expiredate; - - /* store the key flags in the helper variable for later processing */ - uid->help_key_usage = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - uid->help_key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - uid->help_key_usage |= PUBKEY_USAGE_ENC; - /* Note: we do not set the CERT flag here because it can be assumed - * that thre is no real policy to set it. */ - if ( (*p & 0x20) ) - uid->help_key_usage |= PUBKEY_USAGE_AUTH; - } - - /* ditto or the key expiration */ - uid->help_key_expire = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - uid->help_key_expire = keycreated + buffer_to_u32(p); - } - - /* Set the primary user ID flag - we will later wipe out some - * of them to only have one in our keyblock */ - uid->is_primary = 0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL ); - if ( p && *p ) - uid->is_primary = 2; - /* We could also query this from the unhashed area if it is not in - * the hased area and then later try to decide which is the better - * there should be no security problem with this. - * For now we only look at the hashed one. - */ - - /* Now build the preferences list. These must come from the - hashed section so nobody can modify the ciphers a key is - willing to accept. */ - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_SYM, &n ); - sym = p; nsym = p?n:0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_HASH, &n ); - hash = p; nhash = p?n:0; - p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_COMPR, &n ); - zip = p; nzip = p?n:0; - if (uid->prefs) - xfree (uid->prefs); - n = nsym + nhash + nzip; - if (!n) - uid->prefs = NULL; - else { - uid->prefs = xmalloc (sizeof (*uid->prefs) * (n+1)); - n = 0; - for (; nsym; nsym--, n++) { - uid->prefs[n].type = PREFTYPE_SYM; - uid->prefs[n].value = *sym++; - } - for (; nhash; nhash--, n++) { - uid->prefs[n].type = PREFTYPE_HASH; - uid->prefs[n].value = *hash++; - } - for (; nzip; nzip--, n++) { - uid->prefs[n].type = PREFTYPE_ZIP; - uid->prefs[n].value = *zip++; - } - uid->prefs[n].type = PREFTYPE_NONE; /* end of list marker */ - uid->prefs[n].value = 0; - } - - /* see whether we have the MDC feature */ - uid->mdc_feature = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n); - if (p && n && (p[0] & 0x01)) - uid->mdc_feature = 1; - - /* and the keyserver modify flag */ - uid->ks_modify = 1; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n); - if (p && n && (p[0] & 0x80)) - uid->ks_modify = 0; -} - -static void -merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) -{ - PKT_public_key *pk = NULL; - KBNODE k; - u32 kid[2]; - u32 sigdate, uiddate, uiddate2; - KBNODE signode, uidnode, uidnode2; - u32 curtime = make_timestamp (); - unsigned int key_usage = 0; - u32 keytimestamp = 0; - u32 key_expire = 0; - int key_expire_seen = 0; - byte sigversion = 0; - - *r_revoked = 0; - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) - BUG (); - pk = keyblock->pkt->pkt.public_key; - keytimestamp = pk->timestamp; - - keyid_from_pk( pk, kid ); - pk->main_keyid[0] = kid[0]; - pk->main_keyid[1] = kid[1]; - - if ( pk->version < 4 ) { - /* before v4 the key packet itself contains the expiration - * date and there was no way to change it, so we start with - * the one from the key packet */ - key_expire = pk->max_expiredate; - key_expire_seen = 1; - } - - /* first pass: find the latest direct key self-signature. - * We assume that the newest one overrides all others - */ - - /* In case this key was already merged */ - xfree (pk->revkey); - pk->revkey=NULL; - pk->numrevkeys=0; - - signode = NULL; - sigdate = 0; /* helper to find the latest signature */ - for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) { - if ( k->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( IS_KEY_REV (sig) ){ - /* key has been revoked - there is no way to override - * such a revocation, so we theoretically can stop now. - * We should not cope with expiration times for revocations - * here because we have to assume that an attacker can - * generate all kinds of signatures. However due to the - * fact that the key has been revoked it does not harm - * either and by continuing we gather some more info on - * that key. - */ - *r_revoked = 1; - } - else if ( IS_KEY_SIG (sig) ) { - /* Add any revocation keys onto the pk. This is - particularly interesting since we normally only - get data from the most recent 1F signature, but - you need multiple 1F sigs to properly handle - revocation keys (PGP does it this way, and a - revocation key could be sensitive and hence in a - different signature). */ - if(sig->revkey) { - int i; - - pk->revkey= - xrealloc(pk->revkey,sizeof(struct revocation_key)* - (pk->numrevkeys+sig->numrevkeys)); - - for(i=0;i<sig->numrevkeys;i++) - memcpy(&pk->revkey[pk->numrevkeys++], - sig->revkey[i], - sizeof(struct revocation_key)); - } - - if( sig->timestamp >= sigdate ) { - if(sig->flags.expired) - ; /* signature has expired - ignore it */ - else { - sigdate = sig->timestamp; - signode = k; - if( sig->version > sigversion ) - sigversion = sig->version; - - } - } - } - } - } - } - - /* Remove dupes from the revocation keys */ - - if(pk->revkey) - { - int i,j,x,changed=0; - - for(i=0;i<pk->numrevkeys;i++) - { - for(j=i+1;j<pk->numrevkeys;j++) - { - if(memcmp(&pk->revkey[i],&pk->revkey[j], - sizeof(struct revocation_key))==0) - { - /* remove j */ - - for(x=j;x<pk->numrevkeys-1;x++) - pk->revkey[x]=pk->revkey[x+1]; - - pk->numrevkeys--; - j--; - changed=1; - } - } - } - - if(changed) - pk->revkey=xrealloc(pk->revkey, - pk->numrevkeys*sizeof(struct revocation_key)); - } - - if ( signode ) { - /* some information from a direct key signature take precedence - * over the same information given in UID sigs. - */ - PKT_signature *sig = signode->pkt->pkt.signature; - const byte *p; - size_t n; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - key_expire = keytimestamp + buffer_to_u32(p); - key_expire_seen = 1; - } - - /* mark that key as valid: one direct key signature should - * render a key as valid */ - pk->is_valid = 1; - } - - /* pass 1.5: look for key revocation signatures that were not made - by the key (i.e. did a revocation key issue a revocation for - us?). Only bother to do this if there is a revocation key in - the first place. */ - - if(pk->revkey) - for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) - { - if ( k->pkt->pkttype == PKT_SIGNATURE ) - { - PKT_signature *sig = k->pkt->pkt.signature; - - if(IS_KEY_REV(sig) && - (sig->keyid[0]!=kid[0] || sig->keyid[1]!=kid[1])) - { - /* Failure here means the sig did not verify, is was - not issued by a revocation key, or a revocation - key loop was broken. */ - - if(check_revocation_keys(pk,sig)==0) - *r_revoked=1; - - /* In the future handle subkey and cert revocations? - PGP doesn't, but it's in 2440. */ - } - } - } - - /* second pass: look at the self-signature of all user IDs */ - signode = uidnode = NULL; - sigdate = 0; /* helper to find the latest signature in one user ID */ - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - if ( uidnode && signode ) - { - fixup_uidnode ( uidnode, signode, keytimestamp ); - pk->is_valid=1; - } - uidnode = k; - signode = NULL; - sigdate = 0; - } - else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) { - PKT_signature *sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( (IS_UID_SIG (sig) || IS_UID_REV (sig)) - && sig->timestamp >= sigdate ) { - /* Note: we allow to invalidate cert revocations - * by a newer signature. An attacker can't use this - * because a key should be revoced with a key revocation. - * The reason why we have to allow for that is that at - * one time an email address may become invalid but later - * the same email address may become valid again (hired, - * fired, hired again). - */ - if(sig->flags.expired) { - /* Expired uids don't get to be primary unless - they are the only uid there is. */ - uidnode->pkt->pkt.user_id->is_primary=0; - uidnode->pkt->pkt.user_id->is_expired=1; - uidnode->pkt->pkt.user_id->expiredate=sig->expiredate; - } - else { - sigdate = sig->timestamp; - signode = k; - if( sig->version > sigversion ) - sigversion = sig->version; - } - } - } - } - } - if ( uidnode && signode ) { - fixup_uidnode ( uidnode, signode, keytimestamp ); - pk->is_valid = 1; - } - - /* If the key isn't valid yet, and we have - --allow-non-selfsigned-uid set, then force it valid. */ - if(!pk->is_valid && opt.allow_non_selfsigned_uid) - { - if(opt.verbose) - log_info(_("Invalid key %08lX made valid by " - "--allow-non-selfsigned-uid\n"), - (ulong)keyid_from_pk(pk,NULL)); - - pk->is_valid = 1; - } - - /* The key STILL isn't valid, so try and find an ultimately - trusted signature. */ - if(!pk->is_valid) - { - uidnode=NULL; - - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k=k->next) - { - if ( k->pkt->pkttype == PKT_USER_ID ) - uidnode = k; - else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) - { - PKT_signature *sig = k->pkt->pkt.signature; - - if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1]) - { - PKT_public_key *ultimate_pk; - - ultimate_pk=xcalloc (1,sizeof(*ultimate_pk)); - - /* We don't want to use the full get_pubkey to - avoid infinite recursion in certain cases. - There is no reason to check that an ultimately - trusted key is still valid - if it has been - revoked or the user should also renmove the - ultimate trust flag. */ - if(get_pubkey_fast(ultimate_pk,sig->keyid)==0 - && check_key_signature2(keyblock,k,ultimate_pk, - NULL, NULL, NULL, NULL)==0 - && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) - { - free_public_key(ultimate_pk); - pk->is_valid=1; - break; - } - - free_public_key(ultimate_pk); - } - } - } - } - - /* Record the highest selfsig version so we know if this is a v3 - key through and through, or a v3 key with a v4 selfsig - somewhere. This is useful in a few places to know if the key - must be treated as PGP2-style or OpenPGP-style. Note that a - selfsig revocation with a higher version number will also raise - this value. This is okay since such a revocation must be - issued by the user (i.e. it cannot be issued by someone else to - modify the key behavior.) */ - - pk->selfsigversion=sigversion; - - /* Now that we had a look at all user IDs we can now get some information - * from those user IDs. - */ - - if ( !key_usage ) { - /* find the latest user ID with key flags set */ - uiddate = 0; /* helper to find the latest user ID */ - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( uid->help_key_usage && uid->created > uiddate ) { - key_usage = uid->help_key_usage; - uiddate = uid->created; - } - } - } - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ - key_usage = openpgp_pk_algo_usage ( pk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ - int x = openpgp_pk_algo_usage ( pk->pubkey_algo ); - if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } - pk->pubkey_usage = key_usage; - - if ( !key_expire_seen ) { - /* find the latest valid user ID with a key expiration set - * Note, that this may be a different one from the above because - * some user IDs may have no expiration date set */ - uiddate = 0; - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( uid->help_key_expire && uid->created > uiddate ) { - key_expire = uid->help_key_expire; - uiddate = uid->created; - } - } - } - } - - /* Currently only v3 keys have a maximum expiration date, but I'll - bet v5 keys get this feature again. */ - if(key_expire==0 || (pk->max_expiredate && key_expire>pk->max_expiredate)) - key_expire=pk->max_expiredate; - - pk->has_expired = key_expire >= curtime? 0 : key_expire; - pk->expiredate = key_expire; - - /* Fixme: we should see how to get rid of the expiretime fields but - * this needs changes at other places too. */ - - /* and now find the real primary user ID and delete all others */ - uiddate = uiddate2 = 0; - uidnode = uidnode2 = NULL; - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID && - !k->pkt->pkt.user_id->attrib_data) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if (uid->is_primary) - { - if(uid->created > uiddate) - { - uiddate = uid->created; - uidnode = k; - } - else if(uid->created==uiddate && uidnode) - { - /* The dates are equal, so we need to do a - different (and arbitrary) comparison. This - should rarely, if ever, happen. It's good to - try and guarantee that two different GnuPG - users with two different keyrings at least pick - the same primary. */ - if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0) - uidnode=k; - } - } - else - { - if(uid->created > uiddate2) - { - uiddate2 = uid->created; - uidnode2 = k; - } - else if(uid->created==uiddate2 && uidnode2) - { - if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0) - uidnode2=k; - } - } - } - } - if ( uidnode ) { - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID && - !k->pkt->pkt.user_id->attrib_data) { - PKT_user_id *uid = k->pkt->pkt.user_id; - if ( k != uidnode ) - uid->is_primary = 0; - } - } - } - else if( uidnode2 ) { - /* none is flagged primary - use the latest user ID we have, - and disambiguate with the arbitrary packet comparison. */ - uidnode2->pkt->pkt.user_id->is_primary = 1; - } - else - { - /* None of our uids were self-signed, so pick the one that - sorts first to be the primary. This is the best we can do - here since there are no self sigs to date the uids. */ - - uidnode = NULL; - - for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) - { - if(k->pkt->pkttype==PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data) - { - if(!uidnode) - { - uidnode=k; - uidnode->pkt->pkt.user_id->is_primary=1; - continue; - } - else - { - if(cmp_user_ids(k->pkt->pkt.user_id, - uidnode->pkt->pkt.user_id)>0) - { - uidnode->pkt->pkt.user_id->is_primary=0; - uidnode=k; - uidnode->pkt->pkt.user_id->is_primary=1; - } - else - k->pkt->pkt.user_id->is_primary=0; /* just to be - safe */ - } - } - } - } -} - - -static void -merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) -{ - PKT_public_key *mainpk = NULL, *subpk = NULL; - PKT_signature *sig; - KBNODE k; - u32 mainkid[2]; - u32 sigdate = 0; - KBNODE signode; - u32 curtime = make_timestamp (); - unsigned int key_usage = 0; - u32 keytimestamp = 0; - u32 key_expire = 0; - const byte *p; - size_t n; - - if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY ) - BUG (); - mainpk = keyblock->pkt->pkt.public_key; - if ( mainpk->version < 4 ) - return; /* (actually this should never happen) */ - keyid_from_pk( mainpk, mainkid ); - subpk = subnode->pkt->pkt.public_key; - keytimestamp = subpk->timestamp; - - subpk->is_valid = 0; - subpk->main_keyid[0] = mainpk->main_keyid[0]; - subpk->main_keyid[1] = mainpk->main_keyid[1]; - - /* find the latest key binding self-signature. */ - signode = NULL; - sigdate = 0; /* helper to find the latest signature */ - for(k=subnode->next; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; - k = k->next ) { - if ( k->pkt->pkttype == PKT_SIGNATURE ) { - sig = k->pkt->pkt.signature; - if ( sig->keyid[0] == mainkid[0] && sig->keyid[1]==mainkid[1] ) { - if ( check_key_signature( keyblock, k, NULL ) ) - ; /* signature did not verify */ - else if ( IS_SUBKEY_REV (sig) ) { - /* Note that this means that the date on a - revocation sig does not matter - even if the - binding sig is dated after the revocation sig, - the subkey is still marked as revoked. This - seems ok, as it is just as easy to make new - subkeys rather than re-sign old ones as the - problem is in the distribution. Plus, PGP (7) - does this the same way. */ - subpk->is_revoked = 1; - /* although we could stop now, we continue to - * figure out other information like the old expiration - * time */ - } - else if ( IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate ) { - if(sig->flags.expired) - ; /* signature has expired - ignore it */ - else { - sigdate = sig->timestamp; - signode = k; - } - } - } - } - } - - if ( !signode ) { - return; /* no valid key binding */ - } - - subpk->is_valid = 1; - sig = signode->pkt->pkt.signature; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 0x03) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 0x0c) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ - key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ - int x = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } - subpk->pubkey_usage = key_usage; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) - key_expire = keytimestamp + buffer_to_u32(p); - else - key_expire = 0; - subpk->has_expired = key_expire >= curtime? 0 : key_expire; - subpk->expiredate = key_expire; -} - - - -/* - * Merge information from the self-signatures with the key, so that - * we can later use them more easy. - * The function works by first applying the self signatures to the - * primary key and the to each subkey. - * Here are the rules we use to decide which inormation from which - * self-signature is used: - * We check all self signatures or validity and ignore all invalid signatures. - * All signatures are then ordered by their creation date .... - * For the primary key: - * FIXME the docs - */ -static void -merge_selfsigs( KBNODE keyblock ) -{ - KBNODE k; - int revoked; - PKT_public_key *main_pk; - prefitem_t *prefs; - int mdc_feature; - - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) { - if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) { - log_error ("expected public key but found secret key " - "- must stop\n"); - /* we better exit here becuase a public key is expected at - other places too. FIXME: Figure this out earlier and - don't get to here at all */ - g10_exit (1); - } - BUG (); - } - - merge_selfsigs_main ( keyblock, &revoked ); - - /* now merge in the data from each of the subkeys */ - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - merge_selfsigs_subkey ( keyblock, k ); - } - } - - main_pk = keyblock->pkt->pkt.public_key; - if ( revoked || main_pk->has_expired || !main_pk->is_valid ) { - /* if the primary key is revoked, expired, or invalid we - * better set the appropriate flags on that key and all - * subkeys */ - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = k->pkt->pkt.public_key; - if(!main_pk->is_valid) - pk->is_valid = 0; - if(revoked) - pk->is_revoked = 1; - if(main_pk->has_expired) - pk->has_expired = main_pk->has_expired; - } - } - return; - } - - /* set the preference list of all keys to those of the primary real - * user ID. Note: we use these preferences when we don't know by - * which user ID the key has been selected. - * fixme: we should keep atoms of commonly used preferences or - * use reference counting to optimize the preference lists storage. - * FIXME: it might be better to use the intersection of - * all preferences. - * Do a similar thing for the MDC feature flag. - */ - prefs = NULL; - mdc_feature = 0; - for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) { - if (k->pkt->pkttype == PKT_USER_ID - && !k->pkt->pkt.user_id->attrib_data - && k->pkt->pkt.user_id->is_primary) { - prefs = k->pkt->pkt.user_id->prefs; - mdc_feature = k->pkt->pkt.user_id->mdc_feature; - break; - } - } - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = k->pkt->pkt.public_key; - if (pk->prefs) - xfree (pk->prefs); - pk->prefs = copy_prefs (prefs); - pk->mdc_feature = mdc_feature; - } - } -} - - -/* - * Merge the secret keys from secblock into the pubblock thereby - * replacing the public (sub)keys with their secret counterparts Hmmm: - * It might be better to get away from the concept of entire secret - * keys at all and have a way to store just the real secret parts - * from the key. - */ -static void -merge_public_with_secret ( KBNODE pubblock, KBNODE secblock ) -{ - KBNODE pub; - - assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY ); - assert ( secblock->pkt->pkttype == PKT_SECRET_KEY ); - - for (pub=pubblock; pub; pub = pub->next ) { - if ( pub->pkt->pkttype == PKT_PUBLIC_KEY ) { - PKT_public_key *pk = pub->pkt->pkt.public_key; - PKT_secret_key *sk = secblock->pkt->pkt.secret_key; - assert ( pub == pubblock ); /* only in the first node */ - /* there is nothing to compare in this case, so just replace - * some information */ - copy_public_parts_to_secret_key ( pk, sk ); - free_public_key ( pk ); - pub->pkt->pkttype = PKT_SECRET_KEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - } - else if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - /* this is more complicated: it may happen that the sequence - * of the subkeys dosn't match, so we have to find the - * appropriate secret key */ - for (sec=secblock->next; sec; sec = sec->next ) { - if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if ( !cmp_public_secret_key ( pk, sk ) ) { - copy_public_parts_to_secret_key ( pk, sk ); - free_public_key ( pk ); - pub->pkt->pkttype = PKT_SECRET_SUBKEY; - pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk); - break; - } - } - } - if ( !sec ) - BUG(); /* already checked in premerge */ - } - } -} - -/* This function checks that for every public subkey a corresponding - * secret subkey is available and deletes the public subkey otherwise. - * We need this function because we can't delete it later when we - * actually merge the secret parts into the pubring. - * The function also plays some games with the node flags. - */ -static void -premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock ) -{ - KBNODE last, pub; - - assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY ); - assert ( secblock->pkt->pkttype == PKT_SECRET_KEY ); - - for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) { - pub->flag &= ~3; /* reset bits 0 and 1 */ - if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - KBNODE sec; - PKT_public_key *pk = pub->pkt->pkt.public_key; - - for (sec=secblock->next; sec; sec = sec->next ) { - if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = sec->pkt->pkt.secret_key; - if ( !cmp_public_secret_key ( pk, sk ) ) { - if ( sk->protect.s2k.mode == 1001 ) { - /* The secret parts are not available so - we can't use that key for signing etc. - Fix the pubkey usage */ - pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG - |PUBKEY_USAGE_AUTH); - } - /* transfer flag bits 0 and 1 to the pubblock */ - pub->flag |= (sec->flag &3); - break; - } - } - } - if ( !sec ) { - KBNODE next, ll; - - if (opt.verbose) - log_info ( _("no secret subkey " - "for public subkey %08lX - ignoring\n"), - (ulong)keyid_from_pk (pk,NULL) ); - /* we have to remove the subkey in this case */ - assert ( last ); - /* find the next subkey */ - for (next=pub->next,ll=pub; - next && pub->pkt->pkttype != PKT_PUBLIC_SUBKEY; - ll = next, next = next->next ) - ; - /* make new link */ - last->next = next; - /* release this public subkey with all sigs */ - ll->next = NULL; - release_kbnode( pub ); - /* let the loop continue */ - pub = last; - } - } - } - /* We need to copy the found bits (0 and 1) from the secret key to - the public key. This has already been done for the subkeys but - got lost on the primary key - fix it here *. */ - pubblock->flag |= (secblock->flag & 3); -} - - - - -/* See see whether the key fits - * our requirements and in case we do not - * request the primary key, we should select - * a suitable subkey. - * FIXME: Check against PGP 7 whether we still need a kludge - * to favor type 16 keys over type 20 keys when type 20 - * has not been explitely requested. - * Returns: True when a suitable key has been found. - * - * We have to distinguish four cases: FIXME! - * 1. No usage and no primary key requested - * Examples for this case are that we have a keyID to be used - * for decrytion or verification. - * 2. No usage but primary key requested - * This is the case for all functions which work on an - * entire keyblock, e.g. for editing or listing - * 3. Usage and primary key requested - * FXME - * 4. Usage but no primary key requested - * FIXME - * FIXME: Tell what is going to happen here and something about the rationale - * Note: We don't use this function if no specific usage is requested; - * This way the getkey functions can be used for plain key listings. - * - * CTX ist the keyblock we are investigating, if FOUNDK is not NULL this - * is the key we actually found by looking at the keyid or a fingerprint and - * may eitehr point to the primary or one of the subkeys. - */ - -static int -finish_lookup (GETKEY_CTX ctx) -{ - KBNODE keyblock = ctx->keyblock; - KBNODE k; - KBNODE foundk = NULL; - PKT_user_id *foundu = NULL; -#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC) - unsigned int req_usage = ( ctx->req_usage & USAGE_MASK ); - /* Request the primary if we're certifying another key, and also - if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7 - do not understand signatures made by a signing subkey. PGP 8 - does. */ - int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) || - ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG)); - u32 latest_date; - KBNODE latest_key; - u32 curtime = make_timestamp (); - - assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ); - - ctx->found_key = NULL; - - if (ctx->exact) { - for (k=keyblock; k; k = k->next) { - if ( (k->flag & 1) ) { - assert ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - foundk = k; - break; - } - } - } - - for (k=keyblock; k; k = k->next) { - if ( (k->flag & 2) ) { - assert (k->pkt->pkttype == PKT_USER_ID); - foundu = k->pkt->pkt.user_id; - break; - } - } - - if ( DBG_CACHE ) - log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n", - (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL), - foundk? "one":"all", req_usage); - - if (!req_usage) { - latest_key = foundk? foundk:keyblock; - goto found; - } - - if (!req_usage) { - PKT_public_key *pk = foundk->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - ctx->found_key = foundk; - cache_user_id( keyblock ); - return 1; /* found */ - } - - latest_date = 0; - latest_key = NULL; - /* do not look at subkeys if a certification key is requested */ - if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim) { - KBNODE nextk; - /* either start a loop or check just this one subkey */ - for (k=foundk?foundk:keyblock; k; k = nextk ) { - PKT_public_key *pk; - nextk = k->next; - if ( k->pkt->pkttype != PKT_PUBLIC_SUBKEY ) - continue; - if ( foundk ) - nextk = NULL; /* what a hack */ - pk = k->pkt->pkt.public_key; - if (DBG_CACHE) - log_debug( "\tchecking subkey %08lX\n", - (ulong)keyid_from_pk( pk, NULL)); - if ( !pk->is_valid ) { - if (DBG_CACHE) - log_debug( "\tsubkey not valid\n"); - continue; - } - if ( pk->is_revoked ) { - if (DBG_CACHE) - log_debug( "\tsubkey has been revoked\n"); - continue; - } - if ( pk->has_expired ) { - if (DBG_CACHE) - log_debug( "\tsubkey has expired\n"); - continue; - } - if ( pk->timestamp > curtime && !opt.ignore_valid_from ) { - if (DBG_CACHE) - log_debug( "\tsubkey not yet valid\n"); - continue; - } - - if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) { - if (DBG_CACHE) - log_debug( "\tusage does not match: want=%x have=%x\n", - req_usage, pk->pubkey_usage ); - continue; - } - - if (DBG_CACHE) - log_debug( "\tsubkey looks fine\n"); - if ( pk->timestamp > latest_date ) { - latest_date = pk->timestamp; - latest_key = k; - } - } - } - - /* Okay now try the primary key unless we want an exact - * key ID match on a subkey */ - if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_prim) { - PKT_public_key *pk; - if (DBG_CACHE && !foundk && !req_prim ) - log_debug( "\tno suitable subkeys found - trying primary\n"); - pk = keyblock->pkt->pkt.public_key; - if ( !pk->is_valid ) { - if (DBG_CACHE) - log_debug( "\tprimary key not valid\n"); - } - else if ( pk->is_revoked ) { - if (DBG_CACHE) - log_debug( "\tprimary key has been revoked\n"); - } - else if ( pk->has_expired ) { - if (DBG_CACHE) - log_debug( "\tprimary key has expired\n"); - } - else if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) { - if (DBG_CACHE) - log_debug( "\tprimary key usage does not match: " - "want=%x have=%x\n", - req_usage, pk->pubkey_usage ); - } - else { /* okay */ - if (DBG_CACHE) - log_debug( "\tprimary key may be used\n"); - latest_key = keyblock; - latest_date = pk->timestamp; - } - } - - if ( !latest_key ) { - if (DBG_CACHE) - log_debug("\tno suitable key found - giving up\n"); - return 0; - } - - found: - if (DBG_CACHE) - log_debug( "\tusing key %08lX\n", - (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) ); - - if (latest_key) { - PKT_public_key *pk = latest_key->pkt->pkt.public_key; - if (pk->user_id) - free_user_id (pk->user_id); - pk->user_id = scopy_user_id (foundu); - } - - ctx->found_key = latest_key; - - if (latest_key != keyblock && opt.verbose) { - log_info(_("using secondary key %08lX " - "instead of primary key %08lX\n"), - (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL), - (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL) ); - } - - cache_user_id( keyblock ); - - return 1; /* found */ -} - - -static int -lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ) -{ - int rc; - KBNODE secblock = NULL; /* helper */ - int no_suitable_key = 0; - - rc = 0; - while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) { - /* If we are searching for the first key we have to make sure - that the next interation does not no an implicit reset. - This can be triggered by an empty key ring. */ - if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST) - ctx->items->mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock); - if (rc) { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - rc = 0; - goto skip; - } - - if ( secmode ) { - /* find the correspondig public key and use this - * this one for the selection process */ - u32 aki[2]; - KBNODE k = ctx->keyblock; - - if (k->pkt->pkttype != PKT_SECRET_KEY) - BUG(); - - keyid_from_sk (k->pkt->pkt.secret_key, aki); - k = get_pubkeyblock (aki); - if( !k ) { - if (!opt.quiet) - log_info(_("key %08lX: secret key without public key " - "- skipped\n"), (ulong)aki[1] ); - goto skip; - } - secblock = ctx->keyblock; - ctx->keyblock = k; - - premerge_public_with_secret ( ctx->keyblock, secblock ); - } - - /* warning: node flag bits 0 and 1 should be preserved by - * merge_selfsigs. For secret keys, premerge did tranfer the - * keys to the keyblock */ - merge_selfsigs ( ctx->keyblock ); - if ( finish_lookup (ctx) ) { - no_suitable_key = 0; - if ( secmode ) { - merge_public_with_secret ( ctx->keyblock, - secblock); - release_kbnode (secblock); - secblock = NULL; - } - goto found; - } - else - no_suitable_key = 1; - - skip: - /* release resources and continue search */ - if ( secmode ) { - release_kbnode( secblock ); - secblock = NULL; - } - release_kbnode( ctx->keyblock ); - ctx->keyblock = NULL; - } - - found: - if( rc && rc != -1 ) - log_error("keydb_search failed: %s\n", gpg_strerror (rc)); - - if( !rc ) { - *ret_keyblock = ctx->keyblock; /* return the keyblock */ - ctx->keyblock = NULL; - } - else if (rc == -1 && no_suitable_key) - rc = secmode ? GPG_ERR_UNUSABLE_SECKEY : GPG_ERR_UNUSABLE_PUBKEY; - else if( rc == -1 ) - rc = secmode ? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY; - - if ( secmode ) { - release_kbnode( secblock ); - secblock = NULL; - } - release_kbnode( ctx->keyblock ); - ctx->keyblock = NULL; - - ctx->last_rc = rc; - return rc; -} - - - - -/**************** - * FIXME: Replace by the generic function - * It does not work as it is right now - it is used at - * 2 places: a) to get the key for an anonyous recipient - * b) to get the ultimately trusted keys. - * The a) usage might have some problems. - * - * set with_subkeys true to include subkeys - * set with_spm true to include secret-parts-missing keys - * - * Enumerate all primary secret keys. Caller must use these procedure: - * 1) create a void pointer and initialize it to NULL - * 2) pass this void pointer by reference to this function - * and provide space for the secret key (pass a buffer for sk) - * 3) call this function as long as it does not return -1 - * to indicate EOF. - * 4) Always call this function a last time with SK set to NULL, - * so that can free it's context. - */ -int -enum_secret_keys( void **context, PKT_secret_key *sk, - int with_subkeys, int with_spm ) -{ - int rc=0; - struct { - int eof; - int first; - KEYDB_HANDLE hd; - KBNODE keyblock; - KBNODE node; - } *c = *context; - - - if( !c ) { /* make a new context */ - c = xcalloc (1, sizeof *c ); - *context = c; - c->hd = keydb_new (1); - c->first = 1; - c->keyblock = NULL; - c->node = NULL; - } - - if( !sk ) { /* free the context */ - keydb_release (c->hd); - release_kbnode (c->keyblock); - xfree ( c ); - *context = NULL; - return 0; - } - - if( c->eof ) - return -1; - - do { - /* get the next secret key from the current keyblock */ - for (; c->node; c->node = c->node->next) { - if ((c->node->pkt->pkttype == PKT_SECRET_KEY - || (with_subkeys - && c->node->pkt->pkttype == PKT_SECRET_SUBKEY) ) - && !(c->node->pkt->pkt.secret_key->protect.s2k.mode==1001 - && !with_spm)) { - copy_secret_key (sk, c->node->pkt->pkt.secret_key ); - c->node = c->node->next; - return 0; /* found */ - } - } - release_kbnode (c->keyblock); - c->keyblock = c->node = NULL; - - rc = c->first? keydb_search_first (c->hd) : keydb_search_next (c->hd); - c->first = 0; - if (rc) { - keydb_release (c->hd); c->hd = NULL; - c->eof = 1; - return -1; /* eof */ - } - - rc = keydb_get_keyblock (c->hd, &c->keyblock); - c->node = c->keyblock; - } while (!rc); - - return rc; /* error */ -} - - - -/********************************************* - *********** user ID printing helpers ******* - *********************************************/ - -/**************** - * Return a string with a printable representation of the user_id. - * this string must be freed by m_free. - */ -char* -get_user_id_string( u32 *keyid ) -{ - user_id_db_t r; - char *p; - int pass=0; - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len + 10 ); - sprintf(p, "%08lX %.*s", - (ulong)keyid[1], r->len, r->name ); - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xmalloc ( 15 ); - sprintf(p, "%08lX [?]", (ulong)keyid[1] ); - return p; -} - - -char* -get_user_id_string_printable ( u32 *keyid ) -{ - char *p = get_user_id_string( keyid ); - char *p2 = utf8_to_native( p, strlen(p), 0 ); - xfree (p); - p = make_printable_string (p2, strlen (p2), 0); - xfree (p2); - return p; -} - - -char* -get_long_user_id_string( u32 *keyid ) -{ - user_id_db_t r; - char *p; - int pass=0; - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len + 20 ); - sprintf(p, "%08lX%08lX %.*s", - (ulong)keyid[0], (ulong)keyid[1], - r->len, r->name ); - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xmalloc ( 25 ); - sprintf(p, "%08lX%08lX [?]", (ulong)keyid[0], (ulong)keyid[1] ); - return p; -} - -char* -get_user_id( u32 *keyid, size_t *rn ) -{ - user_id_db_t r; - char *p; - int pass=0; - - /* try it two times; second pass reads from key resources */ - do { - for(r=user_id_db; r; r = r->next ) { - keyid_list_t a; - for (a=r->keyids; a; a= a->next ) { - if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) { - p = xmalloc ( r->len ); - memcpy(p, r->name, r->len ); - *rn = r->len; - return p; - } - } - } - } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); - p = xstrdup ( _("[User id not found]") ); - *rn = strlen(p); - return p; -} - -char* -get_user_id_printable( u32 *keyid ) -{ - size_t rn; - char *p = get_user_id( keyid, &rn ); - char *p2 = utf8_to_native( p, rn, 0 ); - xfree (p); - p = make_printable_string (p2, strlen (p2), 0); - xfree (p2); - return p; -} - -KEYDB_HANDLE -get_ctx_handle(GETKEY_CTX ctx) -{ - return ctx->kr_handle; -} diff --git a/g10/global.h b/g10/global.h deleted file mode 100644 index d1c554dce..000000000 --- a/g10/global.h +++ /dev/null @@ -1,31 +0,0 @@ -/* global.h - Local typedefs and constants - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPG_GLOBAL_H -#define GPG_GLOBAL_H - -#define MAX_FINGERPRINT_LEN 20 - -typedef struct kbnode_struct *KBNODE; -typedef struct keydb_search_desc KEYDB_SEARCH_DESC; - -#include "gpg.h" - -#endif /*GPG_GLOBAL_H*/ diff --git a/g10/gpg.h b/g10/gpg.h deleted file mode 100644 index bf61411f7..000000000 --- a/g10/gpg.h +++ /dev/null @@ -1,38 +0,0 @@ -/* gpg.h - top level include file for gpg etc. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_G10_GPG_H -#define GNUPG_G10_GPG_H - -/* Note, that this file should be the first one after the system - header files. This is required to set the error source to the - correct value and may be of advantage if we ever have to do - special things. */ - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPG -#include <gpg-error.h> - - -/* FIXME: merge this with global.h */ - - -#endif /*GNUPG_G10_GPG_H*/ diff --git a/g10/gpgv.c b/g10/gpgv.c deleted file mode 100644 index 9bd954c6f..000000000 --- a/g10/gpgv.c +++ /dev/null @@ -1,389 +0,0 @@ -/* gpgv.c - The GnuPG signature verify utility - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif - -#define INCLUDED_BY_MAIN_MODULE 1 -#include "gpg.h" -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "mpi.h" -#include "cipher.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" -#include "status.h" - - -enum cmd_and_opt_values { aNull = 0, - oQuiet = 'q', - oVerbose = 'v', - oBatch = 500, - oKeyring, - oIgnoreTimeConflict, - oStatusFD, - oLoggerFD, - oHomedir, -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oKeyring, "keyring" ,2, N_("take the keys from this keyring")}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, - N_("make timestamp conflicts only a warning") }, - { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { oLoggerFD, "logger-fd",1, "@" }, - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - -{0} }; - - - -int g10_errors_seen = 0; - -#ifdef __riscos__ -RISCOS_GLOBAL_STATICS("GnuPG (gpgv) Heap") -#endif /* __riscos__ */ - -static const char * -my_strusage( int level ) -{ - const char *p; - switch( level ) { - case 11: p = "gpgv (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to <gnupg-bugs@gnu.org>.\n"); - break; - case 1: - case 40: p = - _("Usage: gpgv [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: gpg [options] [files]\n" - "Check signatures against known trusted keys\n"); - break; - - default: p = NULL; - } - return p; -} - - - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS -#ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); -#else - setlocale( LC_ALL, "" ); -#endif - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int rc=0; - STRLIST sl; - STRLIST nrings=NULL; - unsigned configlineno; - -#ifdef __riscos__ - riscos_global_defaults(); -#endif /* __riscos__ */ - - set_strusage (my_strusage); - log_set_prefix ("gpgv", 1); - gnupg_init_signals(0, NULL); - i18n_init(); - opt.command_fd = -1; /* no command fd */ - opt.pgp2_workarounds = 1; - opt.keyserver_options.auto_key_retrieve = 1; - opt.trust_model = TM_ALWAYS; - opt.batch = 1; - -#if defined (_WIN32) - opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", - "HomeDir" ); -#else - opt.homedir = getenv("GNUPGHOME"); -#endif - if( !opt.homedir || !*opt.homedir ) { - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - } - tty_no_terminal(1); - tty_batchmode(1); - disable_dotlock(); - - set_native_charset (NULL); /* Try to auto set the character set */ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while( optfile_parse( NULL, NULL, &configlineno, &pargs, opts) ) { - switch( pargs.r_opt ) { - case oQuiet: opt.quiet = 1; break; - case oVerbose: g10_opt_verbose++; - opt.verbose++; opt.list_sigs=1; break; - case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; - case oStatusFD: set_status_fd( pargs.r.ret_int ); break; - case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); - break; - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - default : pargs.err = 2; break; - } - } - - if( log_get_errorcount(0) ) - g10_exit(2); - - g10_opt_homedir = opt.homedir; - - if( opt.verbose > 1 ) - set_packet_list_mode(1); - - if( !nrings ) /* no keyring given: use default one */ - keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0); - for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource (sl->d, 0, 0 ); - - FREE_STRLIST(nrings); - - if( (rc = verify_signatures( argc, argv ) )) - log_error("verify signatures failed: %s\n", gpg_strerror (rc) ); - - /* cleanup */ - g10_exit(0); - return 8; /*NEVER REACHED*/ -} - - -void -g10_exit( int rc ) -{ - rc = rc? rc : log_get_errorcount(0)? 2 : - g10_errors_seen? 1 : 0; - exit(rc ); -} - - - -void -read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth) -{ -} - - -/* Stub: - * We have to override the trustcheck from pkclist.c becuase - * this utility assumes that all keys in the keyring are trustworthy - */ -int -check_signatures_trust( PKT_signature *sig ) -{ - return 0; -} - - -/* Stub: - * We don't have the trustdb , so we have to provide some stub functions - * instead - */ - -int -cache_disabled_value(PKT_public_key *pk) -{ - return 0; -} - -int -get_validity_info (PKT_public_key *pk, PKT_user_id *uid) -{ - return '?'; -} - -unsigned int -get_validity (PKT_public_key *pk, PKT_user_id *uid) -{ - return 0; -} - -const char * -trust_value_to_string (unsigned int value) -{ - return "err"; -} - -/* Stub: */ -int -get_ownertrust_info (PKT_public_key *pk) -{ - return '?'; -} - -unsigned int -get_ownertrust (PKT_public_key *pk) -{ - return TRUST_UNKNOWN; -} - - -/* Stub: - * Because we only work with trusted keys, it does not make sense to - * get them from a keyserver - */ -int -keyserver_import_keyid( u32 *keyid, void *dummy ) -{ - return -1; -} - -/* Stub: - * No encryption here but mainproc links to these functions. - */ -int -get_session_key( PKT_pubkey_enc *k, DEK *dek ) -{ - return GPG_ERR_GENERAL; -} -/* Stub: */ -int -get_override_session_key( DEK *dek, const char *string ) -{ - return GPG_ERR_GENERAL; -} -/* Stub: */ -int -decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) -{ - return GPG_ERR_GENERAL; -} - - -/* Stub: - * No interactive commnds, so we don't need the helptexts - */ -void -display_online_help( const char *keyword ) -{ -} - -/* Stub: - * We don't use secret keys, but getkey.c links to this - */ -int -check_secret_key( PKT_secret_key *sk, int n ) -{ - return GPG_ERR_GENERAL; -} - -/* Stub: - * No secret key, so no passphrase needed - */ -DEK * -passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tmp, int *canceled) -{ - if (canceled) - *canceled = 0; - return NULL; -} - -/* Stubs to avoid linking to photoid.c */ -void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk) {} -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) {return 0;} -char *image_type_to_string(byte type,int string) {return NULL;} - -/* Stubs to void linking to ../cipher/cipher.c */ -int string_to_cipher_algo( const char *string ) { return 0; } -const char *cipher_algo_to_string( int algo ) { return "?";} -void disable_cipher_algo( int algo ) {} -int check_cipher_algo( int algo ) { return -1;} -unsigned int cipher_get_keylen( int algo ) { return 0; } -unsigned int cipher_get_blocksize( int algo ) {return 0;} -CIPHER_HANDLE cipher_open( int algo, int mode, int secure ) { return NULL;} -void cipher_close( CIPHER_HANDLE c ) {} -int cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen ) { return -1;} -void cipher_setiv( CIPHER_HANDLE c, const byte *iv, unsigned ivlen ){} -void cipher_encrypt( CIPHER_HANDLE c, byte *outbuf, - byte *inbuf, unsigned nbytes ) {} -void cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, - byte *inbuf, unsigned nbytes ) {} -void cipher_sync( CIPHER_HANDLE c ) {} - - -/* Stubs to avoid linking to ../util/ttyio.c */ -int tty_batchmode( int onoff ) { return 0; } -void tty_printf( const char *fmt, ... ) { } -void tty_print_string( const byte *p, size_t n ) { } -void tty_print_utf8_string( const byte *p, size_t n ) {} -void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) {} -char *tty_get( const char *prompt ) { return NULL;} -char *tty_get_hidden( const char *prompt ) {return NULL; } -void tty_kill_prompt(void) {} -int tty_get_answer_is_yes( const char *prompt ) {return 0;} -int tty_no_terminal(int onoff) {return 0;} - -/* We do not do any locking, so use these stubs here */ -void disable_dotlock(void) {} -DOTLOCK create_dotlock( const char *file_to_lock ) { return NULL; } -int make_dotlock( DOTLOCK h, long timeout ) { return 0;} -int release_dotlock( DOTLOCK h ) {return 0;} -void dotlock_remove_lockfiles(void) {} diff --git a/g10/helptext.c b/g10/helptext.c deleted file mode 100644 index 4a65314eb..000000000 --- a/g10/helptext.c +++ /dev/null @@ -1,316 +0,0 @@ -/* helptext.c - English help texts - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gpg.h" -#include "util.h" -#include "ttyio.h" -#include "main.h" -#include "i18n.h" - - -/**************** - * These helptexts are used for the "online" help feature. We use - * a key consisting of words and dots. Because the lookup is only - * done in an interactive mode on a user request (when she enters a "?" - * as response to a prompt) we can use a simple search through the list. - * - * Mini glossary: - * - * "user ID", "trustdb", "NOTE" and "WARNING". - */ - -static struct helptexts { const char *key; const char *help; } helptexts[] = { - -/* begin of list */ - -{ "edit_ownertrust.value", N_( -"It's up to you to assign a value here; this value will never be exported\n" -"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n" -"to do with the (implicitly created) web-of-certificates." -)}, - -{ "edit_ownertrust.set_ultimate.okay", N_( - "To build the Web-of-Trust, GnuPG needs to know which keys are\n" - "ultimately trusted - those are usually the keys for which you have\n" - "access to the secret key. Answer \"yes\" to set this key to\n" - "ultimately trusted\n" -)}, - -{ "revoked_key.override", N_( -"If you want to use this revoked key anyway, answer \"yes\"." -)}, - -{ "untrusted_key.override", N_( -"If you want to use this untrusted key anyway, answer \"yes\"." -)}, - -{ "pklist.user_id.enter", N_( -"Enter the user ID of the addressee to whom you want to send the message." -)}, - -{ "keygen.algo", N_( -"Select the algorithm to use.\n" -"\n" -"DSA (aka DSS) is the digital signature algorithm which can only be used\n" -"for signatures. This is the suggested algorithm because verification of\n" -"DSA signatures are much faster than those of ElGamal.\n" -"\n" -"ElGamal is an algorithm which can be used for signatures and encryption.\n" -"OpenPGP distinguishs between two flavors of this algorithms: an encrypt only\n" -"and a sign+encrypt; actually it is the same, but some parameters must be\n" -"selected in a special way to create a safe key for signatures: this program\n" -"does this but other OpenPGP implementations are not required to understand\n" -"the signature+encryption flavor.\n" -"\n" -"The first (primary) key must always be a key which is capable of signing;\n" -"this is the reason why the encryption only ElGamal key is not available in\n" -"this menu." -)}, - - -{ "keygen.algo.elg_se", N_( -"Although these keys are defined in RFC2440 they are not suggested\n" -"because they are not supported by all programs and signatures created\n" -"with them are quite large and very slow to verify." -)}, - -{ "keygen.algo.rsa_se", N_( -"In general it is not a good idea to use the same key for signing and\n" -"encryption. This algorithm should only be used in certain domains.\n" -"Please consult your security expert first." -)}, - - -{ "keygen.size", N_( - "Enter the size of the key" -)}, - -{ "keygen.size.huge.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.size.large.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.valid", N_( - "Enter the required value as shown in the prompt.\n" - "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n" - "get a good error response - instead the system tries to interpret\n" - "the given value as an interval." -)}, - -{ "keygen.valid.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keygen.name", N_( - "Enter the name of the key holder" -)}, - - -{ "keygen.email", N_( - "please enter an optional but highly suggested email address" -)}, - -{ "keygen.comment", N_( - "Please enter an optional comment" -)}, - - -{ "keygen.userid.cmd", N_( - "" -"N to change the name.\n" -"C to change the comment.\n" -"E to change the email address.\n" -"O to continue with key generation.\n" -"Q to to quit the key generation." -)}, - -{ "keygen.sub.okay", N_( - "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key." -)}, - -{ "sign_uid.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - -{ "sign_uid.class", N_( -"When you sign a user ID on a key, you should first verify that the key\n" -"belongs to the person named in the user ID. It is useful for others to\n" -"know how carefully you verified this.\n\n" -"\"0\" means you make no particular claim as to how carefully you verified the\n" -" key.\n\n" -"\"1\" means you believe the key is owned by the person who claims to own it\n" -" but you could not, or did not verify the key at all. This is useful for\n" -" a \"persona\" verification, where you sign the key of a pseudonymous user.\n\n" -"\"2\" means you did casual verification of the key. For example, this could\n" -" mean that you verified the key fingerprint and checked the user ID on the\n" -" key against a photo ID.\n\n" -"\"3\" means you did extensive verification of the key. For example, this could\n" -" mean that you verified the key fingerprint with the owner of the key in\n" -" person, and that you checked, by means of a hard to forge document with a\n" -" photo ID (such as a passport) that the name of the key owner matches the\n" -" name in the user ID on the key, and finally that you verified (by exchange\n" -" of email) that the email address on the key belongs to the key owner.\n\n" -"Note that the examples given above for levels 2 and 3 are *only* examples.\n" -"In the end, it is up to you to decide just what \"casual\" and \"extensive\"\n" -"mean to you when you sign other keys.\n\n" -"If you don't know what the right answer is, answer \"0\"." -)}, - -{ "change_passwd.empty.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keyedit.save.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - - -{ "keyedit.cancel.okay", N_( - "Answer \"yes\" or \"no\"" -)}, - -{ "keyedit.sign_all.okay", N_( - "Answer \"yes\" is you want to sign ALL the user IDs" -)}, - -{ "keyedit.remove.uid.okay", N_( - "Answer \"yes\" if you really want to delete this user ID.\n" - "All certificates are then also lost!" -)}, - -{ "keyedit.remove.subkey.okay", N_( - "Answer \"yes\" if it is okay to delete the subkey" -)}, - - -{ "keyedit.delsig.valid", N_( - "This is a valid signature on the key; you normally don't want\n" - "to delete this signature because it may be important to establish a\n" - "trust connection to the key or another key certified by this key." -)}, -{ "keyedit.delsig.unknown", N_( - "This signature can't be checked because you don't have the\n" - "corresponding key. You should postpone its deletion until you\n" - "know which key was used because this signing key might establish\n" - "a trust connection through another already certified key." -)}, -{ "keyedit.delsig.invalid", N_( - "The signature is not valid. It does make sense to remove it from\n" - "your keyring." -)}, -{ "keyedit.delsig.selfsig", N_( - "This is a signature which binds the user ID to the key. It is\n" - "usually not a good idea to remove such a signature. Actually\n" - "GnuPG might not be able to use this key anymore. So do this\n" - "only if this self-signature is for some reason not valid and\n" - "a second one is available." -)}, - -{ "keyedit.updpref.okay", N_( - "Change the preferences of all user IDs (or just of the selected ones)\n" - "to the current list of preferences. The timestamp of all affected\n" - "self-signatures will be advanced by one second.\n" -)}, - - -{ "passphrase.enter", N_( - "" -"Please enter the passhrase; this is a secret sentence \n" -)}, - - -{ "passphrase.repeat", N_( - "Please repeat the last passphrase, so you are sure what you typed in." -)}, - -{ "detached_signature.filename", N_( - "Give the name of the file to which the signature applies" -)}, - -/* openfile.c (overwrite_filep) */ -{ "openfile.overwrite.okay", N_( - "Answer \"yes\" if it is okay to overwrite the file" -)}, - -/* openfile.c (ask_outfile_name) */ -{ "openfile.askoutname", N_( - "Please enter a new filename. If you just hit RETURN the default\n" - "file (which is shown in brackets) will be used." -)}, - -/* revoke.c (ask_revocation_reason) */ -{ "ask_revocation_reason.code", N_( - "You should specify a reason for the certification. Depending on the\n" - "context you have the ability to choose from this list:\n" - " \"Key has been compromised\"\n" - " Use this if you have a reason to believe that unauthorized persons\n" - " got access to your secret key.\n" - " \"Key is superseded\"\n" - " Use this if you have replaced this key with a newer one.\n" - " \"Key is no longer used\"\n" - " Use this if you have retired this key.\n" - " \"User ID is no longer valid\"\n" - " Use this to state that the user ID should not longer be used;\n" - " this is normally used to mark an email address invalid.\n" -)}, - -/* revoke.c (ask_revocation_reason) */ -{ "ask_revocation_reason.text", N_( - "If you like, you can enter a text describing why you issue this\n" - "revocation certificate. Please keep this text concise.\n" - "An empty line ends the text.\n" -)}, - -/* end of list */ -{ NULL, NULL } }; - - -void -display_online_help( const char *keyword ) -{ - - tty_kill_prompt(); - if( !keyword ) - tty_printf(_("No help available") ); - else { - const char *p; - int i; - - for(i=0; (p=helptexts[i].key) && strcmp( p, keyword ); i++ ) - ; - if( !p || !*helptexts[i].help ) - tty_printf(_("No help available for `%s'"), keyword ); - else - tty_printf("%s", _(helptexts[i].help) ); - } - tty_printf("\n"); -} diff --git a/g10/import.c b/g10/import.c deleted file mode 100644 index 9c323243a..000000000 --- a/g10/import.c +++ /dev/null @@ -1,1906 +0,0 @@ -/* import.c - Import OpenPGP key material - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "trustdb.h" -#include "main.h" -#include "i18n.h" -#include "ttyio.h" -#include "status.h" -#include "keyserver-internal.h" - -struct stats_s { - ulong count; - ulong no_user_id; - ulong imported; - ulong imported_rsa; - ulong n_uids; - ulong n_sigs; - ulong n_subk; - ulong unchanged; - ulong n_revoc; - ulong secret_read; - ulong secret_imported; - ulong secret_dups; - ulong skipped_new_keys; - ulong not_imported; -}; - - -static int import( iobuf_t inp, const char* fname, - struct stats_s *stats, unsigned int options ); -static int read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root ); -static void revocation_present(KBNODE keyblock); -static int import_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options); -static int import_secret_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options); -static int import_revoke_cert( const char *fname, KBNODE node, - struct stats_s *stats); -static int chk_self_sigs( const char *fname, KBNODE keyblock, - PKT_public_key *pk, u32 *keyid, int *non_self ); -static int delete_inv_parts( const char *fname, KBNODE keyblock, - u32 *keyid, unsigned int options ); -static int merge_blocks( const char *fname, KBNODE keyblock_orig, - KBNODE keyblock, u32 *keyid, - int *n_uids, int *n_sigs, int *n_subk ); -static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ); -static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ); -static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ); -static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ); - -int -parse_import_options(char *str,unsigned int *options) -{ - struct parse_options import_opts[]= - { - {"allow-local-sigs",IMPORT_ALLOW_LOCAL_SIGS}, - {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG}, - {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG}, - {"fast-import",IMPORT_FAST_IMPORT}, - {"convert-sk-to-pk",IMPORT_SK2PK}, - {NULL,0} - }; - - return parse_options(str,options,import_opts); -} - -void * -import_new_stats_handle (void) -{ - return xcalloc (1, sizeof (struct stats_s) ); -} - -void -import_release_stats_handle (void *p) -{ - xfree (p); -} - -/**************** - * Import the public keys from the given filename. Input may be armored. - * This function rejects all keys which are not validly self signed on at - * least one userid. Only user ids which are self signed will be imported. - * Other signatures are not checked. - * - * Actually this function does a merge. It works like this: - * - * - get the keyblock - * - check self-signatures and remove all userids and their signatures - * without/invalid self-signatures. - * - reject the keyblock, if we have no valid userid. - * - See whether we have this key already in one of our pubrings. - * If not, simply add it to the default keyring. - * - Compare the key and the self-signatures of the new and the one in - * our keyring. If they are different something weird is going on; - * ask what to do. - * - See whether we have only non-self-signature on one user id; if not - * ask the user what to do. - * - compare the signatures: If we already have this signature, check - * that they compare okay; if not, issue a warning and ask the user. - * (consider looking at the timestamp and use the newest?) - * - Simply add the signature. Can't verify here because we may not have - * the signature's public key yet; verification is done when putting it - * into the trustdb, which is done automagically as soon as this pubkey - * is used. - * - Proceed with next signature. - * - * Key revocation certificates have special handling. - * - */ -static int -import_keys_internal( iobuf_t inp, char **fnames, int nnames, - void *stats_handle, unsigned int options ) -{ - int i, rc = 0; - struct stats_s *stats = stats_handle; - - if (!stats) - stats = import_new_stats_handle (); - - if (inp) { - rc = import( inp, "[stream]", stats, options); - } - else { - if( !fnames && !nnames ) - nnames = 1; /* Ohh what a ugly hack to jump into the loop */ - - for(i=0; i < nnames; i++ ) { - const char *fname = fnames? fnames[i] : NULL; - iobuf_t inp2 = iobuf_open(fname); - if( !fname ) - fname = "[stdin]"; - if( !inp2 ) - log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); - else { - rc = import( inp2, fname, stats, options ); - iobuf_close(inp2); - /* Must invalidate that ugly cache to actually close it. */ - iobuf_ioctl (NULL, 2, 0, (char*)fname); - if( rc ) - log_error("import from `%s' failed: %s\n", fname, - gpg_strerror (rc) ); - } - if( !fname ) - break; - } - } - if (!stats_handle) { - import_print_stats (stats); - import_release_stats_handle (stats); - } - /* If no fast import and the trustdb is dirty (i.e. we added a key - or userID that had something other than a selfsig, a signature - that was other than a selfsig, or any revocation), then - update/check the trustdb if the user specified by setting - interactive or by not setting no-auto-check-trustdb */ - if (!(options&IMPORT_FAST_IMPORT) && trustdb_pending_check()) - { - if (opt.interactive) - update_trustdb(); - else if (!opt.no_auto_check_trustdb) - check_trustdb(); - } - - return rc; -} - -void -import_keys( char **fnames, int nnames, - void *stats_handle, unsigned int options ) -{ - import_keys_internal( NULL, fnames, nnames, stats_handle, options); -} - -int -import_keys_stream( iobuf_t inp, void *stats_handle, unsigned int options ) -{ - return import_keys_internal( inp, NULL, 0, stats_handle, options); -} - -static int -import( iobuf_t inp, const char* fname, - struct stats_s *stats, unsigned int options ) -{ - PACKET *pending_pkt = NULL; - KBNODE keyblock; - int rc = 0; - - getkey_disable_caches(); - - if( !opt.no_armor ) { /* armored reading is not disabled */ - armor_filter_context_t *afx = xcalloc (1, sizeof *afx ); - afx->only_keyblocks = 1; - iobuf_push_filter2( inp, armor_filter, afx, 1 ); - } - - while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { - if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) - rc = import_one( fname, keyblock, stats, options ); - else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) - rc = import_secret_one( fname, keyblock, stats, options ); - else if( keyblock->pkt->pkttype == PKT_SIGNATURE - && keyblock->pkt->pkt.signature->sig_class == 0x20 ) - rc = import_revoke_cert( fname, keyblock, stats ); - else { - log_info( _("skipping block of type %d\n"), - keyblock->pkt->pkttype ); - } - release_kbnode(keyblock); - /* fixme: we should increment the not imported counter but this - does only make sense if we keep on going despite of errors. */ - if( rc ) - break; - if( !(++stats->count % 100) && !opt.quiet ) - log_info(_("%lu keys processed so far\n"), stats->count ); - } - if( rc == -1 ) - rc = 0; - else if( rc && rc != GPG_ERR_INV_KEYRING ) - log_error( _("error reading `%s': %s\n"), fname, gpg_strerror (rc)); - - return rc; -} - - -void -import_print_stats (void *hd) -{ - struct stats_s *stats = hd; - - if( !opt.quiet ) { - log_info(_("Total number processed: %lu\n"), stats->count ); - if( stats->skipped_new_keys ) - log_info(_(" skipped new keys: %lu\n"), - stats->skipped_new_keys ); - if( stats->no_user_id ) - log_info(_(" w/o user IDs: %lu\n"), stats->no_user_id ); - if( stats->imported || stats->imported_rsa ) { - log_info(_(" imported: %lu"), stats->imported ); - if( stats->imported_rsa ) - fprintf(stderr, " (RSA: %lu)", stats->imported_rsa ); - putc('\n', stderr); - } - if( stats->unchanged ) - log_info(_(" unchanged: %lu\n"), stats->unchanged ); - if( stats->n_uids ) - log_info(_(" new user IDs: %lu\n"), stats->n_uids ); - if( stats->n_subk ) - log_info(_(" new subkeys: %lu\n"), stats->n_subk ); - if( stats->n_sigs ) - log_info(_(" new signatures: %lu\n"), stats->n_sigs ); - if( stats->n_revoc ) - log_info(_(" new key revocations: %lu\n"), stats->n_revoc ); - if( stats->secret_read ) - log_info(_(" secret keys read: %lu\n"), stats->secret_read ); - if( stats->secret_imported ) - log_info(_(" secret keys imported: %lu\n"), stats->secret_imported ); - if( stats->secret_dups ) - log_info(_(" secret keys unchanged: %lu\n"), stats->secret_dups ); - if( stats->not_imported ) - log_info(_(" not imported: %lu\n"), stats->not_imported ); - } - - if( is_status_enabled() ) { - char buf[14*20]; - sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", - stats->count, - stats->no_user_id, - stats->imported, - stats->imported_rsa, - stats->unchanged, - stats->n_uids, - stats->n_subk, - stats->n_sigs, - stats->n_revoc, - stats->secret_read, - stats->secret_imported, - stats->secret_dups, - stats->skipped_new_keys, - stats->not_imported ); - write_status_text( STATUS_IMPORT_RES, buf ); - } -} - - -/**************** - * Read the next keyblock from stream A. - * PENDING_PKT should be initialzed to NULL - * and not chnaged form the caller. - * Retunr: 0 = okay, -1 no more blocks or another errorcode. - */ -static int -read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root ) -{ - int rc; - PACKET *pkt; - KBNODE root = NULL; - int in_cert; - - if( *pending_pkt ) { - root = new_kbnode( *pending_pkt ); - *pending_pkt = NULL; - in_cert = 1; - } - else - in_cert = 0; - pkt = xmalloc ( sizeof *pkt ); - init_packet(pkt); - while( (rc=parse_packet(a, pkt)) != -1 ) { - if( rc ) { /* ignore errors */ - if( rc != GPG_ERR_UNKNOWN_PACKET ) { - log_error("read_block: read error: %s\n", gpg_strerror (rc) ); - rc = GPG_ERR_INV_KEYRING; - goto ready; - } - free_packet( pkt ); - init_packet(pkt); - continue; - } - - if( !root && pkt->pkttype == PKT_SIGNATURE - && pkt->pkt.signature->sig_class == 0x20 ) { - /* this is a revocation certificate which is handled - * in a special way */ - root = new_kbnode( pkt ); - pkt = NULL; - goto ready; - } - - /* make a linked list of all packets */ - switch( pkt->pkttype ) { - case PKT_COMPRESSED: - if( pkt->pkt.compressed->algorithm < 1 - || pkt->pkt.compressed->algorithm > 2 ) { - rc = GPG_ERR_COMPR_ALGO; - goto ready; - } - { - compress_filter_context_t *cfx = xcalloc (1, sizeof *cfx ); - cfx->algo = pkt->pkt.compressed->algorithm; - pkt->pkt.compressed->buf = NULL; - iobuf_push_filter2( a, compress_filter, cfx, 1 ); - } - free_packet( pkt ); - init_packet(pkt); - break; - - case PKT_RING_TRUST: - /* skip those packets */ - free_packet( pkt ); - init_packet(pkt); - break; - - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - if( in_cert ) { /* store this packet */ - *pending_pkt = pkt; - pkt = NULL; - goto ready; - } - in_cert = 1; - default: - if( in_cert ) { - if( !root ) - root = new_kbnode( pkt ); - else - add_kbnode( root, new_kbnode( pkt ) ); - pkt = xmalloc ( sizeof *pkt ); - } - init_packet(pkt); - break; - } - } - ready: - if( rc == -1 && root ) - rc = 0; - - if( rc ) - release_kbnode( root ); - else - *ret_root = root; - free_packet( pkt ); - xfree ( pkt ); - return rc; -} - -/* Walk through the subkeys on a pk to find if we have the PKS - disease: multiple subkeys with their binding sigs stripped, and the - sig for the first subkey placed after the last subkey. That is, - instead of "pk uid sig sub1 bind1 sub2 bind2 sub3 bind3" we have - "pk uid sig sub1 sub2 sub3 bind1". We can't do anything about sub2 - and sub3, as they are already lost, but we can try and rescue sub1 - by reordering the keyblock so that it reads "pk uid sig sub1 bind1 - sub2 sub3". Returns TRUE if the keyblock was modified. */ - -static int -fix_pks_corruption(KBNODE keyblock) -{ - int changed=0,keycount=0; - KBNODE node,last=NULL,sknode=NULL; - - /* First determine if we have the problem at all. Look for 2 or - more subkeys in a row, followed by a single binding sig. */ - for(node=keyblock;node;last=node,node=node->next) - { - if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY) - { - keycount++; - if(!sknode) - sknode=node; - } - else if(node->pkt->pkttype==PKT_SIGNATURE && - node->pkt->pkt.signature->sig_class==0x18 && - keycount>=2 && node->next==NULL) - { - /* We might have the problem, as this key has two subkeys in - a row without any intervening packets. */ - - /* Sanity check */ - if(last==NULL) - break; - - /* Temporarily attach node to sknode. */ - node->next=sknode->next; - sknode->next=node; - last->next=NULL; - - /* Note we aren't checking whether this binding sig is a - selfsig. This is not necessary here as the subkey and - binding sig will be rejected later if that is the - case. */ - if(check_key_signature(keyblock,node,NULL)) - { - /* Not a match, so undo the changes. */ - sknode->next=node->next; - last->next=node; - node->next=NULL; - break; - } - else - { - sknode->flag |= 1; /* Mark it good so we don't need to - check it again */ - changed=1; - break; - } - } - else - keycount=0; - } - - return changed; -} - - -static void -print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason) -{ - byte array[MAX_FINGERPRINT_LEN], *s; - char buf[MAX_FINGERPRINT_LEN*2+30], *p; - size_t i, n; - - sprintf (buf, "%u ", reason); - p = buf + strlen (buf); - - if (pk) - fingerprint_from_pk (pk, array, &n); - else - fingerprint_from_sk (sk, array, &n); - s = array; - for (i=0; i < n ; i++, s++, p += 2) - sprintf (p, "%02X", *s); - - write_status_text (STATUS_IMPORT_OK, buf); -} - -void -print_import_check (PKT_public_key * pk, PKT_user_id * id) -{ - char * buf; - byte fpr[24]; - u32 keyid[2]; - size_t i, pos = 0, n; - - buf = xmalloc (17+41+id->len+32); - keyid_from_pk (pk, keyid); - sprintf (buf, "%08X%08X ", keyid[0], keyid[1]); - pos = 17; - fingerprint_from_pk (pk, fpr, &n); - for (i = 0; i < n; i++, pos += 2) - sprintf (buf+pos, "%02X", fpr[i]); - strcat (buf, " "); - pos += 1; - strcat (buf, id->name); - write_status_text (STATUS_IMPORT_CHECK, buf); - xfree (buf); -} - -/**************** - * Try to import one keyblock. Return an error only in serious cases, but - * never for an invalid keyblock. It uses log_error to increase the - * internal errorcount, so that invalid input can be detected by programs - * which called g10. - */ -static int -import_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options ) -{ - PKT_public_key *pk; - PKT_public_key *pk_orig; - KBNODE node, uidnode; - KBNODE keyblock_orig = NULL; - u32 keyid[2]; - int rc = 0; - int new_key = 0; - int mod_key = 0; - int non_self = 0; - - /* get the key and print some info about it */ - node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - - pk = node->pkt->pkt.public_key; - keyid_from_pk( pk, keyid ); - uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); - - if(pk->pubkey_algo==PUBKEY_ALGO_ELGAMAL) - log_info(_("NOTE: Elgamal primary key detected - " - "this may take some time to import\n")); - - if( opt.verbose && !opt.interactive ) { - log_info( "pub %4u%c/%08lX %s ", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk(pk) ); - if( uidnode ) - print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len ); - putc('\n', stderr); - } - if( !uidnode ) { - log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]); - return 0; - } - - if (opt.interactive) { - if(is_status_enabled()) - print_import_check (pk, uidnode->pkt->pkt.user_id); - merge_keys_and_selfsig (keyblock); - tty_printf ("\n"); - show_basic_key_info (keyblock); - tty_printf ("\n"); - if (!cpr_get_answer_is_yes ("import.okay", - "Do you want to import this key? (y/N) ")) - return 0; - } - - clear_kbnode_flags( keyblock ); - - if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock) - && opt.verbose) - log_info(_("key %08lX: PKS subkey corruption repaired\n"), - (ulong)keyid[1]); - - rc = chk_self_sigs( fname, keyblock , pk, keyid, &non_self ); - if( rc ) - return rc== -1? 0:rc; - - /* If we allow such a thing, mark unsigned uids as valid */ - if( opt.allow_non_selfsigned_uid ) - for( node=keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) ) - { - char *user=utf8_to_native(node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len,0); - node->flag |= 1; - log_info( _("key %08lX: accepted non self-signed user ID '%s'\n"), - (ulong)keyid[1],user); - xfree (user); - } - - if( !delete_inv_parts( fname, keyblock, keyid, options ) ) { - log_error ( _("key %08lX: no valid user IDs\n"), (ulong)keyid[1]); - if( !opt.quiet ) - log_info(_("this may be caused by a missing self-signature\n")); - stats->no_user_id++; - return 0; - } - - /* do we have this key already in one of our pubrings ? */ - pk_orig = xcalloc (1, sizeof *pk_orig ); - rc = get_pubkey_fast ( pk_orig, keyid ); - if( rc && gpg_err_code (rc) != GPG_ERR_NO_PUBKEY - && gpg_err_code (rc) != GPG_ERR_UNUSABLE_PUBKEY ) { - log_error( _("key %08lX: public key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - } - else if ( rc && opt.merge_only ) { - if( opt.verbose ) - log_info( _("key %08lX: new key - skipped\n"), (ulong)keyid[1] ); - rc = 0; - stats->skipped_new_keys++; - } - else if( rc ) { /* insert this key */ - KEYDB_HANDLE hd = keydb_new (0); - - rc = keydb_locate_writable (hd, NULL); - if (rc) { - log_error (_("no writable keyring found: %s\n"), gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; - } - if( opt.verbose > 1 ) - log_info (_("writing to `%s'\n"), keydb_get_resource_name (hd) ); - rc = keydb_insert_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc)); - else - { - /* This should not be possible since we delete the - ownertrust when a key is deleted, but it can happen if - the keyring and trustdb are out of sync. It can also - be made to happen with the trusted-key command. */ - - clear_ownertrusts (pk); - if(non_self) - revalidation_mark (); - } - keydb_release (hd); - - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable (keyid); - log_info( _("key %08lX: public key \"%s\" imported\n"), - (ulong)keyid[1],p); - xfree (p); - } - if( is_status_enabled() ) { - char *us = get_long_user_id_string( keyid ); - write_status_text( STATUS_IMPORTED, us ); - xfree (us); - print_import_ok (pk,NULL, 1); - } - stats->imported++; - if( is_RSA( pk->pubkey_algo ) ) - stats->imported_rsa++; - new_key = 1; - } - else { /* merge */ - KEYDB_HANDLE hd; - int n_uids, n_sigs, n_subk; - - /* Compare the original against the new key; just to be sure nothing - * weird is going on */ - if( cmp_public_keys( pk_orig, pk ) ) { - log_error( _("key %08lX: doesn't match our copy\n"), - (ulong)keyid[1]); - goto leave; - } - - /* now read the original keyblock */ - hd = keydb_new (0); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk_orig, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (hd, afp); - } - if( rc ) { - log_error (_("key %08lX: can't locate original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - keydb_release (hd); - goto leave; - } - rc = keydb_get_keyblock (hd, &keyblock_orig ); - if (rc) { - log_error (_("key %08lX: can't read original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - keydb_release (hd); - goto leave; - } - - collapse_uids( &keyblock ); - /* and try to merge the block */ - clear_kbnode_flags( keyblock_orig ); - clear_kbnode_flags( keyblock ); - n_uids = n_sigs = n_subk = 0; - rc = merge_blocks( fname, keyblock_orig, keyblock, - keyid, &n_uids, &n_sigs, &n_subk ); - if( rc ) { - keydb_release (hd); - goto leave; - } - if( n_uids || n_sigs || n_subk ) { - mod_key = 1; - /* keyblock_orig has been updated; write */ - rc = keydb_update_keyblock (hd, keyblock_orig); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - else if(non_self) - revalidation_mark (); - - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable(keyid); - if( n_uids == 1 ) - log_info( _("key %08lX: \"%s\" 1 new user ID\n"), - (ulong)keyid[1], p); - else if( n_uids ) - log_info( _("key %08lX: \"%s\" %d new user IDs\n"), - (ulong)keyid[1], p, n_uids ); - if( n_sigs == 1 ) - log_info( _("key %08lX: \"%s\" 1 new signature\n"), - (ulong)keyid[1], p); - else if( n_sigs ) - log_info( _("key %08lX: \"%s\" %d new signatures\n"), - (ulong)keyid[1], p, n_sigs ); - if( n_subk == 1 ) - log_info( _("key %08lX: \"%s\" 1 new subkey\n"), - (ulong)keyid[1], p); - else if( n_subk ) - log_info( _("key %08lX: \"%s\" %d new subkeys\n"), - (ulong)keyid[1], p, n_subk ); - xfree (p); - } - - stats->n_uids +=n_uids; - stats->n_sigs +=n_sigs; - stats->n_subk +=n_subk; - - if (is_status_enabled ()) - print_import_ok (pk, NULL, - ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0))); - } - else { - if (is_status_enabled ()) - print_import_ok (pk, NULL, 0); - - if( !opt.quiet ) { - char *p=get_user_id_printable(keyid); - log_info( _("key %08lX: \"%s\" not changed\n"), - (ulong)keyid[1],p); - xfree (p); - } - stats->unchanged++; - } - keydb_release (hd); hd = NULL; - } - - leave: - release_kbnode( keyblock_orig ); - free_public_key( pk_orig ); - - revocation_present(keyblock); - - return rc; -} - -/* Walk a secret keyblock and produce a public keyblock out of it. */ -static KBNODE -sec_to_pub_keyblock(KBNODE sec_keyblock) -{ - KBNODE secnode,pub_keyblock=NULL,ctx=NULL; - - while((secnode=walk_kbnode(sec_keyblock,&ctx,0))) - { - KBNODE pubnode; - - if(secnode->pkt->pkttype==PKT_SECRET_KEY || - secnode->pkt->pkttype==PKT_SECRET_SUBKEY) - { - /* Make a public key. We only need to convert enough to - write the keyblock out. */ - - PKT_secret_key *sk=secnode->pkt->pkt.secret_key; - PACKET *pkt=xcalloc (1,sizeof(PACKET)); - PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key)); - int n; - - if(secnode->pkt->pkttype==PKT_SECRET_KEY) - pkt->pkttype=PKT_PUBLIC_KEY; - else - pkt->pkttype=PKT_PUBLIC_SUBKEY; - - pkt->pkt.public_key=pk; - - pk->version=sk->version; - pk->timestamp=sk->timestamp; - pk->expiredate=sk->expiredate; - pk->pubkey_algo=sk->pubkey_algo; - - n=pubkey_get_npkey(pk->pubkey_algo); - if(n==0) - pk->pkey[0]=mpi_copy(sk->skey[0]); - else - { - int i; - - for(i=0;i<n;i++) - pk->pkey[i]=mpi_copy(sk->skey[i]); - } - - pubnode=new_kbnode(pkt); - } - else - { - pubnode=clone_kbnode(secnode); - } - - if(pub_keyblock==NULL) - pub_keyblock=pubnode; - else - add_kbnode(pub_keyblock,pubnode); - } - - return pub_keyblock; -} - -/**************** - * Ditto for secret keys. Handling is simpler than for public keys. - * We allow secret key importing only when allow is true, this is so - * that a secret key can not be imported accidently and thereby tampering - * with the trust calculation. - */ -static int -import_secret_one( const char *fname, KBNODE keyblock, - struct stats_s *stats, unsigned int options) -{ - PKT_secret_key *sk; - KBNODE node, uidnode; - u32 keyid[2]; - int rc = 0; - - /* get the key and print some info about it */ - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) - BUG(); - - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); - - if( opt.verbose ) { - log_info( "sec %4u%c/%08lX %s ", - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid[1], datestr_from_sk(sk) ); - if( uidnode ) - print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len ); - putc('\n', stderr); - } - stats->secret_read++; - - if( !uidnode ) { - log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]); - return 0; - } - - if(sk->protect.algo>110) - { - log_error(_("key %08lX: secret key with invalid cipher %d " - "- skipped\n"),(ulong)keyid[1],sk->protect.algo); - return 0; - } - - clear_kbnode_flags( keyblock ); - - /* do we have this key already in one of our secrings ? */ - rc = seckey_available( keyid ); - if( gpg_err_code (rc) == GPG_ERR_NO_SECKEY && !opt.merge_only ) { - /* simply insert this key */ - KEYDB_HANDLE hd = keydb_new (1); - - /* get default resource */ - rc = keydb_locate_writable (hd, NULL); - if (rc) { - log_error (_("no default secret keyring: %s\n"), gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; - } - rc = keydb_insert_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); - /* we are ready */ - if( !opt.quiet ) - log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]); - stats->secret_imported++; - if (is_status_enabled ()) - print_import_ok (NULL, sk, 1|16); - - if(options&IMPORT_SK2PK) - { - /* Try and make a public key out of this. */ - - KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock); - import_one(fname,pub_keyblock,stats,opt.import_options); - release_kbnode(pub_keyblock); - } - - } - else if( !rc ) { /* we can't merge secret keys */ - log_error( _("key %08lX: already in secret keyring\n"), - (ulong)keyid[1]); - stats->secret_dups++; - if (is_status_enabled ()) - print_import_ok (NULL, sk, 16); - - /* TODO: if we ever do merge secret keys, make sure to handle - the sec_to_pub_keyblock feature as well. */ - } - else - log_error( _("key %08lX: secret key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - - return rc; -} - - -/**************** - * Import a revocation certificate; this is a single signature packet. - */ -static int -import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats ) -{ - PKT_public_key *pk=NULL; - KBNODE onode, keyblock = NULL; - KEYDB_HANDLE hd = NULL; - u32 keyid[2]; - int rc = 0; - - assert( !node->next ); - assert( node->pkt->pkttype == PKT_SIGNATURE ); - assert( node->pkt->pkt.signature->sig_class == 0x20 ); - - keyid[0] = node->pkt->pkt.signature->keyid[0]; - keyid[1] = node->pkt->pkt.signature->keyid[1]; - - pk = xcalloc (1, sizeof *pk ); - rc = get_pubkey( pk, keyid ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) { - log_error ( _("key %08lX: no public key - " - "can't apply revocation certificate\n"), (ulong)keyid[1]); - rc = 0; - goto leave; - } - else if( rc ) { - log_error( _("key %08lX: public key not found: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - /* read the original keyblock */ - hd = keydb_new (0); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (hd, afp); - } - if (rc) { - log_error (_("key %08lX: can't locate original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - rc = keydb_get_keyblock (hd, &keyblock ); - if (rc) { - log_error (_("key %08lX: can't read original keyblock: %s\n"), - (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - - /* it is okay, that node is not in keyblock because - * check_key_signature works fine for sig_class 0x20 in this - * special case. */ - rc = check_key_signature( keyblock, node, NULL); - if( rc ) { - log_error( _("key %08lX: invalid revocation certificate" - ": %s - rejected\n"), (ulong)keyid[1], gpg_strerror (rc)); - goto leave; - } - - - /* check whether we already have this */ - for(onode=keyblock->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && !cmp_signatures(node->pkt->pkt.signature, - onode->pkt->pkt.signature)) - { - rc = 0; - goto leave; /* yes, we already know about it */ - } - } - - - /* insert it */ - insert_kbnode( keyblock, clone_kbnode(node), 0 ); - - /* and write the keyblock back */ - rc = keydb_update_keyblock (hd, keyblock ); - if (rc) - log_error (_("error writing keyring `%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); - keydb_release (hd); hd = NULL; - /* we are ready */ - if( !opt.quiet ) { - char *p=get_user_id_printable (keyid); - log_info( _("key %08lX: \"%s\" revocation certificate imported\n"), - (ulong)keyid[1],p); - xfree (p); - } - stats->n_revoc++; - - /* If the key we just revoked was ultimately trusted, remove its - ultimate trust. This doesn't stop the user from putting the - ultimate trust back, but is a reasonable solution for now. */ - if(get_ownertrust(pk)==TRUST_ULTIMATE) - clear_ownertrusts(pk); - - revalidation_mark (); - - leave: - keydb_release (hd); - release_kbnode( keyblock ); - free_public_key( pk ); - return rc; -} - - -/**************** - * loop over the keyblock and check all self signatures. - * Mark all user-ids with a self-signature by setting flag bit 0. - * Mark all user-ids with an invalid self-signature by setting bit 1. - * This works also for subkeys, here the subkey is marked. Invalid or - * extra subkey sigs (binding or revocation) are marked for deletion. - * non_self is set to true if there are any sigs other than self-sigs - * in this keyblock. - */ -static int -chk_self_sigs( const char *fname, KBNODE keyblock, - PKT_public_key *pk, u32 *keyid, int *non_self ) -{ - KBNODE n,knode=NULL; - PKT_signature *sig; - int rc; - u32 bsdate=0,rsdate=0; - KBNODE bsnode=NULL,rsnode=NULL; - - for( n=keyblock; (n = find_next_kbnode(n, 0)); ) { - if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY) - { - knode=n; - bsdate=0; - rsdate=0; - bsnode=NULL; - rsnode=NULL; - continue; - } - else if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = n->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - - /* This just caches the sigs for later use. That way we - import a fully-cached key which speeds things up. */ - if(!opt.no_sig_cache) - check_key_signature(keyblock,n,NULL); - - if( (sig->sig_class&~3) == 0x10 ) { - KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); - if( !unode ) { - log_error( _("key %08lX: no user ID for signature\n"), - (ulong)keyid[1]); - return -1; /* the complete keyblock is invalid */ - } - - /* If it hasn't been marked valid yet, keep trying */ - if(!(unode->flag&1)) { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if (opt.verbose) - { - char *p=utf8_to_native(unode->pkt->pkt.user_id->name, - strlen(unode->pkt->pkt.user_id->name),0); - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key " - "algorithm on user id \"%s\"\n"): - _("key %08lX: invalid self-signature " - "on user id \"%s\"\n"), - (ulong)keyid[1],p); - xfree (p); - } - } - else - unode->flag |= 1; /* mark that signature checked */ - } - } - else if( sig->sig_class == 0x18 ) { - /* Note that this works based solely on the timestamps - like the rest of gpg. If the standard gets - revocation targets, this may need to be revised. */ - - if( !knode ) - { - if (opt.verbose) - log_info( _("key %08lX: no subkey for subkey " - "binding signature\n"),(ulong)keyid[1]); - n->flag |= 4; /* delete this */ - } - else - { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) - { - if (opt.verbose) - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key algorithm\n"): - _("key %08lX: invalid subkey binding\n"), - (ulong)keyid[1]); - n->flag|=4; - } - else - { - /* It's valid, so is it newer? */ - if(sig->timestamp>=bsdate) - { - knode->flag |= 1; /* the subkey is valid */ - if(bsnode) - { - bsnode->flag|=4; /* Delete the last binding - sig since this one is - newer */ - if (opt.verbose) - log_info(_("key %08lX: removed multiple " - "subkey binding\n"), - (ulong)keyid[1]); - } - - bsnode=n; - bsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - else if( sig->sig_class == 0x28 ) { - /* We don't actually mark the subkey as revoked right - now, so just check that the revocation sig is the - most recent valid one. Note that we don't care if - the binding sig is newer than the revocation sig. - See the comment in getkey.c:merge_selfsigs_subkey for - more */ - if( !knode ) { - if (opt.verbose) - log_info( _("key %08lX: no subkey for subkey " - "revocation signature\n"),(ulong)keyid[1]); - n->flag |= 4; /* delete this */ - } - else { - rc = check_key_signature( keyblock, n, NULL); - if( rc ) { - if (opt.verbose) - log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? - _("key %08lX: unsupported public key algorithm\n"): - _("key %08lX: invalid subkey revocation\n"), - (ulong)keyid[1]); - n->flag|=4; - } - else { - /* It's valid, so is it newer? */ - if(sig->timestamp>=rsdate) { - if(rsnode) { - rsnode->flag|=4; /* Delete the last revocation - sig since this one is - newer */ - if (opt.verbose) - log_info(_("key %08lX: removed multiple subkey " - "revocation signatures\n"), - (ulong)keyid[1]); - } - - rsnode=n; - rsdate=sig->timestamp; - } - else - n->flag|=4; /* older */ - } - } - } - } - else - *non_self=1; - } - - return 0; -} - -/**************** - * delete all parts which are invalid and those signatures whose - * public key algorithm is not available in this implemenation; - * but consider RSA as valid, because parse/build_packets knows - * about it. - * returns: true if at least one valid user-id is left over. - */ -static int -delete_inv_parts( const char *fname, KBNODE keyblock, - u32 *keyid, unsigned int options) -{ - KBNODE node; - int nvalid=0, uid_seen=0, subkey_seen=0; - - for(node=keyblock->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - uid_seen = 1; - if( (node->flag & 2) || !(node->flag & 1) ) { - if( opt.verbose ) { - log_info( _("key %08lX: skipped user ID '"), - (ulong)keyid[1]); - print_utf8_string( stderr, node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len ); - fputs("'\n", stderr ); - } - delete_kbnode( node ); /* the user-id */ - /* and all following packets up to the next user-id */ - while( node->next - && node->next->pkt->pkttype != PKT_USER_ID - && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY - && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ){ - delete_kbnode( node->next ); - node = node->next; - } - } - else - nvalid++; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( (node->flag & 2) || !(node->flag & 1) ) { - if( opt.verbose ) { - log_info( _("key %08lX: skipped subkey\n"), - (ulong)keyid[1]); - } - delete_kbnode( node ); /* the subkey */ - /* and all following signature packets */ - while( node->next - && node->next->pkt->pkttype == PKT_SIGNATURE ) { - delete_kbnode( node->next ); - node = node->next; - } - } - else - subkey_seen = 1; - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && openpgp_pk_test_algo( node->pkt->pkt.signature - ->pubkey_algo, 0) - && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) - delete_kbnode( node ); /* build_packet() can't handle this */ - else if( node->pkt->pkttype == PKT_SIGNATURE && - !node->pkt->pkt.signature->flags.exportable && - !(options&IMPORT_ALLOW_LOCAL_SIGS) && - seckey_available( node->pkt->pkt.signature->keyid ) ) { - /* Here we violate the rfc a bit by still allowing - * to import non-exportable signature when we have the - * the secret key used to create this signature - it - * seems that this makes sense. */ - if (opt.verbose) - log_info( _("key %08lX: non exportable signature " - "(class %02x) - skipped\n"), - (ulong)keyid[1], - node->pkt->pkt.signature->sig_class ); - delete_kbnode( node ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x20 ) { - if( uid_seen ) { - if (opt.verbose) - log_error( _("key %08lX: revocation certificate " - "at wrong place - skipped\n"), - (ulong)keyid[1]); - delete_kbnode( node ); - } - else { - /* If the revocation cert is from a different key than - the one we're working on don't check it - it's - probably from a revocation key and won't be - verifiable with this key anyway. */ - - if(node->pkt->pkt.signature->keyid[0]==keyid[0] && - node->pkt->pkt.signature->keyid[1]==keyid[1]) - { - int rc = check_key_signature( keyblock, node, NULL); - if( rc ) - { - if (opt.verbose) - log_info ( _("key %08lX: invalid revocation " - "certificate: %s - skipped\n"), - (ulong)keyid[1], gpg_strerror (rc)); - delete_kbnode( node ); - } - } - } - } - else if( node->pkt->pkttype == PKT_SIGNATURE && - (node->pkt->pkt.signature->sig_class == 0x18 || - node->pkt->pkt.signature->sig_class == 0x28) && - !subkey_seen ) { - if (opt.verbose) - log_info ( _("key %08lX: subkey signature " - "in wrong place - skipped\n"), - (ulong)keyid[1]); - delete_kbnode( node ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE - && !IS_CERT(node->pkt->pkt.signature)) - { - if (opt.verbose) - log_info (_("key %08lX: unexpected signature class (0x%02X) -" - " skipped\n"),(ulong)keyid[1], - node->pkt->pkt.signature->sig_class); - delete_kbnode(node); - } - else if( (node->flag & 4) ) /* marked for deletion */ - delete_kbnode( node ); - } - - /* note: because keyblock is the public key, it is never marked - * for deletion and so keyblock cannot change */ - commit_kbnode( &keyblock ); - return nvalid; -} - - -/**************** - * It may happen that the imported keyblock has duplicated user IDs. - * We check this here and collapse those user IDs together with their - * sigs into one. - * Returns: True if the keyblock hash changed. - */ -int -collapse_uids( KBNODE *keyblock ) -{ - KBNODE n, n2; - int in_uid; - int any=0; - u32 kid1; - - restart: - for( n = *keyblock; n; n = n->next ) { - if( n->pkt->pkttype != PKT_USER_ID ) - continue; - for( n2 = n->next; n2; n2 = n2->next ) { - if( n2->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( n->pkt->pkt.user_id, - n2->pkt->pkt.user_id ) ) { - /* found a duplicate */ - any = 1; - if( !n2->next - || n2->next->pkt->pkttype == PKT_USER_ID - || n2->next->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->next->pkt->pkttype == PKT_SECRET_SUBKEY ) { - /* no more signatures: delete the user ID - * and start over */ - remove_kbnode( keyblock, n2 ); - } - else { - /* The simple approach: Move one signature and - * then start over to delete the next one :-( */ - move_kbnode( keyblock, n2->next, n->next ); - } - goto restart; - } - } - } - if( !any ) - return 0; - - restart_sig: - /* now we may have duplicate signatures on one user ID: fix this */ - for( in_uid = 0, n = *keyblock; n; n = n->next ) { - if( n->pkt->pkttype == PKT_USER_ID ) - in_uid = 1; - else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_SECRET_SUBKEY ) - in_uid = 0; - else if( in_uid ) { - n2 = n; - do { - KBNODE ncmp = NULL; - for( ; n2; n2 = n2->next ) { - if( n2->pkt->pkttype == PKT_USER_ID - || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - if( n2->pkt->pkttype != PKT_SIGNATURE ) - ; - else if( !ncmp ) - ncmp = n2; - else if( !cmp_signatures( ncmp->pkt->pkt.signature, - n2->pkt->pkt.signature )) { - remove_kbnode( keyblock, n2 ); - goto restart_sig; - } - } - n2 = ncmp? ncmp->next : NULL; - } while( n2 ); - } - } - - if( (n = find_kbnode( *keyblock, PKT_PUBLIC_KEY )) ) - kid1 = keyid_from_pk( n->pkt->pkt.public_key, NULL ); - else if( (n = find_kbnode( *keyblock, PKT_SECRET_KEY )) ) - kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL ); - else - kid1 = 0; - if (!opt.quiet) - log_info (_("key %08lX: duplicated user ID detected - merged\n"), - (ulong)kid1); - - return 1; -} - -/* Check for a 0x20 revocation from a revocation key that is not - present. This gets called without the benefit of merge_xxxx so you - can't rely on pk->revkey and friends. */ -static void -revocation_present(KBNODE keyblock) -{ - KBNODE onode,inode; - PKT_public_key *pk=keyblock->pkt->pkt.public_key; - - for(onode=keyblock->next;onode;onode=onode->next) - { - /* If we reach user IDs, we're done. */ - if(onode->pkt->pkttype==PKT_USER_ID) - break; - - if(onode->pkt->pkttype==PKT_SIGNATURE && - onode->pkt->pkt.signature->sig_class==0x1F && - onode->pkt->pkt.signature->revkey) - { - int idx; - PKT_signature *sig=onode->pkt->pkt.signature; - - for(idx=0;idx<sig->numrevkeys;idx++) - { - u32 keyid[2]; - - keyid_from_fingerprint(sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN,keyid); - - for(inode=keyblock->next;inode;inode=inode->next) - { - /* If we reach user IDs, we're done. */ - if(inode->pkt->pkttype==PKT_USER_ID) - break; - - if(inode->pkt->pkttype==PKT_SIGNATURE && - inode->pkt->pkt.signature->sig_class==0x20 && - inode->pkt->pkt.signature->keyid[0]==keyid[0] && - inode->pkt->pkt.signature->keyid[1]==keyid[1]) - { - /* Okay, we have a revocation key, and a - revocation issued by it. Do we have the key - itself? */ - int rc; - - rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - if ( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) - { - /* No, so try and get it */ - if(opt.keyserver_scheme && - opt.keyserver_options.auto_key_retrieve) - { - log_info(_("WARNING: key %08lX may be revoked: " - "fetching revocation key %08lX\n"), - (ulong)keyid_from_pk(pk,NULL), - (ulong)keyid[1]); - keyserver_import_fprint(sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - - /* Do we have it now? */ - rc=get_pubkey_byfprint_fast (NULL, - sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN); - } - - if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) - log_info(_("WARNING: key %08lX may be revoked: " - "revocation key %08lX not present.\n"), - (ulong)keyid_from_pk(pk,NULL), - (ulong)keyid[1]); - } - } - } - } - } - } -} - -/**************** - * compare and merge the blocks - * - * o compare the signatures: If we already have this signature, check - * that they compare okay; if not, issue a warning and ask the user. - * o Simply add the signature. Can't verify here because we may not have - * the signature's public key yet; verification is done when putting it - * into the trustdb, which is done automagically as soon as this pubkey - * is used. - * Note: We indicate newly inserted packets with flag bit 0 - */ -static int -merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, - u32 *keyid, int *n_uids, int *n_sigs, int *n_subk ) -{ - KBNODE onode, node; - int rc, found; - - /* 1st: handle revocation certificates */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x20 ) { - /* check whether we already have this */ - found = 0; - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && onode->pkt->pkt.signature->sig_class == 0x20 - && !cmp_signatures(onode->pkt->pkt.signature, - node->pkt->pkt.signature)) - { - found = 1; - break; - } - } - if( !found ) { - KBNODE n2 = clone_kbnode(node); - insert_kbnode( keyblock_orig, n2, 0 ); - n2->flag |= 1; - ++*n_sigs; - - if (!opt.quiet) - { - char *p=get_user_id_printable (keyid); - log_info(_("key %08lX: \"%s\" " - "revocation certificate added\n"), - (ulong)keyid[1],p); - xfree (p); - } - } - } - } - - /* 2nd: merge in any direct key (0x1F) sigs */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - else if( node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x1F ) { - /* check whether we already have this */ - found = 0; - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( onode->pkt->pkttype == PKT_USER_ID ) - break; - else if( onode->pkt->pkttype == PKT_SIGNATURE - && onode->pkt->pkt.signature->sig_class == 0x1F - && !cmp_signatures(onode->pkt->pkt.signature, - node->pkt->pkt.signature)) { - found = 1; - break; - } - } - if( !found ) { - KBNODE n2 = clone_kbnode(node); - insert_kbnode( keyblock_orig, n2, 0 ); - n2->flag |= 1; - ++*n_sigs; - if (!opt.quiet) - log_info( _("key %08lX: direct key signature added\n"), - (ulong)keyid[1]); - } - } - } - - /* 3rd: try to merge new certificates in */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) { - /* find the user id in the imported keyblock */ - for(node=keyblock->next; node; node=node->next ) - if( node->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( onode->pkt->pkt.user_id, - node->pkt->pkt.user_id ) ) - break; - if( node ) { /* found: merge */ - rc = merge_sigs( onode, node, n_sigs, fname, keyid ); - if( rc ) - return rc; - } - } - } - - /* 4th: add new user-ids */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_USER_ID) { - /* do we have this in the original keyblock */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_USER_ID - && !cmp_user_ids( onode->pkt->pkt.user_id, - node->pkt->pkt.user_id ) ) - break; - if( !onode ) { /* this is a new user id: append */ - rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_uids; - } - } - } - - /* 5th: add new subkeys */ - for(node=keyblock->next; node; node=node->next ) { - onode = NULL; - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - /* do we have this in the original keyblock? */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY - && !cmp_public_keys( onode->pkt->pkt.public_key, - node->pkt->pkt.public_key ) ) - break; - if( !onode ) { /* this is a new subkey: append */ - rc = append_key( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_subk; - } - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - /* do we have this in the original keyblock? */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) - if( onode->pkt->pkttype == PKT_SECRET_SUBKEY - && !cmp_secret_keys( onode->pkt->pkt.secret_key, - node->pkt->pkt.secret_key ) ) - break; - if( !onode ) { /* this is a new subkey: append */ - rc = append_key( keyblock_orig, node, n_sigs, fname, keyid); - if( rc ) - return rc; - ++*n_subk; - } - } - } - - /* 6th: merge subkey certificates */ - for(onode=keyblock_orig->next; onode; onode=onode->next ) { - if( !(onode->flag & 1) - && ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY - || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) { - /* find the subkey in the imported keyblock */ - for(node=keyblock->next; node; node=node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && !cmp_public_keys( onode->pkt->pkt.public_key, - node->pkt->pkt.public_key ) ) - break; - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY - && !cmp_secret_keys( onode->pkt->pkt.secret_key, - node->pkt->pkt.secret_key ) ) - break; - } - if( node ) { /* found: merge */ - rc = merge_keysigs( onode, node, n_sigs, fname, keyid ); - if( rc ) - return rc; - } - } - } - - - return 0; -} - - -/**************** - * append the userid starting with NODE and all signatures to KEYBLOCK. - */ -static int -append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n_where=NULL; - - assert(node->pkt->pkttype == PKT_USER_ID ); - - /* find the position */ - for( n = keyblock; n; n_where = n, n = n->next ) { - if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - } - if( !n ) - n_where = NULL; - - /* and append/insert */ - while( node ) { - /* we add a clone to the original keyblock, because this - * one is released first */ - n = clone_kbnode(node); - if( n_where ) { - insert_kbnode( n_where, n, 0 ); - n_where = n; - } - else - add_kbnode( keyblock, n ); - n->flag |= 1; - node->flag |= 1; - if( n->pkt->pkttype == PKT_SIGNATURE ) - ++*n_sigs; - - node = node->next; - if( node && node->pkt->pkttype != PKT_SIGNATURE ) - break; - } - - return 0; -} - - -/**************** - * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID. - * (how should we handle comment packets here?) - */ -static int -merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n2; - int found=0; - - assert(dst->pkt->pkttype == PKT_USER_ID ); - assert(src->pkt->pkttype == PKT_USER_ID ); - - for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) { - if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - if( n->pkt->pkt.signature->sig_class == 0x18 - || n->pkt->pkt.signature->sig_class == 0x28 ) - continue; /* skip signatures which are only valid on subkeys */ - found = 0; - for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next) - if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature)) - { - found++; - break; - } - if( !found ) { - /* This signature is new or newer, append N to DST. - * We add a clone to the original keyblock, because this - * one is released first */ - n2 = clone_kbnode(n); - insert_kbnode( dst, n2, PKT_SIGNATURE ); - n2->flag |= 1; - n->flag |= 1; - ++*n_sigs; - } - } - - return 0; -} - -/**************** - * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY. - */ -static int -merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n, n2; - int found=0; - - assert( dst->pkt->pkttype == PKT_PUBLIC_SUBKEY - || dst->pkt->pkttype == PKT_SECRET_SUBKEY ); - - for(n=src->next; n ; n = n->next ) { - if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n->pkt->pkttype == PKT_PUBLIC_KEY ) - break; - if( n->pkt->pkttype != PKT_SIGNATURE ) - continue; - found = 0; - for(n2=dst->next; n2; n2 = n2->next){ - if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY - || n2->pkt->pkttype == PKT_PUBLIC_KEY ) - break; - if( n2->pkt->pkttype == PKT_SIGNATURE - && n->pkt->pkt.signature->keyid[0] - == n2->pkt->pkt.signature->keyid[0] - && n->pkt->pkt.signature->keyid[1] - == n2->pkt->pkt.signature->keyid[1] - && n->pkt->pkt.signature->timestamp - <= n2->pkt->pkt.signature->timestamp - && n->pkt->pkt.signature->sig_class - == n2->pkt->pkt.signature->sig_class ) { - found++; - break; - } - } - if( !found ) { - /* This signature is new or newer, append N to DST. - * We add a clone to the original keyblock, because this - * one is released first */ - n2 = clone_kbnode(n); - insert_kbnode( dst, n2, PKT_SIGNATURE ); - n2->flag |= 1; - n->flag |= 1; - ++*n_sigs; - } - } - - return 0; -} - -/**************** - * append the subkey starting with NODE and all signatures to KEYBLOCK. - * Mark all new and copied packets by setting flag bit 0. - */ -static int -append_key( KBNODE keyblock, KBNODE node, int *n_sigs, - const char *fname, u32 *keyid ) -{ - KBNODE n; - - assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ); - - while( node ) { - /* we add a clone to the original keyblock, because this - * one is released first */ - n = clone_kbnode(node); - add_kbnode( keyblock, n ); - n->flag |= 1; - node->flag |= 1; - if( n->pkt->pkttype == PKT_SIGNATURE ) - ++*n_sigs; - - node = node->next; - if( node && node->pkt->pkttype != PKT_SIGNATURE ) - break; - } - - return 0; -} diff --git a/g10/kbnode.c b/g10/kbnode.c deleted file mode 100644 index 58daad871..000000000 --- a/g10/kbnode.c +++ /dev/null @@ -1,401 +0,0 @@ -/* kbnode.c - keyblock node utility functions - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "keydb.h" - -#define USE_UNUSED_NODES 1 - -static KBNODE unused_nodes; - -static KBNODE -alloc_node(void) -{ - KBNODE n; - - n = unused_nodes; - if( n ) - unused_nodes = n->next; - else - n = xmalloc ( sizeof *n ); - n->next = NULL; - n->pkt = NULL; - n->flag = 0; - n->private_flag=0; - n->recno = 0; - return n; -} - -static void -free_node( KBNODE n ) -{ - if( n ) { -#if USE_UNUSED_NODES - n->next = unused_nodes; - unused_nodes = n; -#else - xfree ( n ); -#endif - } -} - - - -KBNODE -new_kbnode( PACKET *pkt ) -{ - KBNODE n = alloc_node(); - n->pkt = pkt; - return n; -} - - -KBNODE -clone_kbnode( KBNODE node ) -{ - KBNODE n = alloc_node(); - - n->pkt = node->pkt; - n->private_flag = node->private_flag | 2; /* mark cloned */ - return n; -} - - -void -release_kbnode( KBNODE n ) -{ - KBNODE n2; - - while( n ) { - n2 = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - n = n2; - } -} - - -/**************** - * Delete NODE. - * Note: This only works with walk_kbnode!! - */ -void -delete_kbnode( KBNODE node ) -{ - node->private_flag |= 1; -} - - - -/**************** - * Append NODE to ROOT. ROOT must exist! - */ -void -add_kbnode( KBNODE root, KBNODE node ) -{ - KBNODE n1; - - for(n1=root; n1->next; n1 = n1->next) - ; - n1->next = node; -} - -/**************** - * Insert NODE into the list after root but before a packet which is not of - * type PKTTYPE - * (only if PKTTYPE != 0) - */ -void -insert_kbnode( KBNODE root, KBNODE node, int pkttype ) -{ - if( !pkttype ) { - node->next = root->next; - root->next = node; - } - else { - KBNODE n1; - - for(n1=root; n1->next; n1 = n1->next) - if( pkttype != n1->next->pkt->pkttype ) { - node->next = n1->next; - n1->next = node; - return; - } - /* no such packet, append */ - node->next = NULL; - n1->next = node; - } -} - - -/**************** - * Find the previous node (if PKTTYPE = 0) or the previous node - * with pkttype PKTTYPE in the list starting with ROOT of NODE. - */ -KBNODE -find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ) -{ - KBNODE n1; - - for (n1=NULL; root && root != node; root = root->next ) { - if (!pkttype ||root->pkt->pkttype == pkttype) - n1 = root; - } - return n1; -} - -/**************** - * Ditto, but find the next packet. The behaviour is trivial if - * PKTTYPE is 0 but if it is specified, the next node with a packet - * of this type is returned. The function has some knowledge about - * the valid ordering of packets: e.g. if the next signature packet - * is requested, the function will not return one if it encounters - * a user-id. - */ -KBNODE -find_next_kbnode( KBNODE node, int pkttype ) -{ - for( node=node->next ; node; node = node->next ) { - if( !pkttype ) - return node; - else if( pkttype == PKT_USER_ID - && ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_SECRET_KEY ) ) - return NULL; - else if( pkttype == PKT_SIGNATURE - && ( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_SECRET_KEY ) ) - return NULL; - else if( node->pkt->pkttype == pkttype ) - return node; - } - return NULL; -} - - -KBNODE -find_kbnode( KBNODE node, int pkttype ) -{ - for( ; node; node = node->next ) { - if( node->pkt->pkttype == pkttype ) - return node; - } - return NULL; -} - - - -/**************** - * Walk through a list of kbnodes. This function returns - * the next kbnode for each call; before using the function the first - * time, the caller must set CONTEXT to NULL (This has simply the effect - * to start with ROOT). - */ -KBNODE -walk_kbnode( KBNODE root, KBNODE *context, int all ) -{ - KBNODE n; - - do { - if( !*context ) { - *context = root; - n = root; - } - else { - n = (*context)->next; - *context = n; - } - } while( !all && n && is_deleted_kbnode(n) ); - - return n; -} - -void -clear_kbnode_flags( KBNODE n ) -{ - for( ; n; n = n->next ) { - n->flag = 0; - } -} - - -/**************** - * Commit changes made to the kblist at ROOT. Note that ROOT my change, - * and it is therefore passed by reference. - * The function has the effect of removing all nodes marked as deleted. - * returns true if any node has been changed - */ -int -commit_kbnode( KBNODE *root ) -{ - KBNODE n, nl; - int changed = 0; - - for( n = *root, nl=NULL; n; n = nl->next ) { - if( is_deleted_kbnode(n) ) { - if( n == *root ) - *root = nl = n->next; - else - nl->next = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - changed = 1; - } - else - nl = n; - } - return changed; -} - -void -remove_kbnode( KBNODE *root, KBNODE node ) -{ - KBNODE n, nl; - - for( n = *root, nl=NULL; n; n = nl->next ) { - if( n == node ) { - if( n == *root ) - *root = nl = n->next; - else - nl->next = n->next; - if( !is_cloned_kbnode(n) ) { - free_packet( n->pkt ); - xfree ( n->pkt ); - } - free_node( n ); - } - else - nl = n; - } -} - - -/**************** - * Move NODE behind right after WHERE or to the beginning if WHERE is NULL. - */ -void -move_kbnode( KBNODE *root, KBNODE node, KBNODE where ) -{ - KBNODE tmp, prev; - - if( !root || !*root || !node ) - return; /* sanity check */ - for( prev = *root; prev && prev->next != node; prev = prev->next ) - ; - if( !prev ) - return; /* node is not in the list */ - - if( !where ) { /* move node before root */ - if( node == *root ) /* move to itself */ - return; - prev->next = node->next; - node->next = *root; - *root = node; - return; - } - /* move it after where */ - if( node == where ) - return; - tmp = node->next; - node->next = where->next; - where->next = node; - prev->next = tmp; -} - - - - -void -dump_kbnode( KBNODE node ) -{ - for(; node; node = node->next ) { - const char *s; - switch( node->pkt->pkttype ) { - case 0: s="empty"; break; - case PKT_PUBLIC_KEY: s="public-key"; break; - case PKT_SECRET_KEY: s="secret-key"; break; - case PKT_SECRET_SUBKEY: s= "secret-subkey"; break; - case PKT_PUBKEY_ENC: s="public-enc"; break; - case PKT_SIGNATURE: s="signature"; break; - case PKT_ONEPASS_SIG: s="onepass-sig"; break; - case PKT_USER_ID: s="user-id"; break; - case PKT_PUBLIC_SUBKEY: s="public-subkey"; break; - case PKT_COMMENT: s="comment"; break; - case PKT_RING_TRUST: s="trust"; break; - case PKT_PLAINTEXT: s="plaintext"; break; - case PKT_COMPRESSED: s="compressed"; break; - case PKT_ENCRYPTED: s="encrypted"; break; - case PKT_GPG_CONTROL: s="gpg-control"; break; - default: s="unknown"; break; - } - fprintf(stderr, "node %p %02x/%02x type=%s", - node, node->flag, node->private_flag, s); - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - fputs(" \"", stderr); - print_string( stderr, uid->name, uid->len, 0 ); - fprintf (stderr, "\" %c%c%c%c\n", - uid->is_expired? 'e':'.', - uid->is_revoked? 'r':'.', - uid->created? 'v':'.', - uid->is_primary? 'p':'.' ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - fprintf(stderr, " class=%02x keyid=%08lX ts=%lu\n", - node->pkt->pkt.signature->sig_class, - (ulong)node->pkt->pkt.signature->keyid[1], - (ulong)node->pkt->pkt.signature->timestamp); - } - else if( node->pkt->pkttype == PKT_GPG_CONTROL ) { - fprintf(stderr, " ctrl=%d len=%u\n", - node->pkt->pkt.gpg_control->control, - (unsigned int)node->pkt->pkt.gpg_control->datalen); - } - else if( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - fprintf(stderr, " keyid=%08lX a=%d u=%d %c%c%c%c\n", - (ulong)keyid_from_pk( pk, NULL ), - pk->pubkey_algo, pk->pubkey_usage, - pk->has_expired? 'e':'.', - pk->is_revoked? 'r':'.', - pk->is_valid? 'v':'.', - pk->mdc_feature? 'm':'.'); - } - else - fputs("\n", stderr); - } -} diff --git a/g10/keydb.c b/g10/keydb.c deleted file mode 100644 index b64f38cbc..000000000 --- a/g10/keydb.c +++ /dev/null @@ -1,725 +0,0 @@ -/* keydb.c - key database dispatcher - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "gpg.h" -#include "util.h" -#include "options.h" -#include "main.h" /*try_make_homedir ()*/ -#include "packet.h" -#include "keyring.h" -#include "keydb.h" -#include "i18n.h" - -static int active_handles; - -typedef enum { - KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYRING -} KeydbResourceType; -#define MAX_KEYDB_RESOURCES 40 - -struct resource_item { - KeydbResourceType type; - union { - KEYRING_HANDLE kr; - } u; - void *token; - int secret; -}; - -static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; -static int used_resources; -static void *primary_keyring=NULL; - -struct keydb_handle { - int locked; - int found; - int current; - int used; /* items in active */ - struct resource_item active[MAX_KEYDB_RESOURCES]; -}; - - -static int lock_all (KEYDB_HANDLE hd); -static void unlock_all (KEYDB_HANDLE hd); - - -/* - * Register a resource (which currently may only be a keyring file). - * The first keyring which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - * Flag 1 == force - * Flag 2 == default - */ -int -keydb_add_resource (const char *url, int flags, int secret) -{ - static int any_secret, any_public; - const char *resname = url; - iobuf_t iobuf = NULL; - char *filename = NULL; - int force=(flags&1); - int rc = 0; - KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; - void *token; - - /* Do we have an URL? - * gnupg-ring:filename := this is a plain keyring - * filename := See what is is, but create as plain keyring. - */ - if (strlen (resname) > 11) { - if (!strncmp( resname, "gnupg-ring:", 11) ) { - rt = KEYDB_RESOURCE_TYPE_KEYRING; - resname += 11; - } -#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) { - log_error ("invalid key resource URL `%s'\n", url ); - rc = GPG_ERR_GENERAL; - goto leave; - } -#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ - } - - if (*resname != DIRSEP_C ) { /* do tilde expansion etc */ - if (strchr(resname, DIRSEP_C) ) - filename = make_filename (resname, NULL); - else - filename = make_filename (opt.homedir, resname, NULL); - } - else - filename = xstrdup (resname); - - if (!force) - force = secret? !any_secret : !any_public; - - /* see whether we can determine the filetype */ - if (rt == KEYDB_RESOURCE_TYPE_NONE) { - FILE *fp = fopen( filename, "rb" ); - - if (fp) { - u32 magic; - - if (fread( &magic, 4, 1, fp) == 1 ) { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - no more support */ - else - rt = KEYDB_RESOURCE_TYPE_KEYRING; - } - else /* maybe empty: assume ring */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; - fclose( fp ); - } - else /* no file yet: create ring */ - rt = KEYDB_RESOURCE_TYPE_KEYRING; - } - - switch (rt) { - case KEYDB_RESOURCE_TYPE_NONE: - log_error ("unknown type of key resource `%s'\n", url ); - rc = GPG_ERR_GENERAL; - goto leave; - - case KEYDB_RESOURCE_TYPE_KEYRING: - if (access(filename, F_OK)) - { /* file does not exist */ - mode_t oldmask; - char *last_slash_in_filename; - - if (!force) - { - rc = gpg_error_from_errno (errno); - goto leave; - } - - last_slash_in_filename = strrchr (filename, DIRSEP_C); - *last_slash_in_filename = 0; - if (access(filename, F_OK)) - { /* On the first time we try to create the default - homedir and check again. */ - static int tried; - - if (!tried) - { - tried = 1; - try_make_homedir (filename); - } - if (access (filename, F_OK)) - { - rc = gpg_error_from_errno (errno); - *last_slash_in_filename = DIRSEP_C; - goto leave; - } - } - *last_slash_in_filename = DIRSEP_C; - - oldmask=umask(077); - iobuf = iobuf_create (filename); - umask(oldmask); - if (!iobuf) - { - log_error ( _("error creating keyring `%s': %s\n"), - filename, strerror(errno)); - rc = gpg_error_from_errno (errno); - goto leave; - } - - if (!opt.quiet) - log_info (_("keyring `%s' created\n"), filename); - iobuf_close (iobuf); - iobuf = NULL; - /* must invalidate that ugly cache */ - iobuf_ioctl (NULL, 2, 0, (char*)filename); - } /* end file creation */ - - if(keyring_register_filename (filename, secret, &token)) - { - if (used_resources >= MAX_KEYDB_RESOURCES) - rc = GPG_ERR_RESOURCE_LIMIT; - else - { - if(flags&2) - primary_keyring=token; - all_resources[used_resources].type = rt; - all_resources[used_resources].u.kr = NULL; /* Not used here */ - all_resources[used_resources].token = token; - all_resources[used_resources].secret = secret; - used_resources++; - } - } - else - { - /* This keyring was already registered, so ignore it. - However, we can still mark it as primary even if it was - already registered. */ - if(flags&2) - primary_keyring=token; - } - break; - - default: - log_error ("resource type of `%s' not supported\n", url); - rc = GPG_ERR_GENERAL; - goto leave; - } - - /* fixme: check directory permissions and print a warning */ - - leave: - if (rc) - log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror (rc)); - else if (secret) - any_secret = 1; - else - any_public = 1; - xfree (filename); - return rc; -} - - - - -KEYDB_HANDLE -keydb_new (int secret) -{ - KEYDB_HANDLE hd; - int i, j; - - hd = xcalloc (1,sizeof *hd); - hd->found = -1; - - assert (used_resources <= MAX_KEYDB_RESOURCES); - for (i=j=0; i < used_resources; i++) - { - if (!all_resources[i].secret != !secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - hd->active[j].type = all_resources[i].type; - hd->active[j].token = all_resources[i].token; - hd->active[j].secret = all_resources[i].secret; - hd->active[j].u.kr = keyring_new (all_resources[i].token, secret); - if (!hd->active[j].u.kr) { - xfree (hd); - return NULL; /* fixme: release all previously allocated handles*/ - } - j++; - break; - } - } - hd->used = j; - - active_handles++; - return hd; -} - -void -keydb_release (KEYDB_HANDLE hd) -{ - int i; - - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - - unlock_all (hd); - for (i=0; i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_release (hd->active[i].u.kr); - break; - } - } - - xfree (hd); -} - - -/* - * Return the name of the current resource. This is function first - * looks for the last found found, then for the current search - * position, and last returns the first available resource. The - * returned string is only valid as long as the handle exists. This - * function does only return NULL if no handle is specified, in all - * other error cases an empty string is returned. - */ -const char * -keydb_get_resource_name (KEYDB_HANDLE hd) -{ - int idx; - const char *s = NULL; - - if (!hd) - return NULL; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - idx = 0; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - s = NULL; - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - s = keyring_get_resource_name (hd->active[idx].u.kr); - break; - } - - return s? s: ""; -} - - - -static int -lock_all (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - for (i=0; !rc && i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_lock (hd->active[i].u.kr, 1); - break; - } - } - - if (rc) { - /* revert the already set locks */ - for (i--; i >= 0; i--) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_lock (hd->active[i].u.kr, 0); - break; - } - } - } - else - hd->locked = 1; - - return rc; -} - -static void -unlock_all (KEYDB_HANDLE hd) -{ - int i; - - if (!hd->locked) - return; - - for (i=hd->used-1; i >= 0; i--) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - keyring_lock (hd->active[i].u.kr, 0); - break; - } - } - hd->locked = 0; -} - - -/* - * Return the last found keyring. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) -{ - int rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); - break; - } - - return rc; -} - -/* - * update the current keyblock with KB - */ -int -keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Insert a new KB into one of the resources. - */ -int -keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = -1; - int idx; - - if (!hd) - return GPG_ERR_INV_ARG; - - if( opt.dry_run ) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return GPG_ERR_GENERAL; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * The current keyblock will be deleted. - */ -int -keydb_delete_keyblock (KEYDB_HANDLE hd) -{ - int rc = -1; - - if (!hd) - return GPG_ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GPG_ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_delete_keyblock (hd->active[hd->found].u.kr); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Locate the default writable key resource, so that the next - * operation (which is only relevant for inserts) will be done on this - * resource. - */ -int -keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) -{ - int rc; - - if (!hd) - return GPG_ERR_INV_ARG; - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - - /* If we have a primary set, try that one first */ - if(primary_keyring) - { - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - if(hd->active[hd->current].token==primary_keyring) - { - if(keyring_is_writable (hd->active[hd->current].token)) - return 0; - else - break; - } - } - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - } - - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - if (keyring_is_writable (hd->active[hd->current].token)) - return 0; /* found (hd->current is set to it) */ - break; - } - } - - return -1; -} - -/* - * Rebuild the caches of all key resources. - */ -void -keydb_rebuild_caches (void) -{ - int i, rc; - - for (i=0; i < used_resources; i++) - { - if (all_resources[i].secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_rebuild_cache (all_resources[i].token); - if (rc) - log_error (_("failed to rebuild keyring cache: %s\n"), - gpg_strerror (rc)); - break; - } - } -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keydb_search_reset (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - if (!hd) - return GPG_ERR_INV_ARG; - - hd->current = 0; - hd->found = -1; - /* and reset all resources */ - for (i=0; !rc && i < hd->used; i++) { - switch (hd->active[i].type) { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_search_reset (hd->active[i].u.kr); - break; - } - } - return rc; -} - - -/* - * Search through all keydb resources, starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) -{ - int rc = -1; - - if (!hd) - return GPG_ERR_INV_ARG; - - while (rc == -1 && hd->current >= 0 && hd->current < hd->used) { - switch (hd->active[hd->current].type) { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); /* we should never see it here */ - break; - case KEYDB_RESOURCE_TYPE_KEYRING: - rc = keyring_search (hd->active[hd->current].u.kr, desc, - ndesc, descindex); - break; - } - if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; - else if (!rc) - hd->found = hd->current; - } - - return rc; -} - -int -keydb_search_first (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_next (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_LONG_KID; - desc.u.kid[0] = kid[0]; - desc.u.kid[1] = kid[1]; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FPR; - memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN); - return keydb_search (hd, &desc, 1); -} diff --git a/g10/keydb.h b/g10/keydb.h deleted file mode 100644 index 4920e88a1..000000000 --- a/g10/keydb.h +++ /dev/null @@ -1,283 +0,0 @@ -/* keydb.h - Key database - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_KEYDB_H -#define G10_KEYDB_H - -#include "types.h" -#include "global.h" -#include "packet.h" -#include "cipher.h" - -/* What qualifies as a certification (rather than a signature?) */ -#define IS_CERT(s) (IS_KEY_SIG(s) || IS_UID_SIG(s) || IS_SUBKEY_SIG(s) \ - || IS_KEY_REV(s) || IS_UID_REV(s) || IS_SUBKEY_REV(s)) -#define IS_SIG(s) (!IS_CERT(s)) -#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f) -#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) -#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18) -#define IS_KEY_REV(s) ((s)->sig_class == 0x20) -#define IS_UID_REV(s) ((s)->sig_class == 0x30) -#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28) - -struct getkey_ctx_s; -typedef struct getkey_ctx_s *GETKEY_CTX; - -/**************** - * A Keyblock is all packets which form an entire certificate; - * i.e. the public key, certificate, trust packets, user ids, - * signatures, and subkey. - * - * This structure is also used to bind arbitrary packets together. - */ - -struct kbnode_struct { - KBNODE next; - PACKET *pkt; - int flag; - int private_flag; - ulong recno; /* used while updating the trustdb */ -}; - -#define is_deleted_kbnode(a) ((a)->private_flag & 1) -#define is_cloned_kbnode(a) ((a)->private_flag & 2) - - -enum resource_type { - rt_UNKNOWN = 0, - rt_RING = 1 -}; - - -/**************** - * A data structre to hold information about the external position - * of a keyblock. - */ -struct keyblock_pos_struct { - int resno; /* resource number */ - enum resource_type rt; - off_t offset; /* position information */ - unsigned count; /* length of the keyblock in packets */ - iobuf_t fp; /* used by enum_keyblocks */ - int secret; /* working on a secret keyring */ - PACKET *pkt; /* ditto */ - int valid; -}; -typedef struct keyblock_pos_struct KBPOS; - -/* structure to hold a couple of public key certificates */ -typedef struct pk_list *PK_LIST; -struct pk_list { - PK_LIST next; - PKT_public_key *pk; - int flags; /* flag bit 1==throw_keyid */ -}; - -/* structure to hold a couple of secret key certificates */ -typedef struct sk_list *SK_LIST; -struct sk_list { - SK_LIST next; - PKT_secret_key *sk; - int mark; /* not used */ -}; - -/* structure to collect all information which can be used to - * identify a public key */ -typedef struct pubkey_find_info *PUBKEY_FIND_INFO; -struct pubkey_find_info { - u32 keyid[2]; - unsigned nbits; - byte pubkey_algo; - byte fingerprint[MAX_FINGERPRINT_LEN]; - char userid[1]; -}; - - -typedef struct keydb_handle *KEYDB_HANDLE; - -typedef enum { - KEYDB_SEARCH_MODE_NONE, - KEYDB_SEARCH_MODE_EXACT, - KEYDB_SEARCH_MODE_SUBSTR, - KEYDB_SEARCH_MODE_MAIL, - KEYDB_SEARCH_MODE_MAILSUB, - KEYDB_SEARCH_MODE_MAILEND, - KEYDB_SEARCH_MODE_WORDS, - KEYDB_SEARCH_MODE_SHORT_KID, - KEYDB_SEARCH_MODE_LONG_KID, - KEYDB_SEARCH_MODE_FPR16, - KEYDB_SEARCH_MODE_FPR20, - KEYDB_SEARCH_MODE_FPR, - KEYDB_SEARCH_MODE_FIRST, - KEYDB_SEARCH_MODE_NEXT -} KeydbSearchMode; - -struct keydb_search_desc { - KeydbSearchMode mode; - int (*skipfnc)(void *,u32*); - void *skipfncvalue; - union { - const char *name; - char fpr[MAX_FINGERPRINT_LEN]; - u32 kid[2]; - } u; - int exact; -}; - -/*-- keydb.c --*/ - -/* - Flag 1 == force - Flag 2 == default -*/ -int keydb_add_resource (const char *url, int flags, int secret); -KEYDB_HANDLE keydb_new (int secret); -void keydb_release (KEYDB_HANDLE hd); -const char *keydb_get_resource_name (KEYDB_HANDLE hd); -int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); -int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_delete_keyblock (KEYDB_HANDLE hd); -int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); -void keydb_rebuild_caches (void); -int keydb_search_reset (KEYDB_HANDLE hd); -#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL) -int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); -int keydb_search_first (KEYDB_HANDLE hd); -int keydb_search_next (KEYDB_HANDLE hd); -int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); -int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); - - -/*-- pkclist.c --*/ -void show_revocation_reason( PKT_public_key *pk, int mode ); -int check_signatures_trust( PKT_signature *sig ); -void release_pk_list( PK_LIST pk_list ); -int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ); -int algo_available( preftype_t preftype, int algo, void *hint ); -int select_algo_from_prefs( PK_LIST pk_list, int preftype, - int request, void *hint ); -int select_mdc_from_pklist (PK_LIST pk_list); - -/*-- skclist.c --*/ -void release_sk_list( SK_LIST sk_list ); -int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, - int unlock, unsigned use ); - -/*-- passphrase.h --*/ -int have_static_passphrase(void); -void read_passphrase_from_fd( int fd ); -void passphrase_clear_cache ( u32 *keyid, int algo ); -DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled); -void set_next_passphrase( const char *s ); -char *get_last_passphrase(void); - -/*-- getkey.c --*/ -int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc); -void cache_public_key( PKT_public_key *pk ); -void getkey_disable_caches(void); -int get_pubkey( PKT_public_key *pk, u32 *keyid ); -int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); -KBNODE get_pubkeyblock( u32 *keyid ); -int get_pubkey_byname( PKT_public_key *pk, const char *name, - KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, - int include_disabled ); -int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk, - STRLIST names, KBNODE *ret_keyblock ); -int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ); -void get_pubkey_end( GETKEY_CTX ctx ); -int get_seckey( PKT_secret_key *sk, u32 *keyid ); -int get_primary_seckey( PKT_secret_key *sk, u32 *keyid ); -int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, - size_t fprint_len ); -int get_pubkey_byfprint_fast (PKT_public_key *pk, - const byte *fprint, size_t fprint_len); -int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, - size_t fprint_len ); -int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid ); -int seckey_available( u32 *keyid ); -int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ); -int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk, - STRLIST names, KBNODE *ret_keyblock ); -int get_seckey_byfprint( PKT_secret_key *sk, - const byte *fprint, size_t fprint_len); -int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock ); -void get_seckey_end( GETKEY_CTX ctx ); -int enum_secret_keys( void **context, PKT_secret_key *sk, - int with_subkeys, int with_spm ); -void merge_keys_and_selfsig( KBNODE keyblock ); -char*get_user_id_string( u32 *keyid ); -char*get_user_id_string_printable( u32 *keyid ); -char*get_long_user_id_string( u32 *keyid ); -char*get_user_id( u32 *keyid, size_t *rn ); -char*get_user_id_printable( u32 *keyid ); -KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx); - -/*-- keyid.c --*/ -int pubkey_letter( int algo ); -u32 v3_keyid (gcry_mpi_t a, u32 *ki); -u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid ); -u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid ); -u32 keyid_from_sig( PKT_signature *sig, u32 *keyid ); -u32 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ); -byte *namehash_from_uid(PKT_user_id *uid); -unsigned nbits_from_pk( PKT_public_key *pk ); -unsigned nbits_from_sk( PKT_secret_key *sk ); -const char *datestr_from_pk( PKT_public_key *pk ); -const char *datestr_from_sk( PKT_secret_key *sk ); -const char *datestr_from_sig( PKT_signature *sig ); -const char *expirestr_from_pk( PKT_public_key *pk ); -const char *expirestr_from_sk( PKT_secret_key *sk ); -const char *expirestr_from_sig( PKT_signature *sig ); - -const char *colon_strtime (u32 t); -const char *colon_datestr_from_pk (PKT_public_key *pk); -const char *colon_datestr_from_sk (PKT_secret_key *sk); -const char *colon_datestr_from_sig (PKT_signature *sig); -const char *colon_expirestr_from_sig (PKT_signature *sig); - -byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len ); -byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); - -char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, - PKT_secret_key *sk); - - -/*-- kbnode.c --*/ -KBNODE new_kbnode( PACKET *pkt ); -KBNODE clone_kbnode( KBNODE node ); -void release_kbnode( KBNODE n ); -void delete_kbnode( KBNODE node ); -void add_kbnode( KBNODE root, KBNODE node ); -void insert_kbnode( KBNODE root, KBNODE node, int pkttype ); -void move_kbnode( KBNODE *root, KBNODE node, KBNODE where ); -void remove_kbnode( KBNODE *root, KBNODE node ); -KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ); -KBNODE find_next_kbnode( KBNODE node, int pkttype ); -KBNODE find_kbnode( KBNODE node, int pkttype ); -KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all ); -void clear_kbnode_flags( KBNODE n ); -int commit_kbnode( KBNODE *root ); -void dump_kbnode( KBNODE node ); - -#endif /*G10_KEYDB_H*/ diff --git a/g10/keyedit.c b/g10/keyedit.c deleted file mode 100644 index 4da174e3c..000000000 --- a/g10/keyedit.c +++ /dev/null @@ -1,3856 +0,0 @@ -/* keyedit.c - keyedit stuff - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "gpg.h" -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "photoid.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "filter.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - -static void show_prefs( PKT_user_id *uid, int verbose ); -static void show_key_with_all_names( KBNODE keyblock, int only_marked, - int with_revoker, int with_fpr, int with_subkeys, int with_prefs ); -static void show_key_and_fingerprint( KBNODE keyblock ); -static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo ); -static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_delsig( KBNODE pub_keyblock ); -static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_addrevoker( KBNODE pub_keyblock, - KBNODE sec_keyblock, int sensitive ); -static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int menu_select_uid( KBNODE keyblock, int idx ); -static int menu_select_key( KBNODE keyblock, int idx ); -static int count_uids( KBNODE keyblock ); -static int count_uids_with_flag( KBNODE keyblock, unsigned flag ); -static int count_keys_with_flag( KBNODE keyblock, unsigned flag ); -static int count_selected_uids( KBNODE keyblock ); -static int real_uids_left( KBNODE keyblock ); -static int count_selected_keys( KBNODE keyblock ); -static int menu_revsig( KBNODE keyblock ); -static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock ); -static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); -static int enable_disable_key( KBNODE keyblock, int disable ); -static void menu_showphoto( KBNODE keyblock ); - -static int update_trust=0; - -#define CONTROL_D ('D' - 'A' + 1) - -#define NODFLG_BADSIG (1<<0) /* bad signature */ -#define NODFLG_NOKEY (1<<1) /* no public key */ -#define NODFLG_SIGERR (1<<2) /* other sig error */ - -#define NODFLG_MARK_A (1<<4) /* temporary mark */ -#define NODFLG_DELSIG (1<<5) /* to be deleted */ - -#define NODFLG_SELUID (1<<8) /* indicate the selected userid */ -#define NODFLG_SELKEY (1<<9) /* indicate the selected key */ -#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */ - -struct sign_attrib { - int non_exportable,non_revocable; - struct revocation_reason_info *reason; - byte trust_depth,trust_value; - char *trust_regexp; -}; - -/**************** - * Print information about a signature, check it and return true - * if the signature is okay. NODE must be a signature packet. - */ -static int -print_and_check_one_sig( KBNODE keyblock, KBNODE node, - int *inv_sigs, int *no_key, int *oth_err, - int *is_selfsig, int print_without_key ) -{ - PKT_signature *sig = node->pkt->pkt.signature; - int rc, sigrc; - int is_rev = sig->sig_class == 0x30; - - /* TODO: Make sure a cached sig record here still has the pk that - issued it. See also keylist.c:list_keyblock_print */ - - rc = check_key_signature (keyblock, node, is_selfsig); - switch ( gpg_err_code (rc) ) { - case 0: - node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR); - sigrc = '!'; - break; - case GPG_ERR_BAD_SIGNATURE: - node->flag = NODFLG_BADSIG; - sigrc = '-'; - if( inv_sigs ) - ++*inv_sigs; - break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: - node->flag = NODFLG_NOKEY; - sigrc = '?'; - if( no_key ) - ++*no_key; - break; - default: - node->flag = NODFLG_SIGERR; - sigrc = '%'; - if( oth_err ) - ++*oth_err; - break; - } - if( sigrc != '?' || print_without_key ) { - tty_printf("%s%c%c %c%c%c%c%c%c ", - is_rev? "rev":"sig",sigrc, - (sig->sig_class-0x10>0 && - sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ', - sig->flags.exportable?' ':'L', - sig->flags.revocable?' ':'R', - sig->flags.policy_url?'P':' ', - sig->flags.notation?'N':' ', - sig->flags.expired?'X':' ', - (sig->trust_depth>9)?'T': - (sig->trust_depth>0)?'0'+sig->trust_depth:' '); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]); - else - tty_printf("%08lX",(ulong)sig->keyid[1]); - tty_printf(" %s", datestr_from_sig(sig)); - if(opt.list_options&LIST_SHOW_SIG_EXPIRE) - tty_printf(" %s",expirestr_from_sig(sig)); - tty_printf(" "); - if( sigrc == '%' ) - tty_printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if( *is_selfsig ) { - tty_printf( is_rev? _("[revocation]") - : _("[self-signature]") ); - } - else { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - tty_print_utf8_string2( p, n, 40 ); - xfree (p); - } - tty_printf("\n"); - - if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY)) - show_policy_url(sig,3,0); - - if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION)) - show_notation(sig,3,0); - - if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER)) - show_keyserver_url(sig,3,0); - } - - return (sigrc == '!'); -} - - - -/**************** - * Check the keysigs and set the flags to indicate errors. - * Returns true if error found. - */ -static int -check_all_keysigs( KBNODE keyblock, int only_selected ) -{ - KBNODE kbctx; - KBNODE node; - int inv_sigs = 0; - int no_key = 0; - int oth_err = 0; - int has_selfsig = 0; - int mis_selfsig = 0; - int selected = !only_selected; - int anyuid = 0; - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - - if( only_selected ) - selected = (node->flag & NODFLG_SELUID); - if( selected ) { - tty_printf("uid "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - if( anyuid && !has_selfsig ) - mis_selfsig++; - has_selfsig = 0; - anyuid = 1; - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE - && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10 - || node->pkt->pkt.signature->sig_class == 0x30 ) ) { - int selfsig; - - if( print_and_check_one_sig( keyblock, node, &inv_sigs, - &no_key, &oth_err, &selfsig, 0 ) ) { - if( selfsig ) - has_selfsig = 1; - } - /* Hmmm: should we update the trustdb here? */ - } - } - if( !has_selfsig ) - mis_selfsig++; - if( inv_sigs == 1 ) - tty_printf(_("1 bad signature\n") ); - else if( inv_sigs ) - tty_printf(_("%d bad signatures\n"), inv_sigs ); - if( no_key == 1 ) - tty_printf(_("1 signature not checked due to a missing key\n") ); - else if( no_key ) - tty_printf(_("%d signatures not checked due to missing keys\n"), no_key ); - if( oth_err == 1 ) - tty_printf(_("1 signature not checked due to an error\n") ); - else if( oth_err ) - tty_printf(_("%d signatures not checked due to errors\n"), oth_err ); - if( mis_selfsig == 1 ) - tty_printf(_("1 user ID without valid self-signature detected\n")); - else if( mis_selfsig ) - tty_printf(_("%d user IDs without valid self-signatures detected\n"), - mis_selfsig); - - return inv_sigs || no_key || oth_err || mis_selfsig; -} - - - - -static int -sign_mk_attrib( PKT_signature *sig, void *opaque ) -{ - struct sign_attrib *attrib = opaque; - byte buf[8]; - - if( attrib->non_exportable ) { - buf[0] = 0; /* not exportable */ - build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 ); - } - - if( attrib->non_revocable ) { - buf[0] = 0; /* not revocable */ - build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 ); - } - - if( attrib->reason ) - revocation_reason_build_cb( sig, attrib->reason ); - - if(attrib->trust_depth) - { - /* Not critical. If someone doesn't understand trust sigs, - this can still be a valid regular signature. */ - buf[0] = attrib->trust_depth; - buf[1] = attrib->trust_value; - build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2); - - /* Critical. If someone doesn't understands regexps, this - whole sig should be invalid. Note the +1 for the length - - regexps are null terminated. */ - if(attrib->trust_regexp) - build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP, - attrib->trust_regexp, - strlen(attrib->trust_regexp)+1); - } - - return 0; -} - -static void -trustsig_prompt(byte *trust_value, byte *trust_depth, char **regexp) -{ - char *p; - - *trust_value=0; - *trust_depth=0; - *regexp=NULL; - - tty_printf("\n"); - /* Same string as pkclist.c:do_edit_ownertrust */ - tty_printf(_( - "Please decide how far you trust this user to correctly\n" - "verify other users' keys (by looking at passports,\n" - "checking fingerprints from different sources...)?\n\n")); - tty_printf (_(" (%d) I trust marginally\n"), 1); - tty_printf (_(" (%d) I trust fully\n"), 2); - tty_printf("\n"); - - while(*trust_value==0) - { - p = cpr_get("trustsig_prompt.trust_value",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - /* 60 and 120 are as per RFC2440 */ - if(p[0]=='1' && !p[1]) - *trust_value=60; - else if(p[0]=='2' && !p[1]) - *trust_value=120; - xfree (p); - } - - tty_printf("\n"); - - tty_printf(_( - "Please enter the depth of this trust signature.\n" - "A depth greater than 1 allows the key you are signing to make\n" - "trust signatures on your behalf.\n")); - tty_printf("\n"); - - while(*trust_depth==0) - { - p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - *trust_depth=atoi(p); - xfree (p); - if(*trust_depth < 1 ) - *trust_depth=0; - } - - tty_printf("\n"); - - tty_printf(_("Please enter a domain to restrict this signature, " - "or enter for none.\n")); - - tty_printf("\n"); - - p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? ")); - trim_spaces(p); - cpr_kill_prompt(); - - if(strlen(p)>0) - { - char *q=p; - int regexplen=100,ind; - - *regexp=xmalloc (regexplen); - - /* Now mangle the domain the user entered into a regexp. To do - this, \-escape everything that isn't alphanumeric, and attach - "<[^>]+[@.]" to the front, and ">$" to the end. */ - - strcpy(*regexp,"<[^>]+[@.]"); - ind=strlen(*regexp); - - while(*q) - { - if(!((*q>='A' && *q<='Z') - || (*q>='a' && *q<='z') || (*q>='0' && *q<='9'))) - (*regexp)[ind++]='\\'; - - (*regexp)[ind++]=*q; - - if((regexplen-ind)<3) - { - regexplen+=100; - *regexp=xrealloc(*regexp,regexplen); - } - - q++; - } - - (*regexp)[ind]='\0'; - strcat(*regexp,">$"); - } - - xfree (p); - tty_printf("\n"); -} - -/**************** - * Loop over all locusr and and sign the uids after asking. - * If no user id is marked, all user ids will be signed; - * if some user_ids are marked those will be signed. - */ -static int -sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, - int local, int nonrevocable, int trust ) -{ - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - PKT_secret_key *sk = NULL; - KBNODE node, uidnode; - PKT_public_key *primary_pk=NULL; - int select_all = !count_selected_uids(keyblock); - int all_v3=1; - - /* Are there any non-v3 sigs on this key already? */ - if(PGP2) - for(node=keyblock;node;node=node->next) - if(node->pkt->pkttype==PKT_SIGNATURE && - node->pkt->pkt.signature->version>3) - { - all_v3=0; - break; - } - - /* build a list of all signators. - * - * We use the CERT flag to request the primary which must always - * be one which is capable of signing keys. I can't see a reason - * why to sign keys using a subkey. Implementation of USAGE_CERT - * is just a hack in getkey.c and does not mean that a subkey - * marked as certification capable will be used */ - rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT); - if( rc ) - goto leave; - - /* loop over all signators */ - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - u32 sk_keyid[2],pk_keyid[2]; - size_t n; - char *p,*trust_regexp=NULL; - int force_v4=0,class=0,selfsig=0; - u32 duration=0,timestamp=0; - byte trust_depth=0,trust_value=0; - - if(local || nonrevocable || trust || - opt.cert_policy_url || opt.cert_notation_data) - force_v4=1; - - /* we have to use a copy of the sk, because make_keysig_packet - * may remove the protection from sk and if we did other - * changes to the secret key, we would save the unprotected - * version */ - if( sk ) - free_secret_key(sk); - sk = copy_secret_key( NULL, sk_rover->sk ); - keyid_from_sk( sk, sk_keyid ); - /* set mark A for all selected user ids */ - for( node=keyblock; node; node = node->next ) { - if( select_all || (node->flag & NODFLG_SELUID) ) - node->flag |= NODFLG_MARK_A; - else - node->flag &= ~NODFLG_MARK_A; - } - /* reset mark for uids which are already signed */ - uidnode = NULL; - for( node=keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - primary_pk=node->pkt->pkt.public_key; - keyid_from_pk( primary_pk, pk_keyid ); - - /* Is this a self-sig? */ - if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1]) - { - selfsig=1; - /* Do not force a v4 sig here, otherwise it would - be difficult to remake a v3 selfsig. If this - is a v3->v4 promotion case, then we set - force_v4 later anyway. */ - force_v4=0; - } - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - uidnode = (node->flag & NODFLG_MARK_A)? node : NULL; - if(uidnode) - { - char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); - - if(uidnode->pkt->pkt.user_id->is_revoked) - { - tty_printf(_("User ID \"%s\" is revoked."),user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.revoke_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - else if(uidnode->pkt->pkt.user_id->is_expired) - { - tty_printf(_("User ID \"%s\" is expired."),user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.expire_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - else if(!uidnode->pkt->pkt.user_id->created && !selfsig) - { - tty_printf(_("User ID \"%s\" is not self-signed."), - user); - - if(opt.expert) - { - tty_printf("\n"); - /* No, so remove the mark and continue */ - if(!cpr_get_answer_is_yes("sign_uid.nosig_okay", - _("Are you sure you " - "still want to sign " - "it? (y/N) "))) - uidnode->flag &= ~NODFLG_MARK_A; - } - else - { - uidnode->flag &= ~NODFLG_MARK_A; - tty_printf(_(" Unable to sign.\n")); - } - } - xfree (user); - } - } - else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE - && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { - if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0] - && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) { - char buf[50]; - char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); - - /* It's a v3 self-sig. Make it into a v4 self-sig? */ - if(node->pkt->pkt.signature->version<4 && selfsig) - { - tty_printf(_("The self-signature on \"%s\"\n" - "is a PGP 2.x-style signature.\n"),user); - - /* Note that the regular PGP2 warning below - still applies if there are no v4 sigs on - this key at all. */ - - if(opt.expert) - if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay", - _("Do you want to promote " - "it to an OpenPGP self-" - "signature? (y/N) "))) - { - force_v4=1; - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - /* Is the current signature expired? */ - if(node->pkt->pkt.signature->flags.expired) - { - tty_printf(_("Your current signature on \"%s\"\n" - "has expired.\n"),user); - - if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay", - _("Do you want to issue a " - "new signature to replace " - "the expired one? (y/N) "))) - { - /* Mark these for later deletion. We - don't want to delete them here, just in - case the replacement signature doesn't - happen for some reason. We only delete - these after the replacement is already - in place. */ - - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - if(!node->pkt->pkt.signature->flags.exportable && !local) - { - /* It's a local sig, and we want to make a - exportable sig. */ - tty_printf(_("Your current signature on \"%s\"\n" - "is a local signature.\n"),user); - - if(cpr_get_answer_is_yes("sign_uid.local_promote_okay", - _("Do you want to promote " - "it to a full exportable " - "signature? (y/N) "))) - { - /* Mark these for later deletion. We - don't want to delete them here, just in - case the replacement signature doesn't - happen for some reason. We only delete - these after the replacement is already - in place. */ - - node->flag|=NODFLG_DELSIG; - xfree (user); - continue; - } - } - - /* Fixme: see whether there is a revocation in which - * case we should allow to sign it again. */ - if (!node->pkt->pkt.signature->flags.exportable && local) - tty_printf(_( - "\"%s\" was already locally signed by key %08lX\n"), - user,(ulong)sk_keyid[1] ); - else - tty_printf(_( - "\"%s\" was already signed by key %08lX\n"), - user,(ulong)sk_keyid[1] ); - - if(opt.expert - && cpr_get_answer_is_yes("sign_uid.dupe_okay", - _("Do you want to sign it " - "again anyway? (y/N) "))) - { - /* Don't delete the old sig here since this is - an --expert thing. */ - xfree (user); - continue; - } - - sprintf (buf, "%08lX%08lX", - (ulong)sk->keyid[0], (ulong)sk->keyid[1] ); - write_status_text (STATUS_ALREADY_SIGNED, buf); - uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */ - - xfree (user); - } - } - } - /* check whether any uids are left for signing */ - if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) { - tty_printf(_("Nothing to sign with key %08lX\n"), - (ulong)sk_keyid[1] ); - continue; - } - /* Ask whether we really should sign these user id(s) */ - tty_printf("\n"); - show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 ); - tty_printf("\n"); - - if(primary_pk->expiredate && !selfsig) - { - u32 now=make_timestamp(); - - if(primary_pk->expiredate<=now) - { - tty_printf(_("This key has expired!")); - - if(opt.expert) - { - tty_printf(" "); - if(!cpr_get_answer_is_yes("sign_uid.expired_okay", - _("Are you sure you still " - "want to sign it? (y/N) "))) - continue; - } - else - { - tty_printf(_(" Unable to sign.\n")); - continue; - } - } - else - { - char *answer; - - tty_printf(_("This key is due to expire on %s.\n"), - expirestr_from_pk(primary_pk)); - - answer=cpr_get("sign_uid.expire", - _("Do you want your signature to " - "expire at the same time? (Y/n) ")); - if(answer_is_yes_no_default(answer,1)) - { - /* This fixes the signature timestamp we're going - to make as now. This is so the expiration date - is exactly correct, and not a few seconds off - (due to the time it takes to answer the - questions, enter the passphrase, etc). */ - timestamp=now; - duration=primary_pk->expiredate-now; - force_v4=1; - } - - cpr_kill_prompt(); - xfree (answer); - } - } - - /* Only ask for duration if we haven't already set it to match - the expiration of the pk */ - if(opt.ask_cert_expire && !duration && !selfsig) - duration=ask_expire_interval(1); - - if(duration) - force_v4=1; - - /* Is --pgp2 on, it's a v3 key, all the sigs on the key are - currently v3 and we're about to sign it with a v4 sig? If - so, danger! */ - if(PGP2 && all_v3 && - (sk->version>3 || force_v4) && primary_pk->version<=3) - { - tty_printf(_("You may not make an OpenPGP signature on a " - "PGP 2.x key while in --pgp2 mode.\n")); - tty_printf(_("This would make the key unusable in PGP 2.x.\n")); - - if(opt.expert) - { - if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay", - _("Are you sure you still " - "want to sign it? (y/N) "))) - continue; - - all_v3=0; - } - else - continue; - } - - if(selfsig) - ; - else - { - if(opt.batch) - class=0x10+opt.def_cert_check_level; - else - { - char *answer; - - tty_printf(_("How carefully have you verified the key you are " - "about to sign actually belongs\nto the person " - "named above? If you don't know what to " - "answer, enter \"0\".\n")); - tty_printf("\n"); - tty_printf(_(" (0) I will not answer.%s\n"), - opt.def_cert_check_level==0?" (default)":""); - tty_printf(_(" (1) I have not checked at all.%s\n"), - opt.def_cert_check_level==1?" (default)":""); - tty_printf(_(" (2) I have done casual checking.%s\n"), - opt.def_cert_check_level==2?" (default)":""); - tty_printf(_(" (3) I have done very careful checking.%s\n"), - opt.def_cert_check_level==3?" (default)":""); - tty_printf("\n"); - - while(class==0) - { - answer = cpr_get("sign_uid.class",_("Your selection? " - "(enter '?' for more information): ")); - - if(answer[0]=='\0') - class=0x10+opt.def_cert_check_level; /* Default */ - else if(ascii_strcasecmp(answer,"0")==0) - class=0x10; /* Generic */ - else if(ascii_strcasecmp(answer,"1")==0) - class=0x11; /* Persona */ - else if(ascii_strcasecmp(answer,"2")==0) - class=0x12; /* Casual */ - else if(ascii_strcasecmp(answer,"3")==0) - class=0x13; /* Positive */ - else - tty_printf(_("Invalid selection.\n")); - - xfree (answer); - } - } - - if(trust) - trustsig_prompt(&trust_value,&trust_depth,&trust_regexp); - } - - tty_printf(_("Are you really sure that you want to sign this key\n" - "with your key: \"")); - p = get_user_id( sk_keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); p = NULL; - tty_printf("\" (%08lX)\n",(ulong)sk_keyid[1]); - - if(selfsig) - { - tty_printf(_("\nThis will be a self-signature.\n")); - - if( local ) - tty_printf( - _("\nWARNING: the signature will not be marked " - "as non-exportable.\n")); - - if( nonrevocable ) - tty_printf( - _("\nWARNING: the signature will not be marked " - "as non-revocable.\n")); - } - else - { - if( local ) - tty_printf( - _("\nThe signature will be marked as non-exportable.\n")); - - if( nonrevocable ) - tty_printf( - _("\nThe signature will be marked as non-revocable.\n")); - - switch(class) - { - case 0x11: - tty_printf(_("\nI have not checked this key at all.\n")); - break; - - case 0x12: - tty_printf(_("\nI have checked this key casually.\n")); - break; - - case 0x13: - tty_printf(_("\nI have checked this key very carefully.\n")); - break; - } - } - - tty_printf("\n"); - - if( opt.batch && opt.answer_yes ) - ; - else if( !cpr_get_answer_is_yes("sign_uid.okay", _("Really sign? ")) ) - continue; - - /* now we can sign the user ids */ - reloop: /* (must use this, because we are modifing the list) */ - primary_pk = NULL; - for( node=keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - primary_pk = node->pkt->pkt.public_key; - else if( node->pkt->pkttype == PKT_USER_ID - && (node->flag & NODFLG_MARK_A) ) { - PACKET *pkt; - PKT_signature *sig; - struct sign_attrib attrib; - - assert( primary_pk ); - memset( &attrib, 0, sizeof attrib ); - attrib.non_exportable = local; - attrib.non_revocable = nonrevocable; - attrib.trust_depth = trust_depth; - attrib.trust_value = trust_value; - attrib.trust_regexp = trust_regexp; - node->flag &= ~NODFLG_MARK_A; - - /* we force creation of a v4 signature for local - * signatures, otherwise we would not generate the - * subpacket with v3 keys and the signature becomes - * exportable */ - - if(selfsig) - rc = make_keysig_packet( &sig, primary_pk, - node->pkt->pkt.user_id, - NULL, - sk, - 0x13, 0, force_v4?4:0, 0, 0, - keygen_add_std_prefs, primary_pk); - else - rc = make_keysig_packet( &sig, primary_pk, - node->pkt->pkt.user_id, - NULL, - sk, - class, 0, force_v4?4:0, - timestamp, duration, - sign_mk_attrib, &attrib ); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - *ret_modified = 1; /* we changed the keyblock */ - update_trust = 1; - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE ); - goto reloop; - } - } - - /* Delete any sigs that got promoted */ - for( node=keyblock; node; node = node->next ) - if( node->flag & NODFLG_DELSIG) - delete_kbnode(node); - } /* end loop over signators */ - - leave: - release_sk_list( sk_list ); - if( sk ) - free_secret_key(sk); - return rc; -} - - - -/**************** - * Change the passphrase of the primary and all secondary keys. - * We use only one passphrase for all keys. - */ -static int -change_passphrase( KBNODE keyblock ) -{ - int rc = 0; - int changed=0; - KBNODE node; - PKT_secret_key *sk; - char *passphrase = NULL; - int no_primary_secrets = 0; - - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) { - log_error("Oops; secret key not found anymore!\n"); - goto leave; - } - sk = node->pkt->pkt.secret_key; - - switch( is_secret_key_protected( sk ) ) { - case -1: - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf(_("This key is not protected.\n")); - break; - default: - if( sk->protect.s2k.mode == 1001 ) { - tty_printf(_("Secret parts of primary key are not available.\n")); - no_primary_secrets = 1; - } - else if( sk->protect.s2k.mode == 1002 ) { - tty_printf(_("Secret key is actually stored on a card.\n")); - goto leave; - } - else { - tty_printf(_("Key is protected.\n")); - rc = check_secret_key( sk, 0 ); - if( !rc ) - passphrase = get_last_passphrase(); - } - break; - } - - /* unprotect all subkeys (use the supplied passphrase or ask)*/ - for(node=keyblock; !rc && node; node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - set_next_passphrase( passphrase ); - rc = check_secret_key( subsk, 0 ); - if( !rc && !passphrase ) - passphrase = get_last_passphrase(); - } - } - - if( rc ) - tty_printf(_("Can't edit this key: %s\n"), gpg_strerror (rc)); - else { - DEK *dek = NULL; - STRING2KEY *s2k = xmalloc_secure ( sizeof *s2k ); - const char *errtext = NULL; - - tty_printf(_("Enter the new passphrase for this secret key.\n\n") ); - - set_next_passphrase( NULL ); - for(;;) { - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, - s2k, 2, errtext, NULL); - if( !dek ) { - errtext = N_("passphrase not correctly repeated; try again"); - tty_printf ("%s.\n", _(errtext)); - } - else if( !dek->keylen ) { - rc = 0; - tty_printf(_( "You don't want a passphrase -" - " this is probably a *bad* idea!\n\n")); - if( cpr_get_answer_is_yes("change_passwd.empty.okay", - _("Do you really want to do this? "))) - { - changed++; - break; - } - } - else { /* okay */ - rc = 0; - if( !no_primary_secrets ) { - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; - rc = protect_secret_key( sk, dek ); - } - for(node=keyblock; !rc && node; node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - subsk->protect.algo = dek->algo; - subsk->protect.s2k = *s2k; - rc = protect_secret_key( subsk, dek ); - } - } - if( rc ) - log_error("protect_secret_key failed: %s\n", gpg_strerror (rc) ); - else - changed++; - break; - } - } - xfree (s2k); - xfree (dek); - } - - leave: - xfree ( passphrase ); - set_next_passphrase( NULL ); - return changed && !rc; -} - - -/**************** - * There are some keys out (due to a bug in gnupg), where the sequence - * of the packets is wrong. This function fixes that. - * Returns: true if the keyblock has been fixed. - * - * Note: This function does not work if there is more than one user ID. - */ -static int -fix_keyblock( KBNODE keyblock ) -{ - KBNODE node, last, subkey; - int fixed=0; - - /* locate key signatures of class 0x10..0x13 behind sub key packets */ - for( subkey=last=NULL, node = keyblock; node; - last=node, node = node->next ) { - switch( node->pkt->pkttype ) { - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - if( !subkey ) - subkey = last; /* actually it is the one before the subkey */ - break; - case PKT_SIGNATURE: - if( subkey ) { - PKT_signature *sig = node->pkt->pkt.signature; - if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) { - log_info(_( - "moving a key signature to the correct place\n")); - last->next = node->next; - node->next = subkey->next; - subkey->next = node; - node = last; - fixed=1; - } - } - break; - default: break; - } - } - - return fixed; -} - -/**************** - * Menu driven key editor. If sign_mode is true semi-automatical signing - * will be performed. commands are ignore in this case - * - * Note: to keep track of some selection we use node->mark MARKBIT_xxxx. - */ - -void -keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, - int sign_mode ) -{ - enum cmdids { cmdNONE = 0, - cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, - cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY, - cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, - cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER, - cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE, - cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF, - cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, - cmdNOP }; - static struct { const char *name; - enum cmdids id; - int need_sk; - int not_with_sk; - int signmode; - const char *desc; - } cmds[] = { - { N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") }, - { N_("q") , cmdQUIT , 0,0,1, NULL }, - { N_("save") , cmdSAVE , 0,0,1, N_("save and quit") }, - { N_("help") , cmdHELP , 0,0,1, N_("show this help") }, - { "?" , cmdHELP , 0,0,1, NULL }, - { N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") }, - { N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") }, - { N_("l") , cmdLIST , 0,0,1, NULL }, - { N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") }, - { N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") }, - { N_("check") , cmdCHECK , 0,0,1, N_("list signatures") }, - { N_("c") , cmdCHECK , 0,0,1, NULL }, - { N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") }, - { N_("s") , cmdSIGN , 0,1,1, NULL }, - { N_("tsign") , cmdTSIGN , 0,1,1, N_("make a trust signature")}, - { N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") }, - { N_("nrsign") , cmdNRSIGN , 0,1,1, N_("sign the key non-revocably") }, - { N_("nrlsign") , cmdNRLSIGN , 0,1,1, N_("sign the key locally and non-revocably") }, - { N_("debug") , cmdDEBUG , 0,0,0, NULL }, - { N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") }, - { N_("addphoto"), cmdADDPHOTO , 1,1,0, N_("add a photo ID") }, - { N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") }, - /* delphoto is really deluid in disguise */ - { N_("delphoto"), cmdDELUID , 0,1,0, NULL }, - { N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") }, - { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") }, - { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") }, - { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") }, - { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") }, - { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")}, - { N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret " - "and public key listing") }, - { N_("t" ) , cmdTOGGLE , 1,0,0, NULL }, - { N_("pref") , cmdPREF , 0,1,0, - N_("list preferences (expert)")}, - { N_("showpref"), cmdSHOWPREF , 0,1,0, - N_("list preferences (verbose)")}, - { N_("setpref") , cmdSETPREF , 1,1,0, N_("set preference list") }, - { N_("updpref") , cmdUPDPREF , 1,1,0, N_("updated preferences") }, - { N_("keyserver"),cmdPREFKS , 1,1,0, - N_("set preferred keyserver URL")}, - { N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") }, - { N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") }, - { N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") }, - { N_("revuid") , cmdREVUID , 1,1,0, N_("revoke a user ID") }, - { N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") }, - { N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") }, - { N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") }, - { N_("showphoto"),cmdSHOWPHOTO , 0,0,0, N_("show photo ID") }, - - { NULL, cmdNONE } }; - enum cmdids cmd = 0; - int rc = 0; - KBNODE keyblock = NULL; - KEYDB_HANDLE kdbhd = NULL; - KBNODE sec_keyblock = NULL; - KEYDB_HANDLE sec_kdbhd = NULL; - KBNODE cur_keyblock; - char *answer = NULL; - int redisplay = 1; - int modified = 0; - int sec_modified = 0; - int toggle; - int have_commands = !!commands; - - if ( opt.command_fd != -1 ) - ; - else if( opt.batch && !have_commands ) { - log_error(_("can't do that in batchmode\n")); - goto leave; - } - - if( sign_mode ) { - commands = NULL; - append_to_strlist( &commands, sign_mode == 1? "sign": - sign_mode == 2?"lsign": - sign_mode == 3?"nrsign":"nrlsign"); - have_commands = 1; - } - - /* get the public key */ - rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1); - if( rc ) - goto leave; - if( fix_keyblock( keyblock ) ) - modified++; - if( collapse_uids( &keyblock ) ) - modified++; - reorder_keyblock(keyblock); - - if( !sign_mode ) {/* see whether we have a matching secret key */ - PKT_public_key *pk = keyblock->pkt->pkt.public_key; - - sec_kdbhd = keydb_new (1); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (sec_kdbhd, afp); - } - if (!rc) { - rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock); - if (rc) { - log_error (_("error reading secret keyblock `%s': %s\n"), - username, gpg_strerror (rc)); - } - else { - merge_keys_and_selfsig( sec_keyblock ); - if( fix_keyblock( sec_keyblock ) ) - sec_modified++; - } - } - - if (rc) { - sec_keyblock = NULL; - keydb_release (sec_kdbhd); sec_kdbhd = NULL; - rc = 0; - } - } - - if( sec_keyblock ) { - tty_printf(_("Secret key is available.\n")); - } - - toggle = 0; - cur_keyblock = keyblock; - for(;;) { /* main loop */ - int i, arg_number, photo; - const char *arg_string = ""; - char *p; - PKT_public_key *pk=keyblock->pkt->pkt.public_key; - - tty_printf("\n"); - if( redisplay ) { - show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 ); - tty_printf("\n"); - redisplay = 0; - } - do { - xfree (answer); - if( have_commands ) { - if( commands ) { - answer = xstrdup ( commands->d ); - commands = commands->next; - } - else if( opt.batch ) { - answer = xstrdup ("quit"); - } - else - have_commands = 0; - } - if( !have_commands ) { - answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); - cpr_kill_prompt(); - } - trim_spaces(answer); - } while( *answer == '#' ); - - arg_number = 0; /* Yes, here is the init which egcc complains about */ - photo = 0; /* This too */ - if( !*answer ) - cmd = cmdLIST; - else if( *answer == CONTROL_D ) - cmd = cmdQUIT; - else if( digitp( answer ) ) { - cmd = cmdSELUID; - arg_number = atoi(answer); - } - else { - if( (p=strchr(answer,' ')) ) { - *p++ = 0; - trim_spaces(answer); - trim_spaces(p); - arg_number = atoi(p); - arg_string = p; - } - - for(i=0; cmds[i].name; i++ ) { - if( !ascii_strcasecmp( answer, cmds[i].name ) ) - break; - } - if( sign_mode && !cmds[i].signmode ) - cmd = cmdINVCMD; - else if( cmds[i].need_sk && !sec_keyblock ) { - tty_printf(_("Need the secret key to do this.\n")); - cmd = cmdNOP; - } - else if( cmds[i].not_with_sk && sec_keyblock && toggle ) { - tty_printf(_("Please use the command \"toggle\" first.\n")); - cmd = cmdNOP; - } - else - cmd = cmds[i].id; - } - switch( cmd ) { - case cmdHELP: - for(i=0; cmds[i].name; i++ ) { - if( sign_mode && !cmds[i].signmode ) - ; - else if( cmds[i].need_sk && !sec_keyblock ) - ; /* skip if we do not have the secret key */ - else if( cmds[i].desc ) - tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - } - break; - - case cmdLIST: - redisplay = 1; - break; - - case cmdFPR: - show_key_and_fingerprint( keyblock ); - break; - - case cmdSELUID: - if( menu_select_uid( cur_keyblock, arg_number ) ) - redisplay = 1; - break; - - case cmdSELKEY: - if( menu_select_key( cur_keyblock, arg_number ) ) - redisplay = 1; - break; - - case cmdCHECK: - /* we can only do this with the public key becuase the - * check functions can't cope with secret keys and it - * is questionable whether this would make sense at all */ - check_all_keysigs( keyblock, count_selected_uids(keyblock) ); - break; - - case cmdSIGN: /* sign (only the public key) */ - case cmdLSIGN: /* sign (only the public key) */ - case cmdNRSIGN: /* sign (only the public key) */ - case cmdNRLSIGN: /* sign (only the public key) */ - case cmdTSIGN: - if( pk->is_revoked ) - { - tty_printf(_("Key is revoked.")); - - if(opt.expert) - { - tty_printf(" "); - if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay", - _("Are you sure you still want " - "to sign it? (y/N) "))) - break; - } - else - { - tty_printf(_(" Unable to sign.\n")); - break; - } - } - - if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) { - if( !cpr_get_answer_is_yes("keyedit.sign_all.okay", - _("Really sign all user IDs? ")) ) { - tty_printf(_("Hint: Select the user IDs to sign\n")); - break; - } - } - if( !sign_uids( keyblock, locusr, &modified, - (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN), - (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN), - (cmd == cmdTSIGN)) - && sign_mode ) - goto do_cmd_save; - break; - - case cmdDEBUG: - dump_kbnode( cur_keyblock ); - break; - - case cmdTOGGLE: - toggle = !toggle; - cur_keyblock = toggle? sec_keyblock : keyblock; - redisplay = 1; - break; - - case cmdADDPHOTO: - if (RFC2440 || RFC1991 || PGP2) - { - tty_printf( - _("This command is not allowed while in %s mode.\n"), - RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991"); - break; - } - photo=1; - /* fall through */ - - case cmdADDUID: - if( menu_adduid( keyblock, sec_keyblock, photo ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - break; - - case cmdDELUID: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( real_uids_left(keyblock) < 1 ) - tty_printf(_("You can't delete the last user ID!\n")); - else if( cpr_get_answer_is_yes( - "keyedit.remove.uid.okay", - n1 > 1? _("Really remove all selected user IDs? ") - : _("Really remove this user ID? ") - ) ) { - menu_deluid( keyblock, sec_keyblock ); - redisplay = 1; - modified = 1; - if( sec_keyblock ) - sec_modified = 1; - } - } - break; - - case cmdDELSIG: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( menu_delsig( keyblock ) ) { - /* no redisplay here, because it may scroll away some - * status output of delsig */ - modified = 1; - } - } - break; - - case cmdADDKEY: - if( generate_subkeypair( keyblock, sec_keyblock ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - break; - - - case cmdDELKEY: { - int n1; - - if( !(n1=count_selected_keys( keyblock )) ) - tty_printf(_("You must select at least one key.\n")); - else if( sec_keyblock && !cpr_get_answer_is_yes( - "keyedit.remove.subkey.okay", - n1 > 1? - _("Do you really want to delete the selected keys? "): - _("Do you really want to delete this key? ") - )) - ; - else { - menu_delkey( keyblock, sec_keyblock ); - redisplay = 1; - modified = 1; - if( sec_keyblock ) - sec_modified = 1; - } - } - break; - - case cmdADDREVOKER: - { - int sensitive=0; - - if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0) - sensitive=1; - if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) { - redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - } - } - break; - - case cmdREVUID: { - int n1; - - if( !(n1=count_selected_uids(keyblock)) ) - tty_printf(_("You must select at least one user ID.\n")); - else if( cpr_get_answer_is_yes( - "keyedit.revoke.uid.okay", - n1 > 1? _("Really revoke all selected user IDs? ") - : _("Really revoke this user ID? ") - ) ) { - if(menu_revuid(keyblock,sec_keyblock)) - { - modified=1; - redisplay=1; - } - } - } - break; - - case cmdREVKEY: { - int n1; - - if( !(n1=count_selected_keys( keyblock )) ) - tty_printf(_("You must select at least one key.\n")); - else if( sec_keyblock && !cpr_get_answer_is_yes( - "keyedit.revoke.subkey.okay", - n1 > 1? - _("Do you really want to revoke the selected keys? "): - _("Do you really want to revoke this key? ") - )) - ; - else { - if( menu_revkey( keyblock, sec_keyblock ) ) { - modified = 1; - /*sec_modified = 1;*/ - } - redisplay = 1; - } - } - break; - - case cmdEXPIRE: - if( menu_expire( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( sec_keyblock ); - merge_keys_and_selfsig( keyblock ); - sec_modified = 1; - modified = 1; - redisplay = 1; - } - break; - - case cmdPRIMARY: - if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( keyblock ); - modified = 1; - redisplay = 1; - } - break; - - case cmdPASSWD: - if( change_passphrase( sec_keyblock ) ) - sec_modified = 1; - break; - - case cmdTRUST: - show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 ); - tty_printf("\n"); - if( edit_ownertrust( find_kbnode( keyblock, - PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) { - redisplay = 1; - /* No real need to set update_trust here as - edit_ownertrust() calls revalidation_mark() - anyway. */ - update_trust=1; - } - break; - - case cmdPREF: - show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 ); - break; - - case cmdSHOWPREF: - show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 ); - break; - - case cmdSETPREF: - keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0); - break; - - case cmdUPDPREF: - { - PKT_user_id *temp=keygen_get_std_prefs(); - tty_printf(_("Current preference list:\n")); - show_prefs(temp,1); - xfree (temp); - } - if (cpr_get_answer_is_yes ("keyedit.updpref.okay", - count_selected_uids (keyblock)? - _("Really update the preferences" - " for the selected user IDs? "): - _("Really update the preferences? "))){ - - if ( menu_set_preferences (keyblock, sec_keyblock) ) { - merge_keys_and_selfsig (keyblock); - modified = 1; - redisplay = 1; - } - } - break; - - case cmdPREFKS: - if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) { - merge_keys_and_selfsig( keyblock ); - modified = 1; - redisplay = 1; - } - break; - - case cmdNOP: - break; - - case cmdREVSIG: - if( menu_revsig( keyblock ) ) { - redisplay = 1; - modified = 1; - } - break; - - case cmdENABLEKEY: - case cmdDISABLEKEY: - if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) { - redisplay = 1; - modified = 1; - } - break; - - case cmdSHOWPHOTO: - menu_showphoto(keyblock); - break; - - case cmdQUIT: - if( have_commands ) - goto leave; - if( !modified && !sec_modified ) - goto leave; - if( !cpr_get_answer_is_yes("keyedit.save.okay", - _("Save changes? ")) ) { - if( cpr_enabled() - || cpr_get_answer_is_yes("keyedit.cancel.okay", - _("Quit without saving? ")) ) - goto leave; - break; - } - /* fall thru */ - case cmdSAVE: - do_cmd_save: - if( modified || sec_modified ) { - if( modified ) { - rc = keydb_update_keyblock (kdbhd, keyblock); - if( rc ) { - log_error(_("update failed: %s\n"), gpg_strerror (rc) ); - break; - } - } - if( sec_modified ) { - rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock ); - if( rc ) { - log_error( _("update secret failed: %s\n"), - gpg_strerror (rc) ); - break; - } - } - } - else - tty_printf(_("Key not changed so no update needed.\n")); - - if( update_trust ) - { - revalidation_mark (); - update_trust=0; - } - goto leave; - - case cmdINVCMD: - default: - tty_printf("\n"); - tty_printf(_("Invalid command (try \"help\")\n")); - break; - } - } /* end main loop */ - - leave: - release_kbnode( keyblock ); - release_kbnode( sec_keyblock ); - keydb_release (kdbhd); - xfree (answer); -} - - -/**************** - * show preferences of a public keyblock. - */ -static void -show_prefs (PKT_user_id *uid, int verbose) -{ - const prefitem_t fake={0,0}; - const prefitem_t *prefs; - int i; - - if( !uid ) - return; - - if( uid->prefs ) - prefs=uid->prefs; - else if(verbose) - prefs=&fake; - else - return; - - if (verbose) { - int any, des_seen=0, sha1_seen=0, uncomp_seen=0; - tty_printf (" "); - tty_printf (_("Cipher: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_SYM ) { - const char *s = gcry_cipher_algo_name (prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == CIPHER_ALGO_3DES ) - des_seen = 1; - } - } - if (!des_seen) { - if (any) - tty_printf (", "); - tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES)); - } - tty_printf ("\n "); - tty_printf (_("Digest: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_HASH ) { - const char *s = gcry_md_algo_name (prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == DIGEST_ALGO_SHA1 ) - sha1_seen = 1; - } - } - if (!sha1_seen) { - if (any) - tty_printf (", "); - tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1)); - } - tty_printf ("\n "); - tty_printf (_("Compression: ")); - for(i=any=0; prefs[i].type; i++ ) { - if( prefs[i].type == PREFTYPE_ZIP ) { - const char *s=compress_algo_to_string(prefs[i].value); - - if (any) - tty_printf (", "); - any = 1; - /* We don't want to display strings for experimental algos */ - if (s && prefs[i].value < 100 ) - tty_printf ("%s", s ); - else - tty_printf ("[%d]", prefs[i].value); - if (prefs[i].value == 0 ) - uncomp_seen = 1; - } - } - if (!uncomp_seen) { - if (any) - tty_printf (", "); - else { - tty_printf ("%s",compress_algo_to_string(1)); - tty_printf (", "); - } - tty_printf ("%s",compress_algo_to_string(0)); - } - if(uid->mdc_feature || !uid->ks_modify) - { - tty_printf ("\n "); - tty_printf (_("Features: ")); - any=0; - if(uid->mdc_feature) - { - tty_printf ("MDC"); - any=1; - } - if(!uid->ks_modify) - { - if(any) - tty_printf (", "); - tty_printf (_("Keyserver no-modify")); - } - } - tty_printf("\n"); - } - else { - tty_printf(" "); - for(i=0; prefs[i].type; i++ ) { - tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' : - prefs[i].type == PREFTYPE_HASH ? 'H' : - prefs[i].type == PREFTYPE_ZIP ? 'Z':'?', - prefs[i].value); - } - if (uid->mdc_feature) - tty_printf (" [mdc]"); - if (!uid->ks_modify) - tty_printf (" [no-ks-modify]"); - tty_printf("\n"); - } -} - - -/* This is the version of show_key_with_all_names used when - opt.with_colons is used. It prints all available data in a easy to - parse format and does not translate utf8 */ -static void -show_key_with_all_names_colon (KBNODE keyblock) -{ - KBNODE node; - int i, j, ulti_hack=0; - byte pk_version=0; - PKT_public_key *primary=NULL; - - /* the keys */ - for ( node = keyblock; node; node = node->next ) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - u32 keyid[2]; - - if (node->pkt->pkttype == PKT_PUBLIC_KEY) - { - pk_version = pk->version; - primary=pk; - } - - keyid_from_pk (pk, keyid); - - fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout); - if (!pk->is_valid) - putchar ('i'); - else if (pk->is_revoked) - putchar ('r'); - else if (pk->has_expired) - putchar ('e'); - else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks )) - { - int trust = get_validity_info (pk, NULL); - if(trust=='u') - ulti_hack=1; - putchar (trust); - } - - printf (":%u:%d:%08lX%08lX:%lu:%lu:", - nbits_from_pk (pk), - pk->pubkey_algo, - (ulong)keyid[0], (ulong)keyid[1], - (ulong)pk->timestamp, - (ulong)pk->expiredate ); - if (pk->local_id) - printf ("%lu", pk->local_id); - putchar (':'); - if (node->pkt->pkttype==PKT_PUBLIC_KEY - && !(opt.fast_list_mode || opt.no_expensive_trust_checks )) - putchar(get_ownertrust_info (pk)); - putchar(':'); - putchar('\n'); - - print_fingerprint (pk, NULL, 0); - - /* print the revoker record */ - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - { - for (i=0; i < pk->numrevkeys; i++) - { - byte *p; - - printf ("rvk:::%d::::::", pk->revkey[i].algid); - p = pk->revkey[i].fpr; - for (j=0; j < 20; j++, p++ ) - printf ("%02X", *p); - printf (":%02x%s:\n", pk->revkey[i].class, - (pk->revkey[i].class&0x40)?"s":""); - } - } - } - } - - /* the user ids */ - i = 0; - for (node = keyblock; node; node = node->next) - { - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - - ++i; - - if(uid->attrib_data) - printf("uat:"); - else - printf("uid:"); - - if ( uid->is_revoked ) - printf("r::::::::"); - else if ( uid->is_expired ) - printf("e::::::::"); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - printf("::::::::"); - else - { - int uid_validity; - - if( primary && !ulti_hack ) - uid_validity = get_validity_info( primary, uid ); - else - uid_validity = 'u'; - printf("%c::::::::",uid_validity); - } - - if(uid->attrib_data) - printf ("%u %lu",uid->numattribs,uid->attrib_len); - else - print_string (stdout, uid->name, uid->len, ':'); - - putchar (':'); - /* signature class */ - putchar (':'); - /* capabilities */ - putchar (':'); - /* preferences */ - if (pk_version>3 || uid->selfsigversion>3) - { - const prefitem_t *prefs = uid->prefs; - - for (j=0; prefs && prefs[j].type; j++) - { - if (j) - putchar (' '); - printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' : - prefs[j].type == PREFTYPE_HASH ? 'H' : - prefs[j].type == PREFTYPE_ZIP ? 'Z':'?', - prefs[j].value); - } - if (uid->mdc_feature) - printf (",mdc"); - if (!uid->ks_modify) - printf (",no-ks-modify"); - } - putchar (':'); - /* flags */ - printf ("%d,", i); - if (uid->is_primary) - putchar ('p'); - if (uid->is_revoked) - putchar ('r'); - if (uid->is_expired) - putchar ('e'); - if ((node->flag & NODFLG_SELUID)) - putchar ('s'); - if ((node->flag & NODFLG_MARK_A)) - putchar ('m'); - putchar (':'); - putchar('\n'); - } - } -} - - -/**************** - * Display the key a the user ids, if only_marked is true, do only - * so for user ids with mark A flag set and dont display the index number - */ -static void -show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker, - int with_fpr, int with_subkeys, int with_prefs ) -{ - KBNODE node; - int i, rc; - int do_warn = 0; - byte pk_version=0; - PKT_public_key *primary=NULL; - - if (opt.with_colons) - { - show_key_with_all_names_colon (keyblock); - return; - } - - /* the keys */ - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY - || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - const char *otrust="err",*trust="err"; - - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - /* do it here, so that debug messages don't clutter the - * output */ - static int did_warn = 0; - - trust = get_validity_string (pk, NULL); - otrust = get_ownertrust_string (pk); - - /* Show a warning once */ - if (!did_warn - && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) { - did_warn = 1; - do_warn = 1; - } - - pk_version = pk->version; - primary = pk; - } - - if(with_revoker) { - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - for(i=0;i<pk->numrevkeys;i++) { - u32 r_keyid[2]; - char *user; - const char *algo= - gcry_pk_algo_name (pk->revkey[i].algid); - - keyid_from_fingerprint(pk->revkey[i].fpr, - MAX_FINGERPRINT_LEN,r_keyid); - - user=get_user_id_string (r_keyid); - tty_printf (_("This key may be revoked by %s key "), - algo?algo:"?"); - tty_print_utf8_string (user, strlen (user)); - if ((pk->revkey[i].class&0x40)) - tty_printf (_(" (sensitive)")); - tty_printf ("\n"); - xfree (user); - } - } - - keyid_from_pk(pk,NULL); - tty_printf("%s%c %4u%c/", - node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", - (node->flag & NODFLG_SELKEY)? '*':' ', - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo )); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf("%08lX",(ulong)pk->keyid[0]); - - tty_printf("%08lX ",(ulong)pk->keyid[1]); - tty_printf(_("created: %s expires: %s"), - datestr_from_pk(pk), - expirestr_from_pk(pk) ); - tty_printf("\n"); - - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - { - tty_printf(" "); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - tty_printf(" "); - tty_printf(_("trust: %-13s"), otrust); - tty_printf(_("validity: %s"), trust ); - tty_printf("\n"); - if( node->pkt->pkttype == PKT_PUBLIC_KEY - && (get_ownertrust (pk)&TRUST_FLAG_DISABLED)) - { - tty_printf("*** "); - tty_printf(_("This key has been disabled")); - tty_printf("\n"); - } - } - - if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr ) - { - print_fingerprint ( pk, NULL, 2 ); - tty_printf("\n"); - } - } - else if( node->pkt->pkttype == PKT_SECRET_KEY - || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb", - (node->flag & NODFLG_SELKEY)? '*':' ', - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk(sk,NULL), - datestr_from_sk(sk), - expirestr_from_sk(sk) ); - tty_printf("\n"); - } - else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE - && node->pkt->pkt.signature->sig_class == 0x28 ) { - PKT_signature *sig = node->pkt->pkt.signature; - - rc = check_key_signature( keyblock, node, NULL ); - if( !rc ) - tty_printf( _("rev! subkey has been revoked: %s\n"), - datestr_from_sig( sig ) ); - else if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) - tty_printf( _("rev- faked revocation found\n") ); - else if( rc ) - tty_printf( _("rev? problem checking revocation: %s\n"), - gpg_strerror (rc) ); - } - } - /* the user ids */ - i = 0; - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - ++i; - if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){ - if(opt.list_options&LIST_SHOW_VALIDITY && primary) - tty_printf("[%8.8s] ", - trust_value_to_string(get_validity(primary,uid))); - if( only_marked ) - tty_printf(" "); - else if( node->flag & NODFLG_SELUID ) - tty_printf("(%d)* ", i); - else if( uid->is_primary ) - tty_printf("(%d). ", i); - else - tty_printf("(%d) ", i); - if ( uid->is_revoked ) - tty_printf (_("[revoked] ")); - if ( uid->is_expired ) - tty_printf (_("[expired] ")); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - if( with_prefs ) - { - if(pk_version>3 || uid->selfsigversion>3) - show_prefs (uid, with_prefs == 2); - else - tty_printf(_("There are no preferences on a " - "PGP 2.x-style user ID.\n")); - } - } - } - } - - if (do_warn) - tty_printf (_("Please note that the shown key validity " - "is not necessarily correct\n" - "unless you restart the program.\n")); - -} - - -/* Display basic key information. This fucntion is suitable to show - information on the key without any dependencies on the trustdb or - any other internal GnuPG stuff. KEYBLOCK may either be a public or - a secret key.*/ -void -show_basic_key_info ( KBNODE keyblock ) -{ - KBNODE node; - int i; - - /* The primary key */ - for (node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - - /* Note, we use the same format string as in other show - functions to make the translation job easier. */ - tty_printf (_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", - ' ', - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk(pk,NULL), - datestr_from_pk(pk), - expirestr_from_pk(pk) ); - tty_printf("\n"); - print_fingerprint ( pk, NULL, 3 ); - tty_printf("\n"); - } - else if (node->pkt->pkttype == PKT_SECRET_KEY) - { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"), - node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb", - ' ', - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk(sk,NULL), - datestr_from_sk(sk), - expirestr_from_sk(sk) ); - tty_printf("\n"); - print_fingerprint (NULL, sk, 3 ); - tty_printf("\n"); - } - } - - /* The user IDs. */ - for (i=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - ++i; - - tty_printf (" "); - if (uid->is_revoked) - tty_printf ("[revoked] "); - if ( uid->is_expired ) - tty_printf ("[expired] "); - tty_print_utf8_string (uid->name, uid->len); - tty_printf ("\n"); - } - } -} - -static void -show_key_and_fingerprint( KBNODE keyblock ) -{ - KBNODE node; - PKT_public_key *pk = NULL; - - for( node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - pk = node->pkt->pkt.public_key; - tty_printf("pub %4u%c/%08lX %s ", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk(pk,NULL), - datestr_from_pk(pk) ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - tty_print_utf8_string( uid->name, uid->len ); - break; - } - } - tty_printf("\n"); - if( pk ) - print_fingerprint( pk, NULL, 2 ); -} - - -/* Show a warning if no uids on the key have the primary uid flag - set. */ -static void -no_primary_warning(KBNODE keyblock, int uids) -{ - KBNODE node; - int select_all=1,have_uid=0,uid_count=0; - - if(uids) - select_all=!count_selected_uids(keyblock); - - /* TODO: if we ever start behaving differently with a primary or - non-primary attribute ID, we will need to check for attributes - here as well. */ - - for(node=keyblock; node; node = node->next) - { - if(node->pkt->pkttype==PKT_USER_ID - && node->pkt->pkt.user_id->attrib_data==NULL) - { - uid_count++; - - if((select_all || (node->flag & NODFLG_SELUID)) - && node->pkt->pkt.user_id->is_primary==2) - have_uid|=2; - else - have_uid|=1; - } - } - - if(uid_count>1 && have_uid&1 && !(have_uid&2)) - log_info(_("WARNING: no user ID has been marked as primary. This command " - "may\n cause a different user ID to become the assumed primary.\n")); -} - -/**************** - * Ask for a new user id, do the selfsignature and put it into - * both keyblocks. - * Return true if there is a new user id - */ -static int -menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo) -{ - PKT_user_id *uid; - PKT_public_key *pk=NULL; - PKT_secret_key *sk=NULL; - PKT_signature *sig=NULL; - PACKET *pkt; - KBNODE node; - KBNODE pub_where=NULL, sec_where=NULL; - int rc; - - for( node = pub_keyblock; node; pub_where = node, node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - pk = node->pkt->pkt.public_key; - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; - } - if( !node ) /* no subkey */ - pub_where = NULL; - for( node = sec_keyblock; node; sec_where = node, node = node->next ) { - if( node->pkt->pkttype == PKT_SECRET_KEY ) - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - } - if( !node ) /* no subkey */ - sec_where = NULL; - assert(pk && sk); - - if(photo) { - int hasattrib=0; - - for( node = pub_keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && - node->pkt->pkt.user_id->attrib_data!=NULL) - { - hasattrib=1; - break; - } - - /* It is legal but bad for compatibility to add a photo ID to a - v3 key as it means that PGP2 will not be able to use that key - anymore. Also, PGP may not expect a photo on a v3 key. - Don't bother to ask this if the key already has a photo - any - damage has already been done at that point. -dms */ - if(pk->version==3 && !hasattrib) - { - if(opt.expert) - { - tty_printf(_("WARNING: This is a PGP2-style key. " - "Adding a photo ID may cause some versions\n" - " of PGP to reject this key.\n")); - - if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay", - _("Are you sure you still want " - "to add it? (y/N) "))) - return 0; - } - else - { - tty_printf(_("You may not add a photo ID to " - "a PGP2-style key.\n")); - return 0; - } - } - - uid = generate_photo_id(pk); - } else - uid = generate_user_id(); - if( !uid ) - return 0; - - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, pk ); - free_secret_key( sk ); - if( rc ) { - log_error("signing failed: %s\n", gpg_strerror (rc) ); - free_user_id(uid); - return 0; - } - - /* insert/append to secret keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = scopy_user_id(uid); - node = new_kbnode(pkt); - if( sec_where ) - insert_kbnode( sec_where, node, 0 ); - else - add_kbnode( sec_keyblock, node ); - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - if( sec_where ) - insert_kbnode( node, new_kbnode(pkt), 0 ); - else - add_kbnode( sec_keyblock, new_kbnode(pkt) ); - /* insert/append to public keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = uid; - node = new_kbnode(pkt); - if( pub_where ) - insert_kbnode( pub_where, node, 0 ); - else - add_kbnode( pub_keyblock, node ); - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - if( pub_where ) - insert_kbnode( node, new_kbnode(pkt), 0 ); - else - add_kbnode( pub_keyblock, new_kbnode(pkt) ); - return 1; -} - - -/**************** - * Remove all selceted userids from the keyrings - */ -static void -menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - KBNODE node; - int selected=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - selected = node->flag & NODFLG_SELUID; - if( selected ) { - /* Only cause a trust update if we delete a - non-revoked user id */ - if(!node->pkt->pkt.user_id->is_revoked) - update_trust=1; - delete_kbnode( node ); - if( sec_keyblock ) { - KBNODE snode; - int s_selected = 0; - PKT_user_id *uid = node->pkt->pkt.user_id; - for( snode = sec_keyblock; snode; snode = snode->next ) { - if( snode->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *suid = snode->pkt->pkt.user_id; - - s_selected = - (uid->len == suid->len - && !memcmp( uid->name, suid->name, uid->len)); - if( s_selected ) - delete_kbnode( snode ); - } - else if( s_selected - && snode->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( snode ); - else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) - s_selected = 0; - } - } - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( node ); - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - selected = 0; - } - commit_kbnode( &pub_keyblock ); - if( sec_keyblock ) - commit_kbnode( &sec_keyblock ); -} - - -static int -menu_delsig( KBNODE pub_keyblock ) -{ - KBNODE node; - PKT_user_id *uid = NULL; - int changed=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL; - } - else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) { - int okay, valid, selfsig, inv_sig, no_key, other_err; - - tty_printf("uid "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - - okay = inv_sig = no_key = other_err = 0; - valid = print_and_check_one_sig( pub_keyblock, node, - &inv_sig, &no_key, &other_err, - &selfsig, 1 ); - - if( valid ) { - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.valid", - _("Delete this good signature? (y/N/q)")); - - /* Only update trust if we delete a good signature. - The other two cases do not affect trust. */ - if(okay) - update_trust=1; - } - else if( inv_sig || other_err ) - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.invalid", - _("Delete this invalid signature? (y/N/q)")); - else if( no_key ) - okay = cpr_get_answer_yes_no_quit( - "keyedit.delsig.unknown", - _("Delete this unknown signature? (y/N/q)")); - - if( okay == -1 ) - break; - if( okay && selfsig && !cpr_get_answer_is_yes( - "keyedit.delsig.selfsig", - _("Really delete this self-signature? (y/N)") )) - okay = 0; - if( okay ) { - delete_kbnode( node ); - changed++; - } - - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - uid = NULL; - } - - if( changed ) { - commit_kbnode( &pub_keyblock ); - tty_printf( changed == 1? _("Deleted %d signature.\n") - : _("Deleted %d signatures.\n"), changed ); - } - else - tty_printf( _("Nothing deleted.\n") ); - - return changed; -} - - -/**************** - * Remove some of the secondary keys - */ -static void -menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - KBNODE node; - int selected=0; - - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - selected = node->flag & NODFLG_SELKEY; - if( selected ) { - delete_kbnode( node ); - if( sec_keyblock ) { - KBNODE snode; - int s_selected = 0; - u32 ki[2]; - - keyid_from_pk( node->pkt->pkt.public_key, ki ); - for( snode = sec_keyblock; snode; snode = snode->next ) { - if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 ki2[2]; - - keyid_from_sk( snode->pkt->pkt.secret_key, ki2 ); - s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]); - if( s_selected ) - delete_kbnode( snode ); - } - else if( s_selected - && snode->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( snode ); - else - s_selected = 0; - } - } - } - } - else if( selected && node->pkt->pkttype == PKT_SIGNATURE ) - delete_kbnode( node ); - else - selected = 0; - } - commit_kbnode( &pub_keyblock ); - if( sec_keyblock ) - commit_kbnode( &sec_keyblock ); - - /* No need to set update_trust here since signing keys are no - longer used to certify other keys, so there is no change in - trust when revoking/removing them */ -} - - -/**************** - * Ask for a new revoker, do the selfsignature and put it into - * both keyblocks. - * Return true if there is a new revoker - */ -static int -menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive ) -{ - PKT_public_key *pk=NULL,*revoker_pk=NULL; - PKT_secret_key *sk=NULL; - PKT_signature *sig=NULL; - PACKET *pkt; - struct revocation_key revkey; - size_t fprlen; - int rc; - - assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY); - assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY); - - pk=pub_keyblock->pkt->pkt.public_key; - - if(pk->numrevkeys==0 && pk->version==3) - { - /* It is legal but bad for compatibility to add a revoker to a - v3 key as it means that PGP2 will not be able to use that key - anymore. Also, PGP may not expect a revoker on a v3 key. - Don't bother to ask this if the key already has a revoker - - any damage has already been done at that point. -dms */ - if(opt.expert) - { - tty_printf(_("WARNING: This is a PGP 2.x-style key. " - "Adding a designated revoker may cause\n" - " some versions of PGP to reject this key.\n")); - - if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay", - _("Are you sure you still want " - "to add it? (y/N) "))) - return 0; - } - else - { - tty_printf(_("You may not add a designated revoker to " - "a PGP 2.x-style key.\n")); - return 0; - } - } - - sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key); - - for(;;) - { - char *answer; - u32 keyid[2]; - char *p; - size_t n; - - if(revoker_pk) - free_public_key(revoker_pk); - - revoker_pk=xcalloc (1,sizeof(*revoker_pk)); - - tty_printf("\n"); - - answer=cpr_get_utf8("keyedit.add_revoker", - _("Enter the user ID of the designated revoker: ")); - if(answer[0]=='\0' || answer[0]=='\004') - { - xfree(answer); answer = NULL; - goto fail; - } - - rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1); - - if(rc) - { - log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc)); - xfree (answer); answer = NULL; - continue; - } - - xfree (answer); answer = NULL; - - - fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen); - if(fprlen!=20) - { - log_error(_("cannot appoint a PGP 2.x style key as a " - "designated revoker\n")); - continue; - } - - revkey.class=0x80; - if(sensitive) - revkey.class|=0x40; - revkey.algid=revoker_pk->pubkey_algo; - - if(cmp_public_keys(revoker_pk,pk)==0) - { - /* This actually causes no harm (after all, a key that - designates itself as a revoker is the same as a - regular key), but it's easy enough to check. */ - log_error(_("you cannot appoint a key as its own " - "designated revoker\n")); - - continue; - } - - keyid_from_pk(pk,NULL); - - /* Does this revkey already exist? */ - if(!pk->revkey && pk->numrevkeys) - BUG(); - else - { - int i; - - for(i=0;i<pk->numrevkeys;i++) - { - if(memcmp(&pk->revkey[i],&revkey, - sizeof(struct revocation_key))==0) - { - char buf[50]; - - log_error(_("this key has already been designated " - "as a revoker\n")); - - sprintf(buf,"%08lX%08lX", - (ulong)pk->keyid[0],(ulong)pk->keyid[1]); - write_status_text(STATUS_ALREADY_SIGNED,buf); - - break; - } - } - - if(i<pk->numrevkeys) - continue; - } - - keyid_from_pk(revoker_pk,keyid); - - tty_printf("\npub %4u%c/%08lX %s ", - nbits_from_pk( revoker_pk ), - pubkey_letter( revoker_pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk(pk) ); - - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - tty_printf("\n"); - print_fingerprint(revoker_pk,NULL,2); - tty_printf("\n"); - - tty_printf(_("WARNING: appointing a key as a designated revoker " - "cannot be undone!\n")); - - tty_printf("\n"); - - if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay", - _("Are you sure you want to appoint this " - "key as a designated revoker? (y/N): "))) - continue; - - free_public_key(revoker_pk); - revoker_pk=NULL; - break; - } - - /* The 1F signature must be at least v4 to carry the revocation key - subpacket. */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0, - keygen_add_revkey,&revkey ); - if( rc ) - { - log_error("signing failed: %s\n", gpg_strerror (rc) ); - goto fail; - } - - free_secret_key(sk); - sk=NULL; - - /* insert into secret keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature(NULL, sig); - insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); - - /* insert into public keyblock */ - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); - - return 1; - - fail: - if(sk) - free_secret_key(sk); - if(sig) - free_seckey_enc(sig); - if(revoker_pk) - free_public_key(revoker_pk); - - return 0; -} - - -static int -menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - int n1, signumber, rc; - u32 expiredate; - int mainkey=0; - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk, *sub_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - - if( count_selected_keys( sec_keyblock ) ) { - tty_printf(_("Please remove selections from the secret keys.\n")); - return 0; - } - - n1 = count_selected_keys( pub_keyblock ); - if( n1 > 1 ) { - tty_printf(_("Please select at most one secondary key.\n")); - return 0; - } - else if( n1 ) - tty_printf(_("Changing expiration time for a secondary key.\n")); - else { - tty_printf(_("Changing expiration time for the primary key.\n")); - mainkey=1; - } - - no_primary_warning(pub_keyblock,0); - - expiredate = ask_expiredate(); - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = sub_pk = NULL; - uid = NULL; - signumber = 0; - for( node=pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - main_pk->expiredate = expiredate; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && (node->flag & NODFLG_SELKEY ) ) { - sub_pk = node->pkt->pkt.public_key; - sub_pk->expiredate = expiredate; - } - else if( node->pkt->pkttype == PKT_USER_ID ) - uid = node->pkt->pkt.user_id; - else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE - && ( mainkey || sub_pk ) ) { - PKT_signature *sig = node->pkt->pkt.signature; - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && ( (mainkey && uid - && uid->created && (sig->sig_class&~3) == 0x10) - || (!mainkey && sig->sig_class == 0x18) ) ) { - /* this is a selfsignature which is to be replaced */ - PKT_signature *newsig; - PACKET *newpkt; - KBNODE sn; - int signumber2 = 0; - - signumber++; - - if( (mainkey && main_pk->version < 4) - || (!mainkey && sub_pk->version < 4 ) ) { - log_info(_( - "You can't change the expiration date of a v3 key\n")); - free_secret_key( sk ); - return 0; - } - - /* find the corresponding secret self-signature */ - for( sn=sec_keyblock; sn; sn = sn->next ) { - if( sn->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *b = sn->pkt->pkt.signature; - if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1] - && sig->sig_class == b->sig_class - && ++signumber2 == signumber ) - break; - } - } - if( !sn ) - log_info(_("No corresponding signature in secret ring\n")); - - if( mainkey ) - rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL, - sk, keygen_add_key_expire, main_pk); - else - rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk, - sk, keygen_add_key_expire, sub_pk ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - if( sn ) { - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = copy_signature( NULL, newsig ); - free_packet( sn->pkt ); - xfree ( sn->pkt ); - sn->pkt = newpkt; - } - sub_pk = NULL; - } - } - } - - free_secret_key( sk ); - update_trust=1; - return 1; -} - -static int -change_primary_uid_cb ( PKT_signature *sig, void *opaque ) -{ - byte buf[1]; - - /* first clear all primary uid flags so that we are sure none are - * lingering around */ - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID); - - /* if opaque is set,we want to set the primary id */ - if (opaque) { - buf[0] = 1; - build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 ); - } - - return 0; -} - - -/* - * Set the primary uid flag for the selected UID. We will also reset - * all other primary uid flags. For this to work with have to update - * all the signature timestamps. If we would do this with the current - * time, we lose quite a lot of information, so we use a a kludge to - * do this: Just increment the timestamp by one second which is - * sufficient to updated a signature during import. - */ -static int -menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected; - int attribute = 0; - int modified = 0; - - if ( count_selected_uids (pub_keyblock) != 1 ) { - tty_printf(_("Please select exactly one user ID.\n")); - return 0; - } - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - - /* Is our selected uid an attribute packet? */ - for ( node=pub_keyblock; node; node = node->next ) - if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID) - attribute = (node->pkt->pkt.user_id->attrib_data!=NULL); - - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = node->flag & NODFLG_SELUID; - } - else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) - && attribute == (uid->attrib_data!=NULL)) { - if(sig->version < 4) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree (user); - } - else { - /* This is a selfsignature which is to be replaced. - We can just ignore v3 signatures because they are - not able to carry the primary ID flag. We also - ignore self-sigs on user IDs that are not of the - same type that we are making primary. That is, if - we are making a user ID primary, we alter user IDs. - If we are making an attribute packet primary, we - alter attribute packets. */ - - /* FIXME: We must make sure that we only have one - self-signature per user ID here (not counting - revocations) */ - PKT_signature *newsig; - PACKET *newpkt; - const byte *p; - int action; - - /* see whether this signature has the primary UID flag */ - p = parse_sig_subpkt (sig->hashed, - SIGSUBPKT_PRIMARY_UID, NULL ); - if ( !p ) - p = parse_sig_subpkt (sig->unhashed, - SIGSUBPKT_PRIMARY_UID, NULL ); - if ( p && *p ) /* yes */ - action = selected? 0 : -1; - else /* no */ - action = selected? 1 : 0; - - if (action) { - int rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - change_primary_uid_cb, - action > 0? "x":NULL ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - modified = 1; - } - } - } - } - } - - free_secret_key( sk ); - return modified; -} - - -/* - * Set preferences to new values for the selected user IDs - */ -static int -menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected, select_all; - int modified = 0; - - no_primary_warning(pub_keyblock,1); - - select_all = !count_selected_uids (pub_keyblock); - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = select_all || (node->flag & NODFLG_SELUID); - } - else if ( main_pk && uid && selected - && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) ) { - if( sig->version < 4 ) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree (user); - } - else { - /* This is a selfsignature which is to be replaced - * We have to ignore v3 signatures because they are - * not able to carry the preferences */ - PKT_signature *newsig; - PACKET *newpkt; - int rc; - - rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - keygen_upd_std_prefs, - NULL ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree ( node->pkt ); - node->pkt = newpkt; - modified = 1; - } - } - } - } - - free_secret_key( sk ); - return modified; -} - - - -static int -menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_secret_key *sk; /* copy of the main sk */ - PKT_public_key *main_pk; - PKT_user_id *uid; - KBNODE node; - u32 keyid[2]; - int selected, select_all; - int modified = 0; - char *answer; - - no_primary_warning(pub_keyblock,1); - - answer=cpr_get_utf8("keyedit.add_keyserver", - _("Enter your preferred keyserver URL: ")); - if(answer[0]=='\0' || answer[0]=='\004') - { - xfree(answer); - return 0; - } - - select_all = !count_selected_uids (pub_keyblock); - - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ - main_pk = NULL; - uid = NULL; - selected = 0; - for ( node=pub_keyblock; node; node = node->next ) { - if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; /* ready */ - - if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { - main_pk = node->pkt->pkt.public_key; - keyid_from_pk( main_pk, keyid ); - } - else if ( node->pkt->pkttype == PKT_USER_ID ) { - uid = node->pkt->pkt.user_id; - selected = select_all || (node->flag & NODFLG_SELUID); - } - else if ( main_pk && uid && selected - && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] - && (uid && (sig->sig_class&~3) == 0x10) ) { - if( sig->version < 4 ) { - char *user=utf8_to_native(uid->name,strlen(uid->name),0); - - log_info(_("skipping v3 self-signature on user id \"%s\"\n"), - user); - xfree(user); - } - else { - /* This is a selfsignature which is to be replaced - * We have to ignore v3 signatures because they are - * not able to carry the preferences */ - PKT_signature *newsig; - PACKET *newpkt; - int rc; - - rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, - keygen_add_keyserver_url, - answer ); - if( rc ) { - log_error ("update_keysig_packet failed: %s\n", - gpg_strerror (rc)); - xfree(answer); - free_secret_key( sk ); - return 0; - } - /* replace the packet */ - newpkt = xcalloc (1, sizeof *newpkt ); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = newsig; - free_packet( node->pkt ); - xfree (node->pkt); - node->pkt = newpkt; - modified = 1; - } - } - } - } - - xfree(answer); - free_secret_key( sk ); - return modified; -} - - -/**************** - * Select one user id or remove all selection if index is 0. - * Returns: True if the selection changed; - */ -static int -menu_select_uid( KBNODE keyblock, int idx ) -{ - KBNODE node; - int i; - - /* first check that the index is valid */ - if( idx ) { - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - if( ++i == idx ) - break; - } - } - if( !node ) { - tty_printf(_("No user ID with index %d\n"), idx ); - return 0; - } - } - else { /* reset all */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) - node->flag &= ~NODFLG_SELUID; - } - return 1; - } - /* and toggle the new index */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID ) { - if( ++i == idx ) { - if( (node->flag & NODFLG_SELUID) ) - node->flag &= ~NODFLG_SELUID; - else - node->flag |= NODFLG_SELUID; - } - } - } - - return 1; -} - -/**************** - * Select secondary keys - * Returns: True if the selection changed; - */ -static int -menu_select_key( KBNODE keyblock, int idx ) -{ - KBNODE node; - int i; - - /* first check that the index is valid */ - if( idx ) { - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( ++i == idx ) - break; - } - } - if( !node ) { - tty_printf(_("No secondary key with index %d\n"), idx ); - return 0; - } - } - else { /* reset all */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - node->flag &= ~NODFLG_SELKEY; - } - return 1; - } - /* and set the new index */ - for( i=0, node = keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( ++i == idx ) { - if( (node->flag & NODFLG_SELKEY) ) - node->flag &= ~NODFLG_SELKEY; - else - node->flag |= NODFLG_SELKEY; - } - } - } - - return 1; -} - - -static int -count_uids_with_flag( KBNODE keyblock, unsigned flag ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) ) - i++; - return i; -} - -static int -count_keys_with_flag( KBNODE keyblock, unsigned flag ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY) - && (node->flag & flag) ) - i++; - return i; -} - -static int -count_uids( KBNODE keyblock ) -{ - KBNODE node; - int i=0; - - for( node = keyblock; node; node = node->next ) - if( node->pkt->pkttype == PKT_USER_ID ) - i++; - return i; -} - - -/**************** - * Returns true if there is at least one selected user id - */ -static int -count_selected_uids( KBNODE keyblock ) -{ - return count_uids_with_flag( keyblock, NODFLG_SELUID); -} - -static int -count_selected_keys( KBNODE keyblock ) -{ - return count_keys_with_flag( keyblock, NODFLG_SELKEY); -} - -/* returns how many real (i.e. not attribute) uids are unmarked */ -static int -real_uids_left( KBNODE keyblock ) -{ - KBNODE node; - int real=0; - - for(node=keyblock;node;node=node->next) - if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) && - !node->pkt->pkt.user_id->attrib_data) - real++; - - return real; -} - -/* - * Ask whether the signature should be revoked. If the user commits this, - * flag bit MARK_A is set on the signature and the user ID. - */ -static void -ask_revoke_sig( KBNODE keyblock, KBNODE node ) -{ - int doit=0; - PKT_signature *sig = node->pkt->pkt.signature; - KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID ); - - if( !unode ) { - log_error("Oops: no user ID for signature\n"); - return; - } - - tty_printf(_("user ID: \"")); - tty_print_utf8_string( unode->pkt->pkt.user_id->name, - unode->pkt->pkt.user_id->len ); - - if(sig->flags.exportable) - tty_printf(_("\"\nsigned with your key %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - else - tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - - if(sig->flags.expired) - { - tty_printf(_("This signature expired on %s.\n"), - expirestr_from_sig(sig)); - /* Use a different question so we can have different help text */ - doit=cpr_get_answer_is_yes("ask_revoke_sig.expired", - _("Are you sure you still want to revoke it? (y/N) ")); - } - else - doit=cpr_get_answer_is_yes("ask_revoke_sig.one", - _("Create a revocation certificate for this signature? (y/N) ")); - - if(doit) { - node->flag |= NODFLG_MARK_A; - unode->flag |= NODFLG_MARK_A; - } -} - -/**************** - * Display all user ids of the current public key together with signatures - * done by one of our keys. Then walk over all this sigs and ask the user - * whether he wants to revoke this signature. - * Return: True when the keyblock has changed. - */ -static int -menu_revsig( KBNODE keyblock ) -{ - PKT_signature *sig; - PKT_public_key *primary_pk; - KBNODE node; - int changed = 0; - int rc, any, skip=1, all=!count_selected_uids(keyblock); - struct revocation_reason_info *reason = NULL; - - /* FIXME: detect duplicates here */ - tty_printf(_("You have signed these user IDs:\n")); - for( node = keyblock; node; node = node->next ) { - node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A); - if( node->pkt->pkttype == PKT_USER_ID ) { - if( node->flag&NODFLG_SELUID || all ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - /* Hmmm: Should we show only UIDs with a signature? */ - tty_printf(" "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - skip=0; - } - else - skip=1; - } - else if( !skip && node->pkt->pkttype == PKT_SIGNATURE - && ((sig = node->pkt->pkt.signature), - !seckey_available(sig->keyid) ) ) { - if( (sig->sig_class&~3) == 0x10 ) { - tty_printf(_(" signed by %08lX at %s%s%s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig), - sig->flags.exportable?"":" (non-exportable)", - sig->flags.revocable?"":" (non-revocable)"); - if(sig->flags.revocable) - node->flag |= NODFLG_SELSIG; - } - else if( sig->sig_class == 0x30 ) { - tty_printf(_(" revoked by %08lX at %s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig) ); - } - } - } - - /* ask */ - for( node = keyblock; node; node = node->next ) { - if( !(node->flag & NODFLG_SELSIG) ) - continue; - ask_revoke_sig( keyblock, node ); - } - - /* present selected */ - any = 0; - for( node = keyblock; node; node = node->next ) { - if( !(node->flag & NODFLG_MARK_A) ) - continue; - if( !any ) { - any = 1; - tty_printf(_("You are about to revoke these signatures:\n")); - } - if( node->pkt->pkttype == PKT_USER_ID ) { - PKT_user_id *uid = node->pkt->pkt.user_id; - tty_printf(" "); - tty_print_utf8_string( uid->name, uid->len ); - tty_printf("\n"); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - sig = node->pkt->pkt.signature; - tty_printf(_(" signed by %08lX at %s%s\n"), - (ulong)sig->keyid[1], datestr_from_sig(sig), - sig->flags.exportable?"":_(" (non-exportable)") ); - } - } - if( !any ) - return 0; /* none selected */ - - if( !cpr_get_answer_is_yes("ask_revoke_sig.okay", - _("Really create the revocation certificates? (y/N) ")) ) - return 0; /* forget it */ - - reason = ask_revocation_reason( 0, 1, 0 ); - if( !reason ) { /* user decided to cancel */ - return 0; - } - - /* now we can sign the user ids */ - reloop: /* (must use this, because we are modifing the list) */ - primary_pk = keyblock->pkt->pkt.public_key; - for( node=keyblock; node; node = node->next ) { - KBNODE unode; - PACKET *pkt; - struct sign_attrib attrib; - PKT_secret_key *sk; - - if( !(node->flag & NODFLG_MARK_A) - || node->pkt->pkttype != PKT_SIGNATURE ) - continue; - unode = find_prev_kbnode( keyblock, node, PKT_USER_ID ); - assert( unode ); /* we already checked this */ - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable; - - node->flag &= ~NODFLG_MARK_A; - sk = xcalloc_secure (1, sizeof *sk ); - if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) { - log_info(_("no secret key\n")); - continue; - } - rc = make_keysig_packet( &sig, primary_pk, - unode->pkt->pkt.user_id, - NULL, - sk, - 0x30, 0, 0, 0, 0, - sign_mk_attrib, - &attrib ); - free_secret_key(sk); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - release_revocation_reason_info( reason ); - return changed; - } - changed = 1; /* we changed the keyblock */ - update_trust = 1; - /* Are we revoking our own uid? */ - if(primary_pk->keyid[0]==sig->keyid[0] && - primary_pk->keyid[1]==sig->keyid[1]) - unode->pkt->pkt.user_id->is_revoked=1; - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( unode, new_kbnode(pkt), 0 ); - goto reloop; - } - - release_revocation_reason_info( reason ); - return changed; -} - -/* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if - keyblock changed. */ -static int -menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key; - PKT_secret_key *sk = copy_secret_key( NULL, - sec_keyblock->pkt->pkt.secret_key ); - KBNODE node; - int changed = 0; - int rc; - struct revocation_reason_info *reason = NULL; - - /* Note that this is correct as per the RFCs, but nevertheless - somewhat meaningless in the real world. 1991 did define the 0x30 - sig class, but PGP 2.x did not actually implement it, so it would - probably be safe to use v4 revocations everywhere. -ds */ - - for( node = pub_keyblock; node; node = node->next ) - if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID && - node->pkt->pkt.user_id->selfsigversion>3)) - { - if((reason = ask_revocation_reason( 0, 1, 4 ))) - break; - else - goto leave; - } - - reloop: /* (better this way because we are modifing the keyring) */ - for( node = pub_keyblock; node; node = node->next ) - if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID)) - { - PKT_user_id *uid=node->pkt->pkt.user_id; - - if(uid->is_revoked) - { - char *user=utf8_to_native(uid->name,uid->len,0); - log_info(_("user ID \"%s\" is already revoked\n"),user); - xfree (user); - } - else - { - PACKET *pkt; - PKT_signature *sig; - struct sign_attrib attrib; - u32 timestamp=make_timestamp(); - - if(uid->created>=timestamp) - { - /* Okay, this is a problem. The user ID selfsig was - created in the future, so we need to warn the user and - set our revocation timestamp one second after that so - everything comes out clean. */ - - log_info(_("WARNING: a user ID signature is dated %d" - " seconds in the future\n"),uid->created-timestamp); - - timestamp=uid->created+1; - } - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - - node->flag &= ~NODFLG_SELUID; - - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0, - (reason==NULL)?3:0, timestamp, 0, - sign_mk_attrib, &attrib ); - if( rc ) - { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - else - { - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), 0 ); - - /* If the trustdb has an entry for this key+uid then the - trustdb needs an update. */ - if(!update_trust - && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED) - update_trust=1; - - changed = 1; - node->pkt->pkt.user_id->is_revoked=1; - - goto reloop; - } - } - } - - if(changed) - commit_kbnode( &pub_keyblock ); - - leave: - free_secret_key(sk); - release_revocation_reason_info( reason ); - return changed; -} - -/**************** - * Revoke some of the secondary keys. - * Hmmm: Should we add a revocation to the secret keyring too? - * Does its all make sense to duplicate most of the information? - */ -static int -menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - PKT_public_key *mainpk; - KBNODE node; - int changed = 0; - int rc; - struct revocation_reason_info *reason = NULL; - - reason = ask_revocation_reason( 1, 0, 0 ); - if( !reason ) { /* user decided to cancel */ - return 0; - } - - reloop: /* (better this way because we are modifing the keyring) */ - mainpk = pub_keyblock->pkt->pkt.public_key; - for( node = pub_keyblock; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY - && (node->flag & NODFLG_SELKEY) ) { - PACKET *pkt; - PKT_signature *sig; - PKT_secret_key *sk; - PKT_public_key *subpk = node->pkt->pkt.public_key; - struct sign_attrib attrib; - - memset( &attrib, 0, sizeof attrib ); - attrib.reason = reason; - - node->flag &= ~NODFLG_SELKEY; - sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key ); - rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, - 0x28, 0, 0, 0, 0, - sign_mk_attrib, &attrib ); - free_secret_key(sk); - if( rc ) { - log_error(_("signing failed: %s\n"), gpg_strerror (rc)); - release_revocation_reason_info( reason ); - return changed; - } - changed = 1; /* we changed the keyblock */ - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - insert_kbnode( node, new_kbnode(pkt), 0 ); - goto reloop; - } - } - commit_kbnode( &pub_keyblock ); - /*commit_kbnode( &sec_keyblock );*/ - - /* No need to set update_trust here since signing keys no longer - are used to certify other keys, so there is no change in trust - when revoking/removing them */ - - release_revocation_reason_info( reason ); - return changed; -} - -/* Note that update_ownertrust is going to mark the trustdb dirty when - enabling or disabling a key. This is arguably sub-optimal as - disabled keys are still counted in the web of trust, but perhaps - not worth adding extra complexity to change. -ds */ -static int -enable_disable_key( KBNODE keyblock, int disable ) -{ - PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY ) - ->pkt->pkt.public_key; - unsigned int trust, newtrust; - - trust = newtrust = get_ownertrust (pk); - newtrust &= ~TRUST_FLAG_DISABLED; - if( disable ) - newtrust |= TRUST_FLAG_DISABLED; - if( trust == newtrust ) - return 0; /* already in that state */ - update_ownertrust(pk, newtrust ); - return 0; -} - - -static void -menu_showphoto( KBNODE keyblock ) -{ - KBNODE node; - int select_all = !count_selected_uids(keyblock); - int count=0; - PKT_public_key *pk=NULL; - u32 keyid[2]; - - /* Look for the public key first. We have to be really, really, - explicit as to which photo this is, and what key it is a UID on - since people may want to sign it. */ - - for( node = keyblock; node; node = node->next ) - { - if( node->pkt->pkttype == PKT_PUBLIC_KEY ) - { - pk = node->pkt->pkt.public_key; - keyid_from_pk(pk, keyid); - } - else if( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - count++; - - if((select_all || (node->flag & NODFLG_SELUID)) && - uid->attribs!=NULL) - { - int i; - - for(i=0;i<uid->numattribs;i++) - { - byte type; - u32 size; - - if(uid->attribs[i].type==ATTRIB_IMAGE && - parse_image_header(&uid->attribs[i],&type,&size)) - { - tty_printf(_("Displaying %s photo ID of size %ld for " - "key 0x%08lX (uid %d)\n"), - image_type_to_string(type,1), - (ulong)size,(ulong)keyid[1],count); - show_photos(&uid->attribs[i],1,pk,NULL); - } - } - } - } - } -} diff --git a/g10/keygen.c b/g10/keygen.c deleted file mode 100644 index 72c5e1e8a..000000000 --- a/g10/keygen.c +++ /dev/null @@ -1,2916 +0,0 @@ -/* keygen.c - generate a key pair - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "packet.h" -#include "cipher.h" -#include "ttyio.h" -#include "options.h" -#include "keydb.h" -#include "trustdb.h" -#include "status.h" -#include "i18n.h" -#include "call-agent.h" - - -#define MAX_PREFS 30 - -enum para_name { - pKEYTYPE, - pKEYLENGTH, - pKEYUSAGE, - pSUBKEYTYPE, - pSUBKEYLENGTH, - pSUBKEYUSAGE, - pAUTHKEYTYPE, - pNAMEREAL, - pNAMEEMAIL, - pNAMECOMMENT, - pPREFERENCES, - pREVOKER, - pUSERID, - pEXPIREDATE, - pKEYEXPIRE, /* in n seconds */ - pSUBKEYEXPIRE, /* in n seconds */ - pPASSPHRASE, - pPASSPHRASE_DEK, - pPASSPHRASE_S2K, - pSERIALNO -}; - -struct para_data_s { - struct para_data_s *next; - int lnr; - enum para_name key; - union { - DEK *dek; - STRING2KEY *s2k; - u32 expire; - unsigned int usage; - struct revocation_key revkey; - char value[1]; - } u; -}; - -struct output_control_s { - int lnr; - int dryrun; - int use_files; - struct { - char *fname; - char *newfname; - iobuf_t stream; - armor_filter_context_t afx; - } pub; - struct { - char *fname; - char *newfname; - iobuf_t stream; - armor_filter_context_t afx; - } sec; -}; - - -struct opaque_data_usage_and_pk { - unsigned int usage; - PKT_public_key *pk; -}; - - -static int prefs_initialized = 0; -static byte sym_prefs[MAX_PREFS]; -static int nsym_prefs; -static byte hash_prefs[MAX_PREFS]; -static int nhash_prefs; -static byte zip_prefs[MAX_PREFS]; -static int nzip_prefs; -static int mdc_available,ks_modify; - -static void do_generate_keypair( struct para_data_s *para, - struct output_control_s *outctrl, int card); -static int write_keyblock( iobuf_t out, KBNODE node ); -static int gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root, - u32 expireval, struct para_data_s *para); - - - -static void -write_uid( KBNODE root, const char *s ) -{ - PACKET *pkt = xcalloc (1,sizeof *pkt ); - size_t n = strlen(s); - - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = xcalloc (1, sizeof *pkt->pkt.user_id + n - 1 ); - pkt->pkt.user_id->len = n; - pkt->pkt.user_id->ref = 1; - strcpy(pkt->pkt.user_id->name, s); - add_kbnode( root, new_kbnode( pkt ) ); -} - -static void -do_add_key_flags (PKT_signature *sig, unsigned int use) -{ - byte buf[1]; - - if (!use) - return; - - buf[0] = 0; - if (use & PUBKEY_USAGE_SIG) - { - if(sig->sig_class==0x18) - buf[0] |= 0x02; /* Don't set the certify flag for subkeys */ - else - buf[0] |= 0x01 | 0x02; - } - if (use & PUBKEY_USAGE_ENC) - buf[0] |= 0x04 | 0x08; - if (use & PUBKEY_USAGE_AUTH) - buf[0] |= 0x20; - build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1); -} - - -int -keygen_add_key_expire( PKT_signature *sig, void *opaque ) -{ - PKT_public_key *pk = opaque; - byte buf[8]; - u32 u; - - if( pk->expiredate ) { - if(pk->expiredate > pk->timestamp) - u= pk->expiredate - pk->timestamp; - else - u= 0; - - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); - } - else - { - /* Make sure we don't leave a key expiration subpacket lying - around */ - delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE); - } - - return 0; -} - -static int -keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) -{ - struct opaque_data_usage_and_pk *oduap = opaque; - - do_add_key_flags (sig, oduap->usage); - return keygen_add_key_expire (sig, oduap->pk); -} - -static int -set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf) -{ - int i; - - for (i=0; i < *nbuf; i++ ) - if (buf[i] == val) - { - log_info (_("preference `%s' duplicated\n"), item); - return -1; - } - - if (*nbuf >= MAX_PREFS) - { - if(type==1) - log_info(_("too many cipher preferences\n")); - else if(type==2) - log_info(_("too many digest preferences\n")); - else if(type==3) - log_info(_("too many compression preferences\n")); - else - BUG(); - - return -1; - } - - buf[(*nbuf)++] = val; - return 0; -} - -#ifdef USE_AES -#define AES "S9 S8 S7 " -#else -#define AES "" -#endif - -#ifdef USE_CAST5 -#define CAST5 "S3 " -#else -#define CAST5 "" -#endif - -/* - * Parse the supplied string and use it to set the standard - * preferences. The string may be in a form like the one printed by - * "pref" (something like: "S10 S3 H3 H2 Z2 Z1") or the actual - * cipher/hash/compress names. Use NULL to set the default - * preferences. Returns: 0 = okay - */ -int -keygen_set_std_prefs (const char *string,int personal) -{ - byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS]; - int nsym=0, nhash=0, nzip=0, val, rc=0; - int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */ - - if (!string || !ascii_strcasecmp (string, "default")) { - if (opt.def_preference_list) - string=opt.def_preference_list; - else if ( !openpgp_cipher_test_algo(CIPHER_ALGO_IDEA) ) - string = AES CAST5 "S2 S1 H2 H3 Z2 Z1"; - else - string = AES CAST5 "S2 H2 H3 Z2 Z1"; - - /* If we have it, IDEA goes *after* 3DES so it won't be used - unless we're encrypting along with a V3 key. Ideally, we - would only put the S1 preference in if the key was RSA and - <=2048 bits, as that is what won't break PGP2, but that is - difficult with the current code, and not really worth - checking as a non-RSA <=2048 bit key wouldn't be usable by - PGP2 anyway. -dms */ - } - else if (!ascii_strcasecmp (string, "none")) - string = ""; - - if(strlen(string)) - { - char *tok,*prefstring; - - prefstring=xstrdup (string); /* need a writable string! */ - - while((tok=strsep(&prefstring," ,"))) - { - if((val=openpgp_cipher_map_name(tok))) - { - if(set_one_pref(val,1,tok,sym,&nsym)) - rc=-1; - } - else if((val=openpgp_md_map_name(tok))) - { - if(set_one_pref(val,2,tok,hash,&nhash)) - rc=-1; - } - else if((val=string_to_compress_algo(tok))>-1) - { - if(set_one_pref(val,3,tok,zip,&nzip)) - rc=-1; - } - else if (ascii_strcasecmp(tok,"mdc")==0) - mdc=1; - else if (ascii_strcasecmp(tok,"no-mdc")==0) - mdc=0; - else if (ascii_strcasecmp(tok,"ks-modify")==0) - modify=1; - else if (ascii_strcasecmp(tok,"no-ks-modify")==0) - modify=0; - else - { - log_info (_("invalid item `%s' in preference string\n"),tok); - - /* Complain if IDEA is not available. */ - if(ascii_strcasecmp(tok,"s1")==0 - || ascii_strcasecmp(tok,"idea")==0) - idea_cipher_warn(1); - - rc=-1; - } - } - - xfree (prefstring); - } - - if(!rc) - { - if(personal) - { - if(personal==PREFTYPE_SYM) - { - xfree (opt.personal_cipher_prefs); - - if(nsym==0) - opt.personal_cipher_prefs=NULL; - else - { - int i; - - opt.personal_cipher_prefs= - xmalloc (sizeof(prefitem_t *)*(nsym+1)); - - for (i=0; i<nsym; i++) - { - opt.personal_cipher_prefs[i].type = PREFTYPE_SYM; - opt.personal_cipher_prefs[i].value = sym[i]; - } - - opt.personal_cipher_prefs[i].type = PREFTYPE_NONE; - opt.personal_cipher_prefs[i].value = 0; - } - } - else if(personal==PREFTYPE_HASH) - { - xfree (opt.personal_digest_prefs); - - if(nhash==0) - opt.personal_digest_prefs=NULL; - else - { - int i; - - opt.personal_digest_prefs= - xmalloc (sizeof(prefitem_t *)*(nhash+1)); - - for (i=0; i<nhash; i++) - { - opt.personal_digest_prefs[i].type = PREFTYPE_HASH; - opt.personal_digest_prefs[i].value = hash[i]; - } - - opt.personal_digest_prefs[i].type = PREFTYPE_NONE; - opt.personal_digest_prefs[i].value = 0; - } - } - else if(personal==PREFTYPE_ZIP) - { - xfree (opt.personal_compress_prefs); - - if(nzip==0) - opt.personal_compress_prefs=NULL; - else - { - int i; - - opt.personal_compress_prefs= - xmalloc (sizeof(prefitem_t *)*(nzip+1)); - - for (i=0; i<nzip; i++) - { - opt.personal_compress_prefs[i].type = PREFTYPE_ZIP; - opt.personal_compress_prefs[i].value = zip[i]; - } - - opt.personal_compress_prefs[i].type = PREFTYPE_NONE; - opt.personal_compress_prefs[i].value = 0; - } - } - } - else - { - memcpy (sym_prefs, sym, (nsym_prefs=nsym)); - memcpy (hash_prefs, hash, (nhash_prefs=nhash)); - memcpy (zip_prefs, zip, (nzip_prefs=nzip)); - mdc_available = mdc; - ks_modify = modify; - prefs_initialized = 1; - } - } - - return rc; -} - -#undef CAST5 -#undef AES - -/* Return a fake user ID containing the preferences. Caller must - free. */ -PKT_user_id *keygen_get_std_prefs(void) -{ - int i,j=0; - PKT_user_id *uid=xcalloc (1,sizeof(PKT_user_id)); - - if(!prefs_initialized) - keygen_set_std_prefs(NULL,0); - - uid->prefs=xmalloc ((sizeof(prefitem_t *)* - (nsym_prefs+nhash_prefs+nzip_prefs+1))); - - for(i=0;i<nsym_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_SYM; - uid->prefs[j].value=sym_prefs[i]; - } - - for(i=0;i<nhash_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_HASH; - uid->prefs[j].value=hash_prefs[i]; - } - - for(i=0;i<nzip_prefs;i++,j++) - { - uid->prefs[j].type=PREFTYPE_ZIP; - uid->prefs[j].value=zip_prefs[i]; - } - - uid->prefs[j].type=PREFTYPE_NONE; - uid->prefs[j].value=0; - - uid->mdc_feature=mdc_available; - uid->ks_modify=ks_modify; - - return uid; -} - -static void -add_feature_mdc (PKT_signature *sig,int enabled) -{ - const byte *s; - size_t n; - int i; - char *buf; - - s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n ); - /* Already set or cleared */ - if (s && n && - ((enabled && (s[0] & 0x01)) || (!enabled && !(s[0] & 0x01)))) - return; - - if (!s || !n) { /* create a new one */ - n = 1; - buf = xcalloc (1,n); - } - else { - buf = xmalloc (n); - memcpy (buf, s, n); - } - - if(enabled) - buf[0] |= 0x01; /* MDC feature */ - else - buf[0] &= ~0x01; - - /* Are there any bits set? */ - for(i=0;i<n;i++) - if(buf[i]!=0) - break; - - if(i==n) - delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES); - else - build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n); - - xfree (buf); -} - -static void -add_keyserver_modify (PKT_signature *sig,int enabled) -{ - const byte *s; - size_t n; - int i; - char *buf; - - /* The keyserver modify flag is a negative flag (i.e. no-modify) */ - enabled=!enabled; - - s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n ); - /* Already set or cleared */ - if (s && n && - ((enabled && (s[0] & 0x80)) || (!enabled && !(s[0] & 0x80)))) - return; - - if (!s || !n) { /* create a new one */ - n = 1; - buf = xcalloc (1,n); - } - else { - buf = xmalloc (n); - memcpy (buf, s, n); - } - - if(enabled) - buf[0] |= 0x80; /* no-modify flag */ - else - buf[0] &= ~0x80; - - /* Are there any bits set? */ - for(i=0;i<n;i++) - if(buf[i]!=0) - break; - - if(i==n) - delete_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS); - else - build_sig_subpkt (sig, SIGSUBPKT_KS_FLAGS, buf, n); - - xfree (buf); -} - -int -keygen_upd_std_prefs( PKT_signature *sig, void *opaque ) -{ - if (!prefs_initialized) - keygen_set_std_prefs (NULL, 0); - - if (nsym_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM, sym_prefs, nsym_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM); - } - - if (nhash_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_HASH); - } - - if (nzip_prefs) - build_sig_subpkt (sig, SIGSUBPKT_PREF_COMPR, zip_prefs, nzip_prefs); - else - { - delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR); - delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_COMPR); - } - - /* Make sure that the MDC feature flag is set if needed */ - add_feature_mdc (sig,mdc_available); - add_keyserver_modify (sig,ks_modify); - - return 0; -} - - -/**************** - * Add preference to the self signature packet. - * This is only called for packets with version > 3. - - */ -int -keygen_add_std_prefs( PKT_signature *sig, void *opaque ) -{ - PKT_public_key *pk = opaque; - - do_add_key_flags (sig, pk->pubkey_usage); - keygen_add_key_expire( sig, opaque ); - keygen_upd_std_prefs (sig, opaque); - - return 0; -} - - -int -keygen_add_keyserver_url(PKT_signature *sig, void *opaque) -{ - const char *url=opaque; - - build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url)); - - return 0; -} - - -int -keygen_add_revkey(PKT_signature *sig, void *opaque) -{ - struct revocation_key *revkey=opaque; - byte buf[2+MAX_FINGERPRINT_LEN]; - - buf[0]=revkey->class; - buf[1]=revkey->algid; - memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN); - - build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN); - - /* All sigs with revocation keys set are nonrevocable */ - sig->flags.revocable=0; - buf[0] = 0; - build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 ); - - parse_revkeys(sig); - - return 0; -} - -static int -write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - struct revocation_key *revkey ) -{ - PACKET *pkt; - PKT_signature *sig; - int rc=0; - KBNODE node; - PKT_public_key *pk; - - if( opt.verbose ) - log_info(_("writing direct signature\n")); - - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* and make the signature */ - rc = make_keysig_packet(&sig,pk,NULL,NULL,sk,0x1F,0,0,0,0, - keygen_add_revkey,revkey); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - -static int -write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - unsigned int use ) -{ - PACKET *pkt; - PKT_signature *sig; - PKT_user_id *uid; - int rc=0; - KBNODE node; - PKT_public_key *pk; - - if( opt.verbose ) - log_info(_("writing self signature\n")); - - /* get the uid packet from the list */ - node = find_kbnode( root, PKT_USER_ID ); - if( !node ) - BUG(); /* no user id packet in tree */ - uid = node->pkt->pkt.user_id; - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - pk->pubkey_usage = use; - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* and make the signature */ - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, pk ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - -static int -write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, - unsigned int use ) -{ - PACKET *pkt; - PKT_signature *sig; - int rc=0; - KBNODE node; - PKT_public_key *pk, *subpk; - struct opaque_data_usage_and_pk oduap; - - if( opt.verbose ) - log_info(_("writing key binding signature\n")); - - /* get the pk packet from the pub_tree */ - node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); - if( !node ) - BUG(); - pk = node->pkt->pkt.public_key; - /* we have to cache the key, so that the verification of the signature - * creation is able to retrieve the public key */ - cache_public_key (pk); - - /* find the last subkey */ - subpk = NULL; - for(node=pub_root; node; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - subpk = node->pkt->pkt.public_key; - } - if( !subpk ) - BUG(); - - /* and make the signature */ - oduap.usage = use; - oduap.pk = subpk; - rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0, 0, - keygen_add_key_flags_and_expire, &oduap ); - if( rc ) { - log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - pkt = xcalloc (1, sizeof *pkt ); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = sig; - add_kbnode( root, new_kbnode( pkt ) ); - return rc; -} - - -static int -key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, - const char *topname, const char *elems) -{ - gcry_sexp_t list, l2; - const char *s; - int i, idx; - int rc = 0; - - list = gcry_sexp_find_token (sexp, topname, 0); - if (!list) - return gpg_error (GPG_ERR_INV_OBJ); - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - if (!list) - return gpg_error (GPG_ERR_NO_OBJ); - - for (idx=0,s=elems; *s; s++, idx++) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - rc = gpg_error (GPG_ERR_NO_OBJ); /* required parameter not found */ - goto leave; - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - rc = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */ - goto leave; - } - } - gcry_sexp_release (list); - - leave: - if (rc) - { - for (i=0; i<idx; i++) - { - xfree (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - } - return rc; -} - - -static int -genhelp_protect (DEK *dek, STRING2KEY *s2k, PKT_secret_key *sk) -{ - int rc = 0; - - if (dek) - { - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; - rc = protect_secret_key (sk, dek); - if (rc) - log_error ("protect_secret_key failed: %s\n", gpg_strerror (rc) ); - } - - return rc; -} - -static void -genhelp_factors (gcry_sexp_t misc_key_info, KBNODE sec_root) -{ - size_t n; - char *buf; - - if (misc_key_info) - { - /* DSA: don't know whether it makes sense to have the factors, so for now - we store them in the secret keyring (but they are not secret) - p = 2 * q * f1 * f2 * ... * fn - We store only f1 to f_n-1; fn can be calculated because p and q - are known. */ - n = gcry_sexp_sprint (misc_key_info, 0, NULL, 0); - buf = xmalloc (n+4); - strcpy (buf, "#::"); - n = gcry_sexp_sprint (misc_key_info, 0, buf+3, n); - if (n) - { - n += 3; - add_kbnode (sec_root, make_comment_node_from_buffer (buf, n)); - } - xfree (buf); - gcry_sexp_release (misc_key_info); - } -} - - -static int -gen_elg(int algo, unsigned int nbits, - KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - gcry_sexp_t misc_key_info; - - assert (is_ELGAMAL(algo)); - - if (nbits < 512) - { - nbits = 1024; - log_info (_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 32)) - { - nbits = ((nbits + 31) / 32) * 32; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build ( &s_parms, NULL, - "(genkey(%s(nbits %d)))", - algo == GCRY_PK_ELG_E ? "openpgp-elg" : - algo == GCRY_PK_ELG ? "elg" : "x-oops" , - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk); - pk = xcalloc (1, sizeof *pk); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "pgy"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "pgyx"); - if (rc) - { - log_error("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0); - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi (sk->skey[3]); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key (NULL, sk); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - gcry_sexp_release (misc_key_info); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - /* don't know whether it makes sense to have the factors, so for now - * we store them in the secret keyring (but they are not secret) */ - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - genhelp_factors (misc_key_info, sec_root); - - return 0; -} - - -/**************** - * Generate a DSA key - */ -static int -gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - gcry_sexp_t misc_key_info; - - if (nbits > 1024 || nbits < 512) - { - nbits = 1024; - log_info(_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 64)) - { - nbits = ((nbits + 63) / 64) * 64; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build (&s_parms, NULL, - "(genkey(dsa(nbits %d)))", - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk ); - pk = xcalloc (1, sizeof *pk ); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "pqgyx"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0); - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi ( sk->skey[4] ); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key( NULL, sk ); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - gcry_sexp_release (misc_key_info); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - genhelp_factors (misc_key_info, sec_root); - - return 0; -} - - -/* - * Generate an RSA key. - */ -static int -gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval ) -{ - int rc; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - gcry_sexp_t s_parms, s_key; - - assert (is_RSA(algo)); - - if (nbits < 1024) - { - nbits = 1024; - log_info(_("keysize invalid; using %u bits\n"), nbits); - } - - if ((nbits % 32)) - { - nbits = ((nbits + 31) / 32) * 32; - log_info (_("keysize rounded up to %u bits\n"), nbits); - } - - rc = gcry_sexp_build (&s_parms, NULL, - "(genkey(rsa(nbits %d)))", - (int)nbits); - if (rc) - log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_genkey (&s_key, s_parms); - gcry_sexp_release (s_parms); - if (rc) - { - log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) ); - return rc; - } - - sk = xcalloc (1, sizeof *sk ); - pk = xcalloc (1, sizeof *pk ); - sk->timestamp = pk->timestamp = make_timestamp(); - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - - rc = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_key); - return rc; - } - rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu"); - if (rc) - { - log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); - gcry_sexp_release (s_key); - return rc; - } - gcry_sexp_release (s_key); - - sk->is_protected = 0; - sk->protect.algo = 0; - - sk->csum = checksum_mpi (sk->skey[2] ); - sk->csum += checksum_mpi (sk->skey[3] ); - sk->csum += checksum_mpi (sk->skey[4] ); - sk->csum += checksum_mpi (sk->skey[5] ); - if (ret_sk) /* not a subkey: return an unprotected version of the sk */ - *ret_sk = copy_secret_key (NULL, sk); - - rc = genhelp_protect (dek, s2k, sk); - if (rc) - { - free_public_key (pk); - free_secret_key (sk); - return rc; - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode (pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - return 0; -} - - -/**************** - * check valid days: - * return 0 on error or the multiplier - */ -static int -check_valid_days( const char *s ) -{ - if( !digitp(s) ) - return 0; - for( s++; *s; s++) - if( !digitp(s) ) - break; - if( !*s ) - return 1; - if( s[1] ) - return 0; /* e.g. "2323wc" */ - if( *s == 'd' || *s == 'D' ) - return 1; - if( *s == 'w' || *s == 'W' ) - return 7; - if( *s == 'm' || *s == 'M' ) - return 30; - if( *s == 'y' || *s == 'Y' ) - return 365; - return 0; -} - - -/**************** - * Returns: 0 to create both a DSA and a ElGamal key. - * and only if key flags are to be written the desired usage. - */ -static int -ask_algo (int addmode, unsigned int *r_usage) -{ - char *answer; - int algo; - - *r_usage = 0; - tty_printf(_("Please select what kind of key you want:\n")); - if( !addmode ) - tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 ); - tty_printf( _(" (%d) DSA (sign only)\n"), 2 ); - if( addmode ) - tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 ); - if (opt.expert) - tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 4 ); - tty_printf( _(" (%d) RSA (sign only)\n"), 5 ); - if (addmode) - tty_printf( _(" (%d) RSA (encrypt only)\n"), 6 ); - if (opt.expert) - tty_printf( _(" (%d) RSA (sign and encrypt)\n"), 7 ); - - for(;;) { - answer = cpr_get("keygen.algo",_("Your selection? ")); - cpr_kill_prompt(); - algo = *answer? atoi(answer): 1; - xfree (answer); - if( algo == 1 && !addmode ) { - algo = 0; /* create both keys */ - break; - } - else if( algo == 7 && opt.expert ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG; - break; - } - else if( algo == 6 && addmode ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 5 ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else if( algo == 4 && opt.expert) - { - tty_printf(_( -"The use of this algorithm is only supported by GnuPG. You will not be\n" -"able to use this key to communicate with PGP users. This algorithm is also\n" -"very slow, and may not be as secure as the other choices.\n")); - - if( cpr_get_answer_is_yes("keygen.algo.elg_se", - _("Create anyway? "))) - { - algo = PUBKEY_ALGO_ELGAMAL; - *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG; - break; - } - } - else if( algo == 3 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; - *r_usage = PUBKEY_USAGE_ENC; - break; - } - else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; - *r_usage = PUBKEY_USAGE_SIG; - break; - } - else - tty_printf(_("Invalid selection.\n")); - } - return algo; -} - - -static unsigned -ask_keysize( int algo ) -{ - char *answer; - unsigned nbits; - - if (algo != PUBKEY_ALGO_DSA && algo != PUBKEY_ALGO_RSA) { - tty_printf (_("About to generate a new %s keypair.\n" - " minimum keysize is 768 bits\n" - " default keysize is 1024 bits\n" - " highest suggested keysize is 2048 bits\n"), - gcry_pk_algo_name (algo) ); - } - - for(;;) { - answer = cpr_get("keygen.size", - _("What keysize do you want? (1024) ")); - cpr_kill_prompt(); - nbits = *answer? atoi(answer): 1024; - xfree (answer); - if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) ) - tty_printf(_("DSA only allows keysizes from 512 to 1024\n")); - else if( algo == PUBKEY_ALGO_RSA && nbits < 1024 ) - tty_printf(_("keysize too small;" - " 1024 is smallest value allowed for RSA.\n")); - else if( nbits < 768 ) - tty_printf(_("keysize too small;" - " 768 is smallest value allowed.\n")); - else if( nbits > 4096 ) { - /* It is ridiculous and an annoyance to use larger key sizes! - * GnuPG can handle much larger sizes; but it takes an eternity - * to create such a key (but less than the time the Sirius - * Computer Corporation needs to process one of the usual - * complaints) and {de,en}cryption although needs some time. - * So, before you complain about this limitation, I suggest that - * you start a discussion with Marvin about this theme and then - * do whatever you want. */ - tty_printf(_("keysize too large; %d is largest value allowed.\n"), - 4096); - } - else if( nbits > 2048 && !cpr_enabled() ) { - tty_printf( - _("Keysizes larger than 2048 are not suggested because\n" - "computations take REALLY long!\n")); - if( cpr_get_answer_is_yes("keygen.size.huge.okay",_( - "Are you sure that you want this keysize? ")) ) { - tty_printf(_("Okay, but keep in mind that your monitor " - "and keyboard radiation is also very vulnerable " - "to attacks!\n")); - break; - } - } - else - break; - } - tty_printf(_("Requested keysize is %u bits\n"), nbits ); - if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { - nbits = ((nbits + 63) / 64) * 64; - tty_printf(_("rounded up to %u bits\n"), nbits ); - } - else if( (nbits % 32) ) { - nbits = ((nbits + 31) / 32) * 32; - tty_printf(_("rounded up to %u bits\n"), nbits ); - } - return nbits; -} - - -/**************** - * Parse an expire string and return it's value in days. - * Returns -1 on error. - */ -static int -parse_expire_string( const char *string ) -{ - int mult; - u32 abs_date=0; - u32 curtime = make_timestamp(); - int valid_days; - - if( !*string ) - valid_days = 0; - else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime ) { - /* This calculation is not perfectly okay because we - * are later going to simply multiply by 86400 and don't - * correct for leapseconds. A solution would be to change - * the whole implemenation to work with dates and not intervals - * which are required for v3 keys. - */ - valid_days = abs_date/86400-curtime/86400+1; - } - else if( (mult=check_valid_days(string)) ) { - valid_days = atoi(string) * mult; - if( valid_days < 0 || valid_days > 39447 ) - valid_days = 0; - } - else { - valid_days = -1; - } - return valid_days; -} - -/* object == 0 for a key, and 1 for a sig */ -u32 -ask_expire_interval(int object) -{ - char *answer; - int valid_days=0; - u32 interval = 0; - - switch(object) - { - case 0: - tty_printf(_("Please specify how long the key should be valid.\n" - " 0 = key does not expire\n" - " <n> = key expires in n days\n" - " <n>w = key expires in n weeks\n" - " <n>m = key expires in n months\n" - " <n>y = key expires in n years\n")); - break; - - case 1: - tty_printf(_("Please specify how long the signature should be valid.\n" - " 0 = signature does not expire\n" - " <n> = signature expires in n days\n" - " <n>w = signature expires in n weeks\n" - " <n>m = signature expires in n months\n" - " <n>y = signature expires in n years\n")); - break; - - default: - BUG(); - } - - /* Note: The elgamal subkey for DSA has no expiration date because - * it must be signed with the DSA key and this one has the expiration - * date */ - - answer = NULL; - for(;;) { - u32 curtime=make_timestamp(); - - xfree (answer); - if(object==0) - answer = cpr_get("keygen.valid",_("Key is valid for? (0) ")); - else - answer = cpr_get("siggen.valid",_("Signature is valid for? (0) ")); - cpr_kill_prompt(); - trim_spaces(answer); - valid_days = parse_expire_string( answer ); - if( valid_days < 0 ) { - tty_printf(_("invalid value\n")); - continue; - } - - if( !valid_days ) { - tty_printf(_("%s does not expire at all\n"), - object==0?"Key":"Signature"); - interval = 0; - } - else { - interval = valid_days * 86400L; - /* print the date when the key expires */ - tty_printf(_("%s expires at %s\n"), - object==0?"Key":"Signature", - asctimestamp((ulong)(curtime + interval) ) ); - /* FIXME: This check yields warning some machines: write a - configure check and do this check here only for 32 bit - machines */ - if( (time_t)((ulong)(curtime+interval)) < 0 ) - tty_printf(_("Your system can't display dates beyond 2038.\n" - "However, it will be correctly handled up to 2106.\n")); - } - - if( cpr_enabled() || cpr_get_answer_is_yes("keygen.valid.okay", - _("Is this correct (y/n)? ")) ) - break; - } - xfree (answer); - return interval; -} - -u32 -ask_expiredate() -{ - u32 x = ask_expire_interval(0); - return x? make_timestamp() + x : 0; -} - - -static int -count_chr( const char *string, int c ) -{ - int count; - - for (count=0; *string; string++ ) - if ( *string == c ) - count++; - return count; -} - - -static int -has_invalid_email_chars( const char *s ) -{ - int at_seen=0; - static char valid_chars[] = "01234567890_-." - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - for( ; *s; s++ ) { - if( *s & 0x80 ) - return 1; - if( *s == '@' ) - at_seen=1; - else if( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) ) - return 1; - else if( at_seen && !strchr( valid_chars, *s ) ) - return 1; - } - return 0; -} - - -static char * -ask_user_id( int mode ) -{ - char *answer; - char *aname, *acomment, *amail, *uid; - - if( !mode ) - tty_printf( _("\n" -"You need a User-ID to identify your key; the software constructs the user id\n" -"from Real Name, Comment and Email Address in this form:\n" -" \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\n\n") ); - uid = aname = acomment = amail = NULL; - for(;;) { - char *p; - int fail=0; - - if( !aname ) { - for(;;) { - xfree (aname); - aname = cpr_get("keygen.name",_("Real name: ")); - trim_spaces(aname); - cpr_kill_prompt(); - - if( opt.allow_freeform_uid ) - break; - - if( strpbrk( aname, "<>" ) ) - tty_printf(_("Invalid character in name\n")); - else if( digitp(aname) ) - tty_printf(_("Name may not start with a digit\n")); - else if( strlen(aname) < 5 ) - tty_printf(_("Name must be at least 5 characters long\n")); - else - break; - } - } - if( !amail ) { - for(;;) { - xfree (amail); - amail = cpr_get("keygen.email",_("Email address: ")); - trim_spaces(amail); - cpr_kill_prompt(); - if( !*amail || opt.allow_freeform_uid ) - break; /* no email address is okay */ - else if( has_invalid_email_chars(amail) - || count_chr(amail,'@') != 1 - || *amail == '@' - || amail[strlen(amail)-1] == '@' - || amail[strlen(amail)-1] == '.' - || strstr(amail, "..") ) - tty_printf(_("Not a valid email address\n")); - else - break; - } - } - if( !acomment ) { - for(;;) { - xfree (acomment); - acomment = cpr_get("keygen.comment",_("Comment: ")); - trim_spaces(acomment); - cpr_kill_prompt(); - if( !*acomment ) - break; /* no comment is okay */ - else if( strpbrk( acomment, "()" ) ) - tty_printf(_("Invalid character in comment\n")); - else - break; - } - } - - - xfree (uid); - uid = p = xmalloc (strlen(aname)+strlen(amail)+strlen(acomment)+12+10); - p = stpcpy(p, aname ); - if( *acomment ) - p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); - if( *amail ) - p = stpcpy(stpcpy(stpcpy(p," <"), amail),">"); - - /* print a note in case that UTF8 mapping has to be done */ - for(p=uid; *p; p++ ) { - if( *p & 0x80 ) { - tty_printf(_("You are using the `%s' character set.\n"), - get_native_charset() ); - break; - } - } - - tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid); - /* fixme: add a warning if this user-id already exists */ - if( !*amail && !opt.allow_freeform_uid - && (strchr( aname, '@' ) || strchr( acomment, '@'))) { - fail = 1; - tty_printf(_("Please don't put the email address " - "into the real name or the comment\n") ); - } - - for(;;) { - const char *ansstr = _("NnCcEeOoQq"); - - if( strlen(ansstr) != 10 ) - BUG(); - if( cpr_enabled() ) { - answer = xstrdup (ansstr+6); - answer[1] = 0; - } - else { - answer = cpr_get("keygen.userid.cmd", fail? - _("Change (N)ame, (C)omment, (E)mail or (Q)uit? ") : - _("Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? ")); - cpr_kill_prompt(); - } - if( strlen(answer) > 1 ) - ; - else if( *answer == ansstr[0] || *answer == ansstr[1] ) { - xfree (aname); aname = NULL; - break; - } - else if( *answer == ansstr[2] || *answer == ansstr[3] ) { - xfree (acomment); acomment = NULL; - break; - } - else if( *answer == ansstr[4] || *answer == ansstr[5] ) { - xfree (amail); amail = NULL; - break; - } - else if( *answer == ansstr[6] || *answer == ansstr[7] ) { - if( fail ) { - tty_printf(_("Please correct the error first\n")); - } - else { - xfree (aname); aname = NULL; - xfree (acomment); acomment = NULL; - xfree (amail); amail = NULL; - break; - } - } - else if( *answer == ansstr[8] || *answer == ansstr[9] ) { - xfree (aname); aname = NULL; - xfree (acomment); acomment = NULL; - xfree (amail); amail = NULL; - xfree (uid); uid = NULL; - break; - } - xfree (answer); - } - xfree (answer); - if( !amail && !acomment && !amail ) - break; - xfree (uid); uid = NULL; - } - if( uid ) { - char *p = native_to_utf8( uid ); - xfree ( uid ); - uid = p; - } - return uid; -} - - -static DEK * -ask_passphrase( STRING2KEY **ret_s2k ) -{ - DEK *dek = NULL; - STRING2KEY *s2k; - const char *errtext = NULL; - - tty_printf(_("You need a Passphrase to protect your secret key.\n\n") ); - - s2k = xmalloc ( sizeof *s2k ); - for(;;) { - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2, - errtext, NULL); - if( !dek ) { - errtext = N_("passphrase not correctly repeated; try again"); - tty_printf(_("%s.\n"), _(errtext)); - } - else if( !dek->keylen ) { - xfree (dek); dek = NULL; - xfree (s2k); s2k = NULL; - tty_printf(_( - "You don't want a passphrase - this is probably a *bad* idea!\n" - "I will do it anyway. You can change your passphrase at any time,\n" - "using this program with the option \"--edit-key\".\n\n")); - break; - } - else - break; /* okay */ - } - *ret_s2k = s2k; - return dek; -} - - -static int -do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root, - DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate ) -{ - int rc=0; - - if( !opt.batch ) - tty_printf(_( -"We need to generate a lot of random bytes. It is a good idea to perform\n" -"some other action (type on the keyboard, move the mouse, utilize the\n" -"disks) during the prime generation; this gives the random number\n" -"generator a better chance to gain enough entropy.\n") ); - - if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) - rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else if( algo == PUBKEY_ALGO_DSA ) - rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else if( algo == PUBKEY_ALGO_RSA ) - rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate); - else - BUG(); - -#ifdef ENABLE_COMMENT_PACKETS - if( !rc ) { - add_kbnode( pub_root, - make_comment_node("#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")")); - add_kbnode( sec_root, - make_comment_node("#created by GNUPG v" VERSION " (" - PRINTABLE_OS_NAME ")")); - } -#endif - return rc; -} - - -/**************** - * Generate a new user id packet, or return NULL if canceled - */ -PKT_user_id * -generate_user_id() -{ - PKT_user_id *uid; - char *p; - size_t n; - - p = ask_user_id( 1 ); - if( !p ) - return NULL; - n = strlen(p); - uid = xcalloc (1, sizeof *uid + n - 1 ); - uid->len = n; - strcpy(uid->name, p); - uid->ref = 1; - return uid; -} - - -static void -release_parameter_list( struct para_data_s *r ) -{ - struct para_data_s *r2; - - for( ; r ; r = r2 ) { - r2 = r->next; - if( r->key == pPASSPHRASE_DEK ) - xfree ( r->u.dek ); - else if( r->key == pPASSPHRASE_S2K ) - xfree ( r->u.s2k ); - - xfree (r); - } -} - -static struct para_data_s * -get_parameter( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r; - - for( r = para; r && r->key != key; r = r->next ) - ; - return r; -} - -static const char * -get_parameter_value( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return (r && *r->u.value)? r->u.value : NULL; -} - -static int -get_parameter_algo( struct para_data_s *para, enum para_name key ) -{ - int i; - struct para_data_s *r = get_parameter( para, key ); - if( !r ) - return -1; - if( digitp( r->u.value ) ) - i = atoi( r->u.value ); - else - i = openpgp_pk_map_name ( r->u.value ); - if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S) - i = 0; /* we don't want to allow generation of these algorithms */ - return i; -} - -/* - * parse the usage parameter and set the keyflags. Return true on error. - */ -static int -parse_parameter_usage (const char *fname, - struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter( para, key ); - char *p, *pn; - unsigned int use; - - if( !r ) - return 0; /* none (this is an optional parameter)*/ - - use = 0; - pn = r->u.value; - while ( (p = strsep (&pn, " \t,")) ) { - if ( !*p) - ; - else if ( !ascii_strcasecmp (p, "sign") ) - use |= PUBKEY_USAGE_SIG; - else if ( !ascii_strcasecmp (p, "encrypt") ) - use |= PUBKEY_USAGE_ENC; - else if ( !ascii_strcasecmp (p, "auth") ) - use |= PUBKEY_USAGE_AUTH; - else { - log_error("%s:%d: invalid usage list\n", fname, r->lnr ); - return -1; /* error */ - } - } - r->u.usage = use; - return 0; -} - -static int -parse_revocation_key (const char *fname, - struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter( para, key ); - struct revocation_key revkey; - char *pn; - int i; - - if( !r ) - return 0; /* none (this is an optional parameter) */ - - pn = r->u.value; - - revkey.class=0x80; - revkey.algid=atoi(pn); - if(!revkey.algid) - goto fail; - - /* Skip to the fpr */ - while(*pn && *pn!=':') - pn++; - - if(*pn!=':') - goto fail; - - pn++; - - for(i=0;i<MAX_FINGERPRINT_LEN && *pn;i++,pn+=2) - { - int c=hextobyte(pn); - if(c==-1) - goto fail; - - revkey.fpr[i]=c; - } - - /* skip to the tag */ - while(*pn && *pn!='s' && *pn!='S') - pn++; - - if(ascii_strcasecmp(pn,"sensitive")==0) - revkey.class|=0x40; - - memcpy(&r->u.revkey,&revkey,sizeof(struct revocation_key)); - - return 0; - - fail: - log_error("%s:%d: invalid revocation key\n", fname, r->lnr ); - return -1; /* error */ -} - - -static u32 -get_parameter_u32( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - - if( !r ) - return 0; - if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE ) - return r->u.expire; - if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE ) - return r->u.usage; - - return (unsigned int)strtoul( r->u.value, NULL, 10 ); -} - -static unsigned int -get_parameter_uint( struct para_data_s *para, enum para_name key ) -{ - return get_parameter_u32( para, key ); -} - -static DEK * -get_parameter_dek( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? r->u.dek : NULL; -} - -static STRING2KEY * -get_parameter_s2k( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? r->u.s2k : NULL; -} - -static struct revocation_key * -get_parameter_revkey( struct para_data_s *para, enum para_name key ) -{ - struct para_data_s *r = get_parameter( para, key ); - return r? &r->u.revkey : NULL; -} - -static int -proc_parameter_file( struct para_data_s *para, const char *fname, - struct output_control_s *outctrl, int card ) -{ - struct para_data_s *r; - const char *s1, *s2, *s3; - size_t n; - char *p; - int i; - - /* check that we have all required parameters */ - assert( get_parameter( para, pKEYTYPE ) ); - i = get_parameter_algo( para, pKEYTYPE ); - if( i < 1 || openpgp_pk_test_algo ( i, PUBKEY_USAGE_SIG ) ) { - r = get_parameter( para, pKEYTYPE ); - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); - return -1; - } - - if (parse_parameter_usage (fname, para, pKEYUSAGE)) - return -1; - - i = get_parameter_algo( para, pSUBKEYTYPE ); - if( i > 0 && openpgp_pk_test_algo ( i, 0 ) ) { - r = get_parameter( para, pSUBKEYTYPE ); - log_error("%s:%d: invalid algorithm\n", fname, r->lnr ); - return -1; - } - if (i > 0 && parse_parameter_usage (fname, para, pSUBKEYUSAGE)) - return -1; - - - if( !get_parameter_value( para, pUSERID ) ) { - /* create the formatted user ID */ - s1 = get_parameter_value( para, pNAMEREAL ); - s2 = get_parameter_value( para, pNAMECOMMENT ); - s3 = get_parameter_value( para, pNAMEEMAIL ); - if( s1 || s2 || s3 ) { - n = (s1?strlen(s1):0) + (s2?strlen(s2):0) + (s3?strlen(s3):0); - r = xcalloc (1, sizeof *r + n + 20 ); - r->key = pUSERID; - p = r->u.value; - if( s1 ) - p = stpcpy(p, s1 ); - if( s2 ) - p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")"); - if( s3 ) - p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">"); - r->next = para; - para = r; - } - } - - /* Set preferences, if any. */ - keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0); - - /* Set revoker, if any. */ - if (parse_revocation_key (fname, para, pREVOKER)) - return -1; - - /* make DEK and S2K from the Passphrase */ - r = get_parameter( para, pPASSPHRASE ); - if( r && *r->u.value ) { - /* we have a plain text passphrase - create a DEK from it. - * It is a little bit ridiculous to keep it in secure memory - * but because we do this always, why not here. */ - STRING2KEY *s2k; - DEK *dek; - - s2k = xmalloc_secure ( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - set_next_passphrase( r->u.value ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL); - set_next_passphrase( NULL ); - assert( dek ); - memset( r->u.value, 0, strlen(r->u.value) ); - - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - } - - /* make KEYEXPIRE from Expire-Date */ - r = get_parameter( para, pEXPIREDATE ); - if( r && *r->u.value ) { - i = parse_expire_string( r->u.value ); - if( i < 0 ) { - log_error("%s:%d: invalid expire date\n", fname, r->lnr ); - return -1; - } - r->u.expire = i * 86400L; - r->key = pKEYEXPIRE; /* change hat entry */ - /* also set it for the subkey */ - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = i * 86400L; - r->next = para; - para = r; - } - - if( !!outctrl->pub.newfname ^ !!outctrl->sec.newfname ) { - log_error("%s:%d: only one ring name is set\n", fname, outctrl->lnr ); - return -1; - } - - do_generate_keypair( para, outctrl, card); - return 0; -} - - -/**************** - * Kludge to allow non interactive key generation controlled - * by a parameter file (which currently is only stdin) - * Note, that string parameters are expected to be in UTF-8 - */ -static void -read_parameter_file( const char *fname ) -{ - static struct { const char *name; - enum para_name key; - } keywords[] = { - { "Key-Type", pKEYTYPE}, - { "Key-Length", pKEYLENGTH }, - { "Key-Usage", pKEYUSAGE }, - { "Subkey-Type", pSUBKEYTYPE }, - { "Subkey-Length", pSUBKEYLENGTH }, - { "Subkey-Usage", pSUBKEYUSAGE }, - { "Name-Real", pNAMEREAL }, - { "Name-Email", pNAMEEMAIL }, - { "Name-Comment", pNAMECOMMENT }, - { "Expire-Date", pEXPIREDATE }, - { "Passphrase", pPASSPHRASE }, - { "Preferences", pPREFERENCES }, - { "Revoker", pREVOKER }, - { NULL, 0 } - }; - FILE *fp; - char line[1024], *p; - int lnr; - const char *err = NULL; - struct para_data_s *para, *r; - int i; - struct output_control_s outctrl; - - memset( &outctrl, 0, sizeof( outctrl ) ); - - if( !fname || !*fname || !strcmp(fname,"-") ) { - fp = stdin; - fname = "-"; - } - else { - fp = fopen( fname, "r" ); - if( !fp ) { - log_error(_("can't open `%s': %s\n"), fname, strerror(errno) ); - return; - } - } - - lnr = 0; - err = NULL; - para = NULL; - while( fgets( line, DIM(line)-1, fp ) ) { - char *keyword, *value; - - lnr++; - if( *line && line[strlen(line)-1] != '\n' ) { - err = "line too long"; - break; - } - for( p = line; isspace(*(byte*)p); p++ ) - ; - if( !*p || *p == '#' ) - continue; - keyword = p; - if( *keyword == '%' ) { - for( ; !isspace(*(byte*)p); p++ ) - ; - if( *p ) - *p++ = 0; - for( ; isspace(*(byte*)p); p++ ) - ; - value = p; - trim_trailing_ws( value, strlen(value) ); - if( !ascii_strcasecmp( keyword, "%echo" ) ) - log_info("%s\n", value ); - else if( !ascii_strcasecmp( keyword, "%dry-run" ) ) - outctrl.dryrun = 1; - else if( !ascii_strcasecmp( keyword, "%commit" ) ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - release_parameter_list( para ); - para = NULL; - } - else if( !ascii_strcasecmp( keyword, "%pubring" ) ) { - if( outctrl.pub.fname && !strcmp( outctrl.pub.fname, value ) ) - ; /* still the same file - ignore it */ - else { - xfree ( outctrl.pub.newfname ); - outctrl.pub.newfname = xstrdup ( value ); - outctrl.use_files = 1; - } - } - else if( !ascii_strcasecmp( keyword, "%secring" ) ) { - if( outctrl.sec.fname && !strcmp( outctrl.sec.fname, value ) ) - ; /* still the same file - ignore it */ - else { - xfree ( outctrl.sec.newfname ); - outctrl.sec.newfname = xstrdup ( value ); - outctrl.use_files = 1; - } - } - else - log_info("skipping control `%s' (%s)\n", keyword, value ); - - - continue; - } - - - if( !(p = strchr( p, ':' )) || p == keyword ) { - err = "missing colon"; - break; - } - if( *p ) - *p++ = 0; - for( ; isspace(*(byte*)p); p++ ) - ; - if( !*p ) { - err = "missing argument"; - break; - } - value = p; - trim_trailing_ws( value, strlen(value) ); - - for(i=0; keywords[i].name; i++ ) { - if( !ascii_strcasecmp( keywords[i].name, keyword ) ) - break; - } - if( !keywords[i].name ) { - err = "unknown keyword"; - break; - } - if( keywords[i].key != pKEYTYPE && !para ) { - err = "parameter block does not start with \"Key-Type\""; - break; - } - - if( keywords[i].key == pKEYTYPE && para ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - release_parameter_list( para ); - para = NULL; - } - else { - for( r = para; r; r = r->next ) { - if( r->key == keywords[i].key ) - break; - } - if( r ) { - err = "duplicate keyword"; - break; - } - } - r = xcalloc (1, sizeof *r + strlen( value ) ); - r->lnr = lnr; - r->key = keywords[i].key; - strcpy( r->u.value, value ); - r->next = para; - para = r; - } - if( err ) - log_error("%s:%d: %s\n", fname, lnr, err ); - else if( ferror(fp) ) { - log_error("%s:%d: read error: %s\n", fname, lnr, strerror(errno) ); - } - else if( para ) { - outctrl.lnr = lnr; - proc_parameter_file( para, fname, &outctrl, 0 ); - } - - if( outctrl.use_files ) { /* close open streams */ - iobuf_close( outctrl.pub.stream ); - iobuf_close( outctrl.sec.stream ); - xfree ( outctrl.pub.fname ); - xfree ( outctrl.pub.newfname ); - xfree ( outctrl.sec.fname ); - xfree ( outctrl.sec.newfname ); - } - - release_parameter_list( para ); - if( strcmp( fname, "-" ) ) - fclose(fp); -} - - -/**************** - * Generate a keypair (fname is only used in batch mode) If - * CARD_SERIALNO is not NULL the fucntion will create the keys on an - * OpenPGP Card. - */ -void -generate_keypair( const char *fname, const char *card_serialno ) -{ - unsigned int nbits; - char *uid = NULL; - DEK *dek; - STRING2KEY *s2k; - int algo; - unsigned int use; - int both = 0; - u32 expire; - struct para_data_s *para = NULL; - struct para_data_s *r; - struct output_control_s outctrl; - - memset (&outctrl, 0, sizeof (outctrl)); - - if (opt.batch && card_serialno) - { - /* We don't yet support unattended key generation. */ - log_error (_("sorry, can't do this in batch mode\n")); - return; - } - - if (opt.batch) - { - read_parameter_file( fname ); - return; - } - - if (card_serialno) - { - r = xcalloc (1, sizeof *r + strlen (card_serialno) ); - r->key = pSERIALNO; - strcpy( r->u.value, card_serialno); - r->next = para; - para = r; - - algo = PUBKEY_ALGO_RSA; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - strcpy (r->u.value, "sign"); - r->next = para; - para = r; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYUSAGE; - strcpy (r->u.value, "encrypt"); - r->next = para; - para = r; - - r = xcalloc (1, sizeof *r + 20 ); - r->key = pAUTHKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - } - else - { - algo = ask_algo (0, &use); - - if (!algo) - { /* default: DSA with ElG subkey of the specified size */ - both = 1; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); - r->next = para; - para = r; - tty_printf(_("DSA keypair will have 1024 bits.\n")); - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYLENGTH; - strcpy( r->u.value, "1024" ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - strcpy( r->u.value, "sign" ); - r->next = para; - para = r; - - algo = PUBKEY_ALGO_ELGAMAL_E; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYUSAGE; - strcpy( r->u.value, "encrypt" ); - r->next = para; - r->next = para; - para = r; - } - else - { - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYTYPE; - sprintf( r->u.value, "%d", algo ); - r->next = para; - para = r; - - if (use) - { - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYUSAGE; - sprintf( r->u.value, "%s%s", - (use & PUBKEY_USAGE_SIG)? "sign ":"", - (use & PUBKEY_USAGE_ENC)? "encrypt ":"" ); - r->next = para; - para = r; - } - } - - nbits = ask_keysize( algo ); - r = xcalloc (1, sizeof *r + 20 ); - r->key = both? pSUBKEYLENGTH : pKEYLENGTH; - sprintf( r->u.value, "%u", nbits); - r->next = para; - para = r; - } - - expire = ask_expire_interval(0); - r = xcalloc (1, sizeof *r + 20 ); - r->key = pKEYEXPIRE; - r->u.expire = expire; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = expire; - r->next = para; - para = r; - - uid = ask_user_id(0); - if (!uid) - { - log_error(_("Key generation canceled.\n")); - release_parameter_list( para ); - return; - } - r = xcalloc (1, sizeof *r + strlen(uid) ); - r->key = pUSERID; - strcpy( r->u.value, uid ); - r->next = para; - para = r; - - dek = card_serialno? NULL : ask_passphrase( &s2k ); - if (dek) - { - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - r = xcalloc (1, sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - } - - proc_parameter_file (para, "[internal]", &outctrl, !!card_serialno); - release_parameter_list (para); -} - - -static void -print_status_key_created (int letter, PKT_public_key *pk) -{ - byte array[MAX_FINGERPRINT_LEN], *s; - char buf[MAX_FINGERPRINT_LEN*2+30], *p; - size_t i, n; - - p = buf; - *p++ = letter; - *p++ = ' '; - fingerprint_from_pk (pk, array, &n); - s = array; - for (i=0; i < n ; i++, s++, p += 2) - sprintf (p, "%02X", *s); - *p = 0; - write_status_text (STATUS_KEY_CREATED, buf); -} - - - -static void -do_generate_keypair (struct para_data_s *para, - struct output_control_s *outctrl, int card) -{ - KBNODE pub_root = NULL; - KBNODE sec_root = NULL; - PKT_secret_key *sk = NULL; - const char *s; - struct revocation_key *revkey; - int rc; - int did_sub = 0; - - if (outctrl->dryrun) - { - log_info ("dry-run mode - key generation skipped\n"); - return; - } - - - if (outctrl->use_files) - { - if (outctrl->pub.newfname) - { - iobuf_close (outctrl->pub.stream); - outctrl->pub.stream = NULL; - xfree (outctrl->pub.fname); - outctrl->pub.fname = outctrl->pub.newfname; - outctrl->pub.newfname = NULL; - - outctrl->pub.stream = iobuf_create (outctrl->pub.fname); - if (!outctrl->pub.stream) - { - log_error ("can't create `%s': %s\n", outctrl->pub.fname, - strerror (errno)); - return; - } - if (opt.armor) - { - outctrl->pub.afx.what = 1; - iobuf_push_filter (outctrl->pub.stream, armor_filter, - &outctrl->pub.afx); - } - } - if (outctrl->sec.newfname) - { - iobuf_close (outctrl->sec.stream); - outctrl->sec.stream = NULL; - xfree (outctrl->sec.fname); - outctrl->sec.fname = outctrl->sec.newfname; - outctrl->sec.newfname = NULL; - - outctrl->sec.stream = iobuf_create (outctrl->sec.fname); - if (!outctrl->sec.stream) - { - log_error ("can't create `%s': %s\n", outctrl->sec.fname, - strerror (errno)); - return; - } - if (opt.armor) - { - outctrl->sec.afx.what = 5; - iobuf_push_filter (outctrl->sec.stream, armor_filter, - &outctrl->sec.afx); - } - } - assert (outctrl->pub.stream); - assert (outctrl->sec.stream); - if (opt.verbose) - { - log_info (_("writing public key to `%s'\n"), outctrl->pub.fname); - if (card) - log_info (_("writing secret key stub to `%s'\n"), - outctrl->sec.fname); - else - log_info (_("writing secret key to `%s'\n"), outctrl->sec.fname); - } - } - - - /* We create the packets as a tree of kbnodes. Because the structure - * we create is known in advance we simply generate a linked list. - * The first packet is a dummy comment packet which we flag - * as deleted. The very first packet must always be a KEY packet. - */ - pub_root = make_comment_node ("#"); - delete_kbnode (pub_root); - sec_root = make_comment_node ("#"); - delete_kbnode (sec_root); - if (!card) - { - rc = do_create (get_parameter_algo (para, pKEYTYPE), - get_parameter_uint (para, pKEYLENGTH), - pub_root, sec_root, - get_parameter_dek (para, pPASSPHRASE_DEK), - get_parameter_s2k (para, pPASSPHRASE_S2K), - &sk, get_parameter_u32 (para, pKEYEXPIRE)); - } - else - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 1, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - if (!rc) - { - sk = sec_root->next->pkt->pkt.secret_key; - assert (sk); - } - - } - - if (!rc && (revkey = get_parameter_revkey (para, pREVOKER))) - { - rc = write_direct_sig (pub_root, pub_root, sk, revkey); - if (!rc) - write_direct_sig (sec_root, pub_root, sk, revkey); - } - - if (!rc && (s = get_parameter_value (para, pUSERID))) - { - write_uid (pub_root, s); - if (!rc) - write_uid (sec_root, s); - if (!rc) - rc = write_selfsig (pub_root, pub_root, sk, - get_parameter_uint (para, pKEYUSAGE)); - if (!rc) - rc = write_selfsig (sec_root, pub_root, sk, - get_parameter_uint (para, pKEYUSAGE)); - } - - if ((! rc) && get_parameter (para, pSUBKEYTYPE)) - { - if (!card) - { - rc = do_create (get_parameter_algo (para, pSUBKEYTYPE), - get_parameter_uint (para, pSUBKEYLENGTH), - pub_root, sec_root, - get_parameter_dek (para, pPASSPHRASE_DEK), - get_parameter_s2k (para, pPASSPHRASE_S2K), - NULL, get_parameter_u32 (para, pSUBKEYEXPIRE)); - } - else - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 2, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - } - - if (!rc) - rc = write_keybinding (pub_root, pub_root, sk, - get_parameter_uint (para, pSUBKEYUSAGE)); - if (!rc) - rc = write_keybinding (sec_root, pub_root, sk, - get_parameter_uint (para, pSUBKEYUSAGE)); - did_sub = 1; - } - - if ((! rc) && card && get_parameter (para, pAUTHKEYTYPE)) - { - rc = gen_card_key (PUBKEY_ALGO_RSA, 3, pub_root, sec_root, - get_parameter_u32 (para, pKEYEXPIRE), para); - - if (!rc) - rc = write_keybinding (pub_root, pub_root, sk, PUBKEY_USAGE_AUTH); - if (!rc) - rc = write_keybinding (sec_root, pub_root, sk, PUBKEY_USAGE_AUTH); - } - - - if (!rc && outctrl->use_files) - { /* direct write to specified files */ - rc = write_keyblock (outctrl->pub.stream, pub_root); - if (rc) - log_error ("can't write public key: %s\n", gpg_strerror (rc)); - if (!rc) - { - rc = write_keyblock (outctrl->sec.stream, sec_root); - if (rc) - log_error ("can't write secret key: %s\n", gpg_strerror (rc)); - } - - } - else if (!rc) - { /* write to the standard keyrings */ - KEYDB_HANDLE pub_hd = keydb_new (0); - KEYDB_HANDLE sec_hd = keydb_new (1); - - /* FIXME: we may have to create the keyring first */ - rc = keydb_locate_writable (pub_hd, NULL); - if (rc) - log_error (_("no writable public keyring found: %s\n"), - gpg_strerror (rc)); - - if (!rc) - { - rc = keydb_locate_writable (sec_hd, NULL); - if (rc) - log_error (_("no writable secret keyring found: %s\n"), - gpg_strerror (rc)); - } - - if (!rc && opt.verbose) - { - log_info (_("writing public key to `%s'\n"), - keydb_get_resource_name (pub_hd)); - if (card) - log_info (_("writing secret key stub to `%s'\n"), - keydb_get_resource_name (sec_hd)); - else - log_info (_("writing secret key to `%s'\n"), - keydb_get_resource_name (sec_hd)); - } - - if (!rc) - { - rc = keydb_insert_keyblock (pub_hd, pub_root); - if (rc) - log_error (_("error writing public keyring `%s': %s\n"), - keydb_get_resource_name (pub_hd), gpg_strerror (rc)); - } - - if (!rc) - { - rc = keydb_insert_keyblock (sec_hd, sec_root); - if (rc) - log_error (_("error writing secret keyring `%s': %s\n"), - keydb_get_resource_name (pub_hd), gpg_strerror (rc)); - } - - keydb_release (pub_hd); - keydb_release (sec_hd); - - if (!rc) - { - int no_enc_rsa = - get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_RSA - && get_parameter_uint (para, pKEYUSAGE) - && !(get_parameter_uint (para, pKEYUSAGE) & PUBKEY_USAGE_ENC); - PKT_public_key *pk = find_kbnode (pub_root, - PKT_PUBLIC_KEY)->pkt->pkt. - public_key; - - update_ownertrust (pk, - ((get_ownertrust (pk) & ~TRUST_MASK) - | TRUST_ULTIMATE)); - - if (!opt.batch) - { - tty_printf (_("public and secret key created and signed.\n")); - tty_printf (_("key marked as ultimately trusted.\n")); - tty_printf ("\n"); - list_keyblock (pub_root, 0, 1, NULL); - } - - - if (!opt.batch - && (get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_DSA - || no_enc_rsa) && !get_parameter (para, pSUBKEYTYPE)) - { - tty_printf (_("Note that this key cannot be used for " - "encryption. You may want to use\n" - "the command \"--edit-key\" to generate a " - "secondary key for this purpose.\n")); - } - - if (!opt.batch && card) - { - tty_printf(_( -"Please create a revocation certificate now, so that you are able\n" -"to revoke the key if it ever happens that you lose your card or\n" -"the card gets damaged. Use the command \"--gen-revoke\".\n" - )); - } - } - } - - if (rc) - { - if (opt.batch) - log_error ("key generation failed: %s\n", gpg_strerror (rc)); - else - tty_printf (_("Key generation failed: %s\n"), gpg_strerror (rc)); - } - else - { - PKT_public_key *pk = find_kbnode (pub_root, - PKT_PUBLIC_KEY)->pkt->pkt.public_key; - print_status_key_created (did_sub ? 'B' : 'P', pk); - } - - release_kbnode (pub_root); - release_kbnode (sec_root); - if (sk && !card) /* The unprotected secret key unless we have */ - free_secret_key (sk); /* a shallow copy in card mode. */ -} - - -/**************** - * add a new subkey to an existing key. - * Returns true if a new key has been generated and put into the keyblocks. - */ -int -generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) -{ - int okay=0, rc=0; - KBNODE node; - PKT_secret_key *sk = NULL; /* this is the primary sk */ - int algo; - unsigned int use; - u32 expire; - unsigned nbits; - char *passphrase = NULL; - DEK *dek = NULL; - STRING2KEY *s2k = NULL; - u32 cur_time; - - /* break out the primary secret key */ - node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); - if( !node ) { - log_error("Oops; secret key not found anymore!\n"); - goto leave; - } - - /* make a copy of the sk to keep the protected one in the keyblock */ - sk = copy_secret_key( NULL, node->pkt->pkt.secret_key ); - - cur_time = make_timestamp(); - if( sk->timestamp > cur_time ) { - ulong d = sk->timestamp - cur_time; - log_info( d==1 ? _("key has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key has been created %lu seconds " - "in future (time warp or clock problem)\n"), d ); - if( !opt.ignore_time_conflict ) { - rc = GPG_ERR_TIME_CONFLICT; - goto leave; - } - } - - if (sk->version < 4) { - log_info (_("NOTE: creating subkeys for v3 keys " - "is not OpenPGP compliant\n")); - goto leave; - } - - /* unprotect to get the passphrase */ - switch( is_secret_key_protected( sk ) ) { - case -1: - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf("This key is not protected.\n"); - break; - default: - tty_printf("Key is protected.\n"); - rc = check_secret_key( sk, 0 ); - if( !rc ) - passphrase = get_last_passphrase(); - break; - } - if( rc ) - goto leave; - - - algo = ask_algo( 1, &use ); - assert(algo); - nbits = ask_keysize( algo ); - expire = ask_expire_interval(0); - if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", - _("Really create? ") ) ) - goto leave; - - if( passphrase ) { - s2k = xmalloc_secure ( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - set_next_passphrase( passphrase ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL ); - } - - rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, - dek, s2k, NULL, expire ); - if( !rc ) - rc = write_keybinding(pub_keyblock, pub_keyblock, sk, use); - if( !rc ) - rc = write_keybinding(sec_keyblock, pub_keyblock, sk, use); - if( !rc ) { - okay = 1; - write_status_text (STATUS_KEY_CREATED, "S"); - } - - leave: - if( rc ) - log_error(_("Key generation failed: %s\n"), gpg_strerror (rc) ); - xfree ( passphrase ); - xfree ( dek ); - xfree ( s2k ); - if( sk ) /* release the copy of the (now unprotected) secret key */ - free_secret_key(sk); - set_next_passphrase( NULL ); - return okay; -} - -/**************** - * Write a keyblock to an output stream - */ -static int -write_keyblock( iobuf_t out, KBNODE node ) -{ - for( ; node ; node = node->next ) { - int rc = build_packet( out, node->pkt ); - if( rc ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - return rc; - } - } - return 0; -} - - - -static int -gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root, - u32 expireval, struct para_data_s *para) -{ - int rc; - const char *s; - struct agent_card_genkey_s info; - PACKET *pkt; - PKT_secret_key *sk; - PKT_public_key *pk; - - assert (algo == PUBKEY_ALGO_RSA); - - rc = agent_scd_genkey (&info, keyno, 1); -/* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */ -/* { */ -/* tty_printf ("\n"); */ -/* log_error ("WARNING: key does already exists!\n"); */ -/* tty_printf ("\n"); */ -/* if ( cpr_get_answer_is_yes( "keygen.card.replace_key", */ -/* _("Replace existing key? "))) */ -/* rc = agent_scd_genkey (&info, keyno, 1); */ -/* } */ - - if (rc) - return rc; - - if ( !info.n || !info.e ) - { - log_error ("communication error with SCD\n"); - gcry_mpi_release (info.n); - gcry_mpi_release (info.e); - return gpg_error (GPG_ERR_GENERAL); - } - - - pk = xcalloc (1, sizeof *pk ); - sk = xcalloc (1, sizeof *sk ); - sk->timestamp = pk->timestamp = info.created_at; - sk->version = pk->version = 4; - if (expireval) - sk->expiredate = pk->expiredate = pk->timestamp + expireval; - sk->pubkey_algo = pk->pubkey_algo = algo; - pk->pkey[0] = info.n; - pk->pkey[1] = info.e; - sk->skey[0] = gcry_mpi_copy (pk->pkey[0]); - sk->skey[1] = gcry_mpi_copy (pk->pkey[1]); - sk->skey[2] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8); - sk->is_protected = 1; - sk->protect.s2k.mode = 1002; - s = get_parameter_value (para, pSERIALNO); - if (s) - { - for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1]; - sk->protect.ivlen++, s += 2) - sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s); - } - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = keyno == 1 ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - - pkt = xcalloc (1,sizeof *pkt); - pkt->pkttype = keyno == 1 ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY; - pkt->pkt.secret_key = sk; - add_kbnode(sec_root, new_kbnode( pkt )); - - return 0; -} - - - diff --git a/g10/keyid.c b/g10/keyid.c deleted file mode 100644 index aaa70cccb..000000000 --- a/g10/keyid.c +++ /dev/null @@ -1,609 +0,0 @@ -/* keyid.c - key ID and fingerprint handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "packet.h" -#include "options.h" -#include "mpi.h" -#include "keydb.h" -#include "i18n.h" - - -int -pubkey_letter( int algo ) -{ - switch( algo ) { - case PUBKEY_ALGO_RSA: return 'R' ; - case PUBKEY_ALGO_RSA_E: return 'r' ; - case PUBKEY_ALGO_RSA_S: return 's' ; - case PUBKEY_ALGO_ELGAMAL_E: return 'g'; - case PUBKEY_ALGO_ELGAMAL: return 'G' ; - case PUBKEY_ALGO_DSA: return 'D' ; - default: return '?'; - } -} - -static gcry_md_hd_t -do_fingerprint_md( PKT_public_key *pk ) -{ - gcry_md_hd_t md; - unsigned int n; - unsigned int nn[PUBKEY_MAX_NPKEY]; - byte *pp[PUBKEY_MAX_NPKEY]; - int i; - int npkey = pubkey_get_npkey( pk->pubkey_algo ); - - gcry_md_open (&md, pk->version < 4 ? DIGEST_ALGO_RMD160 - : DIGEST_ALGO_SHA1, 0); - - n = pk->version < 4 ? 8 : 6; - for(i=0; i < npkey; i++ ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i] )) - BUG (); - /* fixme: we should try to allocate a buffer on the stack */ - pp[i] = xmalloc(nbytes); - if (gcry_mpi_print ( GCRYMPI_FMT_PGP, pp[i], nbytes, &nbytes, - pk->pkey[i] )) - BUG (); - nn[i] = nbytes; - n += nn[i]; - } - - gcry_md_putc ( md, 0x99 ); /* ctb */ - gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ - gcry_md_putc ( md, n ); - if( pk->version < 4 ) - gcry_md_putc ( md, 3 ); - else - gcry_md_putc ( md, 4 ); - - { u32 a = pk->timestamp; - gcry_md_putc ( md, a >> 24 ); - gcry_md_putc ( md, a >> 16 ); - gcry_md_putc ( md, a >> 8 ); - gcry_md_putc ( md, a ); - } - if( pk->version < 4 ) { - u16 a; - - if( pk->expiredate ) - a = (u16)((pk->expiredate - pk->timestamp) / 86400L); - else - a = 0; - gcry_md_putc ( md, a >> 8 ); - gcry_md_putc ( md, a ); - } - gcry_md_putc ( md, pk->pubkey_algo ); - for(i=0; i < npkey; i++ ) { - gcry_md_write( md, pp[i], nn[i] ); - xfree (pp[i]); - } - gcry_md_final ( md ); - - return md; -} - -static gcry_md_hd_t -do_fingerprint_md_sk( PKT_secret_key *sk ) -{ - PKT_public_key pk; - int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */ - int i; - - pk.pubkey_algo = sk->pubkey_algo; - pk.version = sk->version; - pk.timestamp = sk->timestamp; - pk.expiredate = sk->expiredate; - pk.pubkey_algo = sk->pubkey_algo; - for( i=0; i < npkey; i++ ) - pk.pkey[i] = sk->skey[i]; - return do_fingerprint_md( &pk ); -} - - -u32 -v3_keyid (gcry_mpi_t a, u32 *ki) -{ - byte *buffer; - size_t nbytes; - - if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a )) - BUG (); - /* fixme: allocate it on the stack */ - buffer = xmalloc (nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a )) - BUG (); - if (nbytes < 8) /* oops */ - ki[0] = ki[1] = 0; - else - { - memcpy (ki+0, buffer+nbytes-8, 4); - memcpy (ki+1, buffer+nbytes-4, 4); - } - xfree (buffer); - return ki[1]; -} - - - -/**************** - * Get the keyid from the secret key and put it into keyid - * if this is not NULL. Return the 32 low bits of the keyid. - */ -u32 -keyid_from_sk( PKT_secret_key *sk, u32 *keyid ) -{ - u32 lowbits; - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) { - keyid[0] = keyid[1] = 0; - lowbits = pubkey_get_npkey(sk->pubkey_algo) ? - v3_keyid (sk->skey[0], keyid) : 0; - } - else { - const byte *dp; - gcry_md_hd_t md; - md = do_fingerprint_md_sk(sk); - dp = gcry_md_read ( md, 0 ); - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - gcry_md_close (md); - } - - return lowbits; -} - - -/**************** - * Get the keyid from the public key and put it into keyid - * if this is not NULL. Return the 32 low bits of the keyid. - */ -u32 -keyid_from_pk( PKT_public_key *pk, u32 *keyid ) -{ - u32 lowbits; - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( pk->keyid[0] || pk->keyid[1] ) { - keyid[0] = pk->keyid[0]; - keyid[1] = pk->keyid[1]; - lowbits = keyid[1]; - } - else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) { - keyid[0] = keyid[1] = 0; - lowbits = pubkey_get_npkey(pk->pubkey_algo) ? - v3_keyid (pk->pkey[0], keyid) : 0 ; - pk->keyid[0] = keyid[0]; - pk->keyid[1] = keyid[1]; - } - else { - const byte *dp; - gcry_md_hd_t md; - md = do_fingerprint_md(pk); - dp = gcry_md_read ( md, 0 ); - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - lowbits = keyid[1]; - gcry_md_close (md); - pk->keyid[0] = keyid[0]; - pk->keyid[1] = keyid[1]; - } - - return lowbits; -} - - -/**************** - * Get the keyid from the fingerprint. This function is simple for most - * keys, but has to do a keylookup for old stayle keys. - */ -u32 -keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ) -{ - u32 dummy_keyid[2]; - - if( !keyid ) - keyid = dummy_keyid; - - if( fprint_len != 20 ) { - /* This is special as we have to lookup the key first */ - PKT_public_key pk; - int rc; - - memset( &pk, 0, sizeof pk ); - rc = get_pubkey_byfprint( &pk, fprint, fprint_len ); - if( rc ) { - log_error("Oops: keyid_from_fingerprint: no pubkey\n"); - keyid[0] = 0; - keyid[1] = 0; - } - else - keyid_from_pk( &pk, keyid ); - } - else { - const byte *dp = fprint; - keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - } - - return keyid[1]; -} - - -u32 -keyid_from_sig( PKT_signature *sig, u32 *keyid ) -{ - if( keyid ) { - keyid[0] = sig->keyid[0]; - keyid[1] = sig->keyid[1]; - } - return sig->keyid[1]; -} - -byte * -namehash_from_uid(PKT_user_id *uid) -{ - if(uid->namehash==NULL) - { - uid->namehash=xmalloc (20); - - if(uid->attrib_data) - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->attrib_data,uid->attrib_len); - else - gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash, - uid->name,uid->len); - } - - return uid->namehash; -} - -/**************** - * return the number of bits used in the pk - */ -unsigned -nbits_from_pk( PKT_public_key *pk ) -{ - return pubkey_nbits( pk->pubkey_algo, pk->pkey ); -} - -/**************** - * return the number of bits used in the sk - */ -unsigned -nbits_from_sk( PKT_secret_key *sk ) -{ - return pubkey_nbits( sk->pubkey_algo, sk->skey ); -} - -static const char * -mk_datestr (char *buffer, time_t atime) -{ - struct tm *tp; - - if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */ - strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */ - else { - tp = gmtime (&atime); - sprintf (buffer,"%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); - } - return buffer; -} - -/**************** - * return a string with the creation date of the pk - * Note: this is alloced in a static buffer. - * Format is: yyyy-mm-dd - */ -const char * -datestr_from_pk( PKT_public_key *pk ) -{ - static char buffer[11+5]; - time_t atime = pk->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -datestr_from_sk( PKT_secret_key *sk ) -{ - static char buffer[11+5]; - time_t atime = sk->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -datestr_from_sig( PKT_signature *sig ) -{ - static char buffer[11+5]; - time_t atime = sig->timestamp; - - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_pk( PKT_public_key *pk ) -{ - static char buffer[11+5]; - time_t atime; - - if( !pk->expiredate ) - return _("never "); - atime = pk->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_sk( PKT_secret_key *sk ) -{ - static char buffer[11+5]; - time_t atime; - - if( !sk->expiredate ) - return _("never "); - atime = sk->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -expirestr_from_sig( PKT_signature *sig ) -{ - static char buffer[11+5]; - time_t atime; - - if(!sig->expiredate) - return _("never "); - atime=sig->expiredate; - return mk_datestr (buffer, atime); -} - -const char * -colon_strtime (u32 t) -{ - if (!t) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)t); - return buf; - } - return strtimestamp(t); -} - -const char * -colon_datestr_from_pk (PKT_public_key *pk) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)pk->timestamp); - return buf; - } - return datestr_from_pk (pk); -} - -const char * -colon_datestr_from_sk (PKT_secret_key *sk) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sk->timestamp); - return buf; - } - return datestr_from_sk (sk); -} - -const char * -colon_datestr_from_sig (PKT_signature *sig) -{ - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->timestamp); - return buf; - } - return datestr_from_sig (sig); -} - -const char * -colon_expirestr_from_sig (PKT_signature *sig) -{ - if(!sig->expiredate) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->expiredate); - return buf; - } - return expirestr_from_sig (sig); -} - - -/**************** . - * Return a byte array with the fingerprint for the given PK/SK - * The length of the array is returned in ret_len. Caller must free - * the array or provide an array of length MAX_FINGERPRINT_LEN. - */ - -byte * -fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len ) -{ - byte *buf; - const byte *dp; - size_t len; - - if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) { - /* RSA in version 3 packets is special */ - gcry_md_hd_t md; - - gcry_md_open (&md, DIGEST_ALGO_MD5, 0); - if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, - pk->pkey[0])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[0])) - BUG (); - gcry_md_write (md, buf, nbytes); - xfree (buf); - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[1])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[1])) - BUG (); - gcry_md_write( md, buf, nbytes ); - xfree(buf); - } - gcry_md_final (md); - if( !array ) - array = xmalloc ( 16 ); - len = 16; - memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 ); - gcry_md_close (md); - } - else { - gcry_md_hd_t md; - md = do_fingerprint_md(pk); - dp = gcry_md_read ( md, 0 ); - len = gcry_md_get_algo_dlen (gcry_md_get_algo (md)); - assert( len <= MAX_FINGERPRINT_LEN ); - if( !array ) - array = xmalloc ( len ); - memcpy(array, dp, len ); - pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; - pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; - gcry_md_close (md); - } - - *ret_len = len; - return array; -} - -byte * -fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len ) -{ - byte *buf; - const char *dp; - size_t len; - - if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) { - /* RSA in version 3 packets is special */ - gcry_md_hd_t md; - - gcry_md_open (&md, DIGEST_ALGO_MD5, 0); - if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) { - size_t nbytes; - - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[0])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,sk->skey[0])) - BUG (); - gcry_md_write (md, buf, nbytes); - xfree (buf); - if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[1])) - BUG (); - /* fixme: allocate it on the stack */ - buf = xmalloc(nbytes); - if (gcry_mpi_print( GCRYMPI_FMT_USG, buf,nbytes, NULL, sk->skey[1])) - BUG (); - gcry_md_write( md, buf, nbytes ); - xfree(buf); - } - gcry_md_final (md); - if( !array ) - array = xmalloc ( 16 ); - len = 16; - memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 ); - gcry_md_close (md); - } - else { - gcry_md_hd_t md; - - md = do_fingerprint_md_sk(sk); - dp = gcry_md_read ( md, 0 ); - len = gcry_md_get_algo_dlen (gcry_md_get_algo (md)); - assert( len <= MAX_FINGERPRINT_LEN ); - if( !array ) - array = xmalloc ( len ); - memcpy(array, dp, len ); - gcry_md_close (md); - } - - *ret_len = len; - return array; -} - - -/* Create a serialno/fpr string from the serial number and the secret - * key. caller must free the returned string. There is no error - * return. */ -char * -serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, - PKT_secret_key *sk) -{ - unsigned char fpr[MAX_FINGERPRINT_LEN]; - size_t fprlen; - char *buffer, *p; - int i; - - fingerprint_from_sk (sk, fpr, &fprlen); - buffer = p= xmalloc (snlen*2 + 1 + fprlen*2 + 1); - for (i=0; i < snlen; i++, p+=2) - sprintf (p, "%02X", sn[i]); - *p++ = '/'; - for (i=0; i < fprlen; i++, p+=2) - sprintf (p, "%02X", fpr[i]); - *p = 0; - return buffer; -} - - - - - - - - diff --git a/g10/keylist.c b/g10/keylist.c deleted file mode 100644 index 50850de71..000000000 --- a/g10/keylist.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* keylist.c - List all or selected keys - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "photoid.h" -#include "util.h" -#include "ttyio.h" -#include "trustdb.h" -#include "main.h" -#include "i18n.h" -#include "status.h" - -static void list_all(int); -static void list_one( STRLIST names, int secret); -static void print_card_serialno (PKT_secret_key *sk); - -struct sig_stats -{ - int inv_sigs; - int no_key; - int oth_err; -}; - -static FILE *attrib_fp=NULL; - -/**************** - * List the keys - * If list is NULL, all available keys are listed - */ -void -public_key_list( STRLIST list ) -{ - if(opt.with_colons) - { - byte trust_model,marginals,completes,cert_depth; - ulong created,nextcheck; - - read_trust_options(&trust_model,&created,&nextcheck, - &marginals,&completes,&cert_depth); - - printf("tru:"); - - if(nextcheck && nextcheck <= make_timestamp()) - printf("o"); - if(trust_model!=opt.trust_model) - printf("t"); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - { - if(marginals!=opt.marginals_needed) - printf("m"); - if(completes!=opt.completes_needed) - printf("c"); - if(cert_depth!=opt.max_cert_depth) - printf("d"); - } - - printf(":%d:%lu:%lu",trust_model,created,nextcheck); - - /* Only show marginals, completes, and cert_depth in the classic - or PGP trust models since they are not meaningful - otherwise. */ - - if(trust_model==TM_PGP || trust_model==TM_CLASSIC) - printf(":%d:%d:%d",marginals,completes,cert_depth); - - printf("\n"); - } - - if( !list ) - list_all(0); - else - list_one( list, 0 ); -} - -void -secret_key_list( STRLIST list ) -{ - if( !list ) - list_all(1); - else /* List by user id */ - list_one( list, 1 ); -} - -void -print_seckey_info (PKT_secret_key *sk) -{ - u32 sk_keyid[2]; - size_t n; - char *p; - - keyid_from_sk (sk, sk_keyid); - tty_printf ("\nsec %4u%c/%08lX %s ", - nbits_from_sk (sk), - pubkey_letter (sk->pubkey_algo), - (ulong)sk_keyid[1], datestr_from_sk (sk)); - - p = get_user_id (sk_keyid, &n); - tty_print_utf8_string (p, n); - xfree (p); - - tty_printf ("\n"); -} - -/* Print information about the public key. With FP passed as NULL, - the tty output interface is used, otherwise output is directted to - the given stream. */ -void -print_pubkey_info (FILE *fp, PKT_public_key *pk) -{ - u32 pk_keyid[2]; - size_t n; - char *p; - - keyid_from_pk (pk, pk_keyid); - if (fp) - fprintf (fp, "pub %4u%c/%08lX %s ", - nbits_from_pk (pk), - pubkey_letter (pk->pubkey_algo), - (ulong)pk_keyid[1], datestr_from_pk (pk)); - else - tty_printf ("\npub %4u%c/%08lX %s ", - nbits_from_pk (pk), - pubkey_letter (pk->pubkey_algo), - (ulong)pk_keyid[1], datestr_from_pk (pk)); - - p = get_user_id (pk_keyid, &n); - if (fp) - print_utf8_string2 (fp, p, n, '\n'); - else - tty_print_utf8_string (p, n); - xfree (p); - - if (fp) - putc ('\n', fp); - else - tty_printf ("\n\n"); -} - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ - -void -show_policy_url(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit))) - { - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - if(crit) - str=_("Critical signature policy: "); - else - str=_("Signature policy: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p,len); - fprintf(fp,"\n"); - } - - if(mode) - write_status_buffer ( STATUS_POLICY_URL, p, len, 0 ); - } -} - - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ -/* TODO: use this */ -void -show_keyserver_url(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit))) - { - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - if(crit) - str=_("Critical preferred keyserver: "); - else - str=_("Preferred keyserver: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p,len); - fprintf(fp,"\n"); - } - - /* TODO: put in a status-fd tag for preferred keyservers */ - } -} - - -/* - mode=0 for stdout. - mode=1 for log_info + status messages - mode=2 for status messages only -*/ - -void -show_notation(PKT_signature *sig,int indent,int mode) -{ - const byte *p; - size_t len; - int seq=0,crit; - FILE *fp=mode?log_get_stream():stdout; - - /* There may be multiple notations in the same sig. */ - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit))) - if(len>=8) - { - int n1,n2; - - n1=(p[4]<<8)|p[5]; - n2=(p[6]<<8)|p[7]; - - if(8+n1+n2!=len) - { - log_info(_("WARNING: invalid notation data found\n")); - return; - } - - if(mode!=2) - { - int i; - char *str; - - for(i=0;i<indent;i++) - putchar(' '); - - /* This is UTF8 */ - if(crit) - str=_("Critical signature notation: "); - else - str=_("Signature notation: "); - if(mode) - log_info("%s",str); - else - printf("%s",str); - print_utf8_string(fp,p+8,n1); - fprintf(fp,"="); - - if(*p&0x80) - print_utf8_string(fp,p+8+n1,n2); - else - fprintf(fp,"[ %s ]",_("not human readable")); - - fprintf(fp,"\n"); - } - - if(mode) - { - write_status_buffer ( STATUS_NOTATION_NAME, p+8 , n1, 0 ); - write_status_buffer ( STATUS_NOTATION_DATA, p+8+n1, n2, 50 ); - } - } - else - log_info(_("WARNING: invalid notation data found\n")); -} - -static void -print_signature_stats(struct sig_stats *s) -{ - if( s->inv_sigs == 1 ) - tty_printf(_("1 bad signature\n") ); - else if( s->inv_sigs ) - tty_printf(_("%d bad signatures\n"), s->inv_sigs ); - if( s->no_key == 1 ) - tty_printf(_("1 signature not checked due to a missing key\n") ); - else if( s->no_key ) - tty_printf(_("%d signatures not checked due to missing keys\n"),s->no_key); - if( s->oth_err == 1 ) - tty_printf(_("1 signature not checked due to an error\n") ); - else if( s->oth_err ) - tty_printf(_("%d signatures not checked due to errors\n"), s->oth_err ); -} - -static void -list_all( int secret ) -{ - KEYDB_HANDLE hd; - KBNODE keyblock = NULL; - int rc=0; - const char *lastresname, *resname; - struct sig_stats stats; - - memset(&stats,0,sizeof(stats)); - - hd = keydb_new (secret); - if (!hd) - rc = GPG_ERR_GENERAL; - else - rc = keydb_search_first (hd); - if( rc ) { - if( rc != -1 ) - log_error("keydb_search_first failed: %s\n", gpg_strerror (rc) ); - goto leave; - } - - lastresname = NULL; - do { - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if(!opt.with_colons) - { - resname = keydb_get_resource_name (hd); - if (lastresname != resname ) - { - int i; - - printf("%s\n", resname ); - for(i=strlen(resname); i; i-- ) - putchar('-'); - putchar('\n'); - lastresname = resname; - } - } - merge_keys_and_selfsig( keyblock ); - list_keyblock( keyblock, secret, opt.fingerprint, - opt.check_sigs?&stats:NULL); - release_kbnode( keyblock ); - keyblock = NULL; - } while (!(rc = keydb_search_next (hd))); - if( rc && rc != -1 ) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - - if(opt.check_sigs && !opt.with_colons) - print_signature_stats(&stats); - - leave: - release_kbnode (keyblock); - keydb_release (hd); -} - - -static void -list_one( STRLIST names, int secret ) -{ - int rc = 0; - KBNODE keyblock = NULL; - GETKEY_CTX ctx; - const char *resname; - char *keyring_str = _("Keyring"); - int i; - struct sig_stats stats; - - memset(&stats,0,sizeof(stats)); - - /* fixme: using the bynames function has the disadvantage that we - * don't know wether one of the names given was not found. OTOH, - * this function has the advantage to list the names in the - * sequence as defined by the keyDB and does not duplicate - * outputs. A solution could be do test whether all given have - * been listed (this needs a way to use the keyDB search - * functions) or to have the search function return indicators for - * found names. Yet another way is to use the keydb search - * facilities directly. */ - if( secret ) { - rc = get_seckey_bynames( &ctx, NULL, names, &keyblock ); - if( rc ) { - log_error("error reading key: %s\n", gpg_strerror (rc) ); - get_seckey_end( ctx ); - return; - } - do { - if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) { - resname = keydb_get_resource_name (get_ctx_handle(ctx)); - printf("%s: %s\n", keyring_str, resname); - for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- ) - putchar('-'); - putchar('\n'); - } - list_keyblock( keyblock, 1, opt.fingerprint, NULL ); - release_kbnode( keyblock ); - } while( !get_seckey_next( ctx, NULL, &keyblock ) ); - get_seckey_end( ctx ); - } - else { - rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock ); - if( rc ) { - log_error("error reading key: %s\n", gpg_strerror (rc) ); - get_pubkey_end( ctx ); - return; - } - do { - if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) { - resname = keydb_get_resource_name (get_ctx_handle(ctx)); - printf("%s: %s\n", keyring_str, resname); - for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- ) - putchar('-'); - putchar('\n'); - } - list_keyblock( keyblock, 0, opt.fingerprint, - opt.check_sigs?&stats:NULL ); - release_kbnode( keyblock ); - } while( !get_pubkey_next( ctx, NULL, &keyblock ) ); - get_pubkey_end( ctx ); - } - - if(opt.check_sigs && !opt.with_colons) - print_signature_stats(&stats); -} - -static void -print_key_data( PKT_public_key *pk, u32 *keyid ) -{ - int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0; - int i; - - for(i=0; i < n; i++ ) { - printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) ); - mpi_print(stdout, pk->pkey[i], 1 ); - putchar(':'); - putchar('\n'); - } -} - -static void -print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock) -{ - if(pk || (sk && sk->protect.s2k.mode!=1001)) - { - unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage; - - if ( (use & PUBKEY_USAGE_ENC) ) - putchar ('e'); - - if ( (use & PUBKEY_USAGE_SIG) ) - { - putchar ('s'); - if( pk? pk->is_primary : sk->is_primary ) - putchar ('c'); - } - - if ( (use & PUBKEY_USAGE_AUTH) ) - putchar ('a'); - } - - if ( keyblock ) { /* figure out the usable capabilities */ - KBNODE k; - int enc=0, sign=0, cert=0, auth=0, disabled=0; - - for (k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - pk = k->pkt->pkt.public_key; - - if(pk->is_primary) - disabled=pk_is_disabled(pk); - - if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) { - if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) ) - enc = 1; - if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) ) - { - sign = 1; - if(pk->is_primary) - cert = 1; - } - if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) ) - auth = 1; - } - } - else if ( k->pkt->pkttype == PKT_SECRET_KEY - || k->pkt->pkttype == PKT_SECRET_SUBKEY ) { - sk = k->pkt->pkt.secret_key; - if ( sk->is_valid && !sk->is_revoked && !sk->has_expired - && sk->protect.s2k.mode!=1001 ) { - if ( (sk->pubkey_usage & PUBKEY_USAGE_ENC) ) - enc = 1; - if ( (sk->pubkey_usage & PUBKEY_USAGE_SIG) ) - { - sign = 1; - if(sk->is_primary) - cert = 1; - } - if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) ) - auth = 1; - } - } - } - if (enc) - putchar ('E'); - if (sign) - putchar ('S'); - if (cert) - putchar ('C'); - if (auth) - putchar ('A'); - if (disabled) - putchar ('D'); - } - - putchar(':'); -} - -void -dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk) -{ - int i; - - if(!attrib_fp) - return; - - for(i=0;i<uid->numattribs;i++) - { - if(is_status_enabled()) - { - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[(MAX_FINGERPRINT_LEN*2)+90]; - size_t j,n; - - if(pk) - fingerprint_from_pk( pk, array, &n ); - else if(sk) - fingerprint_from_sk( sk, array, &n ); - else - BUG(); - - p = array; - for(j=0; j < n ; j++, p++ ) - sprintf(buf+2*j, "%02X", *p ); - - sprintf(buf+strlen(buf)," %lu %u %u %u %lu %lu %u", - (ulong)uid->attribs[i].len,uid->attribs[i].type,i+1, - uid->numattribs,(ulong)uid->created,(ulong)uid->expiredate, - ((uid->is_primary?0x01:0)| - (uid->is_revoked?0x02:0)| - (uid->is_expired?0x04:0))); - write_status_text(STATUS_ATTRIBUTE,buf); - } - - fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp); - } -} - -static void -list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque ) -{ - int rc = 0; - KBNODE kbctx; - KBNODE node; - PKT_public_key *pk; - PKT_secret_key *sk; - u32 keyid[2]; - int any=0; - struct sig_stats *stats=opaque; - int newformat=((opt.list_options&LIST_SHOW_VALIDITY) && !secret) - || (opt.list_options&LIST_SHOW_LONG_KEYID); - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key lost!\n"); - dump_kbnode( keyblock ); - return; - } - - if( secret ) - { - pk = NULL; - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - - printf("sec%c %4u%c/",(sk->protect.s2k.mode==1001)?'#':' ', - nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo )); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]); - else - printf("%08lX",(ulong)keyid[1]); - - printf(" %s%s",datestr_from_sk( sk ),newformat?"":" " ); - - if(newformat && sk->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_sk( sk ) ); - } - else - { - int validity; - pk = node->pkt->pkt.public_key; - sk = NULL; - keyid_from_pk( pk, keyid ); - - validity=get_validity(pk,NULL); - - printf("pub %4u%c/", - nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo)); - - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]); - else - printf("%08lX",(ulong)keyid[1]); - - printf(" %s%s",datestr_from_pk( pk ),newformat?"":" " ); - - /* We didn't include this before in the key listing, but there - is room in the new format, so why not? */ - if(newformat && pk->expiredate) - printf(_(" [expires: %s]"), expirestr_from_pk( pk ) ); - - if(opt.list_options&LIST_SHOW_VALIDITY) - printf(" [%s]",trust_value_to_string(validity)); - } - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { - int indent; - /* don't list revoked or expired UIDS unless we are in - * verbose mode and signature listing has not been - * requested */ - if ( !opt.verbose && !opt.list_sigs && - (node->pkt->pkt.user_id->is_revoked || - node->pkt->pkt.user_id->is_expired )) - continue; - - if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL) - dump_attribs(node->pkt->pkt.user_id,pk,sk); - - if(!any && newformat) - printf("\n"); - - if((opt.list_options&LIST_SHOW_VALIDITY) && pk) - { - const char *validity= - trust_value_to_string(get_validity(pk,node->pkt->pkt.user_id)); - - /* Includes the 3 spaces for [, ], and " ". */ - indent=((opt.list_options&LIST_SHOW_LONG_KEYID)?23:15) - -strlen(validity); - - if(indent<0) - indent=0; - - printf("uid%*s[%s] ",indent,"",validity); - } - else if(newformat) - printf("uid%*s",26,""); - else if(any) - printf("uid%*s",29,""); - - if ( node->pkt->pkt.user_id->is_revoked ) - fputs ("[revoked] ", stdout); - if ( node->pkt->pkt.user_id->is_expired ) - fputs ("[expired] ", stdout); - - print_utf8_string( stdout, node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len ); - putchar('\n'); - if( !any ) { - if( fpr ) - print_fingerprint( pk, sk, 0 ); - print_card_serialno (sk); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - - if((opt.list_options&LIST_SHOW_PHOTOS) - && node->pkt->pkt.user_id->attribs!=NULL) - show_photos(node->pkt->pkt.user_id->attribs, - node->pkt->pkt.user_id->numattribs,pk,sk); - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - u32 keyid2[2]; - PKT_public_key *pk2 = node->pkt->pkt.public_key; - - if( !any ) { - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_pk( pk2, keyid2 ); - printf("sub %4u%c/", - nbits_from_pk( pk2 ),pubkey_letter( pk2->pubkey_algo )); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]); - else - printf("%08lX",(ulong)keyid2[1]); - printf(" %s",datestr_from_pk(pk2)); - if( pk2->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) ); - putchar('\n'); - if( fpr > 1 ) - print_fingerprint( pk2, NULL, 0 ); - if( opt.with_key_data ) - print_key_data( pk2, keyid2 ); - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 keyid2[2]; - PKT_secret_key *sk2 = node->pkt->pkt.secret_key; - - if( !any ) { - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - print_card_serialno (sk); - any = 1; - } - - keyid_from_sk( sk2, keyid2 ); - printf("ssb %4u%c/", - nbits_from_sk( sk2 ),pubkey_letter( sk2->pubkey_algo )); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]); - else - printf("%08lX",(ulong)keyid2[1]); - printf(" %s",datestr_from_sk( sk2 ) ); - if( sk2->expiredate ) - printf(_(" [expires: %s]"), expirestr_from_sk( sk2 ) ); - putchar('\n'); - if( fpr > 1 ) - { - print_fingerprint( NULL, sk2, 0 ); - print_card_serialno (sk); - } - } - else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int sigrc; - char *sigstr; - - if( stats ) { - /*fflush(stdout);*/ - rc = check_key_signature( keyblock, node, NULL ); - switch( gpg_err_code (rc) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: stats->inv_sigs++; sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: stats->no_key++; continue; - default: stats->oth_err++; sigrc = '%'; break; - } - - /* TODO: Make sure a cached sig record here still has - the pk that issued it. See also - keyedit.c:print_and_check_one_sig */ - - } - else { - rc = 0; - sigrc = ' '; - } - - if( !any ) { /* no user id, (maybe a revocation follows)*/ - /* Check if the pk is really revoked - there could be a - 0x20 sig packet there even if we are not revoked - (say, if a revocation key issued the packet, but the - revocation key isn't present to verify it.) */ - if( sig->sig_class == 0x20 && pk->is_revoked ) - puts("[revoked]"); - else if( sig->sig_class == 0x18 ) - puts("[key binding]"); - else if( sig->sig_class == 0x28 ) - puts("[subkey revoked]"); - else - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - print_card_serialno (sk); - any=1; - } - - if( sig->sig_class == 0x20 || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) - sigstr = "rev"; - else if( (sig->sig_class&~3) == 0x10 ) - sigstr = "sig"; - else if( sig->sig_class == 0x18 ) - sigstr = "sig"; - else if( sig->sig_class == 0x1F ) - sigstr = "sig"; - else { - printf("sig " - "[unexpected signature class 0x%02x]\n",sig->sig_class ); - continue; - } - - fputs( sigstr, stdout ); - printf("%c%c %c%c%c%c%c%c ", - sigrc,(sig->sig_class-0x10>0 && - sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ', - sig->flags.exportable?' ':'L', - sig->flags.revocable?' ':'R', - sig->flags.policy_url?'P':' ', - sig->flags.notation?'N':' ', - sig->flags.expired?'X':' ', - (sig->trust_depth>9)?'T': - (sig->trust_depth>0)?'0'+sig->trust_depth:' '); - if(opt.list_options&LIST_SHOW_LONG_KEYID) - printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]); - else - printf("%08lX",(ulong)sig->keyid[1]); - printf(" %s ", datestr_from_sig(sig)); - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if ( !opt.fast_list_mode ) { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - print_utf8_string( stdout, p, n ); - xfree (p); - } - putchar('\n'); - - if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY)) - show_policy_url(sig,3,0); - - if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION)) - show_notation(sig,3,0); - - if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER)) - show_keyserver_url(sig,3,0); - - /* fixme: check or list other sigs here */ - } - } - putchar('\n'); -} - - -static void -list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) -{ - int rc = 0; - KBNODE kbctx; - KBNODE node; - PKT_public_key *pk; - PKT_secret_key *sk; - u32 keyid[2]; - int any=0; - int trustletter = 0; - int ulti_hack = 0; - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key lost!\n"); - dump_kbnode( keyblock ); - return; - } - - if( secret ) { - pk = NULL; - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - printf("sec::%u:%d:%08lX%08lX:%s:%s:::", - nbits_from_sk( sk ), - sk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_sk( sk ), - colon_strtime (sk->expiredate) - /* fixme: add LID here */ ); - } - else { - pk = node->pkt->pkt.public_key; - sk = NULL; - keyid_from_pk( pk, keyid ); - fputs( "pub:", stdout ); - if ( !pk->is_valid ) - putchar ('i'); - else if ( pk->is_revoked ) - putchar ('r'); - else if ( pk->has_expired ) - putchar ('e'); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - ; - else { - trustletter = get_validity_info ( pk, NULL ); - if( trustletter == 'u' ) - ulti_hack = 1; - putchar(trustletter); - } - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk ), - pk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_pk( pk ), - colon_strtime (pk->expiredate) ); - if( pk->local_id ) - printf("%lu", pk->local_id ); - putchar(':'); - if( !opt.fast_list_mode && !opt.no_expensive_trust_checks ) - putchar( get_ownertrust_info(pk) ); - putchar(':'); - } - - if (opt.fixed_list_mode) { - /* do not merge the first uid with the primary key */ - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - - - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { - PKT_user_id *uid=node->pkt->pkt.user_id; - if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL) - dump_attribs(node->pkt->pkt.user_id,pk,sk); - /* - * Fixme: We need a is_valid flag here too - */ - if( any ) { - int i; - char *str=uid->attrib_data?"uat":"uid"; - /* If we're listing a secret key, leave out the - validity values for now. FIXME: This should be - handled better in 1.9. */ - if ( sk ) - printf("%s:::::",str); - else if ( uid->is_revoked ) - printf("%s:r::::",str); - else if ( uid->is_expired ) - printf("%s:e::::",str); - else if ( opt.no_expensive_trust_checks ) - printf("%s:::::",str); - else { - int uid_validity; - - if( pk && !ulti_hack ) - uid_validity=get_validity_info (pk, uid); - else - uid_validity = 'u'; - printf("%s:%c::::",str,uid_validity); - } - - printf("%s:",colon_strtime(uid->created)); - printf("%s:",colon_strtime(uid->expiredate)); - - namehash_from_uid(uid); - - for(i=0; i < 20; i++ ) - printf("%02X",uid->namehash[i]); - - printf("::"); - } - if(uid->attrib_data) - printf("%u %lu",uid->numattribs,uid->attrib_len); - else - print_string(stdout,uid->name,uid->len, ':' ); - putchar(':'); - if (any) - putchar('\n'); - else { - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - if( opt.with_key_data ) - print_key_data( pk, keyid ); - any = 1; - } - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - u32 keyid2[2]; - PKT_public_key *pk2 = node->pkt->pkt.public_key; - - if( !any ) { - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_pk( pk2, keyid2 ); - fputs ("sub:", stdout ); - if ( !pk2->is_valid ) - putchar ('i'); - else if ( pk2->is_revoked ) - putchar ('r'); - else if ( pk2->has_expired ) - putchar ('e'); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) - ; - else { - /* trustletter should always be defined here */ - if(trustletter) - printf("%c", trustletter ); - } - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk2 ), - pk2->pubkey_algo, - (ulong)keyid2[0],(ulong)keyid2[1], - colon_datestr_from_pk( pk2 ), - colon_strtime (pk2->expiredate) - /* fixme: add LID and ownertrust here */ - ); - if( pk->local_id ) /* use the local_id of the main key??? */ - printf("%lu", pk->local_id ); - putchar(':'); - putchar(':'); - putchar(':'); - putchar(':'); - print_capabilities (pk2, NULL, NULL); - putchar('\n'); - if( fpr > 1 ) - print_fingerprint( pk2, NULL, 0 ); - if( opt.with_key_data ) - print_key_data( pk2, keyid2 ); - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - u32 keyid2[2]; - PKT_secret_key *sk2 = node->pkt->pkt.secret_key; - - if( !any ) { - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); /* of the main key */ - any = 1; - } - - keyid_from_sk( sk2, keyid2 ); - printf("ssb::%u:%d:%08lX%08lX:%s:%s:::::", - nbits_from_sk( sk2 ), - sk2->pubkey_algo, - (ulong)keyid2[0],(ulong)keyid2[1], - colon_datestr_from_sk( sk2 ), - colon_strtime (sk2->expiredate) - /* fixme: add LID */ ); - print_capabilities (NULL, sk2, NULL); - putchar ('\n'); - if( fpr > 1 ) - print_fingerprint( NULL, sk2, 0 ); - } - else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int sigrc, fprokay=0; - char *sigstr; - size_t fplen; - byte fparray[MAX_FINGERPRINT_LEN]; - - if( !any ) { /* no user id, (maybe a revocation follows)*/ - if( sig->sig_class == 0x20 ) - fputs("[revoked]:", stdout); - else if( sig->sig_class == 0x18 ) - fputs("[key binding]:", stdout); - else if( sig->sig_class == 0x28 ) - fputs("[subkey revoked]:", stdout); - else - putchar (':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - any=1; - } - - if( sig->sig_class == 0x20 || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) - sigstr = "rev"; - else if( (sig->sig_class&~3) == 0x10 ) - sigstr = "sig"; - else if( sig->sig_class == 0x18 ) - sigstr = "sig"; - else if( sig->sig_class == 0x1F ) - sigstr = "sig"; - else { - printf ("sig::::::::::%02x%c:\n", - sig->sig_class, sig->flags.exportable?'x':'l'); - continue; - } - if( opt.check_sigs ) { - PKT_public_key *signer_pk=NULL; - - fflush(stdout); - if(opt.no_sig_cache) - signer_pk = xcalloc (1, sizeof(PKT_public_key)); - - rc = check_key_signature2( keyblock, node, NULL, signer_pk, - NULL, NULL, NULL ); - switch( gpg_err_code (rc) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; - default: sigrc = '%'; break; - } - - if(opt.no_sig_cache) - { - if(!rc) - { - fingerprint_from_pk (signer_pk, fparray, &fplen); - fprokay=1; - } - free_public_key(signer_pk); - } - } - else { - rc = 0; - sigrc = ' '; - } - fputs( sigstr, stdout ); - putchar(':'); - if( sigrc != ' ' ) - putchar(sigrc); - printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - colon_datestr_from_sig(sig), - colon_expirestr_from_sig(sig)); - - if(sig->trust_depth || sig->trust_value) - printf("%d %d",sig->trust_depth,sig->trust_value); - printf(":"); - - if(sig->trust_regexp) - print_string(stdout,sig->trust_regexp, - strlen(sig->trust_regexp),':'); - printf(":"); - - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc) ); - else if( sigrc == '?' ) - ; - else if ( !opt.fast_list_mode ) { - size_t n; - char *p = get_user_id( sig->keyid, &n ); - print_string( stdout, p, n, ':' ); - xfree (p); - } - printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l'); - if(opt.no_sig_cache && opt.check_sigs && fprokay) - { - size_t i; - - printf(":"); - - for (i=0; i < fplen ; i++ ) - printf ("%02X", fparray[i] ); - - printf(":"); - } - - printf("\n"); - /* fixme: check or list other sigs here */ - } - } - if( !any ) {/* oops, no user id */ - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - putchar('\n'); - } -} - -/* - * Reorder the keyblock so that the primary user ID (and not attribute - * packet) comes first. Fixme: Replace this by a generic sort - * function. */ -void -reorder_keyblock (KBNODE keyblock) -{ - KBNODE primary = NULL, primary0 = NULL, primary2 = NULL; - KBNODE last, node; - - for (node=keyblock; node; primary0=node, node = node->next) { - if( node->pkt->pkttype == PKT_USER_ID && - !node->pkt->pkt.user_id->attrib_data && - node->pkt->pkt.user_id->is_primary ) { - primary = primary2 = node; - for (node=node->next; node; primary2=node, node = node->next ) { - if( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - break; - } - } - break; - } - } - if ( !primary ) - return; /* no primary key flag found (should not happen) */ - - for (last=NULL, node=keyblock; node; last = node, node = node->next) { - if( node->pkt->pkttype == PKT_USER_ID ) - break; - } - assert (node); - assert (last); /* the user ID is never the first packet */ - assert (primary0); /* ditto (this is the node before primary) */ - if ( node == primary ) - return; /* already the first one */ - - last->next = primary; - primary0->next = primary2->next; - primary2->next = node; -} - -void -list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque ) -{ - reorder_keyblock (keyblock); - if (opt.with_colons) - list_keyblock_colon (keyblock, secret, fpr ); - else - list_keyblock_print (keyblock, secret, fpr, opaque ); -} - -/* - * standard function to print the finperprint. - * mode 0: as used in key listings, opt.with_colons is honored - * 1: print using log_info () - * 2: direct use of tty - * 3: direct use of tty but only primary key. - * modes 1 and 2 will try and print both subkey and primary key fingerprints - */ -void -print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode ) -{ - byte array[MAX_FINGERPRINT_LEN], *p; - size_t i, n; - FILE *fp; - const char *text; - int primary=0; - - if(sk) - { - if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1]) - primary=1; - } - else - { - if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1]) - primary=1; - } - - /* Just to be safe */ - if(mode&0x80 && !primary) - { - log_error("primary key is not really primary!\n"); - return; - } - - mode&=~0x80; - - if(!primary && (mode==1 || mode==2)) - { - if(sk) - { - PKT_secret_key *primary_sk=xcalloc (1,sizeof(*primary_sk)); - get_seckey(primary_sk,sk->main_keyid); - print_fingerprint(NULL,primary_sk,mode|0x80); - free_secret_key(primary_sk); - } - else - { - PKT_public_key *primary_pk=xcalloc (1,sizeof(*primary_pk)); - get_pubkey(primary_pk,pk->main_keyid); - print_fingerprint(primary_pk,NULL,mode|0x80); - free_public_key(primary_pk); - } - } - - if (mode == 1) { - fp = log_get_stream (); - if(primary) - text = _("Primary key fingerprint:"); - else - text = _(" Subkey fingerprint:"); - } - else if (mode == 2) { - fp = NULL; /* use tty */ - /* Translators: this should fit into 24 bytes to that the fingerprint - * data is properly aligned with the user ID */ - if(primary) - text = _(" Primary key fingerprint:"); - else - text = _(" Subkey fingerprint:"); - } - else if (mode == 3) { - fp = NULL; /* use tty */ - text = _(" Key fingerprint ="); - } - else { - fp = stdout; - text = _(" Key fingerprint ="); - } - - if (sk) - fingerprint_from_sk (sk, array, &n); - else - fingerprint_from_pk (pk, array, &n); - p = array; - if (opt.with_colons && !mode) { - fprintf (fp, "fpr:::::::::"); - for (i=0; i < n ; i++, p++ ) - fprintf (fp, "%02X", *p ); - putc(':', fp); - } - else { - if (fp) - fputs (text, fp); - else - tty_printf ("%s", text); - if (n == 20) { - for (i=0; i < n ; i++, i++, p += 2 ) { - if (fp) { - if (i == 10 ) - putc(' ', fp); - fprintf (fp, " %02X%02X", *p, p[1] ); - } - else { - if (i == 10 ) - tty_printf (" "); - tty_printf (" %02X%02X", *p, p[1]); - } - } - } - else { - for (i=0; i < n ; i++, p++ ) { - if (fp) { - if (i && !(i%8) ) - putc (' ', fp); - fprintf (fp, " %02X", *p ); - } - else { - if (i && !(i%8) ) - tty_printf (" "); - tty_printf (" %02X", *p ); - } - } - } - } - if (fp) - putc ('\n', fp); - else - tty_printf ("\n"); -} - - -/* Print the serial number of an OpenPGP card if available. */ -static void -print_card_serialno (PKT_secret_key *sk) -{ - int i; - - if (!sk) - return; - if (!sk->is_protected || sk->protect.s2k.mode != 1002) - return; /* Not a card. */ - if (opt.with_colons) - return; /* Format not yet defined. */ - - fputs (_(" Card serial no. ="), stdout); - putchar (' '); - if (sk->protect.ivlen == 16 - && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6) ) - { /* This is an OpenPGP card. Just print the relevant part. */ - for (i=8; i < 14; i++) - { - if (i == 10) - putchar (' '); - printf ("%02X", sk->protect.iv[i]); - } - } - else - { /* Something is wrong: Print all. */ - for (i=0; i < sk->protect.ivlen; i++) - printf ("%02X", sk->protect.iv[i]); - } - putchar ('\n'); -} - -void set_attrib_fd(int fd) -{ - static int last_fd=-1; - - if ( fd != -1 && last_fd == fd ) - return; - - if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr ) - fclose (attrib_fp); - attrib_fp = NULL; - if ( fd == -1 ) - return; - - if( fd == 1 ) - attrib_fp = stdout; - else if( fd == 2 ) - attrib_fp = stderr; - else - attrib_fp = fdopen( fd, "w" ); - if( !attrib_fp ) { - log_fatal("can't open fd %d for attribute output: %s\n", - fd, strerror(errno)); - } - last_fd = fd; -} diff --git a/g10/keyring.c b/g10/keyring.c deleted file mode 100644 index 03a22667c..000000000 --- a/g10/keyring.c +++ /dev/null @@ -1,1588 +0,0 @@ -/* keyring.c - keyring file handling - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "gpg.h" -#include "util.h" -#include "keyring.h" -#include "packet.h" -#include "keydb.h" -#include "options.h" -#include "main.h" /*for check_key_signature()*/ -#include "i18n.h" - -/* off_item is a funny named for an object used to keep track of known - * keys. The idea was to use the offset to seek to the known keyblock, but - * this is not possible if more than one process is using the keyring. - */ -struct off_item { - struct off_item *next; - u32 kid[2]; - /*off_t off;*/ -}; - -typedef struct off_item **OffsetHashTable; - - -typedef struct keyring_name *KR_NAME; -struct keyring_name { - struct keyring_name *next; - int secret; - DOTLOCK lockhd; - int is_locked; - int did_full_scan; - char fname[1]; -}; -typedef struct keyring_name const * CONST_KR_NAME; - -static KR_NAME kr_names; -static int active_handles; - -static OffsetHashTable kr_offtbl; -static int kr_offtbl_ready; - - -struct keyring_handle { - CONST_KR_NAME resource; - int secret; /* this is for a secret keyring */ - struct { - CONST_KR_NAME kr; - iobuf_t iobuf; - int eof; - int error; - } current; - struct { - CONST_KR_NAME kr; - off_t offset; - size_t pk_no; - size_t uid_no; - unsigned int n_packets; /*used for delete and update*/ - } found; - struct { - char *name; - char *pattern; - } word_match; -}; - - - -static int do_copy (int mode, const char *fname, KBNODE root, int secret, - off_t start_offset, unsigned int n_packets ); - - - -static struct off_item * -new_offset_item (void) -{ - struct off_item *k; - - k = xcalloc (1,sizeof *k); - return k; -} - -#if 0 -static void -release_offset_items (struct off_item *k) -{ - struct off_item *k2; - - for (; k; k = k2) - { - k2 = k->next; - xfree (k); - } -} -#endif - -static OffsetHashTable -new_offset_hash_table (void) -{ - struct off_item **tbl; - - tbl = xcalloc (2048, sizeof *tbl); - return tbl; -} - -#if 0 -static void -release_offset_hash_table (OffsetHashTable tbl) -{ - int i; - - if (!tbl) - return; - for (i=0; i < 2048; i++) - release_offset_items (tbl[i]); - xfree (tbl); -} -#endif - -static struct off_item * -lookup_offset_hash_table (OffsetHashTable tbl, u32 *kid) -{ - struct off_item *k; - - for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return k; - return NULL; -} - -static void -update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off) -{ - struct off_item *k; - - for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next) - { - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - { - /*k->off = off;*/ - return; - } - } - - k = new_offset_item (); - k->kid[0] = kid[0]; - k->kid[1] = kid[1]; - /*k->off = off;*/ - k->next = tbl[(kid[1] & 0x07ff)]; - tbl[(kid[1] & 0x07ff)] = k; -} - -static void -update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off) -{ - for (; node; node = node->next) - { - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - u32 aki[2]; - keyid_from_pk (node->pkt->pkt.public_key, aki); - update_offset_hash_table (tbl, aki, off); - } - } -} - -/* - * Register a filename for plain keyring files. ptr is set to a - * pointer to be used to create a handles etc, or the already-issued - * pointer if it has already been registered. The function returns 1 - * if a new keyring was registered. -*/ -int -keyring_register_filename (const char *fname, int secret, void **ptr) -{ - KR_NAME kr; - - if (active_handles) - BUG (); /* We don't allow that */ - - for (kr=kr_names; kr; kr = kr->next) - { - if ( !compare_filenames (kr->fname, fname) ) - { - *ptr=kr; - return 0; /* already registered */ - } - } - - kr = xmalloc (sizeof *kr + strlen (fname)); - strcpy (kr->fname, fname); - kr->secret = !!secret; - kr->lockhd = NULL; - kr->is_locked = 0; - kr->did_full_scan = 0; - /* keep a list of all issued pointers */ - kr->next = kr_names; - kr_names = kr; - - /* create the offset table the first time a function here is used */ - if (!kr_offtbl) - kr_offtbl = new_offset_hash_table (); - - *ptr=kr; - - return 1; -} - -int -keyring_is_writable (void *token) -{ - KR_NAME r = token; - - return r? !access (r->fname, W_OK) : 0; -} - - - -/* Create a new handle for the resource associated with TOKEN. SECRET - is just just as a cross-check. - - The returned handle must be released using keyring_release (). */ -KEYRING_HANDLE -keyring_new (void *token, int secret) -{ - KEYRING_HANDLE hd; - KR_NAME resource = token; - - assert (resource && !resource->secret == !secret); - - hd = xcalloc (1,sizeof *hd); - hd->resource = resource; - hd->secret = !!secret; - active_handles++; - return hd; -} - -void -keyring_release (KEYRING_HANDLE hd) -{ - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - iobuf_close (hd->current.iobuf); - xfree (hd); -} - - -const char * -keyring_get_resource_name (KEYRING_HANDLE hd) -{ - if (!hd || !hd->resource) - return NULL; - return hd->resource->fname; -} - - -/* - * Lock the keyring with the given handle, or unlok if yes is false. - * We ignore the handle and lock all registered files. - */ -int -keyring_lock (KEYRING_HANDLE hd, int yes) -{ - KR_NAME kr; - int rc = 0; - - if (yes) { - /* first make sure the lock handles are created */ - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (!kr->lockhd) { - kr->lockhd = create_dotlock( kr->fname ); - if (!kr->lockhd) { - log_info ("can't allocate lock for `%s'\n", kr->fname ); - rc = GPG_ERR_GENERAL; - } - } - } - if (rc) - return rc; - - /* and now set the locks */ - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (kr->is_locked) - ; - else if (make_dotlock (kr->lockhd, -1) ) { - log_info ("can't lock `%s'\n", kr->fname ); - rc = GPG_ERR_GENERAL; - } - else - kr->is_locked = 1; - } - } - - if (rc || !yes) { - for (kr=kr_names; kr; kr = kr->next) { - if (!keyring_is_writable(kr)) - continue; - if (!kr->is_locked) - ; - else if (release_dotlock (kr->lockhd)) - log_info ("can't unlock `%s'\n", kr->fname ); - else - kr->is_locked = 0; - } - } - - return rc; -} - - - -/* - * Return the last found keyring. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) -{ - PACKET *pkt; - int rc; - KBNODE keyblock = NULL, node, lastnode; - iobuf_t a; - int in_cert = 0; - int pk_no = 0; - int uid_no = 0; - int save_mode; - - if (ret_kb) - *ret_kb = NULL; - - if (!hd->found.kr) - return -1; /* no successful search */ - - a = iobuf_open (hd->found.kr->fname); - if (!a) { - log_error ("can't open `%s'\n", hd->found.kr->fname); - return GPG_ERR_KEYRING_OPEN; - } - - if (iobuf_seek (a, hd->found.offset) ) { - log_error ("can't seek `%s'\n", hd->found.kr->fname); - iobuf_close(a); - return GPG_ERR_KEYRING_OPEN; - } - - pkt = xmalloc (sizeof *pkt); - init_packet (pkt); - hd->found.n_packets = 0;; - lastnode = NULL; - save_mode = set_packet_list_mode(0); - while ((rc=parse_packet (a, pkt)) != -1) { - hd->found.n_packets++; - if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) { - free_packet (pkt); - init_packet (pkt); - continue; - } - if (rc) { - log_error ("keyring_get_keyblock: read error: %s\n", - gpg_strerror (rc) ); - rc = GPG_ERR_INV_KEYRING; - break; - } - if (pkt->pkttype == PKT_COMPRESSED) { - log_error ("skipped compressed packet in keyring\n"); - free_packet(pkt); - init_packet(pkt); - continue; - } - - if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_SECRET_KEY)) { - hd->found.n_packets--; /* fix counter */ - break; /* ready */ - } - - in_cert = 1; - if (pkt->pkttype == PKT_RING_TRUST) { - /*(this code is duplicated after the loop)*/ - if ( lastnode - && lastnode->pkt->pkttype == PKT_SIGNATURE - && (pkt->pkt.ring_trust->sigcache & 1) ) { - /* this is a ring trust packet with a checked signature - * status cache following directly a signature paket. - * Set the cache status into that signature packet */ - PKT_signature *sig = lastnode->pkt->pkt.signature; - - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); - } - /* reset lastnode, so that we set the cache status only from - * the ring trust packet immediately folling a signature */ - lastnode = NULL; - } - else { - node = lastnode = new_kbnode (pkt); - if (!keyblock) - keyblock = node; - else - add_kbnode (keyblock, node); - - if ( pkt->pkttype == PKT_PUBLIC_KEY - || pkt->pkttype == PKT_PUBLIC_SUBKEY - || pkt->pkttype == PKT_SECRET_KEY - || pkt->pkttype == PKT_SECRET_SUBKEY) { - if (++pk_no == hd->found.pk_no) - node->flag |= 1; - } - else if ( pkt->pkttype == PKT_USER_ID) { - if (++uid_no == hd->found.uid_no) - node->flag |= 2; - } - } - - pkt = xmalloc (sizeof *pkt); - init_packet(pkt); - } - set_packet_list_mode(save_mode); - - if (rc == -1 && keyblock) - rc = 0; /* got the entire keyblock */ - - if (rc || !ret_kb) - release_kbnode (keyblock); - else { - /*(duplicated form the loop body)*/ - if ( pkt && pkt->pkttype == PKT_RING_TRUST - && lastnode - && lastnode->pkt->pkttype == PKT_SIGNATURE - && (pkt->pkt.ring_trust->sigcache & 1) ) { - PKT_signature *sig = lastnode->pkt->pkt.signature; - sig->flags.checked = 1; - sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2); - } - *ret_kb = keyblock; - } - free_packet (pkt); - xfree (pkt); - iobuf_close(a); - - /* Make sure that future search operations fail immediately when - * we know that we are working on a invalid keyring - */ - if (gpg_err_code (rc) == GPG_ERR_INV_KEYRING) - hd->current.error = rc; - - return rc; -} - -int -keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb) -{ - int rc; - - if (!hd->found.kr) - return -1; /* no successful prior search */ - - if (!hd->found.n_packets) { - /* need to know the number of packets - do a dummy get_keyblock*/ - rc = keyring_get_keyblock (hd, NULL); - if (rc) { - log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (!hd->found.n_packets) - BUG (); - } - - /* The open iobuf isn't needed anymore and in fact is a problem when - it comes to renaming the keyring files on some operating systems, - so close it here */ - iobuf_close(hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the update */ - rc = do_copy (3, hd->found.kr->fname, kb, hd->secret, - hd->found.offset, hd->found.n_packets ); - if (!rc) { - if (!hd->secret && kr_offtbl) - { - update_offset_hash_table_from_kb (kr_offtbl, kb, 0); - } - /* better reset the found info */ - hd->found.kr = NULL; - hd->found.offset = 0; - } - return rc; -} - -int -keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb) -{ - int rc; - const char *fname; - - if (!hd) - fname = NULL; - else if (hd->found.kr) - fname = hd->found.kr->fname; - else if (hd->current.kr) - fname = hd->current.kr->fname; - else - fname = hd->resource? hd->resource->fname:NULL; - - if (!fname) - return GPG_ERR_GENERAL; - - /* close this one otherwise we will lose the position for - * a next search. Fixme: it would be better to adjust the position - * after the write opertions. - */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the insert */ - rc = do_copy (1, fname, kb, hd->secret, 0, 0 ); - if (!rc && !hd->secret && kr_offtbl) - { - update_offset_hash_table_from_kb (kr_offtbl, kb, 0); - } - - return rc; -} - - -int -keyring_delete_keyblock (KEYRING_HANDLE hd) -{ - int rc; - - if (!hd->found.kr) - return -1; /* no successful prior search */ - - if (!hd->found.n_packets) { - /* need to know the number of packets - do a dummy get_keyblock*/ - rc = keyring_get_keyblock (hd, NULL); - if (rc) { - log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (!hd->found.n_packets) - BUG (); - } - - /* close this one otherwise we will lose the position for - * a next search. Fixme: it would be better to adjust the position - * after the write opertions. - */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - - /* do the delete */ - rc = do_copy (2, hd->found.kr->fname, NULL, hd->secret, - hd->found.offset, hd->found.n_packets ); - if (!rc) { - /* better reset the found info */ - hd->found.kr = NULL; - hd->found.offset = 0; - /* Delete is a rare operations, so we don't remove the keys - * from the offset table */ - } - return rc; -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keyring_search_reset (KEYRING_HANDLE hd) -{ - assert (hd); - - hd->current.kr = NULL; - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - hd->current.eof = 0; - hd->current.error = 0; - - hd->found.kr = NULL; - hd->found.offset = 0; - return 0; -} - - -static int -prepare_search (KEYRING_HANDLE hd) -{ - if (hd->current.error) - return hd->current.error; /* still in error state */ - - if (hd->current.kr && !hd->current.eof) { - if ( !hd->current.iobuf ) - return GPG_ERR_GENERAL; /* position invalid after a modify */ - return 0; /* okay */ - } - - if (!hd->current.kr && hd->current.eof) - return -1; /* still EOF */ - - if (!hd->current.kr) { /* start search with first keyring */ - hd->current.kr = hd->resource; - if (!hd->current.kr) { - hd->current.eof = 1; - return -1; /* keyring not available */ - } - assert (!hd->current.iobuf); - } - else { /* EOF */ - iobuf_close (hd->current.iobuf); - hd->current.iobuf = NULL; - hd->current.kr = NULL; - hd->current.eof = 1; - return -1; - } - - hd->current.eof = 0; - hd->current.iobuf = iobuf_open (hd->current.kr->fname); - if (!hd->current.iobuf) { - hd->current.error = gpg_error_from_errno (errno); - log_error ("can't open `%s'\n", hd->current.kr->fname ); - return hd->current.error; - } - - return 0; -} - - -/* A map of the all characters valid used for word_match() - * Valid characters are in in this table converted to uppercase. - * because the upper 128 bytes have special meaning, we assume - * that they are all valid. - * Note: We must use numerical values here in case that this program - * will be converted to those little blue HAL9000s with their strange - * EBCDIC character set (user ids are UTF-8). - * wk 2000-04-13: Hmmm, does this really make sense, given the fact that - * we can run gpg now on a S/390 running GNU/Linux, where the code - * translation is done by the device drivers? - */ -static const byte word_match_chars[256] = { - /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - /* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 40 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - /* 48 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - /* 58 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 60 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - /* 68 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - /* 78 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - /* 88 */ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - /* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - /* 98 */ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - /* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - /* a8 */ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - /* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - /* b8 */ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - /* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - /* c8 */ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - /* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - /* d8 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - /* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - /* e8 */ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - /* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - /* f8 */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -/**************** - * Do a word match (original user id starts with a '+'). - * The pattern is already tokenized to a more suitable format: - * There are only the real words in it delimited by one space - * and all converted to uppercase. - * - * Returns: 0 if all words match. - * - * Note: This algorithm is a straightforward one and not very - * fast. It works for UTF-8 strings. The uidlen should - * be removed but due to the fact that old versions of - * pgp don't use UTF-8 we still use the length; this should - * be fixed in parse-packet (and replace \0 by some special - * UTF-8 encoding) - */ -static int -word_match( const byte *uid, size_t uidlen, const byte *pattern ) -{ - size_t wlen, n; - const byte *p; - const byte *s; - - for( s=pattern; *s; ) { - do { - /* skip leading delimiters */ - while( uidlen && !word_match_chars[*uid] ) - uid++, uidlen--; - /* get length of the word */ - n = uidlen; p = uid; - while( n && word_match_chars[*p] ) - p++, n--; - wlen = p - uid; - /* and compare against the current word from pattern */ - for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) { - if( word_match_chars[*p] != s[n] ) - break; - } - if( n == wlen && (s[n] == ' ' || !s[n]) ) - break; /* found */ - uid += wlen; - uidlen -= wlen; - } while( uidlen ); - if( !uidlen ) - return -1; /* not found */ - - /* advance to next word in pattern */ - for(; *s != ' ' && *s ; s++ ) - ; - if( *s ) - s++ ; - } - return 0; /* found */ -} - -/**************** - * prepare word word_match; that is parse the name and - * build the pattern. - * caller has to free the returned pattern - */ -static char* -prepare_word_match (const byte *name) -{ - byte *pattern, *p; - int c; - - /* the original length is always enough for the pattern */ - p = pattern = xmalloc (strlen(name)+1); - do { - /* skip leading delimiters */ - while( *name && !word_match_chars[*name] ) - name++; - /* copy as long as we don't have a delimiter and convert - * to uppercase. - * fixme: how can we handle utf8 uppercasing */ - for( ; *name && (c=word_match_chars[*name]); name++ ) - *p++ = c; - *p++ = ' '; /* append pattern delimiter */ - } while( *name ); - p[-1] = 0; /* replace last pattern delimiter by EOS */ - - return pattern; -} - - - - -static int -compare_name (int mode, const char *name, const char *uid, size_t uidlen) -{ - int i; - const char *s, *se; - - if (mode == KEYDB_SEARCH_MODE_EXACT) { - for (i=0; name[i] && uidlen; i++, uidlen--) - if (uid[i] != name[i]) - break; - if (!uidlen && !name[i]) - return 0; /* found */ - } - else if (mode == KEYDB_SEARCH_MODE_SUBSTR) { - if (ascii_memistr( uid, uidlen, name )) - return 0; - } - else if ( mode == KEYDB_SEARCH_MODE_MAIL - || mode == KEYDB_SEARCH_MODE_MAILSUB - || mode == KEYDB_SEARCH_MODE_MAILEND) { - for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++) - ; - if (i < uidlen) { - /* skip opening delim and one char and look for the closing one*/ - s++; i++; - for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++) - ; - if (i < uidlen) { - i = se - s; - if (mode == KEYDB_SEARCH_MODE_MAIL) { - if( strlen(name)-2 == i - && !ascii_memcasecmp( s, name+1, i) ) - return 0; - } - else if (mode == KEYDB_SEARCH_MODE_MAILSUB) { - if( ascii_memistr( s, i, name ) ) - return 0; - } - else { /* email from end */ - /* nyi */ - } - } - } - } - else if (mode == KEYDB_SEARCH_MODE_WORDS) - return word_match (uid, uidlen, name); - else - BUG(); - - return -1; /* not found */ -} - - -/* - * Search through the keyring(s), starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex) -{ - int rc; - PACKET pkt; - int save_mode; - off_t offset, main_offset; - size_t n; - int need_uid, need_words, need_keyid, need_fpr, any_skip; - int pk_no, uid_no; - int initial_skip; - int use_offtbl; - PKT_user_id *uid = NULL; - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - u32 aki[2]; - - /* figure out what information we need */ - need_uid = need_words = need_keyid = need_fpr = any_skip = 0; - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_EXACT: - case KEYDB_SEARCH_MODE_SUBSTR: - case KEYDB_SEARCH_MODE_MAIL: - case KEYDB_SEARCH_MODE_MAILSUB: - case KEYDB_SEARCH_MODE_MAILEND: - need_uid = 1; - break; - case KEYDB_SEARCH_MODE_WORDS: - need_uid = 1; - need_words = 1; - break; - case KEYDB_SEARCH_MODE_SHORT_KID: - case KEYDB_SEARCH_MODE_LONG_KID: - need_keyid = 1; - break; - case KEYDB_SEARCH_MODE_FPR16: - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - need_fpr = 1; - break; - case KEYDB_SEARCH_MODE_FIRST: - /* always restart the search in this mode */ - keyring_search_reset (hd); - break; - default: break; - } - if (desc[n].skipfnc) - { - any_skip = 1; - need_keyid = 1; - } - } - - rc = prepare_search (hd); - if (rc) - return rc; - - use_offtbl = !hd->secret && kr_offtbl; - if (!use_offtbl) - ; - else if (!kr_offtbl_ready) - need_keyid = 1; - else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) - { - struct off_item *oi; - - oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid); - if (!oi) - { /* We know that we don't have this key */ - hd->found.kr = NULL; - hd->current.eof = 1; - return -1; - } - /* We could now create a positive search status and return. - * However the problem is that another instance of gpg may - * have changed the keyring so that the offsets are not valid - * anymore - therefore we don't do it - */ - } - - if (need_words) - { - const char *name = NULL; - - log_debug ("word search mode does not yet work\n"); - /* FIXME: here is a long standing bug in our function and in addition we - just use the first search description */ - for (n=0; n < ndesc && !name; n++) - { - if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) - name = desc[n].u.name; - } - assert (name); - if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) - { - /* name changed */ - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - hd->word_match.name = xstrdup (name); - hd->word_match.pattern = prepare_word_match (name); - } - name = hd->word_match.pattern; - } - - init_packet(&pkt); - save_mode = set_packet_list_mode(0); - - hd->found.kr = NULL; - main_offset = 0; - pk_no = uid_no = 0; - initial_skip = 1; /* skip until we see the start of a keyblock */ - while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) - { - main_offset = offset; - pk_no = uid_no = 0; - initial_skip = 0; - } - if (initial_skip) - { - free_packet (&pkt); - continue; - } - - pk = NULL; - sk = NULL; - uid = NULL; - if ( pkt.pkttype == PKT_PUBLIC_KEY - || pkt.pkttype == PKT_PUBLIC_SUBKEY) - { - pk = pkt.pkt.public_key; - ++pk_no; - - if (need_fpr) { - fingerprint_from_pk (pk, afp, &an); - while (an < 20) /* fill up to 20 bytes */ - afp[an++] = 0; - } - if (need_keyid) - keyid_from_pk (pk, aki); - - if (use_offtbl && !kr_offtbl_ready) - update_offset_hash_table (kr_offtbl, aki, main_offset); - } - else if (pkt.pkttype == PKT_USER_ID) - { - uid = pkt.pkt.user_id; - ++uid_no; - } - else if ( pkt.pkttype == PKT_SECRET_KEY - || pkt.pkttype == PKT_SECRET_SUBKEY) - { - sk = pkt.pkt.secret_key; - ++pk_no; - - if (need_fpr) { - fingerprint_from_sk (sk, afp, &an); - while (an < 20) /* fill up to 20 bytes */ - afp[an++] = 0; - } - if (need_keyid) - keyid_from_sk (sk, aki); - - } - - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) { - case KEYDB_SEARCH_MODE_NONE: - BUG (); - break; - case KEYDB_SEARCH_MODE_EXACT: - case KEYDB_SEARCH_MODE_SUBSTR: - case KEYDB_SEARCH_MODE_MAIL: - case KEYDB_SEARCH_MODE_MAILSUB: - case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: - if ( uid && !compare_name (desc[n].mode, - desc[n].u.name, - uid->name, uid->len)) - goto found; - break; - - case KEYDB_SEARCH_MODE_SHORT_KID: - if ((pk||sk) && desc[n].u.kid[1] == aki[1]) - goto found; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if ((pk||sk) && desc[n].u.kid[0] == aki[0] - && desc[n].u.kid[1] == aki[1]) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR16: - if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16)) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR20: - case KEYDB_SEARCH_MODE_FPR: - if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20)) - goto found; - break; - case KEYDB_SEARCH_MODE_FIRST: - if (pk||sk) - goto found; - break; - case KEYDB_SEARCH_MODE_NEXT: - if (pk||sk) - goto found; - break; - default: - rc = GPG_ERR_INV_ARG; - goto found; - } - } - free_packet (&pkt); - continue; - found: - /* Record which desc we matched on. Note this value is only - meaningful if this function returns with no errors. */ - if(descindex) - *descindex=n; - for (n=any_skip?0:ndesc; n < ndesc; n++) - { - if (desc[n].skipfnc - && desc[n].skipfnc (desc[n].skipfncvalue, aki)) - break; - } - if (n == ndesc) - goto real_found; - free_packet (&pkt); - } - real_found: - if (!rc) - { - hd->found.offset = main_offset; - hd->found.kr = hd->current.kr; - hd->found.pk_no = (pk||sk)? pk_no : 0; - hd->found.uid_no = uid? uid_no : 0; - } - else if (rc == -1) - { - hd->current.eof = 1; - /* if we scanned all keyrings, we are sure that - * all known key IDs are in our offtbl, mark that. */ - if (use_offtbl && !kr_offtbl_ready) - { - KR_NAME kr; - - /* First set the did_full_scan flag for this keyring (ignore - secret keyrings) */ - for (kr=kr_names; kr; kr = kr->next) - { - if (!kr->secret && hd->resource == kr) - { - kr->did_full_scan = 1; - break; - } - } - /* Then check whether all flags are set and if so, mark the - offtbl ready */ - for (kr=kr_names; kr; kr = kr->next) - { - if (!kr->secret && !kr->did_full_scan) - break; - } - if (!kr) - kr_offtbl_ready = 1; - } - } - else - hd->current.error = rc; - - free_packet(&pkt); - set_packet_list_mode(save_mode); - return rc; -} - - -static int -create_tmp_file (const char *template, - char **r_bakfname, char **r_tmpfname, iobuf_t *r_fp) -{ - char *bakfname, *tmpfname; - mode_t oldmask; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.gpg.tmp", "pubring.gpg"); - * but rename("pubring.gpg.tmp", "pubring.aaa"); - * works. So we replace .gpg by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") ) - { - bakfname = xmalloc (strlen (template) + 1); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); - - tmpfname = xmalloc (strlen( template ) + 1 ); - strcpy (tmpfname,template); - strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp"); - } - else - { /* file does not end with gpg; hmmm */ - bakfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(bakfname, template), EXTSEP_S "bak"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp"); - } -# else /* Posix file names */ - bakfname = xmalloc (strlen( template ) + 2); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xmalloc (strlen( template ) + 5); - strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - /* Create the temp file with limited access */ - oldmask=umask(077); - *r_fp = iobuf_create (tmpfname); - umask(oldmask); - if (!*r_fp) { - int tmperr = gpg_error_from_errno (errno); - log_error ("can't create `%s': %s\n", tmpfname, strerror(errno) ); - xfree (tmpfname); - xfree (bakfname); - return tmperr; - } - - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; -} - - -static int -rename_tmp_file (const char *bakfname, const char *tmpfname, - const char *fname, int secret ) -{ - int rc=0; - - /* invalidate close caches*/ - iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); - iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); - iobuf_ioctl (NULL, 2, 0, (char*)fname ); - - /* first make a backup file except for secret keyrings */ - if (!secret) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - int tmperr = gpg_error_from_errno (errno); - log_error ("renaming `%s' to `%s' failed: %s\n", - fname, bakfname, strerror(errno) ); - return tmperr; - } - } - - /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove( fname ); -#endif - if (rename (tmpfname, fname) ) - { - rc = gpg_error_from_errno (errno); - log_error ("renaming `%s' to `%s' failed: %s\n", - tmpfname, fname, strerror(errno) ); - if (secret) - { - log_info(_("WARNING: 2 files with confidential" - " information exists.\n")); - log_info(_("%s is the unchanged one\n"), fname ); - log_info(_("%s is the new one\n"), tmpfname ); - log_info(_("Please fix this possible security flaw\n")); - } - return rc; - } - - /* Now make sure the file has the same permissions as the original */ - -#ifndef HAVE_DOSISH_SYSTEM - { - struct stat statbuf; - - statbuf.st_mode=S_IRUSR | S_IWUSR; - - if(((secret && !opt.preserve_permissions) || - (stat(bakfname,&statbuf)==0)) && - (chmod(fname,statbuf.st_mode)==0)) - ; - else - log_error("WARNING: unable to restore permissions to `%s': %s", - fname,strerror(errno)); - } -#endif - - return 0; -} - - -static int -write_keyblock (iobuf_t fp, KBNODE keyblock) -{ - KBNODE kbctx = NULL, node; - int rc; - - while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) - { - if (node->pkt->pkttype == PKT_RING_TRUST) - continue; /* we write it later on our own */ - - if ( (rc = build_packet (fp, node->pkt) )) - { - log_error ("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - return rc; - } - if (node->pkt->pkttype == PKT_SIGNATURE) - { /* always write a signature cache packet */ - PKT_signature *sig = node->pkt->pkt.signature; - unsigned int cacheval = 0; - - if (sig->flags.checked) - { - cacheval |= 1; - if (sig->flags.valid) - cacheval |= 2; - } - iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/ - iobuf_put (fp, 2); /* 2 bytes */ - iobuf_put (fp, 0); /* unused */ - if (iobuf_put (fp, cacheval)) { - int tmperr = gpg_error_from_errno (errno); - log_error ("writing sigcache packet failed\n"); - return tmperr; - } - } - } - return 0; -} - -/* - * Walk over all public keyrings, check the signatures and replace the - * keyring with a new one where the signature cache is then updated. - * This is only done for the public keyrings. - */ -int -keyring_rebuild_cache (void *token) -{ - KEYRING_HANDLE hd; - KEYDB_SEARCH_DESC desc; - KBNODE keyblock = NULL, node; - const char *lastresname = NULL, *resname; - iobuf_t tmpfp = NULL; - char *tmpfilename = NULL; - char *bakfilename = NULL; - int rc; - ulong count = 0, sigcount = 0; - - hd = keyring_new (token, 0); - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - - rc=keyring_lock (hd, 1); - if(rc) - goto leave; - - while ( !(rc = keyring_search (hd, &desc, 1, NULL)) ) - { - desc.mode = KEYDB_SEARCH_MODE_NEXT; - resname = keyring_get_resource_name (hd); - if (lastresname != resname ) - { /* we have switched to a new keyring - commit changes */ - if (tmpfp) - { - if (iobuf_close (tmpfp)) - { - rc = gpg_error_from_errno (errno); - log_error ("error closing `%s': %s\n", - tmpfilename, strerror (errno)); - goto leave; - } - /* because we have switched resources, we can be sure that - * the original file is closed */ - tmpfp = NULL; - } - rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, - lastresname, 0) : 0; - xfree (tmpfilename); tmpfilename = NULL; - xfree (bakfilename); bakfilename = NULL; - if (rc) - goto leave; - lastresname = resname; - if (!opt.quiet) - log_info (_("checking keyring `%s'\n"), resname); - rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp); - if (rc) - goto leave; - } - - release_kbnode (keyblock); - rc = keyring_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keyring_get_keyblock failed: %s\n", gpg_strerror (rc)); - goto leave; - } - assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); - - /* check all signature to set the signature's cache flags */ - for (node=keyblock; node; node=node->next) - { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - /* Note that this doesn't cache the result of a - revocation issued by a designated revoker. This is - because the pk in question does not carry the revkeys - as we haven't merged the key and selfsigs. It is - questionable whether this matters very much since - there are very very few designated revoker revocation - packets out there. */ - check_key_signature (keyblock, node, NULL); - sigcount++; - } - } - - /* write the keyblock to the temporary file */ - rc = write_keyblock (tmpfp, keyblock); - if (rc) - goto leave; - - if ( !(++count % 50) && !opt.quiet) - log_info(_("%lu keys checked so far (%lu signatures)\n"), - count, sigcount ); - - } /* end main loop */ - if (rc == -1) - rc = 0; - if (rc) - { - log_error ("keyring_search failed: %s\n", gpg_strerror (rc)); - goto leave; - } - log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount ); - if (tmpfp) - { - if (iobuf_close (tmpfp)) - { - rc = gpg_error_from_errno (errno); - log_error ("error closing `%s': %s\n", - tmpfilename, strerror (errno)); - goto leave; - } - /* because we have switched resources, we can be sure that - * the original file is closed */ - tmpfp = NULL; - } - rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, - lastresname, 0) : 0; - xfree (tmpfilename); tmpfilename = NULL; - xfree (bakfilename); bakfilename = NULL; - - leave: - if (tmpfp) - iobuf_cancel (tmpfp); - xfree (tmpfilename); - xfree (bakfilename); - release_kbnode (keyblock); - keyring_lock (hd, 0); - keyring_release (hd); - return rc; -} - - -/**************** - * Perform insert/delete/update operation. - * mode 1 = insert - * 2 = delete - * 3 = update - */ -static int -do_copy (int mode, const char *fname, KBNODE root, int secret, - off_t start_offset, unsigned int n_packets ) -{ - iobuf_t fp, newfp; - int rc=0; - char *bakfname = NULL; - char *tmpfname = NULL; - - /* Open the source file. Because we do a rname, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error_from_errno (errno); - - - fp = iobuf_open (fname); - if (mode == 1 && !fp && errno == ENOENT) { - /* insert mode but file does not exist: create a new file */ - KBNODE kbctx, node; - mode_t oldmask; - - oldmask=umask(077); - newfp = iobuf_create (fname); - umask(oldmask); - if( !newfp ) { - int tmperr = gpg_error_from_errno (errno); - log_error (_("%s: can't create: %s\n"), - fname, strerror(errno)); - return tmperr; - } - if( !opt.quiet ) - log_info(_("%s: keyring created\n"), fname ); - - kbctx=NULL; - while ( (node = walk_kbnode( root, &kbctx, 0 )) ) { - if( (rc = build_packet( newfp, node->pkt )) ) { - log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_strerror (rc) ); - iobuf_cancel(newfp); - return rc; - } - } - if (iobuf_close(newfp)) { - int tmperr = gpg_error_from_errno (errno); - log_error ("%s: close failed: %s\n", fname, strerror(errno)); - return tmperr; - } - return 0; /* ready */ - } - - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error ("%s: can't open: %s\n", fname, strerror(errno) ); - goto leave; - } - - /* create the new file */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) { - iobuf_close(fp); - goto leave; - } - if( mode == 1 ) { /* insert */ - /* copy everything to the new file */ - rc = copy_all_packets (fp, newfp); - if( rc != -1 ) { - log_error("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - rc = 0; - } - - if( mode == 2 || mode == 3 ) { /* delete or update */ - /* copy first part to the new file */ - rc = copy_some_packets( fp, newfp, start_offset ); - if( rc ) { /* should never get EOF here */ - log_error ("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - /* skip this keyblock */ - assert( n_packets ); - rc = skip_some_packets( fp, n_packets ); - if( rc ) { - log_error("%s: skipping %u packets failed: %s\n", - fname, n_packets, gpg_strerror (rc)); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - } - - if( mode == 1 || mode == 3 ) { /* insert or update */ - rc = write_keyblock (newfp, root); - if (rc) { - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - } - - if( mode == 2 || mode == 3 ) { /* delete or update */ - /* copy the rest */ - rc = copy_all_packets( fp, newfp ); - if( rc != -1 ) { - log_error("%s: copy to `%s' failed: %s\n", - fname, tmpfname, gpg_strerror (rc) ); - iobuf_close(fp); - iobuf_cancel(newfp); - goto leave; - } - rc = 0; - } - - /* close both files */ - if( iobuf_close(fp) ) { - rc = gpg_error_from_errno (errno); - log_error("%s: close failed: %s\n", fname, strerror(errno) ); - goto leave; - } - if( iobuf_close(newfp) ) { - rc = gpg_error_from_errno (errno); - log_error("%s: close failed: %s\n", tmpfname, strerror(errno) ); - goto leave; - } - - rc = rename_tmp_file (bakfname, tmpfname, fname, secret); - - leave: - xfree (bakfname); - xfree (tmpfname); - return rc; -} diff --git a/g10/keyring.h b/g10/keyring.h deleted file mode 100644 index 528557a70..000000000 --- a/g10/keyring.h +++ /dev/null @@ -1,46 +0,0 @@ -/* keyring.h - Keyring operations - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPG_KEYRING_H -#define GPG_KEYRING_H 1 - -#include "global.h" - - -typedef struct keyring_handle *KEYRING_HANDLE; - -int keyring_register_filename (const char *fname, int secret, void **ptr); -int keyring_is_writable (void *token); - -KEYRING_HANDLE keyring_new (void *token, int secret); -void keyring_release (KEYRING_HANDLE hd); -const char *keyring_get_resource_name (KEYRING_HANDLE hd); -int keyring_lock (KEYRING_HANDLE hd, int yes); -int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb); -int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb); -int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb); -int keyring_locate_writable (KEYRING_HANDLE hd); -int keyring_delete_keyblock (KEYRING_HANDLE hd); -int keyring_search_reset (KEYRING_HANDLE hd); -int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, - size_t ndesc, size_t *descindex); -int keyring_rebuild_cache (void *); - -#endif /*GPG_KEYRING_H*/ diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h deleted file mode 100644 index 314d7898e..000000000 --- a/g10/keyserver-internal.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Keyserver internals */ - -#ifndef _KEYSERVER_INTERNAL_H_ -#define _KEYSERVER_INTERNAL_H_ - -#include <time.h> -#include "keyserver.h" -#include "../common/iobuf.h" -#include "types.h" - -void parse_keyserver_options(char *options); -int parse_keyserver_uri(char *uri, - const char *configname,unsigned int configlineno); -int keyserver_export(STRLIST users); -int keyserver_import(STRLIST users); -int keyserver_import_fprint(const byte *fprint,size_t fprint_len); -int keyserver_import_keyid(u32 *keyid); -int keyserver_refresh(STRLIST users); -int keyserver_search(STRLIST tokens); - -#endif /* !_KEYSERVER_INTERNAL_H_ */ diff --git a/g10/keyserver.c b/g10/keyserver.c deleted file mode 100644 index 445c07620..000000000 --- a/g10/keyserver.c +++ /dev/null @@ -1,1381 +0,0 @@ -/* keyserver.c - generic keyserver code - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#include "gpg.h" -#include "filter.h" -#include "keydb.h" -#include "status.h" -#include "exec.h" -#include "main.h" -#include "i18n.h" -#include "iobuf.h" -#include "memory.h" -#include "ttyio.h" -#include "options.h" -#include "packet.h" -#include "keyserver-internal.h" -#include "util.h" - -#define GET 0 -#define SEND 1 -#define SEARCH 2 - -struct keyrec -{ - KEYDB_SEARCH_DESC desc; - time_t createtime,expiretime; - int size,flags; - byte type; - iobuf_t uidbuf; - int lines; -}; - -struct kopts -{ - char *name; - int tell; /* tell remote process about this one */ - int *flag; -} keyserver_opts[]= -{ - {"include-revoked",1,&opt.keyserver_options.include_revoked}, - {"include-disabled",1,&opt.keyserver_options.include_disabled}, - {"include-subkeys",1,&opt.keyserver_options.include_subkeys}, - {"keep-temp-files",0,&opt.keyserver_options.keep_temp_files}, - {"honor-http-proxy",1,&opt.keyserver_options.honor_http_proxy}, - {"broken-http-proxy",1,&opt.keyserver_options.broken_http_proxy}, - {"refresh-add-fake-v3-keyids",0,&opt.keyserver_options.fake_v3_keyids}, - {"auto-key-retrieve",0,&opt.keyserver_options.auto_key_retrieve}, - {"try-dns-srv",1,&opt.keyserver_options.try_dns_srv}, - {NULL} -}; - -static int keyserver_work(int action,STRLIST list, - KEYDB_SEARCH_DESC *desc,int count); - -void -parse_keyserver_options(char *options) -{ - char *tok; - - while((tok=strsep(&options," ,"))) - { - int i,hit=0; - - if(tok[0]=='\0') - continue; - - for(i=0;keyserver_opts[i].name;i++) - { - if(ascii_strcasecmp(tok,keyserver_opts[i].name)==0) - { - *(keyserver_opts[i].flag)=1; - hit=1; - break; - } - else if(ascii_strncasecmp("no-",tok,3)==0 && - ascii_strcasecmp(&tok[3],keyserver_opts[i].name)==0) - { - *(keyserver_opts[i].flag)=0; - hit=1; - break; - } - } - - /* These options need more than just a flag */ - if(!hit) - { - if(ascii_strcasecmp(tok,"verbose")==0) - opt.keyserver_options.verbose++; - else if(ascii_strcasecmp(tok,"no-verbose")==0) - opt.keyserver_options.verbose--; -#ifdef EXEC_TEMPFILE_ONLY - else if(ascii_strcasecmp(tok,"use-temp-files")==0 || - ascii_strcasecmp(tok,"no-use-temp-files")==0) - log_info(_("WARNING: keyserver option \"%s\" is not used " - "on this platform\n"),tok); -#else - else if(ascii_strcasecmp(tok,"use-temp-files")==0) - opt.keyserver_options.use_temp_files=1; - else if(ascii_strcasecmp(tok,"no-use-temp-files")==0) - opt.keyserver_options.use_temp_files=0; -#endif - else - if(!parse_import_options(tok, - &opt.keyserver_options.import_options) && - !parse_export_options(tok, - &opt.keyserver_options.export_options)) - add_to_strlist(&opt.keyserver_options.other,tok); - } - } -} - -int -parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno) -{ - int assume_hkp=0; - - assert(uri!=NULL); - - opt.keyserver_host=NULL; - opt.keyserver_port=NULL; - opt.keyserver_opaque=NULL; - - /* Get the scheme */ - - opt.keyserver_scheme=strsep(&uri,":"); - if(uri==NULL) - { - /* Assume HKP if there is no scheme */ - assume_hkp=1; - uri=opt.keyserver_scheme; - opt.keyserver_scheme="hkp"; - } - else - { - /* Force to lowercase */ - char *i; - - for(i=opt.keyserver_scheme;*i!='\0';i++) - *i=ascii_tolower(*i); - } - - if(ascii_strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0) - { - deprecated_warning(configname,configlineno,"x-broken-hkp", - "--keyserver-options ","broken-http-proxy"); - opt.keyserver_scheme="hkp"; - opt.keyserver_options.broken_http_proxy=1; - } - else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0 - || ascii_strcasecmp(opt.keyserver_scheme,"http")==0) - { - /* Canonicalize this to "hkp" so it works with both the internal - and external keyserver interface. */ - opt.keyserver_scheme="hkp"; - } - - if(assume_hkp || (uri[0]=='/' && uri[1]=='/')) - { - /* Two slashes means network path. */ - - /* Skip over the "//", if any */ - if(!assume_hkp) - uri+=2; - - /* Get the host */ - opt.keyserver_host=strsep(&uri,":/"); - if(opt.keyserver_host[0]=='\0') - return GPG_ERR_BAD_URI; - - if(uri==NULL || uri[0]=='\0') - opt.keyserver_port=NULL; - else - { - char *ch; - - /* Get the port */ - opt.keyserver_port=strsep(&uri,"/"); - - /* Ports are digits only */ - ch=opt.keyserver_port; - while(*ch!='\0') - { - if(!digitp(ch)) - return GPG_ERR_BAD_URI; - - ch++; - } - - /* It would seem to be reasonable to limit the range of the - ports to values between 1-65535, but RFC 1738 and 1808 - imply there is no limit. Of course, the real world has - limits. */ - } - - /* (any path part of the URI is discarded for now as no keyserver - uses it yet) */ - } - else if(uri[0]!='/') - { - /* No slash means opaque. Just record the opaque blob and get - out. */ - opt.keyserver_opaque=uri; - return 0; - } - else - { - /* One slash means absolute path. We don't need to support that - yet. */ - return GPG_ERR_BAD_URI; - } - - if(opt.keyserver_scheme[0]=='\0') - return GPG_ERR_BAD_URI; - - return 0; -} - -static void -print_keyrec(int number,struct keyrec *keyrec) -{ - int i; - - iobuf_writebyte(keyrec->uidbuf,0); - iobuf_flush_temp(keyrec->uidbuf); - printf("(%d)\t%s ",number,iobuf_get_temp_buffer(keyrec->uidbuf)); - - if(keyrec->size>0) - printf("%d bit ",keyrec->size); - - if(keyrec->type) - { - const char *str = gcry_pk_algo_name (keyrec->type); - - if(str) - printf("%s ",str); - else - printf("unknown "); - } - - switch(keyrec->desc.mode) - { - case KEYDB_SEARCH_MODE_SHORT_KID: - printf("key %08lX",(ulong)keyrec->desc.u.kid[1]); - break; - - case KEYDB_SEARCH_MODE_LONG_KID: - printf("key %08lX%08lX",(ulong)keyrec->desc.u.kid[0], - (ulong)keyrec->desc.u.kid[1]); - break; - - case KEYDB_SEARCH_MODE_FPR16: - printf("key "); - for(i=0;i<16;i++) - printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]); - break; - - case KEYDB_SEARCH_MODE_FPR20: - printf("key "); - for(i=0;i<20;i++) - printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]); - break; - - default: - BUG(); - break; - } - - if(keyrec->createtime>0) - printf(", created %s",strtimestamp(keyrec->createtime)); - - if(keyrec->expiretime>0) - printf(", expires %s",strtimestamp(keyrec->expiretime)); - - if(keyrec->flags&1) - printf(" (%s)",("revoked")); - if(keyrec->flags&2) - printf(" (%s)",("disabled")); - if(keyrec->flags&4) - printf(" (%s)",("expired")); - - printf("\n"); -} - -/* Returns a keyrec (which must be freed) once a key is complete, and - NULL otherwise. Call with a NULL keystring once key parsing is - complete to return any unfinished keys. */ -static struct keyrec * -parse_keyrec(char *keystring) -{ - static struct keyrec *work=NULL; - struct keyrec *ret=NULL; - char *record; - int i; - - if(keystring==NULL) - { - if(work==NULL) - return NULL; - else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE) - { - xfree (work); - return NULL; - } - else - { - ret=work; - work=NULL; - return ret; - } - } - - if(work==NULL) - { - work=xcalloc (1,sizeof(struct keyrec)); - work->uidbuf=iobuf_temp(); - } - - /* Remove trailing whitespace */ - for(i=strlen(keystring);i>0;i--) - if(ascii_isspace(keystring[i-1])) - keystring[i-1]='\0'; - else - break; - - if((record=strsep(&keystring,":"))==NULL) - return ret; - - if(ascii_strcasecmp("pub",record)==0) - { - char *tok; - - if(work->desc.mode) - { - ret=work; - work=xcalloc (1,sizeof(struct keyrec)); - work->uidbuf=iobuf_temp(); - } - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - classify_user_id(tok,&work->desc); - if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID - && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID - && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16 - && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20) - { - work->desc.mode=KEYDB_SEARCH_MODE_NONE; - return ret; - } - - /* Note all items after this are optional. This allows us to - have a pub line as simple as pub:keyid and nothing else. */ - - work->lines++; - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->type=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->size=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->createtime=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - work->expiretime=atoi(tok); - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - while(*tok) - switch(*tok++) - { - case 'r': - case 'R': - work->flags|=1; - break; - - case 'd': - case 'D': - work->flags|=2; - break; - - case 'e': - case 'E': - work->flags|=4; - break; - } - - if(work->expiretime && work->expiretime<=make_timestamp()) - work->flags|=4; - } - else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode) - { - char *userid,*tok,*decoded; - - if((tok=strsep(&keystring,":"))==NULL) - return ret; - - if(strlen(tok)==0) - return ret; - - userid=tok; - - /* By definition, de-%-encoding is always smaller than the - original string so we can decode in place. */ - - i=0; - - while(*tok) - if(tok[0]=='%' && tok[1] && tok[2]) - { - if((userid[i]=hextobyte(&tok[1]))==-1) - userid[i]='?'; - - i++; - tok+=3; - } - else - userid[i++]=*tok++; - - /* We don't care about the other info provided in the uid: line - since no keyserver supports marking userids with timestamps - or revoked/expired/disabled yet. */ - - /* No need to check for control characters, as utf8_to_native - does this for us. */ - - decoded=utf8_to_native(userid,i,0); - iobuf_writestr(work->uidbuf,decoded); - xfree (decoded); - iobuf_writestr(work->uidbuf,"\n\t"); - work->lines++; - } - - /* Ignore any records other than "pri" and "uid" for easy future - growth. */ - - return ret; -} - -/* TODO: do this as a list sent to keyserver_work rather than calling - it once for each key to get the correct counts after the import - (cosmetics, really) and to better take advantage of the keyservers - that can do multiple fetches in one go (LDAP). */ -static int -show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) -{ - char *answer; - - if(count && opt.command_fd==-1) - { - static int from=1; - tty_printf("Keys %d-%d of %d for \"%s\". ",from,numdesc,count,search); - from=numdesc+1; - } - - answer=cpr_get_no_help("keysearch.prompt", - _("Enter number(s), N)ext, or Q)uit > ")); - /* control-d */ - if(answer[0]=='\x04') - { - printf("Q\n"); - answer[0]='q'; - } - - if(answer[0]=='q' || answer[0]=='Q') - { - xfree (answer); - return 1; - } - else if(atoi(answer)>=1 && atoi(answer)<=numdesc) - { - char *split=answer,*num; - - while((num=strsep(&split," ,"))!=NULL) - if(atoi(num)>=1 && atoi(num)<=numdesc) - keyserver_work(GET,NULL,&desc[atoi(num)-1],1); - - xfree (answer); - return 1; - } - - return 0; -} - -/* Count and searchstr are just for cosmetics. If the count is too - small, it will grow safely. If negative it disables the "Key x-y - of z" messages. */ -static void -keyserver_search_prompt(iobuf_t buffer,const char *searchstr) -{ - int i=0,validcount=0,started=0,header=0,count=1; - unsigned int maxlen,buflen; - KEYDB_SEARCH_DESC *desc; - byte *line=NULL; - /* TODO: Something other than 23? That's 24-1 (the prompt). */ - int maxlines=23,numlines=0; - - desc=xmalloc (count*sizeof(KEYDB_SEARCH_DESC)); - - for(;;) - { - struct keyrec *keyrec; - int rl; - - maxlen=1024; - rl=iobuf_read_line(buffer,&line,&buflen,&maxlen); - - if(opt.with_colons) - { - if(!header && ascii_strncasecmp("SEARCH ",line,7)==0 - && ascii_strncasecmp(" BEGIN",&line[strlen(line)-7],6)==0) - { - header=1; - continue; - } - else if(ascii_strncasecmp("SEARCH ",line,7)==0 - && ascii_strncasecmp(" END",&line[strlen(line)-5],4)==0) - continue; - - printf("%s",line); - } - - /* Look for an info: line. The only current info: values - defined are the version and key count. */ - if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0) - { - char *tok,*str=&line[5]; - - if((tok=strsep(&str,":"))!=NULL) - { - int version; - - if(sscanf(tok,"%d",&version)!=1) - version=1; - - if(version!=1) - { - log_error(_("invalid keyserver protocol " - "(us %d!=handler %d)\n"),1,version); - break; - } - } - - if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1) - { - if(count==0) - goto notfound; - else if(count<0) - count=10; - else - validcount=1; - - desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC)); - } - - started=1; - continue; - } - - if(rl==0) - { - keyrec=parse_keyrec(NULL); - - if(keyrec==NULL) - { - if(i==0) - { - count=0; - break; - } - - if(i!=count) - validcount=0; - - for(;;) - { - if(show_prompt(desc,i,validcount?count:0,searchstr)) - break; - validcount=0; - } - - break; - } - } - else - keyrec=parse_keyrec(line); - - if(i==count) - { - /* keyserver helper sent more keys than they claimed in the - info: line. */ - count+=10; - desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC)); - validcount=0; - } - - if(keyrec) - { - desc[i]=keyrec->desc; - - if(!opt.with_colons) - { - if(numlines+keyrec->lines>maxlines) - { - if(show_prompt(desc,i,validcount?count:0,searchstr)) - break; - else - numlines=0; - } - - print_keyrec(i+1,keyrec); - } - - numlines+=keyrec->lines; - iobuf_close(keyrec->uidbuf); - xfree (keyrec); - - started=1; - i++; - } - } - - xfree (desc); - xfree (line); - - notfound: - if(count==0) - { - if(searchstr) - log_info(_("key \"%s\" not found on keyserver\n"),searchstr); - else - log_info(_("key not found on keyserver\n")); - return; - } -} - -#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\"" -#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" - -static int -keyserver_spawn(int action,STRLIST list, - KEYDB_SEARCH_DESC *desc,int count,int *prog) -{ - int ret=0,i,gotversion=0,outofband=0; - STRLIST temp; - unsigned int maxlen,buflen; - char *command=NULL,*searchstr=NULL; - byte *line=NULL; - struct kopts *kopts; - struct exec_info *spawn; - -#ifdef EXEC_TEMPFILE_ONLY - opt.keyserver_options.use_temp_files=1; -#endif - - /* Push the libexecdir into path. If DISABLE_KEYSERVER_PATH is set, - use the 0 arg to replace the path. */ -#ifdef DISABLE_KEYSERVER_PATH - set_exec_path(GNUPG_LIBEXECDIR,0); -#else - set_exec_path(GNUPG_LIBEXECDIR,opt.exec_path_set); -#endif - - /* Build the filename for the helper to execute */ - command=xmalloc (strlen("gpgkeys_")+strlen(opt.keyserver_scheme)+1); - strcpy(command,"gpgkeys_"); - strcat(command,opt.keyserver_scheme); - - if(opt.keyserver_options.use_temp_files) - { - if(opt.keyserver_options.keep_temp_files) - { - command=xrealloc(command,strlen(command)+ - strlen(KEYSERVER_ARGS_KEEP)+1); - strcat(command,KEYSERVER_ARGS_KEEP); - } - else - { - command=xrealloc(command,strlen(command)+ - strlen(KEYSERVER_ARGS_NOKEEP)+1); - strcat(command,KEYSERVER_ARGS_NOKEEP); - } - - ret=exec_write(&spawn,NULL,command,NULL,0,0); - } - else - ret=exec_write(&spawn,command,NULL,NULL,0,0); - - if(ret) - return ret; - - fprintf(spawn->tochild,"# This is a gpg keyserver communications file\n"); - fprintf(spawn->tochild,"VERSION %d\n",KEYSERVER_PROTO_VERSION); - fprintf(spawn->tochild,"PROGRAM %s\n",VERSION); - - if(opt.keyserver_opaque) - fprintf(spawn->tochild,"OPAQUE %s\n",opt.keyserver_opaque); - else - { - if(opt.keyserver_host) - fprintf(spawn->tochild,"HOST %s\n",opt.keyserver_host); - - if(opt.keyserver_port) - fprintf(spawn->tochild,"PORT %s\n",opt.keyserver_port); - } - - /* Write options */ - - for(i=0,kopts=keyserver_opts;kopts[i].name;i++) - if(*(kopts[i].flag) && kopts[i].tell) - fprintf(spawn->tochild,"OPTION %s\n",kopts[i].name); - - for(i=0;i<opt.keyserver_options.verbose;i++) - fprintf(spawn->tochild,"OPTION verbose\n"); - - temp=opt.keyserver_options.other; - - for(;temp;temp=temp->next) - fprintf(spawn->tochild,"OPTION %s\n",temp->d); - - switch(action) - { - case GET: - { - fprintf(spawn->tochild,"COMMAND GET\n\n"); - - /* Which keys do we want? */ - - for(i=0;i<count;i++) - { - if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20) - { - int f; - - fprintf(spawn->tochild,"0x"); - - for(f=0;f<MAX_FINGERPRINT_LEN;f++) - fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]); - - fprintf(spawn->tochild,"\n"); - } - else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16) - { - int f; - - fprintf(spawn->tochild,"0x"); - - for(f=0;f<16;f++) - fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]); - - fprintf(spawn->tochild,"\n"); - } - else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID) - fprintf(spawn->tochild,"0x%08lX%08lX\n", - (ulong)desc[i].u.kid[0], - (ulong)desc[i].u.kid[1]); - else - fprintf(spawn->tochild,"0x%08lX\n", - (ulong)desc[i].u.kid[1]); - } - - fprintf(spawn->tochild,"\n"); - - break; - } - - case SEND: - { - STRLIST key; - - /* Note the extra \n here to send an empty keylist block */ - fprintf(spawn->tochild,"COMMAND SEND\n\n\n"); - - for(key=list;key!=NULL;key=key->next) - { - armor_filter_context_t afx; - iobuf_t buffer=iobuf_temp(); - KBNODE block; - - temp=NULL; - add_to_strlist(&temp,key->d); - - memset(&afx,0,sizeof(afx)); - afx.what=1; - iobuf_push_filter(buffer,armor_filter,&afx); - - /* TODO: Don't use the keyblock hack here - instead, - output each key as a different ascii armored blob with - its own INFO section. */ - - if(export_pubkeys_stream(buffer,temp,&block, - opt.keyserver_options.export_options)==-1) - iobuf_close(buffer); - else - { - KBNODE node; - - iobuf_flush_temp(buffer); - - merge_keys_and_selfsig(block); - - fprintf(spawn->tochild,"INFO %s BEGIN\n",key->d); - - for(node=block;node;node=node->next) - { - switch(node->pkt->pkttype) - { - default: - continue; - - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - { - PKT_public_key *pk=node->pkt->pkt.public_key; - - keyid_from_pk(pk,NULL); - - fprintf(spawn->tochild,"%sb:%08lX%08lX:%u:%u:%u:%u:", - node->pkt->pkttype==PKT_PUBLIC_KEY?"pu":"su", - (ulong)pk->keyid[0],(ulong)pk->keyid[1], - pk->pubkey_algo, - nbits_from_pk(pk), - pk->timestamp, - pk->expiredate); - - if(pk->is_revoked) - fprintf(spawn->tochild,"r"); - if(pk->has_expired) - fprintf(spawn->tochild,"e"); - - fprintf(spawn->tochild,"\n"); - - break; - } - - case PKT_USER_ID: - { - PKT_user_id *uid=node->pkt->pkt.user_id; - int r; - - if(uid->attrib_data) - continue; - - fprintf(spawn->tochild,"uid:"); - - /* Quote ':', '%', and any 8-bit - characters */ - for(r=0;r<uid->len;r++) - { - if(uid->name[r]==':' || uid->name[r]=='%' - || uid->name[r]&0x80) - fprintf(spawn->tochild,"%%%02X",uid->name[r]); - else - fprintf(spawn->tochild,"%c",uid->name[r]); - } - - fprintf(spawn->tochild,":%u:%u:", - uid->created,uid->expiredate); - - if(uid->is_revoked) - fprintf(spawn->tochild,"r"); - if(uid->is_expired) - fprintf(spawn->tochild,"e"); - - fprintf(spawn->tochild,"\n"); - } - } - } - - fprintf(spawn->tochild,"INFO %s END\n",key->d); - - fprintf(spawn->tochild,"KEY %s BEGIN\n",key->d); - fwrite(iobuf_get_temp_buffer(buffer), - iobuf_get_temp_length(buffer),1,spawn->tochild); - fprintf(spawn->tochild,"KEY %s END\n",key->d); - - iobuf_close(buffer); - release_kbnode(block); - } - - free_strlist(temp); - } - - break; - } - - case SEARCH: - { - STRLIST key; - - fprintf(spawn->tochild,"COMMAND SEARCH\n\n"); - - /* Which keys do we want? Remember that the gpgkeys_ program - is going to lump these together into a search string. */ - - for(key=list;key!=NULL;key=key->next) - { - fprintf(spawn->tochild,"%s\n",key->d); - if(key!=list) - { - searchstr=xrealloc(searchstr, - strlen(searchstr)+strlen(key->d)+2); - strcat(searchstr," "); - } - else - { - searchstr=xmalloc (strlen(key->d)+1); - searchstr[0]='\0'; - } - - strcat(searchstr,key->d); - } - - fprintf(spawn->tochild,"\n"); - - break; - } - - default: - log_fatal(_("no keyserver action!\n")); - break; - } - - /* Done sending, so start reading. */ - ret=exec_read(spawn); - if(ret) - goto fail; - - /* Now handle the response */ - - for(;;) - { - int plen; - char *ptr; - - maxlen=1024; - if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0) - { - ret = iobuf_error (spawn->fromchild); - goto fail; /* i.e. EOF */ - } - - ptr=line; - - /* remove trailing whitespace */ - plen=strlen(ptr); - while(plen>0 && ascii_isspace(ptr[plen-1])) - plen--; - plen[ptr]='\0'; - - if(*ptr=='\0') - break; - - if(ascii_strncasecmp(ptr,"VERSION ",8)==0) - { - gotversion=1; - - if(atoi(&ptr[8])!=KEYSERVER_PROTO_VERSION) - { - log_error(_("invalid keyserver protocol (us %d!=handler %d)\n"), - KEYSERVER_PROTO_VERSION,atoi(&ptr[8])); - goto fail; - } - } - else if(ascii_strncasecmp(ptr,"PROGRAM ",8)==0) - { - if(ascii_strncasecmp(&ptr[8],VERSION,strlen(VERSION))!=0) - log_info(_("WARNING: keyserver handler from a different " - "version of GnuPG (%s)\n"),&ptr[8]); - } - else if(ascii_strncasecmp(ptr,"OPTION OUTOFBAND",16)==0) - outofband=1; /* Currently the only OPTION */ - } - - if(!gotversion) - { - log_error(_("keyserver did not send VERSION\n")); - goto fail; - } - - if(!outofband) - switch(action) - { - case GET: - { - void *stats_handle; - - stats_handle=import_new_stats_handle(); - - /* Slurp up all the key data. In the future, it might be - nice to look for KEY foo OUTOFBAND and FAILED indicators. - It's harmless to ignore them, but ignoring them does make - gpg complain about "no valid OpenPGP data found". One - way to do this could be to continue parsing this - line-by-line and make a temp iobuf for each key. */ - - import_keys_stream(spawn->fromchild,stats_handle, - opt.keyserver_options.import_options); - - import_print_stats(stats_handle); - import_release_stats_handle(stats_handle); - - break; - } - - /* Nothing to do here */ - case SEND: - break; - - case SEARCH: - { - keyserver_search_prompt(spawn->fromchild,searchstr); - - break; - } - - default: - log_fatal(_("no keyserver action!\n")); - break; - } - - fail: - xfree (line); - - *prog=exec_finish(spawn); - - return ret; -} - -static int -keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count) -{ - int rc=0,ret=0; - - if(opt.keyserver_scheme==NULL) - { - log_error(_("no keyserver known (use option --keyserver)\n")); - return GPG_ERR_BAD_URI; - } - -#ifdef DISABLE_KEYSERVER_HELPERS - - log_error(_("external keyserver calls are not supported in this build\n")); - return GPG_ERR_KEYSERVER; - -#else - /* Spawn a handler */ - - rc=keyserver_spawn(action,list,desc,count,&ret); - if(ret) - { - switch(ret) - { - case KEYSERVER_SCHEME_NOT_FOUND: - log_error(_("no handler for keyserver scheme \"%s\"\n"), - opt.keyserver_scheme); - break; - - case KEYSERVER_NOT_SUPPORTED: - log_error(_("action \"%s\" not supported with keyserver " - "scheme \"%s\"\n"), - action==GET?"get":action==SEND?"send": - action==SEARCH?"search":"unknown", - opt.keyserver_scheme); - break; - - case KEYSERVER_VERSION_ERROR: - log_error(_("gpgkeys_%s does not support handler version %d\n"), - opt.keyserver_scheme,KEYSERVER_PROTO_VERSION); - break; - - case KEYSERVER_INTERNAL_ERROR: - default: - log_error(_("keyserver internal error\n")); - break; - } - - return GPG_ERR_KEYSERVER; - } - - if(rc) - { - log_error(_("keyserver communications error: %s\n"),gpg_strerror (rc)); - - return rc; - } - - return 0; -#endif /* ! DISABLE_KEYSERVER_HELPERS*/ -} - -int -keyserver_export(STRLIST users) -{ - /* We better ask for confirmation when the user entered --send-keys - without arguments. Sending all keys might not be the thing he - intended to do */ - if (users || opt.batch || opt.answer_yes) - ; - else if ( !cpr_get_answer_is_yes - ("keyserver_export.send_all", - _("Do you really want to send all your " - "public keys to the keyserver? (y/N) "))) - return -1; - - return keyserver_work(SEND,users,NULL,0); -} - -int -keyserver_import(STRLIST users) -{ - KEYDB_SEARCH_DESC *desc; - int num=100,count=0; - int rc=0; - - /* Build a list of key ids */ - desc=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num); - - for(;users;users=users->next) - { - classify_user_id (users->d, &desc[count]); - if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID && - desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID && - desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 && - desc[count].mode!=KEYDB_SEARCH_MODE_FPR20) - { - log_error(_("skipping invalid key ID \"%s\"\n"),users->d); - continue; - } - - count++; - if(count==num) - { - num+=100; - desc=xrealloc(desc,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - - if(count>0) - rc=keyserver_work(GET,NULL,desc,count); - - xfree (desc); - - return rc; -} - -int -keyserver_import_fprint(const byte *fprint,size_t fprint_len) -{ - KEYDB_SEARCH_DESC desc; - - memset(&desc,0,sizeof(desc)); - - if(fprint_len==16) - desc.mode=KEYDB_SEARCH_MODE_FPR16; - else if(fprint_len==20) - desc.mode=KEYDB_SEARCH_MODE_FPR20; - else - return -1; - - memcpy(desc.u.fpr,fprint,fprint_len); - - return keyserver_work(GET,NULL,&desc,1); -} - -int -keyserver_import_keyid(u32 *keyid) -{ - KEYDB_SEARCH_DESC desc; - - memset(&desc,0,sizeof(desc)); - - desc.mode=KEYDB_SEARCH_MODE_LONG_KID; - desc.u.kid[0]=keyid[0]; - desc.u.kid[1]=keyid[1]; - - return keyserver_work(GET,NULL,&desc,1); -} - -/* code mostly stolen from do_export_stream */ -static int -keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) -{ - int rc=0,ndesc,num=100; - KBNODE keyblock=NULL,node; - KEYDB_HANDLE kdbhd; - KEYDB_SEARCH_DESC *desc; - STRLIST sl; - - *count=0; - - *klist=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num); - - kdbhd=keydb_new(0); - - if(!users) - { - ndesc = 1; - desc = xcalloc (1, ndesc * sizeof *desc); - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - } - else - { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) - ; - desc = xmalloc ( ndesc * sizeof *desc); - - for (ndesc=0, sl=users; sl; sl = sl->next) - { - if(classify_user_id (sl->d, desc+ndesc)) - ndesc++; - else - log_error (_("key `%s' not found: %s\n"), - sl->d, gpg_strerror (GPG_ERR_INV_USER_ID)); - } - } - - while (!(rc = keydb_search (kdbhd, desc, ndesc))) - { - if (!users) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - /* read the keyblock */ - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) - { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY))) - { - /* This is to work around a bug in some keyservers (pksd and - OKS) that calculate v4 RSA keyids as if they were v3 RSA. - The answer is to refresh both the correct v4 keyid - (e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7). - This only happens for key refresh using the HKP scheme - and if the refresh-add-fake-v3-keyids keyserver option is - set. */ - if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) && - node->pkt->pkt.public_key->version>=4) - { - (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - v3_keyid (node->pkt->pkt.public_key->pkey[0], - (*klist)[*count].u.kid); - (*count)++; - - if(*count==num) - { - num+=100; - *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - - /* v4 keys get full fingerprints. v3 keys get long keyids. - This is because it's easy to calculate any sort of key id - from a v4 fingerprint, but not a v3 fingerprint. */ - - if(node->pkt->pkt.public_key->version<4) - { - (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - keyid_from_pk(node->pkt->pkt.public_key, - (*klist)[*count].u.kid); - } - else - { - size_t dummy; - - (*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20; - fingerprint_from_pk(node->pkt->pkt.public_key, - (*klist)[*count].u.fpr,&dummy); - } - - (*count)++; - - if(*count==num) - { - num+=100; - *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - } - - if(rc==-1) - rc=0; - - leave: - xfree (desc); - keydb_release(kdbhd); - release_kbnode(keyblock); - - return rc; -} - -/* Note this is different than the original HKP refresh. It allows - usernames to refresh only part of the keyring. */ - -int -keyserver_refresh(STRLIST users) -{ - int rc,count,fakev3=0; - KEYDB_SEARCH_DESC *desc; - - /* We switch merge_only on during a refresh, as 'refresh' should - never import new keys, even if their keyids match. Is it worth - preserving the old merge_only value here? */ - opt.merge_only=1; - - /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO - scheme, then enable fake v3 keyid generation. */ - if(opt.keyserver_options.fake_v3_keyids && opt.keyserver_scheme && - (ascii_strcasecmp(opt.keyserver_scheme,"hkp")==0 || - ascii_strcasecmp(opt.keyserver_scheme,"mailto")==0)) - fakev3=1; - - rc=keyidlist(users,&desc,&count,fakev3); - if(rc) - return rc; - - if(count>0) - { - if(opt.keyserver_uri) - { - if(count==1) - log_info(_("refreshing 1 key from %s\n"),opt.keyserver_uri); - else - log_info(_("refreshing %d keys from %s\n"), - count,opt.keyserver_uri); - } - - rc=keyserver_work(GET,NULL,desc,count); - } - - xfree (desc); - - return rc; -} - -int -keyserver_search(STRLIST tokens) -{ - if(tokens) - return keyserver_work(SEARCH,tokens,NULL,0); - else - return 0; -} diff --git a/g10/main.h b/g10/main.h deleted file mode 100644 index 52bfa7659..000000000 --- a/g10/main.h +++ /dev/null @@ -1,272 +0,0 @@ -/* main.h - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_MAIN_H -#define G10_MAIN_H -#include "types.h" -#include "gpg.h" -#include "../common/iobuf.h" -#include "mpi.h" -#include "cipher.h" -#include "keydb.h" - -/* It could be argued that the default cipher should be 3DES rather - than CAST5, and the default compression should be 0 - (i.e. uncompressed) rather than 1 (zip). */ -#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5 -#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1 -#define DEFAULT_COMPRESS_ALGO 1 - -typedef struct { - int header_okay; - PK_LIST pk_list; - cipher_filter_context_t cfx; -} encrypt_filter_context_t; - -struct groupitem -{ - char *name; - STRLIST values; - struct groupitem *next; -}; - -/*-- g10.c --*/ -extern int g10_errors_seen; - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) - void g10_exit(int rc) __attribute__ ((noreturn)); -#else - void g10_exit(int rc); -#endif -void print_pubkey_algo_note( int algo ); -void print_cipher_algo_note( int algo ); -void print_digest_algo_note( int algo ); - -/*-- armor.c --*/ -char *make_radix64_string( const byte *data, size_t len ); - -/*-- misc.c --*/ -void trap_unaligned(void); -int disable_core_dumps(void); -u16 checksum_u16( unsigned n ); -u16 checksum( byte *p, unsigned n ); -u16 checksum_mpi( gcry_mpi_t a ); -u32 buffer_to_u32( const byte *buffer ); -const byte *get_session_marker( size_t *rlen ); -int openpgp_cipher_test_algo( int algo ); -int openpgp_pk_test_algo( int algo, unsigned int usage_flags ); -int openpgp_pk_algo_usage ( int algo ); -int openpgp_md_test_algo( int algo ); -int openpgp_md_map_name (const char *string); -int openpgp_cipher_map_name (const char *string); -int openpgp_pk_map_name (const char *string); - -#ifdef USE_IDEA -void idea_cipher_warn( int show ); -#else -#define idea_cipher_warn(a) -#endif - -struct expando_args -{ - PKT_public_key *pk; - PKT_secret_key *sk; - byte imagetype; -}; - -char *pct_expando(const char *string,struct expando_args *args); -int hextobyte( const char *s ); -void deprecated_warning(const char *configname,unsigned int configlineno, - const char *option,const char *repl1,const char *repl2); -const char *compress_algo_to_string(int algo); -int string_to_compress_algo(const char *string); -int check_compress_algo(int algo); -int default_cipher_algo(void); -int default_compress_algo(void); -const char *compliance_option_string(void); -void compliance_failure(void); - -struct parse_options -{ - char *name; - unsigned int bit; -}; - -int parse_options(char *str,unsigned int *options,struct parse_options *opts); - - -/* Temporary helpers. */ -int pubkey_get_npkey( int algo ); -int pubkey_get_nskey( int algo ); -int pubkey_get_nsig( int algo ); -int pubkey_get_nenc( int algo ); -unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); - -/* MPI helpers. */ -int mpi_write( iobuf_t out, gcry_mpi_t a ); -int mpi_write_opaque( iobuf_t out, gcry_mpi_t a ); -gcry_mpi_t mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure ); -gcry_mpi_t mpi_read_opaque(iobuf_t inp, unsigned int *ret_nread ); -int mpi_print( FILE *fp, gcry_mpi_t a, int mode ); - - - - -/*-- helptext.c --*/ -void display_online_help( const char *keyword ); - -/*-- encode.c --*/ -int encode_symmetric( const char *filename ); -int encode_store( const char *filename ); -int encode_crypt( const char *filename, STRLIST remusr ); -void encode_crypt_files(int nfiles, char **files, STRLIST remusr); -int encrypt_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len); - - -/*-- sign.c --*/ -int complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md ); -int sign_file( STRLIST filenames, int detached, STRLIST locusr, - int do_encrypt, STRLIST remusr, const char *outfile ); -int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); -int sign_symencrypt_file (const char *fname, STRLIST locusr); - -/*-- sig-check.c --*/ -int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig); -int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); -int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, - PKT_public_key *ret_pk, int *is_selfsig, - u32 *r_expiredate, int *r_expired ); - -/*-- delkey.c --*/ -int delete_keys( STRLIST names, int secret, int allow_both ); - -/*-- keyedit.c --*/ -void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds, - int sign_mode ); -void show_basic_key_info (KBNODE keyblock); - -/*-- keygen.c --*/ -u32 ask_expire_interval(int object); -u32 ask_expiredate(void); -void generate_keypair( const char *fname, const char *card_serialno ); -int keygen_set_std_prefs (const char *string,int personal); -PKT_user_id *keygen_get_std_prefs (void); -int keygen_add_key_expire( PKT_signature *sig, void *opaque ); -int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); -int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ); -int keygen_add_keyserver_url(PKT_signature *sig, void *opaque); -int keygen_add_revkey(PKT_signature *sig, void *opaque); -int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ); - -/*-- openfile.c --*/ -int overwrite_filep( const char *fname ); -char *make_outfile_name( const char *iname ); -char *ask_outfile_name( const char *name, size_t namelen ); -int open_outfile( const char *iname, int mode, iobuf_t *a ); -iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx ); -void try_make_homedir( const char *fname ); - -/*-- seskey.c --*/ -void make_session_key( DEK *dek ); -gcry_mpi_t encode_session_key( DEK *dek, unsigned int nbits); -gcry_mpi_t encode_md_value( int pubkey_algo, MD_HANDLE md, - int hash_algo, unsigned nbits, int v3compathack ); - -/*-- comment.c --*/ -KBNODE make_comment_node_from_buffer (const char *s, size_t n); -KBNODE make_comment_node( const char *s ); -KBNODE make_mpi_comment_node( const char *s, gcry_mpi_t a ); - -/*-- import.c --*/ -int parse_import_options(char *str,unsigned int *options); -void import_keys( char **fnames, int nnames, - void *stats_hd, unsigned int options ); -int import_keys_stream( iobuf_t inp, - void *stats_hd, unsigned int options ); -void *import_new_stats_handle (void); -void import_release_stats_handle (void *p); -void import_print_stats (void *hd); - -int collapse_uids( KBNODE *keyblock ); - -/*-- export.c --*/ -int parse_export_options(char *str,unsigned int *options); -int export_pubkeys( STRLIST users, unsigned int options ); -int export_pubkeys_stream( iobuf_t out, STRLIST users, - KBNODE *keyblock_out, unsigned int options ); -int export_seckeys( STRLIST users ); -int export_secsubkeys( STRLIST users ); - -/* dearmor.c --*/ -int dearmor_file( const char *fname ); -int enarmor_file( const char *fname ); - -/*-- revoke.c --*/ -struct revocation_reason_info; -int gen_revoke( const char *uname ); -int gen_desig_revoke( const char *uname ); -int revocation_reason_build_cb( PKT_signature *sig, void *opaque ); -struct revocation_reason_info * - ask_revocation_reason( int key_rev, int cert_rev, int hint ); -void release_revocation_reason_info( struct revocation_reason_info *reason ); - -/*-- keylist.c --*/ -void public_key_list( STRLIST list ); -void secret_key_list( STRLIST list ); -void reorder_keyblock (KBNODE keyblock); -void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque ); -void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode); -void show_policy_url(PKT_signature *sig,int indent,int mode); -void show_keyserver_url(PKT_signature *sig,int indent,int mode); -void show_notation(PKT_signature *sig,int indent,int mode); -void dump_attribs(const PKT_user_id *uid, - PKT_public_key *pk,PKT_secret_key *sk); -void set_attrib_fd(int fd); -void print_seckey_info (PKT_secret_key *sk); -void print_pubkey_info (FILE *fp, PKT_public_key *pk); - -/*-- verify.c --*/ -void print_file_status( int status, const char *name, int what ); -int verify_signatures( int nfiles, char **files ); -int verify_files( int nfiles, char **files ); - -/*-- decrypt.c --*/ -int decrypt_message( const char *filename ); -void decrypt_messages(int nfiles, char **files); - -/*-- plaintext.c --*/ -int hash_datafiles( MD_HANDLE md, MD_HANDLE md2, - STRLIST files, const char *sigfilename, int textmode ); - -/*-- pipemode.c --*/ -void run_in_pipemode (void); - -/*-- card-util.c --*/ -void change_pin (int no); -void card_status (FILE *fp, char *serialnobuf, size_t serialnobuflen); -void card_edit (STRLIST commands); - -/*-- signal.c --*/ -void init_signals(void); -void pause_on_sigusr( int which ); -void block_all_signals(void); -void unblock_all_signals(void); - -#endif /*G10_MAIN_H*/ diff --git a/g10/mainproc.c b/g10/mainproc.c deleted file mode 100644 index 40b9bd20a..000000000 --- a/g10/mainproc.c +++ /dev/null @@ -1,1758 +0,0 @@ -/* mainproc.c - handle packets - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "options.h" -#include "util.h" -#include "cipher.h" -#include "keydb.h" -#include "filter.h" -#include "main.h" -#include "status.h" -#include "i18n.h" -#include "trustdb.h" -#include "keyserver-internal.h" -#include "photoid.h" - - -struct kidlist_item { - struct kidlist_item *next; - u32 kid[2]; - int pubkey_algo; - int reason; -}; - - - -/**************** - * Structure to hold the context - */ -typedef struct mainproc_context *CTX; -struct mainproc_context { - struct mainproc_context *anchor; /* may be useful in the future */ - PKT_public_key *last_pubkey; - PKT_secret_key *last_seckey; - PKT_user_id *last_user_id; - md_filter_context_t mfx; - int sigs_only; /* process only signatures and reject all other stuff */ - int encrypt_only; /* process only encrytion messages */ - STRLIST signed_data; - const char *sigfilename; - DEK *dek; - int last_was_session_key; - KBNODE list; /* the current list of packets */ - int have_data; - iobuf_t iobuf; /* used to get the filename etc. */ - int trustletter; /* temp usage in list_node */ - ulong local_id; /* ditto */ - struct kidlist_item *pkenc_list; /* list of encryption packets */ - struct { - int op; - int stop_now; - } pipemode; -}; - - -static int do_proc_packets( CTX c, iobuf_t a ); - -static void list_node( CTX c, KBNODE node ); -static void proc_tree( CTX c, KBNODE node ); - - -static void -release_list( CTX c ) -{ - if( !c->list ) - return; - proc_tree(c, c->list ); - release_kbnode( c->list ); - while( c->pkenc_list ) { - struct kidlist_item *tmp = c->pkenc_list->next; - xfree ( c->pkenc_list ); - c->pkenc_list = tmp; - } - c->pkenc_list = NULL; - c->list = NULL; - c->have_data = 0; - c->last_was_session_key = 0; - c->pipemode.op = 0; - c->pipemode.stop_now = 0; - xfree (c->dek); c->dek = NULL; -} - - -static int -add_onepass_sig( CTX c, PACKET *pkt ) -{ - KBNODE node; - - if( c->list ) { /* add another packet */ - /* We can only append another onepass packet if the list - * does contain only onepass packets */ - for( node=c->list; node && node->pkt->pkttype == PKT_ONEPASS_SIG; - node = node->next ) - ; - if( node ) { - /* this is not the case, so we flush the current thing and - * allow this packet to start a new verification thing */ - release_list( c ); - c->list = new_kbnode( pkt ); - } - else - add_kbnode( c->list, new_kbnode( pkt )); - } - else /* insert the first one */ - c->list = node = new_kbnode( pkt ); - - return 1; -} - - -static int -add_gpg_control( CTX c, PACKET *pkt ) -{ - if ( pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START ) { - /* New clear text signature. - * Process the last one and reset everything */ - release_list(c); - } - else if ( pkt->pkt.gpg_control->control == CTRLPKT_PIPEMODE ) { - /* Pipemode control packet */ - if ( pkt->pkt.gpg_control->datalen < 2 ) - log_fatal ("invalid pipemode control packet length\n"); - if (pkt->pkt.gpg_control->data[0] == 1) { - /* start the whole thing */ - assert ( !c->list ); /* we should be in a pretty virgin state */ - assert ( !c->pipemode.op ); - c->pipemode.op = pkt->pkt.gpg_control->data[1]; - } - else if (pkt->pkt.gpg_control->data[0] == 2) { - /* the signed material follows in a plaintext packet */ - assert ( c->pipemode.op == 'B' ); - } - else if (pkt->pkt.gpg_control->data[0] == 3) { - assert ( c->pipemode.op == 'B' ); - release_list (c); - /* and tell the outer loop to terminate */ - c->pipemode.stop_now = 1; - } - else - log_fatal ("invalid pipemode control packet code\n"); - return 0; /* no need to store the packet */ - } - - if( c->list ) /* add another packet */ - add_kbnode( c->list, new_kbnode( pkt )); - else /* insert the first one */ - c->list = new_kbnode( pkt ); - - return 1; -} - - - -static int -add_user_id( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("orphaned user ID\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - -static int -add_subkey( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("subkey w/o mainkey\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - -static int -add_ring_trust( CTX c, PACKET *pkt ) -{ - if( !c->list ) { - log_error("ring trust w/o key\n" ); - return 0; - } - add_kbnode( c->list, new_kbnode( pkt ) ); - return 1; -} - - -static int -add_signature( CTX c, PACKET *pkt ) -{ - KBNODE node; - - if( pkt->pkttype == PKT_SIGNATURE && !c->list ) { - /* This is the first signature for the following datafile. - * GPG does not write such packets; instead it always uses - * onepass-sig packets. The drawback of PGP's method - * of prepending the signature to the data is - * that it is not possible to make a signature from data read - * from stdin. (GPG is able to read PGP stuff anyway.) */ - node = new_kbnode( pkt ); - c->list = node; - return 1; - } - else if( !c->list ) - return 0; /* oops (invalid packet sequence)*/ - else if( !c->list->pkt ) - BUG(); /* so nicht */ - - /* add a new signature node id at the end */ - node = new_kbnode( pkt ); - add_kbnode( c->list, node ); - return 1; -} - -static void -symkey_decrypt_sesskey (DEK * dek, byte *sesskey, size_t slen) -{ - CIPHER_HANDLE hd; - int n; - - if (slen < 17 || slen > 33) - { - log_error ( _("weird size for an encrypted session key (%d)\n"), - (int)slen); - return; - } - /* we checked the DEK values before, so consider all errors as fatal */ - if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG(); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG(); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_decrypt (hd, sesskey, slen, NULL, 0); - gcry_cipher_close (hd); - /* check first byte (the cipher algo) */ - if (openpgp_cipher_test_algo (sesskey[0])) - { - log_error (_("invalid symkey algorithm detected (%d)\n"), - sesskey[0]); - return; - } - n = gcry_cipher_get_algo_keylen (sesskey[0]); - if (n > DIM(dek->key)) - BUG (); - /* now we replace the dek components with the real session key - to decrypt the contents of the sequencing packet. */ - dek->keylen = n; - dek->algo = sesskey[0]; - memcpy (dek->key, sesskey + 1, dek->keylen); - /*log_hexdump ("thekey", dek->key, dek->keylen);*/ -} - -static void -proc_symkey_enc( CTX c, PACKET *pkt ) -{ - PKT_symkey_enc *enc; - - enc = pkt->pkt.symkey_enc; - if (!enc) - log_error ("invalid symkey encrypted packet\n"); - else { - int algo = enc->cipher_algo; - const char *s; - - s = gcry_cipher_algo_name (algo); - if (s && *s) - log_info(_("%s encrypted data\n"), s ); - else - log_info(_("encrypted with unknown algorithm %d\n"), algo ); - - c->last_was_session_key = 2; - if ( opt.list_only ) - goto leave; - c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL ); - if (c->dek) - c->dek->algo_info_printed = 1; - if ( c->dek && enc->seskeylen ) - symkey_decrypt_sesskey( c->dek, enc->seskey, enc->seskeylen ); - } -leave: - free_packet(pkt); -} - -static void -proc_pubkey_enc( CTX c, PACKET *pkt ) -{ - PKT_pubkey_enc *enc; - int result = 0; - - /* check whether the secret key is available and store in this case */ - c->last_was_session_key = 1; - enc = pkt->pkt.pubkey_enc; - /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/ - /* Hmmm: why do I have this algo check here - anyway there is - * function to check it. */ - if( opt.verbose ) - log_info(_("public key is %08lX\n"), (ulong)enc->keyid[1] ); - - if( is_status_enabled() ) { - char buf[50]; - sprintf(buf, "%08lX%08lX %d 0", - (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo ); - write_status_text( STATUS_ENC_TO, buf ); - } - - if( !opt.list_only && opt.override_session_key ) { - /* It does not make much sense to store the session key in - * secure memory because it has already been passed on the - * command line and the GCHQ knows about it */ - c->dek = xcalloc (1, sizeof *c->dek ); - result = get_override_session_key ( c->dek, opt.override_session_key ); - if ( result ) { - xfree (c->dek); c->dek = NULL; - } - } - else if( is_ELGAMAL(enc->pubkey_algo) - || enc->pubkey_algo == PUBKEY_ALGO_DSA - || is_RSA(enc->pubkey_algo) ) { - if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1]) - || opt.try_all_secrets - || !seckey_available( enc->keyid )) ) { - if( opt.list_only ) - result = -1; - else { - c->dek = xcalloc_secure (1, sizeof *c->dek); - if( (result = get_session_key( enc, c->dek )) ) { - /* error: delete the DEK */ - xfree (c->dek); c->dek = NULL; - } - } - } - else - result = GPG_ERR_NO_SECKEY; - } - else - result = GPG_ERR_PUBKEY_ALGO; - - if( result == -1 ) - ; - else { - if( !result ) { - if( opt.verbose > 1 ) - log_info( _("public key encrypted data: good DEK\n") ); - if ( opt.show_session_key ) { - int i; - char *buf = xmalloc ( c->dek->keylen*2 + 20 ); - sprintf ( buf, "%d:", c->dek->algo ); - for(i=0; i < c->dek->keylen; i++ ) - sprintf(buf+strlen(buf), "%02X", c->dek->key[i] ); - log_info( "session key: \"%s\"\n", buf ); - write_status_text ( STATUS_SESSION_KEY, buf ); - } - } - /* store it for later display */ - { - struct kidlist_item *x = xmalloc ( sizeof *x ); - x->kid[0] = enc->keyid[0]; - x->kid[1] = enc->keyid[1]; - x->pubkey_algo = enc->pubkey_algo; - x->reason = result; - x->next = c->pkenc_list; - c->pkenc_list = x; - } - } - free_packet(pkt); -} - - - -/**************** - * Print the list of public key encrypted packets which we could - * not decrypt. - */ -static void -print_pkenc_list( struct kidlist_item *list, int failed ) -{ - for( ; list; list = list->next ) { - PKT_public_key *pk; - const char *algstr; - - if ( failed && !list->reason ) - continue; - if ( !failed && list->reason ) - continue; - - algstr = gcry_pk_algo_name (list->pubkey_algo); - pk = xcalloc (1, sizeof *pk ); - - if (!algstr || !*algstr) - algstr = "[?]"; - pk->pubkey_algo = list->pubkey_algo; - if( !get_pubkey( pk, list->kid ) ) { - size_t n; - char *p; - log_info( _("encrypted with %u-bit %s key, ID %08lX, created %s\n"), - nbits_from_pk( pk ), algstr, (ulong)list->kid[1], - strtimestamp(pk->timestamp) ); - fputs(" \"", log_get_stream() ); - p = get_user_id( list->kid, &n ); - print_utf8_string2 ( log_get_stream(), p, n, '"' ); - xfree (p); - fputs("\"\n", log_get_stream() ); - } - else { - log_info(_("encrypted with %s key, ID %08lX\n"), - algstr, (ulong) list->kid[1] ); - } - free_public_key( pk ); - - if( gpg_err_code (list->reason) == GPG_ERR_NO_SECKEY ) { - if( is_status_enabled() ) { - char buf[20]; - sprintf(buf,"%08lX%08lX", (ulong)list->kid[0], - (ulong)list->kid[1] ); - write_status_text( STATUS_NO_SECKEY, buf ); - } - } - else if (list->reason) - log_info(_("public key decryption failed: %s\n"), - gpg_strerror (list->reason)); - } -} - - -static void -proc_encrypted( CTX c, PACKET *pkt ) -{ - int result = 0; - - if (!opt.quiet) { - print_pkenc_list ( c->pkenc_list, 1 ); - print_pkenc_list ( c->pkenc_list, 0 ); - } - - write_status( STATUS_BEGIN_DECRYPTION ); - - /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/ - if( opt.list_only ) - result = -1; - else if( !c->dek && !c->last_was_session_key ) { - int algo; - STRING2KEY s2kbuf, *s2k = NULL; - - /* assume this is old style conventional encrypted data */ - if ( (algo = opt.def_cipher_algo)) - log_info (_("assuming %s encrypted data\n"), - gcry_cipher_algo_name (algo)); - else if ( gcry_cipher_test_algo(CIPHER_ALGO_IDEA) ) { - algo = opt.def_cipher_algo; - if (!algo) - algo = opt.s2k_cipher_algo; - idea_cipher_warn(1); - log_info (_("IDEA cipher unavailable, " - "optimistically attempting to use %s instead\n"), - gcry_cipher_algo_name (algo)); - } - else { - algo = CIPHER_ALGO_IDEA; - if (!opt.s2k_digest_algo) { - /* If no digest is given we assume MD5 */ - s2kbuf.mode = 0; - s2kbuf.hash_algo = GCRY_MD_MD5; - s2k = &s2kbuf; - } - log_info (_("assuming %s encrypted data\n"), "IDEA"); - } - - c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL ); - if (c->dek) - c->dek->algo_info_printed = 1; - } - else if( !c->dek ) - result = GPG_ERR_NO_SECKEY; - if( !result ) - result = decrypt_data( c, pkt->pkt.encrypted, c->dek ); - - xfree (c->dek); c->dek = NULL; - if( result == -1 ) - ; - else if( !result || (gpg_err_code (result)==GPG_ERR_BAD_SIGNATURE - && opt.ignore_mdc_error)) { - write_status( STATUS_DECRYPTION_OKAY ); - if( opt.verbose > 1 ) - log_info(_("decryption okay\n")); - if( pkt->pkt.encrypted->mdc_method && !result ) - write_status( STATUS_GOODMDC ); - else if(!opt.no_mdc_warn) - log_info (_("WARNING: message was not integrity protected\n")); - } - else if( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) { - log_error(_("WARNING: encrypted message has been manipulated!\n")); - write_status( STATUS_BADMDC ); - write_status( STATUS_DECRYPTION_FAILED ); - } - else { - write_status( STATUS_DECRYPTION_FAILED ); - log_error(_("decryption failed: %s\n"), gpg_strerror (result)); - /* Hmmm: does this work when we have encrypted using multiple - * ways to specify the session key (symmmetric and PK)*/ - } - free_packet(pkt); - c->last_was_session_key = 0; - write_status( STATUS_END_DECRYPTION ); -} - - - -static void -proc_plaintext( CTX c, PACKET *pkt ) -{ - PKT_plaintext *pt = pkt->pkt.plaintext; - int any, clearsig, only_md5, rc; - KBNODE n; - - if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) - log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n")); - else if( opt.verbose ) - log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name); - free_md_filter_context( &c->mfx ); - gcry_md_open (&c->mfx.md, 0, 0); - /* fixme: we may need to push the textfilter if we have sigclass 1 - * and no armoring - Not yet tested - * Hmmm, why don't we need it at all if we have sigclass 1 - * Should we assume that plaintext in mode 't' has always sigclass 1?? - * See: Russ Allbery's mail 1999-02-09 - */ - any = clearsig = only_md5 = 0; - for(n=c->list; n; n = n->next ) { - if( n->pkt->pkttype == PKT_ONEPASS_SIG ) { - if( n->pkt->pkt.onepass_sig->digest_algo ) { - gcry_md_enable ( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo ); - if( !any && n->pkt->pkt.onepass_sig->digest_algo - == DIGEST_ALGO_MD5 ) - only_md5 = 1; - else - only_md5 = 0; - any = 1; - } - if( n->pkt->pkt.onepass_sig->sig_class != 0x01 ) - only_md5 = 0; - } - else if( n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - size_t datalen = n->pkt->pkt.gpg_control->datalen; - const byte *data = n->pkt->pkt.gpg_control->data; - - /* check that we have at least the sigclass and one hash */ - if ( datalen < 2 ) - log_fatal("invalid control packet CTRLPKT_CLEARSIGN_START\n"); - /* Note that we don't set the clearsig flag for not-dash-escaped - * documents */ - clearsig = (*data == 0x01); - for( data++, datalen--; datalen; datalen--, data++ ) - gcry_md_enable ( c->mfx.md, *data ); - any = 1; - break; /* no pass signature pakets are expected */ - } - } - - if( !any && !opt.skip_verify ) { - /* no onepass sig packet: enable all standard algos */ - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_RMD160 ); - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_SHA1 ); - gcry_md_enable ( c->mfx.md, DIGEST_ALGO_MD5 ); - } - if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) { - /* This is a kludge to work around a bug in pgp2. It does only - * catch those mails which are armored. To catch the non-armored - * pgp mails we could see whether there is the signature packet - * in front of the plaintext. If someone needs this, send me a patch. - */ - gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0); - } - if ( DBG_HASHING ) { - gcry_md_start_debug ( c->mfx.md, "verify" ); - if ( c->mfx.md2 ) - gcry_md_start_debug ( c->mfx.md2, "verify2" ); - } - if ( c->pipemode.op == 'B' ) - rc = handle_plaintext( pt, &c->mfx, 1, 0, NULL ); - else { - int failed; - - rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig, &failed); - if( rc && failed && !c->sigs_only) { - /* can't write output but we hash it anyway to - * check the signature */ - rc = handle_plaintext( pt, &c->mfx, 1, clearsig, NULL ); - } - } - if( rc ) - log_error( "handle plaintext failed: %s\n", gpg_strerror (rc)); - free_packet(pkt); - c->last_was_session_key = 0; - - /* We add a marker control packet instead of the plaintext packet. - * This is so that we can later detect invalid packet sequences. - */ - n = new_kbnode (create_gpg_control (CTRLPKT_PLAINTEXT_MARK, NULL, 0)); - if (c->list) - add_kbnode (c->list, n); - else - c->list = n; -} - - -static int -proc_compressed_cb( iobuf_t a, void *info ) -{ - return proc_signature_packets( info, a, ((CTX)info)->signed_data, - ((CTX)info)->sigfilename ); -} - -static int -proc_encrypt_cb( iobuf_t a, void *info ) -{ - return proc_encryption_packets( info, a ); -} - -static void -proc_compressed( CTX c, PACKET *pkt ) -{ - PKT_compressed *zd = pkt->pkt.compressed; - int rc; - - /*printf("zip: compressed data packet\n");*/ - if( c->sigs_only ) - rc = handle_compressed( c, zd, proc_compressed_cb, c ); - else if( c->encrypt_only ) - rc = handle_compressed( c, zd, proc_encrypt_cb, c ); - else - rc = handle_compressed( c, zd, NULL, NULL ); - if( rc ) - log_error("uncompressing failed: %s\n", gpg_strerror (rc)); - free_packet(pkt); - c->last_was_session_key = 0; -} - -/**************** - * check the signature - * Returns: 0 = valid signature or an error code - */ -static int -do_check_sig( CTX c, KBNODE node, int *is_selfsig, - int *is_expkey, int *is_revkey ) -{ - PKT_signature *sig; - MD_HANDLE md = NULL, md2 = NULL; - int algo, rc; - - assert( node->pkt->pkttype == PKT_SIGNATURE ); - if( is_selfsig ) - *is_selfsig = 0; - sig = node->pkt->pkt.signature; - - algo = sig->digest_algo; - if( (rc = gcry_md_test_algo(algo)) ) - return rc; - - if( sig->sig_class == 0x00 ) { - if( c->mfx.md ) - gcry_md_copy (&md,c->mfx.md); - else /* detached signature */ - gcry_md_open (&md, 0, 0 ); /* signature_check() will - enable the md*/ - } - else if( sig->sig_class == 0x01 ) { - /* how do we know that we have to hash the (already hashed) text - * in canonical mode ??? (calculating both modes???) */ - if( c->mfx.md ) { - gcry_md_copy (&md, c->mfx.md); - if (c->mfx.md2) - gcry_md_copy (&md2, c->mfx.md2); - } - else { /* detached signature */ - log_debug("Do we really need this here?"); - gcry_md_open (&md, 0, 0 ); /* signature_check() will - enable the md*/ - gcry_md_open (&md2, 0, 0 ); - } - } - else if( (sig->sig_class&~3) == 0x10 - || sig->sig_class == 0x18 - || sig->sig_class == 0x1f - || sig->sig_class == 0x20 - || sig->sig_class == 0x28 - || sig->sig_class == 0x30 ) { - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY - || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - return check_key_signature( c->list, node, is_selfsig ); - } - else if( sig->sig_class == 0x20 ) { - log_info(_("standalone revocation - " - "use \"gpg --import\" to apply\n")); - return GPG_ERR_NOT_PROCESSED; - } - else { - log_error("invalid root packet for sigclass %02x\n", - sig->sig_class); - return GPG_ERR_SIG_CLASS; - } - } - else - return GPG_ERR_SIG_CLASS; - rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL ); - if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 ) - rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL ); - gcry_md_close (md); - gcry_md_close (md2); - - return rc; -} - - -static void -print_userid( PACKET *pkt ) -{ - if( !pkt ) - BUG(); - if( pkt->pkttype != PKT_USER_ID ) { - printf("ERROR: unexpected packet type %d", pkt->pkttype ); - return; - } - if( opt.with_colons ) - { - if(pkt->pkt.user_id->attrib_data) - printf("%u %lu", - pkt->pkt.user_id->numattribs, - pkt->pkt.user_id->attrib_len); - else - print_string( stdout, pkt->pkt.user_id->name, - pkt->pkt.user_id->len, ':'); - } - else - print_utf8_string( stdout, pkt->pkt.user_id->name, - pkt->pkt.user_id->len ); -} - - -/**************** - * List the certificate in a user friendly way - */ - -static void -list_node( CTX c, KBNODE node ) -{ - int any=0; - int mainkey; - - if( !node ) - ; - else if( (mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY) ) - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = node->pkt->pkt.public_key; - - if( opt.with_colons ) { - u32 keyid[2]; - keyid_from_pk( pk, keyid ); - if( mainkey ) { - c->local_id = pk->local_id; - c->trustletter = opt.fast_list_mode? - 0 : get_validity_info( pk, NULL ); - } - printf("%s:", mainkey? "pub":"sub" ); - if( c->trustletter ) - putchar( c->trustletter ); - printf(":%u:%d:%08lX%08lX:%s:%s:", - nbits_from_pk( pk ), - pk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_pk( pk ), - colon_strtime (pk->expiredate) ); - if( c->local_id ) - printf("%lu", c->local_id ); - putchar(':'); - if( mainkey && !opt.fast_list_mode ) - putchar( get_ownertrust_info (pk) ); - putchar(':'); - if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) { - putchar('\n'); any=1; - if( opt.fingerprint ) - print_fingerprint( pk, NULL, 0 ); - printf("rtv:1:%u:\n", - node->next->pkt->pkt.ring_trust->trustval ); - } - } - else - printf("%s %4u%c/%08lX %s ", - mainkey? "pub":"sub", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid_from_pk( pk, NULL ), - datestr_from_pk( pk ) ); - - if( mainkey ) { - /* and now list all userids with their signatures */ - for( node = node->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_SIGNATURE ) { - if( !any ) { - if( node->pkt->pkt.signature->sig_class == 0x20 ) - puts("[revoked]"); - else - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - if( any ) { - if( opt.with_colons ) - printf("%s:::::::::", - node->pkt->pkt.user_id->attrib_data?"uat":"uid"); - else - printf( "uid%*s", 28, "" ); - } - print_userid( node->pkt ); - if( opt.with_colons ) - putchar(':'); - putchar('\n'); - if( opt.fingerprint && !any ) - print_fingerprint( pk, NULL, 0 ); - if( node->next - && node->next->pkt->pkttype == PKT_RING_TRUST ) { - printf("rtv:2:%u:\n", - node->next->pkt->pkt.ring_trust->trustval ); - } - any=1; - } - else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - if( !any ) { - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - } - } - else if( pk->expiredate ) { /* of subkey */ - printf(_(" [expires: %s]"), expirestr_from_pk( pk ) ); - } - - if( !any ) - putchar('\n'); - if( !mainkey && opt.fingerprint > 1 ) - print_fingerprint( pk, NULL, 0 ); - } - else if( (mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) ) - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = node->pkt->pkt.secret_key; - - if( opt.with_colons ) { - u32 keyid[2]; - keyid_from_sk( sk, keyid ); - printf("%s::%u:%d:%08lX%08lX:%s:%s:::", - mainkey? "sec":"ssb", - nbits_from_sk( sk ), - sk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_sk( sk ), - colon_strtime (sk->expiredate) - /* fixme: add LID */ ); - } - else - printf("%s %4u%c/%08lX %s ", - mainkey? "sec":"ssb", - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - (ulong)keyid_from_sk( sk, NULL ), - datestr_from_sk( sk ) ); - if( mainkey ) { - /* and now list all userids with their signatures */ - for( node = node->next; node; node = node->next ) { - if( node->pkt->pkttype == PKT_SIGNATURE ) { - if( !any ) { - if( node->pkt->pkt.signature->sig_class == 0x20 ) - puts("[revoked]"); - else - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - else if( node->pkt->pkttype == PKT_USER_ID ) { - if( any ) { - if( opt.with_colons ) - printf("%s:::::::::", - node->pkt->pkt.user_id->attrib_data?"uat":"uid"); - else - printf( "uid%*s", 28, "" ); - } - print_userid( node->pkt ); - if( opt.with_colons ) - putchar(':'); - putchar('\n'); - if( opt.fingerprint && !any ) - print_fingerprint( NULL, sk, 0 ); - any=1; - } - else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { - if( !any ) { - putchar('\n'); - any = 1; - } - list_node(c, node ); - } - } - } - if( !any ) - putchar('\n'); - if( !mainkey && opt.fingerprint > 1 ) - print_fingerprint( NULL, sk, 0 ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int is_selfsig = 0; - int rc2=0; - size_t n; - char *p; - int sigrc = ' '; - - if( !opt.list_sigs ) - return; - - if( sig->sig_class == 0x20 || sig->sig_class == 0x30 ) - fputs("rev", stdout); - else - fputs("sig", stdout); - if( opt.check_sigs ) { - fflush(stdout); - switch( gpg_err_code (rc2=do_check_sig( c, node, - &is_selfsig, - NULL, NULL )) ) { - case 0: sigrc = '!'; break; - case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; - default: sigrc = '%'; break; - } - } - else { /* check whether this is a self signature */ - u32 keyid[2]; - - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY - || c->list->pkt->pkttype == PKT_SECRET_KEY ) { - if( c->list->pkt->pkttype == PKT_PUBLIC_KEY ) - keyid_from_pk( c->list->pkt->pkt.public_key, keyid ); - else - keyid_from_sk( c->list->pkt->pkt.secret_key, keyid ); - - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - is_selfsig = 1; - } - } - if( opt.with_colons ) { - putchar(':'); - if( sigrc != ' ' ) - putchar(sigrc); - printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - colon_datestr_from_sig(sig), - colon_expirestr_from_sig(sig)); - - if(sig->trust_depth || sig->trust_value) - printf("%d %d",sig->trust_depth,sig->trust_value); - printf(":"); - - if(sig->trust_regexp) - print_string(stdout,sig->trust_regexp, - strlen(sig->trust_regexp),':'); - printf(":"); - } - else - printf("%c %08lX %s ", - sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig)); - if( sigrc == '%' ) - printf("[%s] ", gpg_strerror (rc2) ); - else if( sigrc == '?' ) - ; - else if( is_selfsig ) { - if( opt.with_colons ) - putchar(':'); - fputs( sig->sig_class == 0x18? "[keybind]":"[selfsig]", stdout); - if( opt.with_colons ) - putchar(':'); - } - else if( !opt.fast_list_mode ) { - p = get_user_id( sig->keyid, &n ); - print_string( stdout, p, n, opt.with_colons ); - xfree (p); - } - if( opt.with_colons ) - printf(":%02x%c:", sig->sig_class, sig->flags.exportable?'x':'l'); - putchar('\n'); - } - else - log_error("invalid node with packet of type %d\n", node->pkt->pkttype); -} - - - -int -proc_packets( void *anchor, iobuf_t a ) -{ - int rc; - CTX c = xcalloc (1, sizeof *c ); - - c->anchor = anchor; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - - - -int -proc_signature_packets( void *anchor, iobuf_t a, - STRLIST signedfiles, const char *sigfilename ) -{ - CTX c = xcalloc (1, sizeof *c ); - int rc; - - c->anchor = anchor; - c->sigs_only = 1; - c->signed_data = signedfiles; - c->sigfilename = sigfilename; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - -int -proc_encryption_packets( void *anchor, iobuf_t a ) -{ - CTX c = xcalloc (1, sizeof *c ); - int rc; - - c->anchor = anchor; - c->encrypt_only = 1; - rc = do_proc_packets( c, a ); - xfree ( c ); - return rc; -} - - -int -do_proc_packets( CTX c, iobuf_t a ) -{ - PACKET *pkt = xmalloc ( sizeof *pkt ); - int rc=0; - int any_data=0; - int newpkt; - - c->iobuf = a; - init_packet(pkt); - while( (rc=parse_packet(a, pkt)) != -1 ) { - any_data = 1; - if( rc ) { - free_packet(pkt); - /* stop processing when an invalid packet has been encountered - * but don't do so when we are doing a --list-packet. */ - if( gpg_err_code (rc) == GPG_ERR_INV_PACKET && opt.list_packets != 2 ) - break; - continue; - } - newpkt = -1; - if( opt.list_packets ) { - switch( pkt->pkttype ) { - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - default: newpkt = 0; break; - } - } - else if( c->sigs_only ) { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_USER_ID: - case PKT_SYMKEY_ENC: - case PKT_PUBKEY_ENC: - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - write_status_text( STATUS_UNEXPECTED, "0" ); - rc = GPG_ERR_UNEXPECTED; - goto leave; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - default: newpkt = 0; break; - } - } - else if( c->encrypt_only ) { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_USER_ID: - write_status_text( STATUS_UNEXPECTED, "0" ); - rc = GPG_ERR_UNEXPECTED; - goto leave; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - default: newpkt = 0; break; - } - } - else { - switch( pkt->pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - release_list( c ); - c->list = new_kbnode( pkt ); - newpkt = 1; - break; - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: - newpkt = add_subkey( c, pkt ); - break; - case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break; - case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break; - case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPRESSED: proc_compressed( c, pkt ); break; - case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; - case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break; - case PKT_RING_TRUST: newpkt = add_ring_trust( c, pkt ); break; - default: newpkt = 0; break; - } - } - /* This is a very ugly construct and frankly, I don't remember why - * I used it. Adding the MDC check here is a hack. - * The right solution is to initiate another context for encrypted - * packet and not to reuse the current one ... It works right - * when there is a compression packet inbetween which adds just - * an extra layer. - * Hmmm: Rewrite this whole module here?? - */ - if( pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC ) - c->have_data = pkt->pkttype == PKT_PLAINTEXT; - - if( newpkt == -1 ) - ; - else if( newpkt ) { - pkt = xmalloc ( sizeof *pkt ); - init_packet(pkt); - } - else - free_packet(pkt); - if ( c->pipemode.stop_now ) { - /* we won't get an EOF in pipemode, so we have to - * break the loop here */ - rc = -1; - break; - } - } - if( gpg_err_code (rc) == GPG_ERR_INV_PACKET ) - write_status_text( STATUS_NODATA, "3" ); - if( any_data ) - rc = 0; - else if( rc == -1 ) - write_status_text( STATUS_NODATA, "2" ); - - - leave: - release_list( c ); - xfree (c->dek); - free_packet( pkt ); - xfree ( pkt ); - free_md_filter_context( &c->mfx ); - return rc; -} - - -static int -check_sig_and_print( CTX c, KBNODE node ) -{ - PKT_signature *sig = node->pkt->pkt.signature; - const char *astr, *tstr; - int rc, is_expkey=0, is_revkey=0; - - if( opt.skip_verify ) { - log_info(_("signature verification suppressed\n")); - return 0; - } - - /* It is not in all cases possible to check multiple signatures: - * PGP 2 (which is also allowed by OpenPGP), does use the packet - * sequence: sig+data, OpenPGP does use onepas+data=sig and GnuPG - * sometimes uses (because I did'nt read the specs right) data+sig. - * Because it is possible to create multiple signatures with - * different packet sequence (e.g. data+sig and sig+data) it might - * not be possible to get it right: let's say we have: - * data+sig, sig+data,sig+data and we have not yet encountered the last - * data, we could also see this a one data with 2 signatures and then - * data+sig. - * To protect against this we check that all signatures follow - * without any intermediate packets. Note, that we won't get this - * error when we use onepass packets or cleartext signatures because - * we reset the list every time - * - * FIXME: Now that we have these marker packets, we should create a - * real grammar and check against this. - */ - { - KBNODE n; - int n_sig=0; - - for (n=c->list; n; n=n->next ) { - if ( n->pkt->pkttype == PKT_SIGNATURE ) - n_sig++; - } - if (n_sig > 1) { /* more than one signature - check sequence */ - int tmp, onepass; - - for (tmp=onepass=0,n=c->list; n; n=n->next ) { - if (n->pkt->pkttype == PKT_ONEPASS_SIG) - onepass++; - else if (n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - onepass++; /* handle the same way as a onepass */ - } - else if ( (tmp && n->pkt->pkttype != PKT_SIGNATURE) ) { - log_error(_("can't handle these multiple signatures\n")); - return 0; - } - else if ( n->pkt->pkttype == PKT_SIGNATURE ) - tmp = 1; - else if (!tmp && !onepass - && n->pkt->pkttype == PKT_GPG_CONTROL - && n->pkt->pkt.gpg_control->control - == CTRLPKT_PLAINTEXT_MARK ) { - /* plaintext before signatures but no one-pass packets*/ - log_error(_("can't handle these multiple signatures\n")); - return 0; - } - } - } - } - - tstr = asctimestamp(sig->timestamp); - astr = gcry_pk_algo_name (sig->pubkey_algo); - if(opt.verify_options&VERIFY_SHOW_LONG_KEYID) - { - log_info(_("Signature made %.*s\n"),(int)strlen(tstr), tstr); - log_info(_(" using %s key %08lX%08lX\n"), - astr? astr: "?",(ulong)sig->keyid[0],(ulong)sig->keyid[1] ); - } - else - log_info(_("Signature made %.*s using %s key ID %08lX\n"), - (int)strlen(tstr), tstr, astr? astr: "?", - (ulong)sig->keyid[1] ); - - rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) { - if( keyserver_import_keyid ( sig->keyid )==0 ) - rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); - } - - - /* If the key still isn't found, try to inform the user where it - can be found. */ - if(gpg_err_code (rc)==GPG_ERR_NO_PUBKEY && sig->flags.pref_ks) - { - const byte *p; - int seq=0; - size_t n; - - while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL))) - { - /* According to my favorite copy editor, in English - grammar, you say "at" if the key is located on a web - page, but "from" if it is located on a keyserver. I'm - not going to even try to make two strings here :) */ - log_info(_("Key available at: ") ); - print_string( log_get_stream(), p, n, 0 ); - putc( '\n', log_get_stream() ); - } - } - - - if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) { - KBNODE un, keyblock; - int count=0, statno; - char keyid_str[50]; - PKT_public_key *pk=NULL; - - if(rc) - statno=STATUS_BADSIG; - else if(sig->flags.expired) - statno=STATUS_EXPSIG; - else if(is_expkey) - statno=STATUS_EXPKEYSIG; - else if(is_revkey) - statno=STATUS_REVKEYSIG; - else - statno=STATUS_GOODSIG; - - keyblock = get_pubkeyblock( sig->keyid ); - - sprintf (keyid_str, "%08lX%08lX [uncertain] ", - (ulong)sig->keyid[0], (ulong)sig->keyid[1]); - - /* find and print the primary user ID */ - for( un=keyblock; un; un = un->next ) { - int valid; - - if(un->pkt->pkttype==PKT_PUBLIC_KEY) - { - pk=un->pkt->pkt.public_key; - continue; - } - if( un->pkt->pkttype != PKT_USER_ID ) - continue; - if ( !un->pkt->pkt.user_id->created ) - continue; - if ( un->pkt->pkt.user_id->is_revoked ) - continue; - if ( un->pkt->pkt.user_id->is_expired ) - continue; - if ( !un->pkt->pkt.user_id->is_primary ) - continue; - /* We want the textual user ID here */ - if ( un->pkt->pkt.user_id->attrib_data ) - continue; - - assert(pk); - - /* Get it before we print anything to avoid interrupting - the output with the "please do a --check-trustdb" - line. */ - valid=get_validity(pk,un->pkt->pkt.user_id); - - keyid_str[17] = 0; /* cut off the "[uncertain]" part */ - write_status_text_and_buffer (statno, keyid_str, - un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len, - -1 ); - - log_info(rc? _("BAD signature from \"") - : sig->flags.expired ? _("Expired signature from \"") - : _("Good signature from \"")); - print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - if(opt.verify_options&VERIFY_SHOW_VALIDITY) - fprintf (log_get_stream(), - "\" [%s]\n",trust_value_to_string(valid)); - else - fputs("\"\n", log_get_stream() ); - count++; - } - if( !count ) { /* just in case that we have no valid textual - userid */ - /* Try for an invalid textual userid */ - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype == PKT_USER_ID && - !un->pkt->pkt.user_id->attrib_data ) - break; - } - - /* Try for any userid at all */ - if(!un) { - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype == PKT_USER_ID ) - break; - } - } - - if (opt.trust_model==TM_ALWAYS || !un) - keyid_str[17] = 0; /* cut off the "[uncertain]" part */ - - write_status_text_and_buffer (statno, keyid_str, - un? un->pkt->pkt.user_id->name:"[?]", - un? un->pkt->pkt.user_id->len:3, - -1 ); - - log_info(rc? _("BAD signature from \"") - : sig->flags.expired ? _("Expired signature from \"") - : _("Good signature from \"")); - if (opt.trust_model!=TM_ALWAYS && un) { - fputs(_("[uncertain]"), log_get_stream() ); - putc(' ', log_get_stream() ); - } - print_utf8_string( log_get_stream(), - un? un->pkt->pkt.user_id->name:"[?]", - un? un->pkt->pkt.user_id->len:3 ); - fputs("\"\n", log_get_stream() ); - } - - /* If we have a good signature and already printed - * the primary user ID, print all the other user IDs */ - if ( count && !rc ) { - for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype != PKT_USER_ID ) - continue; - if ( un->pkt->pkt.user_id->is_revoked ) - continue; - if ( un->pkt->pkt.user_id->is_expired ) - continue; - /* Only skip textual primaries */ - if ( un->pkt->pkt.user_id->is_primary && - !un->pkt->pkt.user_id->attrib_data ) - continue; - - if(un->pkt->pkt.user_id->attrib_data) - { - dump_attribs(un->pkt->pkt.user_id,pk,NULL); - - if(opt.verify_options&VERIFY_SHOW_PHOTOS) - show_photos(un->pkt->pkt.user_id->attribs, - un->pkt->pkt.user_id->numattribs,pk,NULL); - } - - log_info( _(" aka \"")); - print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - if(opt.verify_options&VERIFY_SHOW_VALIDITY) - fprintf (log_get_stream(), "\" [%s]\n", - trust_value_to_string(get_validity(pk, - un->pkt-> - pkt.user_id))); - else - fputs("\"\n", log_get_stream() ); - } - } - release_kbnode( keyblock ); - - if( !rc ) - { - if(opt.verify_options&VERIFY_SHOW_POLICY) - show_policy_url(sig,0,1); - else - show_policy_url(sig,0,2); - - if(opt.verify_options&VERIFY_SHOW_KEYSERVER) - show_keyserver_url(sig,0,1); - else - show_keyserver_url(sig,0,2); - - if(opt.verify_options&VERIFY_SHOW_NOTATION) - show_notation(sig,0,1); - else - show_notation(sig,0,2); - } - - if( !rc && is_status_enabled() ) { - /* print a status response with the fingerprint */ - PKT_public_key *vpk = xcalloc (1, sizeof *vpk ); - - if( !get_pubkey( vpk, sig->keyid ) ) { - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[MAX_FINGERPRINT_LEN*4+90], *bufp; - size_t i, n; - - bufp = buf; - fingerprint_from_pk( vpk, array, &n ); - p = array; - for(i=0; i < n ; i++, p++, bufp += 2) - sprintf(bufp, "%02X", *p ); - /* TODO: Replace the reserved '0' in the field below - with bits for status flags (policy url, notation, - etc.). Remember to make the buffer larger to - match! */ - sprintf(bufp, " %s %lu %lu %d 0 %d %d %02X ", - strtimestamp( sig->timestamp ), - (ulong)sig->timestamp,(ulong)sig->expiredate, - sig->version,sig->pubkey_algo,sig->digest_algo, - sig->sig_class); - bufp = bufp + strlen (bufp); - if (!vpk->is_primary) { - u32 akid[2]; - - akid[0] = vpk->main_keyid[0]; - akid[1] = vpk->main_keyid[1]; - free_public_key (vpk); - vpk = xcalloc (1, sizeof *vpk ); - if (get_pubkey (vpk, akid)) { - /* impossible error, we simply return a zeroed out fpr */ - n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20; - memset (array, 0, n); - } - else - fingerprint_from_pk( vpk, array, &n ); - } - p = array; - for(i=0; i < n ; i++, p++, bufp += 2) - sprintf(bufp, "%02X", *p ); - write_status_text( STATUS_VALIDSIG, buf ); - } - free_public_key( vpk ); - } - - if( !rc ) - rc = check_signatures_trust( sig ); - - if(sig->flags.expired) - { - log_info(_("Signature expired %s\n"), - asctimestamp(sig->expiredate)); - rc=GPG_ERR_GENERAL; /* need a better error here? */ - } - else if(sig->expiredate) - log_info(_("Signature expires %s\n"),asctimestamp(sig->expiredate)); - - if(opt.verbose) - log_info(_("%s signature, digest algorithm %s\n"), - sig->sig_class==0x00?_("binary"): - sig->sig_class==0x01?_("textmode"):_("unknown"), - gcry_md_algo_name (sig->digest_algo)); - - if( rc ) - g10_errors_seen = 1; - if( opt.batch && rc ) - g10_exit(1); - } - else { - char buf[50]; - sprintf(buf, "%08lX%08lX %d %d %02x %lu %d", - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - sig->pubkey_algo, sig->digest_algo, - sig->sig_class, (ulong)sig->timestamp, rc ); - write_status_text( STATUS_ERRSIG, buf ); - if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) { - buf[16] = 0; - write_status_text( STATUS_NO_PUBKEY, buf ); - } - if( rc != GPG_ERR_NOT_PROCESSED ) - log_error(_("Can't check signature: %s\n"), gpg_strerror (rc) ); - } - return rc; -} - - -/**************** - * Process the tree which starts at node - */ -static void -proc_tree( CTX c, KBNODE node ) -{ - KBNODE n1; - int rc; - - if( opt.list_packets || opt.list_only ) - return; - - /* we must skip our special plaintext marker packets here becuase - they may be the root packet. These packets are only used in - addionla checks and skipping them here doesn't matter */ - while ( node - && node->pkt->pkttype == PKT_GPG_CONTROL - && node->pkt->pkt.gpg_control->control - == CTRLPKT_PLAINTEXT_MARK ) { - node = node->next; - } - if (!node) - return; - - c->local_id = 0; - c->trustletter = ' '; - if( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - merge_keys_and_selfsig( node ); - list_node( c, node ); - } - else if( node->pkt->pkttype == PKT_SECRET_KEY ) { - merge_keys_and_selfsig( node ); - list_node( c, node ); - } - else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) { - /* check all signatures */ - if( !c->have_data ) { - free_md_filter_context( &c->mfx ); - /* prepare to create all requested message digests */ - gcry_md_open (&c->mfx.md, 0, 0); - - /* fixme: why looking for the signature packet and not 1passpacket*/ - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) { - gcry_md_enable ( c->mfx.md, n1->pkt->pkt.signature->digest_algo); - } - /* ask for file and hash it */ - if( c->sigs_only ) { - rc = hash_datafiles( c->mfx.md, NULL, - c->signed_data, c->sigfilename, - n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 ); - } - else { - rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2, - iobuf_get_real_fname(c->iobuf), - n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 ); - } - if( rc ) { - log_error("can't hash datafile: %s\n", gpg_strerror (rc)); - return; - } - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) - check_sig_and_print( c, n1 ); - } - else if( node->pkt->pkttype == PKT_GPG_CONTROL - && node->pkt->pkt.gpg_control->control - == CTRLPKT_CLEARSIGN_START ) { - /* clear text signed message */ - if( !c->have_data ) { - log_error("cleartext signature without data\n" ); - return; - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - - for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) - check_sig_and_print( c, n1 ); - } - else if( node->pkt->pkttype == PKT_SIGNATURE ) { - PKT_signature *sig = node->pkt->pkt.signature; - int multiple_ok=1; - - n1=find_next_kbnode(node, PKT_SIGNATURE); - if(n1) - { - byte class=sig->sig_class; - byte hash=sig->digest_algo; - - for(; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE))) - { - /* We can't currently handle multiple signatures of - different classes or digests (we'd pretty much have - to run a different hash context for each), but if - they are all the same, make an exception. */ - if(n1->pkt->pkt.signature->sig_class!=class - || n1->pkt->pkt.signature->digest_algo!=hash) - { - multiple_ok=0; - log_info(_("WARNING: multiple signatures detected. " - "Only the first will be checked.\n")); - break; - } - } - } - - if( sig->sig_class != 0x00 && sig->sig_class != 0x01 ) - log_info(_("standalone signature of class 0x%02x\n"), - sig->sig_class); - else if( !c->have_data ) { - /* detached signature */ - free_md_filter_context( &c->mfx ); - gcry_md_open (&c->mfx.md, sig->digest_algo, 0); - if( !opt.pgp2_workarounds ) - ; - else if( sig->digest_algo == DIGEST_ALGO_MD5 - && is_RSA( sig->pubkey_algo ) ) { - /* enable a workaround for a pgp2 bug */ - gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0 ); - } - else if( sig->digest_algo == DIGEST_ALGO_SHA1 - && sig->pubkey_algo == PUBKEY_ALGO_DSA - && sig->sig_class == 0x01 ) { - /* enable the workaround also for pgp5 when the detached - * signature has been created in textmode */ - gcry_md_open (&c->mfx.md2, sig->digest_algo, 0 ); - } -#if 0 /* workaround disabled */ - /* Here we have another hack to work around a pgp 2 bug - * It works by not using the textmode for detached signatures; - * this will let the first signature check (on md) fail - * but the second one (on md2) which adds an extra CR should - * then produce the "correct" hash. This is very, very ugly - * hack but it may help in some cases (and break others) - */ - /* c->mfx.md2? 0 :(sig->sig_class == 0x01) */ -#endif - if ( DBG_HASHING ) { - gcry_md_start_debug ( c->mfx.md, "verify" ); - if ( c->mfx.md2 ) - gcry_md_start_debug ( c->mfx.md2, "verify2" ); - } - if( c->sigs_only ) { - rc = hash_datafiles( c->mfx.md, c->mfx.md2, - c->signed_data, c->sigfilename, - (sig->sig_class == 0x01) ); - } - else { - rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2, - iobuf_get_real_fname(c->iobuf), - (sig->sig_class == 0x01) ); - } - if( rc ) { - log_error("can't hash datafile: %s\n", gpg_strerror (rc)); - return; - } - } - else if ( c->signed_data ) { - log_error (_("not a detached signature\n") ); - return; - } - else if ( c->pipemode.op == 'B' ) - ; /* this is a detached signature trough the pipemode handler */ - else if (!opt.quiet) - log_info(_("old style (PGP 2.x) signature\n")); - - if(multiple_ok) - for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) ) - check_sig_and_print( c, n1 ); - else - check_sig_and_print( c, node ); - } - else { - dump_kbnode (c->list); - log_error(_("invalid root packet detected in proc_tree()\n")); - dump_kbnode (node); - } -} diff --git a/g10/mdfilter.c b/g10/mdfilter.c deleted file mode 100644 index b58189146..000000000 --- a/g10/mdfilter.c +++ /dev/null @@ -1,76 +0,0 @@ -/* mdfilter.c - filter data and calculate a message digest - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" - - - -/**************** - * This filter is used to collect a message digest - */ -int -md_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - md_filter_context_t *mfx = opaque; - int i, rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - if( mfx->maxbuf_size && size > mfx->maxbuf_size ) - size = mfx->maxbuf_size; - i = iobuf_read( a, buf, size ); - if( i == -1 ) i = 0; - if( i ) { - gcry_md_write(mfx->md, buf, i ); - if( mfx->md2 ) - gcry_md_write(mfx->md2, buf, i ); - } - else - rc = -1; /* eof */ - *ret_len = i; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "md_filter"; - return rc; -} - - -void -free_md_filter_context( md_filter_context_t *mfx ) -{ - gcry_md_close (mfx->md); - gcry_md_close (mfx->md2); - mfx->md = NULL; - mfx->md2 = NULL; - mfx->maxbuf_size = 0; -} - diff --git a/g10/misc.c b/g10/misc.c deleted file mode 100644 index 7012a8a25..000000000 --- a/g10/misc.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* misc.c - miscellaneous functions - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <assert.h> -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -#include <asm/sysinfo.h> -#include <asm/unistd.h> -#endif -#ifdef HAVE_SETRLIMIT -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif - -#include "gpg.h" -#include "util.h" -#include "main.h" -#include "photoid.h" -#include "options.h" -#include "i18n.h" - -#define MAX_EXTERN_MPI_BITS 16384 - - -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -static int -setsysinfo(unsigned long op, void *buffer, unsigned long size, - int *start, void *arg, unsigned long flag) -{ - return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); -} - -void -trap_unaligned(void) -{ - unsigned int buf[2]; - - buf[0] = SSIN_UACPROC; - buf[1] = UAC_SIGBUS | UAC_NOPRINT; - setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); -} -#else -void -trap_unaligned(void) -{ /* dummy */ -} -#endif - - -int -disable_core_dumps() -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -#ifdef HAVE_SETRLIMIT - struct rlimit limit; - - limit.rlim_cur = 0; - limit.rlim_max = 0; - if( !setrlimit( RLIMIT_CORE, &limit ) ) - return 0; - if( errno != EINVAL && errno != ENOSYS ) - log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) ); -#endif - return 1; -#endif -} - - - -u16 -checksum_u16( unsigned n ) -{ - u16 a; - - a = (n >> 8) & 0xff; - a += n & 0xff; - return a; -} - - -u16 -checksum( byte *p, unsigned n ) -{ - u16 a; - - for(a=0; n; n-- ) - a += *p++; - return a; -} - -u16 -checksum_mpi( gcry_mpi_t a ) -{ - int rc; - u16 csum; - byte *buffer; - size_t nbytes; - - rc = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a ); - if (rc) - BUG (); - /* fixme: for numbers not in secure memory we should use a stack - * based buffer and only allocate a larger one if mpi_print return - * an error */ - buffer = gcry_is_secure(a)? gcry_xmalloc_secure(nbytes):gcry_xmalloc(nbytes); - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a ); - if (rc) - BUG (); - csum = checksum (buffer, nbytes ); - xfree (buffer ); - return csum; -} - -u32 -buffer_to_u32( const byte *buffer ) -{ - unsigned long a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - - -static void -no_exp_algo(void) -{ - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("Experimental algorithms should not be used!\n")); - } -} - -void -print_pubkey_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); -} - -void -print_cipher_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); - else if( algo == CIPHER_ALGO_3DES - || algo == CIPHER_ALGO_CAST5 - || algo == CIPHER_ALGO_BLOWFISH - || algo == CIPHER_ALGO_TWOFISH - || algo == CIPHER_ALGO_RIJNDAEL - || algo == CIPHER_ALGO_RIJNDAEL192 - || algo == CIPHER_ALGO_RIJNDAEL256 - ) - ; - else { - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("this cipher algorithm is deprecated; " - "please use a more standard one!\n")); - } - } -} - -void -print_digest_algo_note( int algo ) -{ - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); -} - - -/* Return a string which is used as a kind of process ID */ -const byte * -get_session_marker( size_t *rlen ) -{ - static byte marker[SIZEOF_UNSIGNED_LONG*2]; - static int initialized; - - if ( !initialized ) { - volatile ulong aa, bb; /* we really want the uninitialized value */ - ulong a, b; - - initialized = 1; - /* also this marker is guessable it is not easy to use this - * for a faked control packet because an attacker does not - * have enough control about the time the verification does - * take place. Of course, we can add just more random but - * than we need the random generator even for verification - * tasks - which does not make sense. */ - a = aa ^ (ulong)getpid(); - b = bb ^ (ulong)time(NULL); - memcpy( marker, &a, SIZEOF_UNSIGNED_LONG ); - memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG ); - } - *rlen = sizeof(marker); - return marker; -} - -/**************** - * Wrapper around the libgcrypt function with addional checks on - * openPGP contraints for the algo ID. - */ -int -openpgp_cipher_test_algo( int algo ) -{ - if( algo < 0 || algo > 110 ) - return GPG_ERR_CIPHER_ALGO; - return gcry_cipher_test_algo (algo); -} - -int -openpgp_pk_test_algo( int algo, unsigned int usage_flags ) -{ - size_t value = usage_flags; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; -#ifdef __GNUC__ -#warning need to handle the usage here? -#endif - if (algo < 0 || algo > 110) - return GPG_ERR_PUBKEY_ALGO; - return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &value); -} - -int -openpgp_pk_algo_usage ( int algo ) -{ - int use = 0; - - /* they are hardwired in gpg 1.0 */ - switch ( algo ) { - case PUBKEY_ALGO_RSA: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH; - break; - case PUBKEY_ALGO_RSA_E: - use = PUBKEY_USAGE_ENC; - break; - case PUBKEY_ALGO_RSA_S: - use = PUBKEY_USAGE_SIG; - break; - case PUBKEY_ALGO_ELGAMAL_E: - use = PUBKEY_USAGE_ENC; - break; - case PUBKEY_ALGO_DSA: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; - break; - case PUBKEY_ALGO_ELGAMAL: - use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH; - break; - default: - break; - } - return use; -} - -int -openpgp_md_test_algo( int algo ) -{ - if( algo < 0 || algo > 110 ) - return GPG_ERR_DIGEST_ALGO; - return gcry_md_test_algo (algo); -} - -int -openpgp_md_map_name (const char *string) -{ - int i = gcry_md_map_name (string); - - if (!i && (string[0]=='H' || string[0]=='h')) - { /* Didn't find it, so try the Hx format */ - long val; - char *endptr; - - string++; - - val=strtol(string,&endptr,10); - if (*string!='\0' && *endptr=='\0' && !openpgp_md_test_algo(val)) - i = val; - } - return i < 0 || i > 110? 0 : i; -} - -int -openpgp_cipher_map_name (const char *string) -{ - int i = gcry_cipher_map_name (string); - - if (!i && (string[0]=='S' || string[0]=='s')) - { /* Didn't find it, so try the Sx format */ - long val; - char *endptr; - - string++; - - val=strtol(string,&endptr,10); - if (*string!='\0' && *endptr=='\0' && !openpgp_cipher_test_algo(val)) - i = val; - } - return i < 0 || i > 110? 0 : i; -} - -int -openpgp_pk_map_name (const char *string) -{ - int i = gcry_pk_map_name (string); - return i < 0 || i > 110? 0 : i; -} - -#ifdef USE_IDEA -/* Special warning for the IDEA cipher */ -void -idea_cipher_warn(int show) -{ - static int warned=0; - - if(!warned || show) - { - log_info(_("the IDEA cipher plugin is not present\n")); - log_info(_("please see http://www.gnupg.org/why-not-idea.html " - "for more information\n")); - warned=1; - } -} -#endif - -/* Expand %-strings. Returns a string which must be m_freed. Returns - NULL if the string cannot be expanded (too large). */ -char * -pct_expando(const char *string,struct expando_args *args) -{ - const char *ch=string; - int idx=0,maxlen=0,done=0; - u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0}; - char *ret=NULL; - - if(args->pk) - keyid_from_pk(args->pk,pk_keyid); - - if(args->sk) - keyid_from_sk(args->sk,sk_keyid); - - /* This is used so that %k works in photoid command strings in - --list-secret-keys (which of course has a sk, but no pk). */ - if(!args->pk && args->sk) - keyid_from_sk(args->sk,pk_keyid); - - while(*ch!='\0') - { - char *str=NULL; - - if(!done) - { - /* 8192 is way bigger than we'll need here */ - if(maxlen>=8192) - goto fail; - - maxlen+=1024; - ret= xrealloc(ret,maxlen); - } - - done=0; - - if(*ch=='%') - { - switch(*(ch+1)) - { - case 's': /* short key id */ - if(idx+8<maxlen) - { - sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]); - idx+=8; - done=1; - } - break; - - case 'S': /* long key id */ - if(idx+16<maxlen) - { - sprintf(&ret[idx],"%08lX%08lX", - (ulong)sk_keyid[0],(ulong)sk_keyid[1]); - idx+=16; - done=1; - } - break; - - case 'k': /* short key id */ - if(idx+8<maxlen) - { - sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]); - idx+=8; - done=1; - } - break; - - case 'K': /* long key id */ - if(idx+16<maxlen) - { - sprintf(&ret[idx],"%08lX%08lX", - (ulong)pk_keyid[0],(ulong)pk_keyid[1]); - idx+=16; - done=1; - } - break; - - case 'p': /* primary pk fingerprint of a sk */ - case 'f': /* pk fingerprint */ - case 'g': /* sk fingerprint */ - { - byte array[MAX_FINGERPRINT_LEN]; - size_t len; - int i; - - if( ch[1]=='p' && args->sk) - { - if(args->sk->is_primary) - fingerprint_from_sk(args->sk,array,&len); - else if(args->sk->main_keyid[0] || args->sk->main_keyid[1]) - { - PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key)); - - if(get_pubkey_fast(pk,args->sk->main_keyid)==0) - fingerprint_from_pk(pk,array,&len); - else - memset(array,0,(len=MAX_FINGERPRINT_LEN)); - free_public_key(pk); - } - else - memset(array,0,(len=MAX_FINGERPRINT_LEN)); - } - else if( ch[1]=='f' && args->pk) - fingerprint_from_pk(args->pk,array,&len); - else if( ch[1]=='g' && args->sk) - fingerprint_from_sk(args->sk,array,&len); - else - memset(array, 0, (len=MAX_FINGERPRINT_LEN)); - - if(idx+(len*2)<maxlen) - { - for(i=0;i<len;i++) - { - sprintf(&ret[idx],"%02X",array[i]); - idx+=2; - } - done=1; - } - } - break; - - case 't': /* e.g. "jpg" */ - str=image_type_to_string(args->imagetype,0); - /* fall through */ - - case 'T': /* e.g. "image/jpeg" */ - if(str==NULL) - str=image_type_to_string(args->imagetype,2); - - if(idx+strlen(str)<maxlen) - { - strcpy(&ret[idx],str); - idx+=strlen(str); - done=1; - } - break; - - case '%': - if(idx+1<maxlen) - { - ret[idx++]='%'; - ret[idx]='\0'; - done=1; - } - break; - - /* Any unknown %-keys (like %i, %o, %I, and %O) are - passed through for later expansion. Note this also - handles the case where the last character in the - string is a '%' - the terminating \0 will end up here - and properly terminate the string. */ - default: - if(idx+2<maxlen) - { - ret[idx++]='%'; - ret[idx++]=*(ch+1); - ret[idx]='\0'; - done=1; - } - break; - } - - if(done) - ch++; - } - else - { - if(idx+1<maxlen) - { - ret[idx++]=*ch; - ret[idx]='\0'; - done=1; - } - } - - if(done) - ch++; - } - - return ret; - - fail: - xfree (ret); - return NULL; -} - -int -hextobyte( const char *s ) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - -void -deprecated_warning(const char *configname,unsigned int configlineno, - const char *option,const char *repl1,const char *repl2) -{ - if(configname) - { - if(strncmp("--",option,2)==0) - option+=2; - - if(strncmp("--",repl1,2)==0) - repl1+=2; - - log_info(_("%s:%d: deprecated option \"%s\"\n"), - configname,configlineno,option); - } - else - log_info(_("WARNING: \"%s\" is a deprecated option\n"),option); - - log_info(_("please use \"%s%s\" instead\n"),repl1,repl2); -} - -const char * -compress_algo_to_string(int algo) -{ - const char *s="?"; - - switch(algo) - { - case 0: - s="Uncompressed"; - break; - - case 1: - s="ZIP"; - break; - - case 2: - s="ZLIB"; - break; - } - - return s; -} - -int -string_to_compress_algo(const char *string) -{ - if(ascii_strcasecmp(string,"uncompressed")==0) - return 0; - else if(ascii_strcasecmp(string,"zip")==0) - return 1; - else if(ascii_strcasecmp(string,"zlib")==0) - return 2; - else if(ascii_strcasecmp(string,"z0")==0) - return 0; - else if(ascii_strcasecmp(string,"z1")==0) - return 1; - else if(ascii_strcasecmp(string,"z2")==0) - return 2; - else - return -1; -} - -int -check_compress_algo(int algo) -{ - if(algo>=0 && algo<=2) - return 0; - - return GPG_ERR_COMPR_ALGO; -} - -int -default_cipher_algo(void) -{ - if(opt.def_cipher_algo) - return opt.def_cipher_algo; - else if(opt.personal_cipher_prefs) - return opt.personal_cipher_prefs[0].value; - else - return opt.s2k_cipher_algo; -} - -/* There is no default_digest_algo function, but see - sign.c:hash_for */ - -int -default_compress_algo(void) -{ - if(opt.def_compress_algo!=-1) - return opt.def_compress_algo; - else if(opt.personal_compress_prefs) - return opt.personal_compress_prefs[0].value; - else - return DEFAULT_COMPRESS_ALGO; -} - -const char * -compliance_option_string(void) -{ - switch(opt.compliance) - { - case CO_RFC2440: - return "--openpgp"; - case CO_PGP2: - return "--pgp2"; - case CO_PGP6: - return "--pgp6"; - case CO_PGP7: - return "--pgp7"; - case CO_PGP8: - return "--pgp8"; - default: - return "???"; - } -} - -static const char * -compliance_string(void) -{ - switch(opt.compliance) - { - case CO_RFC2440: - return "OpenPGP"; - case CO_PGP2: - return "PGP 2.x"; - case CO_PGP6: - return "PGP 6.x"; - case CO_PGP7: - return "PGP 7.x"; - case CO_PGP8: - return "PGP 8.x"; - default: - return "???"; - } -} - -void -compliance_failure(void) -{ - log_info(_("this message may not be usable by %s\n"),compliance_string()); - opt.compliance=CO_GNUPG; -} - -int -parse_options(char *str,unsigned int *options,struct parse_options *opts) -{ - char *tok; - - while((tok=strsep(&str," ,"))) - { - int i,rev=0; - - if(tok[0]=='\0') - continue; - - if(ascii_strncasecmp("no-",tok,3)==0) - { - rev=1; - tok+=3; - } - - for(i=0;opts[i].name;i++) - { - if(ascii_strcasecmp(opts[i].name,tok)==0) - { - if(rev) - *options&=~opts[i].bit; - else - *options|=opts[i].bit; - break; - } - } - - if(!opts[i].name) - return 0; - } - - return 1; -} - - - -/* Temporary helper. */ -int -pubkey_get_npkey( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nskey( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n )) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nsig( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n)) - n = 0; - return n; -} - -/* Temporary helper. */ -int -pubkey_get_nenc( int algo ) -{ - size_t n; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) - n = 0; - return n; -} - - -/* Temporary helper. */ -unsigned int -pubkey_nbits( int algo, gcry_mpi_t *key ) -{ - int rc, nbits; - gcry_sexp_t sexp; - - if( algo == GCRY_PK_DSA ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - key[0], key[1], key[2], key[3] ); - } - else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - key[0], key[1], key[2] ); - } - else if( algo == GCRY_PK_RSA ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(rsa(n%m)(e%m)))", - key[0], key[1] ); - } - else - return 0; - - if ( rc ) - BUG (); - - nbits = gcry_pk_get_nbits( sexp ); - gcry_sexp_release( sexp ); - return nbits; -} - - -/* MPI helper functions. */ - - -/**************** - * write an mpi to out. - */ -int -mpi_write( iobuf_t out, gcry_mpi_t a ) -{ - char buffer[(MAX_EXTERN_MPI_BITS+7)/8]; - size_t nbytes; - int rc; - - nbytes = (MAX_EXTERN_MPI_BITS+7)/8; - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); - if( !rc ) - rc = iobuf_write( out, buffer, nbytes ); - - return rc; -} - -/**************** - * Writyeg a MPI to out, but in this case it is an opaque one, - * s used vor v3 protected keys. - */ -int -mpi_write_opaque( iobuf_t out, gcry_mpi_t a ) -{ - size_t nbytes, nbits; - int rc; - char *p; - - assert( gcry_mpi_get_flag( a, GCRYMPI_FLAG_OPAQUE ) ); - p = gcry_mpi_get_opaque( a, &nbits ); - nbytes = (nbits+7) / 8; - iobuf_put( out, nbits >> 8 ); - iobuf_put( out, nbits ); - rc = iobuf_write( out, p, nbytes ); - return rc; -} - - -/**************** - * Read an external representation of an mpi and return the MPI - * The external format is a 16 bit unsigned value stored in network byte order, - * giving the number of bits for the following integer. The integer is stored - * with MSB first (left padded with zeroes to align on a byte boundary). - */ -gcry_mpi_t -mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure) -{ - int c, c1, c2, i; - unsigned int nbits, nbytes, nread=0; - gcry_mpi_t a = NULL; - byte *buf = NULL; - byte *p; - - if( (c = c1 = iobuf_get(inp)) == -1 ) - goto leave; - nbits = c << 8; - if( (c = c2 = iobuf_get(inp)) == -1 ) - goto leave; - nbits |= c; - if( nbits > MAX_EXTERN_MPI_BITS ) { - log_error("mpi too large (%u bits)\n", nbits); - goto leave; - } - nread = 2; - nbytes = (nbits+7) / 8; - buf = secure? gcry_xmalloc_secure( nbytes+2 ) : gcry_xmalloc( nbytes+2 ); - p = buf; - p[0] = c1; - p[1] = c2; - for( i=0 ; i < nbytes; i++ ) { - p[i+2] = iobuf_get(inp) & 0xff; - nread++; - } - nread += nbytes; - if( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) ) - a = NULL; - - leave: - gcry_free(buf); - if( nread > *ret_nread ) - log_bug("mpi larger than packet"); - else - *ret_nread = nread; - return a; -} - -/**************** - * Same as mpi_read but the value is stored as an opaque MPI. - * This function is used to read encrypted MPI of v3 packets. - */ -gcry_mpi_t -mpi_read_opaque(iobuf_t inp, unsigned *ret_nread ) -{ - int c, c1, c2, i; - unsigned nbits, nbytes, nread=0; - gcry_mpi_t a = NULL; - byte *buf = NULL; - byte *p; - - if( (c = c1 = iobuf_get(inp)) == -1 ) - goto leave; - nbits = c << 8; - if( (c = c2 = iobuf_get(inp)) == -1 ) - goto leave; - nbits |= c; - if( nbits > MAX_EXTERN_MPI_BITS ) { - log_error("mpi too large (%u bits)\n", nbits); - goto leave; - } - nread = 2; - nbytes = (nbits+7) / 8; - buf = gcry_xmalloc( nbytes ); - p = buf; - for( i=0 ; i < nbytes; i++ ) { - p[i] = iobuf_get(inp) & 0xff; - } - nread += nbytes; - a = gcry_mpi_set_opaque(NULL, buf, nbits ); - buf = NULL; - - leave: - gcry_free(buf); - if( nread > *ret_nread ) - log_bug("mpi larger than packet"); - else - *ret_nread = nread; - return a; -} - - -int -mpi_print( FILE *fp, gcry_mpi_t a, int mode ) -{ - int n=0; - - if( !a ) - return fprintf(fp, "[MPI_NULL]"); - if( !mode ) { - unsigned int n1; - n1 = gcry_mpi_get_nbits(a); - n += fprintf(fp, "[%u bits]", n1); - } - else { - int rc; - unsigned char *buffer; - - rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a ); - assert( !rc ); - fputs( buffer, fp ); - n += strlen(buffer); - gcry_free( buffer ); - } - return n; -} - - diff --git a/g10/mkdtemp.c b/g10/mkdtemp.c deleted file mode 100644 index 55e5b189f..000000000 --- a/g10/mkdtemp.c +++ /dev/null @@ -1,98 +0,0 @@ -/* mkdtemp.c - libc replacement function - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a replacement function for mkdtemp in case the platform - we're building on (like mine!) doesn't have it. */ - -#include <config.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include "types.h" -#include "cipher.h" - -#ifdef MKDIR_TAKES_ONE_ARG -# undef mkdir -# define mkdir(a,b) mkdir(a) -#endif - -char *mkdtemp(char *template) -{ - unsigned int attempts,idx,count=0; - byte *ch; - - idx=strlen(template); - - /* Walk backwards to count all the Xes */ - while(idx>0 && template[idx-1]=='X') - { - count++; - idx--; - } - - if(count==0) - { - errno=EINVAL; - return NULL; - } - - ch=&template[idx]; - - /* Try 4 times to make the temp directory */ - for(attempts=0;attempts<4;attempts++) - { - unsigned int remaining=count; - char *marker=ch; - byte *randombits; - - idx=0; - - /* Using really random bits is probably overkill here. The - worst thing that can happen with a directory name collision - is that the function will return an error. */ - - randombits=get_random_bits(4*remaining,0,0); - - while(remaining>1) - { - sprintf(marker,"%02X",randombits[idx++]); - marker+=2; - remaining-=2; - } - - /* Any leftover Xes? get_random_bits rounds up to full bytes, - so this is safe. */ - if(remaining>0) - sprintf(marker,"%X",randombits[idx]&0xF); - - xfree (randombits); - - if(mkdir(template,0700)==0) - break; - } - - if(attempts==4) - return NULL; /* keeps the errno from mkdir, whatever it is */ - - return template; -} diff --git a/g10/openfile.c b/g10/openfile.c deleted file mode 100644 index 7dbbf7d6a..000000000 --- a/g10/openfile.c +++ /dev/null @@ -1,391 +0,0 @@ -/* openfile.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "ttyio.h" -#include "options.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - -#ifdef USE_ONLY_8DOT3 -#define SKELEXT ".skl" -#else -#define SKELEXT EXTSEP_S "skel" -#endif - -#if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__) -#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) ) -#else -#define CMP_FILENAME(a,b) strcmp( (a), (b) ) -#endif - -#ifdef MKDIR_TAKES_ONE_ARG -#undef mkdir -#define mkdir(a,b) mkdir(a) -#endif - -/* FIXME: Implement opt.interactive. */ - -/**************** - * Check whether FNAME exists and ask if it's okay to overwrite an - * existing one. - * Returns: True: it's okay to overwrite or the file does not exist - * False: Do not overwrite - */ -int -overwrite_filep( const char *fname ) -{ - if( !fname || (*fname == '-' && !fname[1]) ) - return 1; /* writing to stdout is always okay */ - - if( access( fname, F_OK ) ) - return 1; /* does not exist */ - -#ifndef HAVE_DOSISH_SYSTEM - if ( !strcmp ( fname, "/dev/null" ) ) - return 1; /* does not do any harm */ -#endif - - /* fixme: add some backup stuff in case of overwrite */ - if( opt.answer_yes ) - return 1; - if( opt.answer_no || opt.batch ) - return 0; /* do not overwrite */ - - tty_printf(_("File `%s' exists. "), fname); - if( cpr_get_answer_is_yes("openfile.overwrite.okay", - _("Overwrite (y/N)? ")) ) - return 1; - return 0; -} - - -/**************** - * Strip know extensions from iname and return a newly allocated - * filename. Return NULL if we can't do that. - */ -char * -make_outfile_name( const char *iname ) -{ - size_t n; - - if( (!iname || (*iname=='-' && !iname[1]) )) - return xstrdup ("-"); - - n = strlen(iname); - if( n > 4 && ( !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig") - || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) { - char *buf = xstrdup ( iname ); - buf[n-4] = 0; - return buf; - } - else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) { - char *buf = xstrdup ( iname ); - buf[n-5] = 0; - return buf; - } - - log_info(_("%s: unknown suffix\n"), iname ); - return NULL; -} - - -/**************** - * Ask for a outputfilename and use the given one as default. - * Return NULL if no file has been given or it is not possible to - * ask the user. - */ -char * -ask_outfile_name( const char *name, size_t namelen ) -{ - size_t n; - const char *s; - char *prompt; - char *fname; - char *defname; - - if( opt.batch ) - return NULL; - - s = _("Enter new filename"); - - n = strlen(s) + namelen + 10; - defname = name && namelen? make_printable_string( name, namelen, 0): NULL; - prompt = xmalloc (n); - if( defname ) - sprintf(prompt, "%s [%s]: ", s, defname ); - else - sprintf(prompt, "%s: ", s ); - fname = cpr_get("openfile.askoutname", prompt ); - cpr_kill_prompt(); - xfree (prompt); - if( !*fname ) { - xfree ( fname ); fname = NULL; - fname = defname; defname = NULL; - } - xfree (defname); - if (fname) - trim_spaces (fname); - return fname; -} - - -/**************** - * Make an output filename for the inputfile INAME. - * Returns an iobuf_t and an errorcode - * Mode 0 = use ".gpg" - * 1 = use ".asc" - * 2 = use ".sig" - */ -int -open_outfile( const char *iname, int mode, iobuf_t *a ) -{ - int rc = 0; - - *a = NULL; - if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) { - if( !(*a = iobuf_create(NULL)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't open: %s\n"), "[stdout]", strerror(errno) ); - } - else if( opt.verbose ) - log_info(_("writing to stdout\n")); - } - else { - char *buf = NULL; - const char *name; - - if( opt.dry_run ) - name = "/dev/null"; - else if( opt.outfile ) - name = opt.outfile; - else { -#ifdef USE_ONLY_8DOT3 - if (opt.mangle_dos_filenames) - { - /* It is quite common DOS system to have only one dot in a - * a filename So if we have something like this, we simple - * replace the suffix execpt in cases where the suffix is - * larger than 3 characters and not the same as. - * We should really map the filenames to 8.3 but this tends to - * be more complicated and is probaly a duty of the filesystem - */ - char *dot; - const char *newsfx = mode==1 ? ".asc" : - mode==2 ? ".sig" : ".gpg"; - - buf = xmalloc (strlen(iname)+4+1); - strcpy(buf,iname); - dot = strchr(buf, '.' ); - if ( dot && dot > buf && dot[1] && strlen(dot) <= 4 - && CMP_FILENAME(newsfx, dot) ) - { - strcpy(dot, newsfx ); - } - else if ( dot && !dot[1] ) /* don't duplicate a dot */ - strcpy( dot, newsfx+1 ); - else - strcat ( buf, newsfx ); - } - if (!buf) -#endif /* USE_ONLY_8DOT3 */ - { - buf = xmalloc (strlen(iname)+4+1); - strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" : - mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg"); - } - name = buf; - } - - rc = 0; - while( !overwrite_filep (name) ) - { - char *tmp = ask_outfile_name (NULL, 0); - if ( !tmp || !*tmp ) - { - xfree (tmp); - rc = GPG_ERR_EEXIST; - break; - } - xfree (buf); - name = buf = tmp; - } - - if( !rc ) - { - if( !(*a = iobuf_create( name )) ) - { - rc = gpg_error_from_errno (errno); - log_error(_("%s: can't create: %s\n"), name, strerror(errno) ); - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), name ); - } - xfree (buf); - } - - return rc; -} - - -/**************** - * Try to open a file without the extension ".sig" or ".asc" - * Return NULL if such a file is not available. - */ -iobuf_t -open_sigfile( const char *iname, progress_filter_context_t *pfx ) -{ - iobuf_t a = NULL; - size_t len; - - if( iname && !(*iname == '-' && !iname[1]) ) { - len = strlen(iname); - if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig") - || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") ) - || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) { - char *buf; - buf = xstrdup (iname); - buf[len-(buf[len-1]=='n'?5:4)] = 0 ; - a = iobuf_open( buf ); - if( a && opt.verbose ) - log_info(_("assuming signed data in `%s'\n"), buf ); - if (a && pfx) - handle_progress (pfx, a, buf); - xfree (buf); - } - } - return a; -} - -/**************** - * Copy the option file skeleton to the given directory. - */ -static void -copy_options_file( const char *destdir ) -{ - const char *datadir = GNUPG_DATADIR; - char *fname; - FILE *src, *dst; - int linefeeds=0; - int c; - mode_t oldmask; - int esc = 0; - int any_option = 0; - - if( opt.dry_run ) - return; - - fname = xmalloc ( strlen(datadir) + strlen(destdir) + 15 ); - strcpy(stpcpy(fname, datadir), DIRSEP_S "options" SKELEXT ); - src = fopen( fname, "r" ); - if( !src ) { - log_error(_("%s: can't open: %s\n"), fname, strerror(errno) ); - xfree (fname); - return; - } - strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" ); - oldmask=umask(077); - dst = fopen( fname, "w" ); - umask(oldmask); - if( !dst ) { - log_error(_("%s: can't create: %s\n"), fname, strerror(errno) ); - fclose( src ); - xfree (fname); - return; - } - - while( (c=getc(src)) != EOF ) { - if( linefeeds < 3 ) { - if( c == '\n' ) - linefeeds++; - } - else { - putc( c, dst ); - if (c== '\n') - esc = 1; - else if (esc == 1) { - if (c == ' ' || c == '\t') - ; - else if (c == '#') - esc = 2; - else - any_option = 1; - } - } - } - fclose( dst ); - fclose( src ); - log_info(_("new configuration file `%s' created\n"), fname ); - if (any_option) - log_info (_("WARNING: options in `%s'" - " are not yet active during this run\n"), - fname); - xfree (fname); -} - - -void -try_make_homedir( const char *fname ) -{ - const char *defhome = GNUPG_DEFAULT_HOMEDIR; - - /* Create the directory only if the supplied directory name - * is the same as the default one. This way we avoid to create - * arbitrary directories when a non-default homedirectory is used. - * To cope with HOME, we do compare only the suffix if we see that - * the default homedir does start with a tilde. - */ - if( opt.dry_run || opt.no_homedir_creation ) - return; - - if ( ( *defhome == '~' - && ( strlen(fname) >= strlen (defhome+1) - && !strcmp(fname+strlen(fname)-strlen(defhome+1), - defhome+1 ) )) - || ( *defhome != '~' - && !compare_filenames( fname, defhome ) ) - ) { - if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) - log_fatal( _("%s: can't create directory: %s\n"), - fname, strerror(errno) ); - else if( !opt.quiet ) - log_info( _("%s: directory created\n"), fname ); - copy_options_file( fname ); -/* log_info(_("you have to start GnuPG again, " */ -/* "so it can read the new configuration file\n") ); */ -/* g10_exit(1); */ - } -} diff --git a/g10/options.h b/g10/options.h deleted file mode 100644 index a4cbc3834..000000000 --- a/g10/options.h +++ /dev/null @@ -1,255 +0,0 @@ -/* options.h - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_OPTIONS_H -#define G10_OPTIONS_H - -#include <types.h> -#include "main.h" -#include "packet.h" - -#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */ - -#ifndef EXTERN_UNLESS_MAIN_MODULE -/* Norcraft can't cope with common symbols */ -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif - -EXTERN_UNLESS_MAIN_MODULE -struct { - int verbose; - int quiet; - unsigned debug; - int armor; - int compress; - char *outfile; - int dry_run; - int list_only; - int textmode; - int expert; - int ask_sig_expire; - int ask_cert_expire; - int batch; /* run in batch mode */ - int answer_yes; /* answer yes on most questions */ - int answer_no; /* answer no on most questions */ - int check_sigs; /* check key signatures */ - int with_colons; - int with_key_data; - int with_fingerprint; /* opt --with-fingerprint active */ - int fingerprint; /* list fingerprints */ - int list_sigs; /* list signatures */ - int no_armor; - int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/ - int def_cipher_algo; - int force_v3_sigs; - int force_v4_certs; - int force_mdc; - int disable_mdc; - int def_digest_algo; - int cert_digest_algo; - int def_compress_algo; - const char *def_secret_key; - char *def_recipient; - int def_recipient_self; - int def_cert_check_level; - int sk_comments; - int no_version; - int marginals_needed; - int completes_needed; - int max_cert_depth; - const char *homedir; - const char *agent_program; - char *display; /* 5 options to be passed to the gpg-agent */ - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - - int skip_verify; - int compress_keys; - int compress_sigs; - /* TM_CLASSIC must be zero to accomodate trustdbs generated before - we started storing the trust model inside the trustdb. */ - enum {TM_CLASSIC=0, TM_PGP=1, TM_ALWAYS, TM_AUTO} trust_model; - unsigned int force_ownertrust; - enum - { - CO_GNUPG=0, CO_RFC2440, CO_RFC1991, CO_PGP2, CO_PGP6, CO_PGP7, CO_PGP8 - } compliance; - int pgp2_workarounds; - unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */ - int shm_coprocess; - const char *set_filename; - STRLIST comments; - int throw_keyid; - const char *photo_viewer; - int s2k_mode; - int s2k_digest_algo; - int s2k_cipher_algo; - int simple_sk_checksum; /* create the deprecated rfc2440 secret - key protection*/ - int not_dash_escaped; - int escape_from; - int lock_once; - char *keyserver_uri; - char *keyserver_scheme; - char *keyserver_host; - char *keyserver_port; - char *keyserver_opaque; - struct - { - int verbose; - int include_revoked; - int include_disabled; - int include_subkeys; - int honor_http_proxy; - int broken_http_proxy; - int use_temp_files; - int keep_temp_files; - int fake_v3_keyids; - int auto_key_retrieve; - int try_dns_srv; - unsigned int import_options; - unsigned int export_options; - STRLIST other; - } keyserver_options; - int exec_disable; - int exec_path_set; - unsigned int import_options; - unsigned int export_options; - unsigned int list_options; - unsigned int verify_options; - char *def_preference_list; - prefitem_t *personal_cipher_prefs; - prefitem_t *personal_digest_prefs; - prefitem_t *personal_compress_prefs; - int no_perm_warn; - int no_mdc_warn; - char *temp_dir; - int no_encrypt_to; - int interactive; - STRLIST sig_notation_data; - STRLIST cert_notation_data; - STRLIST sig_policy_url; - STRLIST cert_policy_url; - STRLIST sig_keyserver_url; - int use_embedded_filename; - int allow_non_selfsigned_uid; - int allow_freeform_uid; - int no_literal; - ulong set_filesize; - int fast_list_mode; - int fixed_list_mode; - int ignore_time_conflict; - int ignore_valid_from; - int ignore_crc_error; - int ignore_mdc_error; - int command_fd; - const char *override_session_key; - int show_session_key; - int use_agent; - const char *gpg_agent_info; - int merge_only; - int try_all_secrets; - int no_expensive_trust_checks; - int no_sig_cache; - int no_sig_create_check; - int no_auto_check_trustdb; - int preserve_permissions; - int no_homedir_creation; - struct groupitem *grouplist; - int strict; - int mangle_dos_filenames; - int enable_progress_filter; -} opt; - - -#define EMUBUG_MDENCODE 4 - -#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CIPHER_VALUE 4 /* debug cipher handling */ - /* (may reveal sensitive data) */ -#define DBG_FILTER_VALUE 8 /* debug internal filter handling */ -#define DBG_IOBUF_VALUE 16 /* debug iobuf stuff */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the cacheing */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_TRUST_VALUE 256 /* debug the trustdb */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_EXTPROG_VALUE 1024 /* debug external program calls */ - - -#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE) -#define DBG_CIPHER (opt.debug & DBG_CIPHER_VALUE) -#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) - -#define GNUPG (opt.compliance==CO_GNUPG) -#define RFC1991 (opt.compliance==CO_RFC1991 || opt.compliance==CO_PGP2) -#define RFC2440 (opt.compliance==CO_RFC2440) -#define PGP2 (opt.compliance==CO_PGP2) -#define PGP6 (opt.compliance==CO_PGP6) -#define PGP7 (opt.compliance==CO_PGP7) -#define PGP8 (opt.compliance==CO_PGP8) - -/* Various option flags */ - -#define IMPORT_ALLOW_LOCAL_SIGS 1 -#define IMPORT_REPAIR_PKS_SUBKEY_BUG 2 -#define IMPORT_FAST_IMPORT 4 -#define IMPORT_SK2PK 8 - -#define EXPORT_INCLUDE_NON_RFC 1 -#define EXPORT_INCLUDE_LOCAL_SIGS 2 -#define EXPORT_INCLUDE_ATTRIBUTES 4 -#define EXPORT_INCLUDE_SENSITIVE_REVKEYS 8 -#define EXPORT_SEXP_FORMAT 16 - - -#define LIST_SHOW_PHOTOS 1 -#define LIST_SHOW_POLICY 2 -#define LIST_SHOW_NOTATION 4 -#define LIST_SHOW_KEYSERVER 8 -#define LIST_SHOW_VALIDITY 16 -#define LIST_SHOW_LONG_KEYID 32 -#define LIST_SHOW_KEYRING 64 -#define LIST_SHOW_SIG_EXPIRE 128 - - -#define VERIFY_SHOW_PHOTOS 1 -#define VERIFY_SHOW_POLICY 2 -#define VERIFY_SHOW_NOTATION 4 -#define VERIFY_SHOW_KEYSERVER 8 -#define VERIFY_SHOW_VALIDITY 16 -#define VERIFY_SHOW_LONG_KEYID 32 - -#endif /*G10_OPTIONS_H*/ - - - - diff --git a/g10/options.skel b/g10/options.skel deleted file mode 100644 index 3d15f811c..000000000 --- a/g10/options.skel +++ /dev/null @@ -1,212 +0,0 @@ -# These first three lines are not copied to the gpg.conf file in -# the users home directory. -# $Id$ -# Options for GnuPG -# Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Unless you specify which option file to use (with the command line -# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf -# by default. -# -# An options file can contain any long options which are available in -# GnuPG. If the first non white space character of a line is a '#', -# this line is ignored. Empty lines are also ignored. -# -# See the man page for a list of options. - -# Uncomment the following option to get rid of the copyright notice - -#no-greeting - -# If you have more than 1 secret key in your keyring, you may want to -# uncomment the following option and set your preferred keyid. - -#default-key 621CC013 - -# If you do not pass a recipient to gpg, it will ask for one. Using -# this option you can encrypt to a default key. Key validation will -# not be done in this case. The second form uses the default key as -# default recipient. - -#default-recipient some-user-id -#default-recipient-self - -# By default GnuPG creates version 3 signatures for data files. This -# is not strictly OpenPGP compliant but PGP 6 and most versions of PGP -# 7 require them. To disable this behavior, you may use this option -# or --openpgp. - -#no-force-v3-sigs - -# Because some mailers change lines starting with "From " to ">From " -# it is good to handle such lines in a special way when creating -# cleartext signatures; all other PGP versions do it this way too. -# To enable full OpenPGP compliance you may want to use this option. - -#no-escape-from-lines - -# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell -# GnuPG which is the native character set. Please check the man page -# for supported character sets. This character set is only used for -# metadata and not for the actual message which does not undergo any -# translation. Note that future version of GnuPG will change to UTF-8 -# as default character set. - -#charset utf-8 - -# Group names may be defined like this: -# group mynames = paige 0x12345678 joe patti -# -# Any time "mynames" is a recipient (-r or --recipient), it will be -# expanded to the names "paige", "joe", and "patti", and the key ID -# "0x12345678". Note there is only one level of expansion - you -# cannot make an group that points to another group. Note also that -# if there are spaces in the recipient name, this will appear as two -# recipients. In these cases it is better to use the key ID. - -#group mynames = paige 0x12345678 joe patti - -# Some old Windows platforms require 8.3 filenames. If your system -# can handle long filenames, uncomment this. - -#no-mangle-dos-filenames - -# Lock the file only once for the lifetime of a process. If you do -# not define this, the lock will be obtained and released every time -# it is needed - normally this is not needed. - -#lock-once - -# GnuPG can send and receive keys to and from a keyserver. These -# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP -# support). -# -# Example HKP keyserver: -# hkp://subkeys.pgp.net -# -# Example email keyserver: -# mailto:pgp-public-keys@keys.pgp.net -# -# Example LDAP keyservers: -# ldap://pgp.surfnet.nl:11370 -# ldap://keyserver.pgp.com -# -# Regular URL syntax applies, and you can set an alternate port -# through the usual method: -# hkp://keyserver.example.net:22742 -# -# If you have problems connecting to a HKP server through a buggy http -# proxy, you can use keyserver option broken-http-proxy (see below), -# but first you should make sure that you have read the man page -# regarding proxies (keyserver option honor-http-proxy) -# -# Most users just set the name and type of their preferred keyserver. -# Note that most servers (with the notable exception of -# ldap://keyserver.pgp.com) synchronize changes with each other. Note -# also that a single server name may actually point to multiple -# servers via DNS round-robin. hkp://subkeys.pgp.net is an example of -# such a "server", which spreads the load over a number of physical -# servers. - -keyserver hkp://subkeys.pgp.net -#keyserver mailto:pgp-public-keys@keys.nl.pgp.net -#keyserver ldap://pgp.surfnet.nl:11370 -#keyserver ldap://keyserver.pgp.com - -# Common options for keyserver functions: -# -# include-disabled = when searching, include keys marked as "disabled" -# on the keyserver (not all keyservers support this). -# -# no-include-revoked = when searching, do not include keys marked as -# "revoked" on the keyserver. -# -# verbose = show more information as the keys are fetched. -# Can be used more than once to increase the amount -# of information shown. -# -# use-temp-files = use temporary files instead of a pipe to talk to the -# keyserver. Some platforms (Win32 for one) always -# have this on. -# -# keep-temp-files = do not delete temporary files after using them -# (really only useful for debugging) -# -# honor-http-proxy = if the keyserver uses HTTP, honor the http_proxy -# environment variable -# -# broken-http-proxy = try to work around a buggy HTTP proxy -# -# auto-key-retrieve = automatically fetch keys as needed from the keyserver -# when verifying signatures or when importing keys that -# have been revoked by a revocation key that is not -# present on the keyring. -# -# no-include-attributes = do not include attribute IDs (aka "photo IDs") -# when sending keys to the keyserver. - -#keyserver-options auto-key-retrieve - -# Uncomment this line to display photo user IDs in key listings and -# when a signature from a key with a photo is verified. - -#show-photos - -# Use this program to display photo user IDs -# -# %i is expanded to a temporary file that contains the photo. -# %I is the same as %i, but the file isn't deleted afterwards by GnuPG. -# %k is expanded to the key ID of the key. -# %K is expanded to the long OpenPGP key ID of the key. -# %t is expanded to the extension of the image (e.g. "jpg"). -# %T is expanded to the MIME type of the image (e.g. "image/jpeg"). -# %f is expanded to the fingerprint of the key. -# %% is %, of course. -# -# If %i or %I are not present, then the photo is supplied to the -# viewer on standard input. If your platform supports it, standard -# input is the best way to do this as it avoids the time and effort in -# generating and then cleaning up a secure temp file. -# -# The default program is "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin" -# On Mac OS X and Windows, the default is to use your regular JPEG image -# viewer. -# -# Some other viewers: -# photo-viewer "qiv %i" -# photo-viewer "ee %i" -# photo-viewer "display -title 'KeyID 0x%k'" -# -# This one saves a copy of the photo ID in your home directory: -# photo-viewer "cat > ~/photoid-for-key-%k.%t" -# -# Use your MIME handler to view photos: -# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG" - -# Passphrase agent -# -# We support the old experimental passphrase agent protocol as well as -# the new Assuan based one (currently available in the "newpg" package -# at ftp.gnupg.org/gcrypt/alpha/aegypten/). To make use of the agent, -# you have to run an agent as daemon and use the option -# -# use-agent -# -# which tries to use the agent but will fallback to the regular mode -# if there is a problem connecting to the agent. The normal way to -# locate the agent is by looking at the environment variable -# GPG_AGENT_INFO which should have been set during gpg-agent startup. -# In certain situations the use of this variable is not possible, thus -# the option -# -# --gpg-agent-info=<path>:<pid>:1 -# -# may be used to override it. diff --git a/g10/packet.h b/g10/packet.h deleted file mode 100644 index 2d87c9c7d..000000000 --- a/g10/packet.h +++ /dev/null @@ -1,514 +0,0 @@ -/* packet.h - packet definitions - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_PACKET_H -#define G10_PACKET_H - -#include "gpg.h" -#include <gcrypt.h> - -#include "types.h" -#include "../common/iobuf.h" -#include "../jnlib/strlist.h" -#include "cipher.h" -#include "filter.h" -#include "global.h" - -#define DEBUG_PARSE_PACKET 1 - -typedef enum { - PKT_NONE =0, - PKT_PUBKEY_ENC =1, /* public key encrypted packet */ - PKT_SIGNATURE =2, /* secret key encrypted packet */ - PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/ - PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/ - PKT_SECRET_KEY =5, /* secret key */ - PKT_PUBLIC_KEY =6, /* public key */ - PKT_SECRET_SUBKEY =7, /* secret subkey (OpenPGP) */ - PKT_COMPRESSED =8, /* compressed data packet */ - PKT_ENCRYPTED =9, /* conventional encrypted data */ - PKT_MARKER =10, /* marker packet (OpenPGP) */ - PKT_PLAINTEXT =11, /* plaintext data with filename and mode */ - PKT_RING_TRUST =12, /* keyring trust packet */ - PKT_USER_ID =13, /* user id packet */ - PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */ - PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */ - PKT_ATTRIBUTE =17, /* PGP's attribute packet */ - PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */ - PKT_MDC =19, /* manipulation detection code packet */ - PKT_COMMENT =61, /* new comment packet (private) */ - PKT_GPG_CONTROL =63 /* internal control packet */ -} pkttype_t; - -typedef struct packet_struct PACKET; - -/* PKT_GPG_CONTROL types */ -typedef enum { - CTRLPKT_CLEARSIGN_START = 1, - CTRLPKT_PIPEMODE = 2, - CTRLPKT_PLAINTEXT_MARK =3 -} ctrlpkttype_t; - -typedef enum { - PREFTYPE_NONE = 0, - PREFTYPE_SYM = 1, - PREFTYPE_HASH = 2, - PREFTYPE_ZIP = 3 -} preftype_t; - -typedef struct { - byte type; - byte value; -} prefitem_t; - -typedef struct { - int mode; - byte hash_algo; - byte salt[8]; - u32 count; -} STRING2KEY; - -typedef struct { - byte version; - byte cipher_algo; /* cipher algorithm used */ - STRING2KEY s2k; - byte seskeylen; /* keylength in byte or 0 for no seskey */ - byte seskey[1]; -} PKT_symkey_enc; - -typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte version; - byte pubkey_algo; /* algorithm used for public key scheme */ - byte throw_keyid; - gcry_mpi_t data[PUBKEY_MAX_NENC]; -} PKT_pubkey_enc; - - -typedef struct { - u32 keyid[2]; /* 64 bit keyid */ - byte sig_class; /* sig classification */ - byte digest_algo; /* algorithm used for digest */ - byte pubkey_algo; /* algorithm used for public key scheme */ - byte last; /* a stupid flag */ -} PKT_onepass_sig; - - -typedef struct { - size_t size; /* allocated */ - size_t len; /* used */ - byte data[1]; -} subpktarea_t; - -struct revocation_key { - byte class; - byte algid; - byte fpr[MAX_FINGERPRINT_LEN]; -}; - -typedef struct { - ulong local_id; /* internal use, valid if > 0 */ - struct { - unsigned checked:1; /* signature has been checked */ - unsigned valid:1; /* signature is good (if checked is set) */ - unsigned unknown_critical:1; - unsigned exportable:1; - unsigned revocable:1; - unsigned policy_url:1; /* At least one policy URL is present */ - unsigned notation:1; /* At least one notation is present */ - unsigned pref_ks:1; /* At least one preferred keyserver is present */ - unsigned expired:1; - } flags; - u32 keyid[2]; /* 64 bit keyid */ - u32 timestamp; /* signature made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - byte version; - byte sig_class; /* sig classification, append for MD calculation*/ - byte pubkey_algo; /* algorithm used for public key scheme */ - /* (PUBKEY_ALGO_xxx) */ - byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */ - byte trust_depth; - byte trust_value; - const byte *trust_regexp; - struct revocation_key **revkey; - int numrevkeys; - subpktarea_t *hashed; /* all subpackets with hashed data (v4 only) */ - subpktarea_t *unhashed; /* ditto for unhashed data */ - byte digest_start[2]; /* first 2 bytes of the digest */ - gcry_mpi_t data[PUBKEY_MAX_NSIG]; -} PKT_signature; - -#define ATTRIB_IMAGE 1 - -/* This is the cooked form of attributes */ -struct user_attribute { - byte type; - const byte *data; - u32 len; -}; - -typedef struct { - int ref; /* reference counter */ - int len; /* length of the name */ - struct user_attribute *attribs; - int numattribs; - byte *attrib_data; /* if this is not NULL, the packet is an attribute */ - unsigned long attrib_len; - byte *namehash; - int help_key_usage; - u32 help_key_expire; - int help_full_count; - int help_marginal_count; - int is_primary; /* 2 if set via the primary flag, 1 if calculated */ - int is_revoked; - int is_expired; - u32 expiredate; /* expires at this date or 0 if not at all */ - prefitem_t *prefs; /* list of preferences (may be NULL)*/ - int mdc_feature; - int ks_modify; - u32 created; /* according to the self-signature */ - byte selfsigversion; - char name[1]; -} PKT_user_id; - - -/**************** - * Note about the pkey/skey elements: We assume that the secret keys - * has the same elemts as the public key at the begin of the array, so - * that npkey < nskey and it is possible to compare the secret and - * public keys by comparing the first npkey elements of pkey against skey. - */ -typedef struct { - u32 timestamp; /* key made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - u32 max_expiredate; /* must not expire past this date */ - byte hdrbytes; /* number of header bytes */ - byte version; - byte selfsigversion; /* highest version of all of the self-sigs */ - byte pubkey_algo; /* algorithm used for public key scheme */ - byte pubkey_usage; /* for now only used to pass it to getkey() */ - byte req_usage; /* hack to pass a request to getkey() */ - byte req_algo; /* Ditto */ - u32 has_expired; /* set to the expiration date if expired */ - int is_revoked; /* key has been revoked */ - int is_valid; /* key (especially subkey) is valid */ - int dont_cache; /* do not cache this */ - ulong local_id; /* internal use, valid if > 0 */ - u32 main_keyid[2]; /* keyid of the primary key */ - u32 keyid[2]; /* calculated by keyid_from_pk() */ - byte is_primary; - byte is_disabled; /* 0 for unset, 1 for enabled, 2 for disabled. */ - prefitem_t *prefs; /* list of preferences (may be NULL) */ - int mdc_feature; /* mdc feature set */ - PKT_user_id *user_id; /* if != NULL: found by that uid */ - struct revocation_key *revkey; - int numrevkeys; - u32 trust_timestamp; - byte trust_depth; - byte trust_value; - const byte *trust_regexp; - gcry_mpi_t pkey[PUBKEY_MAX_NPKEY]; -} PKT_public_key; - -/* Evaluates as true if the pk is disabled, and false if it isn't. If - there is no disable value cached, fill one in. */ -#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a)))) - -typedef struct { - u32 timestamp; /* key made */ - u32 expiredate; /* expires at this date or 0 if not at all */ - u32 max_expiredate; /* must not expire past this date */ - byte hdrbytes; /* number of header bytes */ - byte version; - byte pubkey_algo; /* algorithm used for public key scheme */ - byte pubkey_usage; - byte req_usage; - byte req_algo; - u32 has_expired; /* set to the expiration date if expired */ - int is_revoked; /* key has been revoked */ - int is_valid; /* key (especially subkey) is valid */ - u32 main_keyid[2]; /* keyid of the primary key */ - u32 keyid[2]; - byte is_primary; - byte is_protected; /* The secret info is protected and must */ - /* be decrypted before use, the protected */ - /* MPIs are simply (void*) pointers to memory */ - /* and should never be passed to a mpi_xxx() */ - struct { - byte algo; /* cipher used to protect the secret information*/ - byte sha1chk; /* SHA1 is used instead of a 16 bit checksum */ - STRING2KEY s2k; - byte ivlen; /* used length of the iv */ - byte iv[16]; /* initialization vector for CFB mode */ - } protect; - gcry_mpi_t skey[PUBKEY_MAX_NSKEY]; - u16 csum; /* checksum */ -} PKT_secret_key; - - -typedef struct { - int len; /* length of data */ - char data[1]; -} PKT_comment; - -typedef struct { - u32 len; /* reserved */ - byte new_ctb; - byte algorithm; - iobuf_t buf; /* iobuf_t reference */ -} PKT_compressed; - -typedef struct { - u32 len; /* length of encrypted data */ - int extralen; /* this is (blocksize+2) */ - byte new_ctb; /* uses a new CTB */ - byte mdc_method; /* > 0: integrity protected encrypted data packet */ - iobuf_t buf; /* iobuf_t reference */ -} PKT_encrypted; - -typedef struct { - byte hash[20]; -} PKT_mdc; - -typedef struct { - unsigned int trustval; - unsigned int sigcache; -} PKT_ring_trust; - -typedef struct { - u32 len; /* length of encrypted data */ - iobuf_t buf; /* iobuf_t reference */ - byte new_ctb; - byte is_partial; /* partial length encoded */ - int mode; - u32 timestamp; - int namelen; - char name[1]; -} PKT_plaintext; - -typedef struct { - int control; - size_t datalen; - char data[1]; -} PKT_gpg_control; - -/* combine all packets into a union */ -struct packet_struct { - pkttype_t pkttype; - union { - void *generic; - PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */ - PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */ - PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */ - PKT_signature *signature; /* PKT_SIGNATURE */ - PKT_public_key *public_key; /* PKT_PUBLIC_[SUB)KEY */ - PKT_secret_key *secret_key; /* PKT_SECRET_[SUB]KEY */ - PKT_comment *comment; /* PKT_COMMENT */ - PKT_user_id *user_id; /* PKT_USER_ID */ - PKT_compressed *compressed; /* PKT_COMPRESSED */ - PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC] */ - PKT_mdc *mdc; /* PKT_MDC */ - PKT_ring_trust *ring_trust; /* PKT_RING_TRUST */ - PKT_plaintext *plaintext; /* PKT_PLAINTEXT */ - PKT_gpg_control *gpg_control; /* PKT_GPG_CONTROL */ - } pkt; -}; - -#define init_packet(a) do { (a)->pkttype = 0; \ - (a)->pkt.generic = NULL; \ - } while(0) - -typedef enum { - SIGSUBPKT_TEST_CRITICAL=-3, - SIGSUBPKT_LIST_UNHASHED=-2, - SIGSUBPKT_LIST_HASHED =-1, - SIGSUBPKT_NONE = 0, - SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */ - SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */ - SIGSUBPKT_EXPORTABLE = 4, /* exportable */ - SIGSUBPKT_TRUST = 5, /* trust signature */ - SIGSUBPKT_REGEXP = 6, /* regular expression */ - SIGSUBPKT_REVOCABLE = 7, /* revocable */ - SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */ - SIGSUBPKT_ARR =10, /* additional recipient request */ - SIGSUBPKT_PREF_SYM =11, /* preferred symmetric algorithms */ - SIGSUBPKT_REV_KEY =12, /* revocation key */ - SIGSUBPKT_ISSUER =16, /* issuer key ID */ - SIGSUBPKT_NOTATION =20, /* notation data */ - SIGSUBPKT_PREF_HASH =21, /* preferred hash algorithms */ - SIGSUBPKT_PREF_COMPR =22, /* preferred compression algorithms */ - SIGSUBPKT_KS_FLAGS =23, /* key server preferences */ - SIGSUBPKT_PREF_KS =24, /* preferred key server */ - SIGSUBPKT_PRIMARY_UID =25, /* primary user id */ - SIGSUBPKT_POLICY =26, /* policy URL */ - SIGSUBPKT_KEY_FLAGS =27, /* key flags */ - SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */ - SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */ - SIGSUBPKT_FEATURES =30, /* feature flags */ - - SIGSUBPKT_FLAG_CRITICAL=128 -} sigsubpkttype_t; - - -/*-- mainproc.c --*/ -int proc_packets( void *ctx, iobuf_t a ); -int proc_signature_packets( void *ctx, iobuf_t a, - STRLIST signedfiles, const char *sigfile ); -int proc_encryption_packets( void *ctx, iobuf_t a ); -int list_packets( iobuf_t a ); - -/*-- parse-packet.c --*/ -int set_packet_list_mode( int mode ); - -#if DEBUG_PARSE_PACKET -int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid, - const char* file, int lineno ); -int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt, - const char* file, int lineno ); -int dbg_copy_all_packets( iobuf_t inp, iobuf_t out, - const char* file, int lineno ); -int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff, - const char* file, int lineno ); -int dbg_skip_some_packets( iobuf_t inp, unsigned n, - const char* file, int lineno ); -#define search_packet( a,b,c,d ) \ - dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ ) -#define parse_packet( a, b ) \ - dbg_parse_packet( (a), (b), __FILE__, __LINE__ ) -#define copy_all_packets( a,b ) \ - dbg_copy_all_packets((a),(b), __FILE__, __LINE__ ) -#define copy_some_packets( a,b,c ) \ - dbg_copy_some_packets((a),(b),(c), __FILE__, __LINE__ ) -#define skip_some_packets( a,b ) \ - dbg_skip_some_packets((a),(b), __FILE__, __LINE__ ) -#else -int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid ); -int parse_packet( iobuf_t inp, PACKET *ret_pkt); -int copy_all_packets( iobuf_t inp, iobuf_t out ); -int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff ); -int skip_some_packets( iobuf_t inp, unsigned n ); -#endif - -const byte *enum_sig_subpkt ( const subpktarea_t *subpkts, - sigsubpkttype_t reqtype, - size_t *ret_n, int *start, int *critical ); -const byte *parse_sig_subpkt ( const subpktarea_t *buffer, - sigsubpkttype_t reqtype, - size_t *ret_n ); -const byte *parse_sig_subpkt2 ( PKT_signature *sig, - sigsubpkttype_t reqtype, - size_t *ret_n ); -int parse_one_sig_subpkt( const byte *buffer, size_t n, int type ); -void parse_revkeys(PKT_signature *sig); -int parse_attribute_subpkts(PKT_user_id *uid); -void make_attribute_uidname(PKT_user_id *uid, size_t max_namelen); -PACKET *create_gpg_control ( ctrlpkttype_t type, - const byte *data, - size_t datalen ); - -/*-- build-packet.c --*/ -int build_packet( iobuf_t inp, PACKET *pkt ); -u32 calc_packet_length( PACKET *pkt ); -void hash_public_key( MD_HANDLE md, PKT_public_key *pk ); -void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, - const byte *buffer, size_t buflen ); -void build_sig_subpkt_from_sig( PKT_signature *sig ); -int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type ); -void build_attribute_subpkt(PKT_user_id *uid,byte type, - const void *buf,u32 buflen, - const void *header,u32 headerlen); - -/*-- free-packet.c --*/ -void free_symkey_enc( PKT_symkey_enc *enc ); -void free_pubkey_enc( PKT_pubkey_enc *enc ); -void free_seckey_enc( PKT_signature *enc ); -int digest_algo_from_sig( PKT_signature *sig ); -void release_public_key_parts( PKT_public_key *pk ); -void free_public_key( PKT_public_key *key ); -void release_secret_key_parts( PKT_secret_key *sk ); -void free_secret_key( PKT_secret_key *sk ); -void free_attributes(PKT_user_id *uid); -void free_user_id( PKT_user_id *uid ); -void free_comment( PKT_comment *rem ); -void free_packet( PACKET *pkt ); -prefitem_t *copy_prefs (const prefitem_t *prefs); -PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s ); -void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); -PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ); -PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s ); -PKT_user_id *scopy_user_id (PKT_user_id *sd ); -int cmp_public_keys( PKT_public_key *a, PKT_public_key *b ); -int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b ); -int cmp_signatures( PKT_signature *a, PKT_signature *b ); -int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); -int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); - - -/*-- sig-check.c --*/ -int signature_check( PKT_signature *sig, MD_HANDLE digest ); -int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ); - -/*-- seckey-cert.c --*/ -int is_secret_key_protected( PKT_secret_key *sk ); -int check_secret_key( PKT_secret_key *sk, int retries ); -int protect_secret_key( PKT_secret_key *sk, DEK *dek ); - -/*-- pubkey-enc.c --*/ -int get_session_key( PKT_pubkey_enc *k, DEK *dek ); -int get_override_session_key( DEK *dek, const char *string ); - -/*-- compress.c --*/ -int handle_compressed( void *ctx, PKT_compressed *cd, - int (*callback)(iobuf_t, void *), void *passthru ); - -/*-- encr-data.c --*/ -int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek ); - -/*-- plaintext.c --*/ -int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, - int nooutput, int clearsig, int *create_failed ); -int ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2, - const char *inname, int textmode ); - -/*-- comment.c --*/ -int write_comment( iobuf_t out, const char *s ); - -/*-- sign.c --*/ -int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, - PKT_user_id *uid, PKT_public_key *subpk, - PKT_secret_key *sk, int sigclass, int digest_algo, - int sigversion, u32 timestamp, u32 duration, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque ); -int update_keysig_packet( PKT_signature **ret_sig, - PKT_signature *orig_sig, - PKT_public_key *pk, - PKT_user_id *uid, - PKT_public_key *subpk, - PKT_secret_key *sk, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque ); - -/*-- keygen.c --*/ -PKT_user_id *generate_user_id(void); - -#endif /*G10_PACKET_H*/ diff --git a/g10/parse-packet.c b/g10/parse-packet.c deleted file mode 100644 index c922eb5d9..000000000 --- a/g10/parse-packet.c +++ /dev/null @@ -1,2332 +0,0 @@ -/* parse-packet.c - read packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "packet.h" -#include "iobuf.h" -#include "mpi.h" -#include "util.h" -#include "cipher.h" -#include "memory.h" -#include "filter.h" -#include "photoid.h" -#include "options.h" -#include "main.h" -#include "i18n.h" - -static int mpi_print_mode = 0; -static int list_mode = 0; - -static int parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, - off_t *retpos, int *skip, iobuf_t out, int do_skip -#ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l -#endif - ); -static int copy_packet( iobuf_t inp, iobuf_t out, int pkttype, - unsigned long pktlen ); -static void skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen ); -static void skip_rest( iobuf_t inp, unsigned long pktlen ); -static void *read_rest( iobuf_t inp, size_t pktlen ); -static int parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_signature *sig ); -static int parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_onepass_sig *ops ); -static int parse_key( iobuf_t inp, int pkttype, unsigned long pktlen, - byte *hdr, int hdrlen, PACKET *packet ); -static int parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static void parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb ); -static int parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_gpg_control( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *packet ); - -static unsigned short -read_16(iobuf_t inp) -{ - unsigned short a; - a = iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; -} - -static unsigned long -read_32(iobuf_t inp) -{ - unsigned long a; - a = iobuf_get_noeof(inp) << 24; - a |= iobuf_get_noeof(inp) << 16; - a |= iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; -} - - -int -set_packet_list_mode( int mode ) -{ - int old = list_mode; - list_mode = mode; - /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */ - return old; -} - -static void -unknown_pubkey_warning( int algo ) -{ - static byte unknown_pubkey_algos[256]; - - algo &= 0xff; - if( !unknown_pubkey_algos[algo] ) { - if( opt.verbose ) - log_info(_("can't handle public key algorithm %d\n"), algo ); - unknown_pubkey_algos[algo] = 1; - } -} - -/**************** - * Parse a Packet and return it in packet - * Returns: 0 := valid packet in pkt - * -1 := no more packets - * >0 := error - * Note: The function may return an error and a partly valid packet; - * caller must free this packet. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_parse_packet( iobuf_t inp, PACKET *pkt, const char *dbg_f, int dbg_l ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l ); - } while( skip ); - return rc; -} -#else -int -parse_packet( iobuf_t inp, PACKET *pkt ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 ); - } while( skip ); - return rc; -} -#endif - -/**************** - * Like parse packet, but only return secret or public (sub)key packets. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid, - const char *dbg_f, int dbg_l ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l ); - } while( skip ); - return rc; -} -#else -int -search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid ) -{ - int skip, rc; - - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 ); - } while( skip ); - return rc; -} -#endif - -/**************** - * Copy all packets from INP to OUT, thereby removing unused spaces. - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_copy_all_packets( iobuf_t inp, iobuf_t out, - const char *dbg_f, int dbg_l ) -{ - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l ))); - return rc; -} -#else -int -copy_all_packets( iobuf_t inp, iobuf_t out ) -{ - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 ))); - return rc; -} -#endif - -/**************** - * Copy some packets from INP to OUT, thereby removing unused spaces. - * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets) - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff, - const char *dbg_f, int dbg_l ) -{ - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, - "some", dbg_f, dbg_l )) ); - return rc; -} -#else -int -copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff ) -{ - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) ); - return rc; -} -#endif - -/**************** - * Skip over N packets - */ -#ifdef DEBUG_PARSE_PACKET -int -dbg_skip_some_packets( iobuf_t inp, unsigned n, - const char *dbg_f, int dbg_l ) -{ - int skip, rc=0; - PACKET pkt; - - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l ); - } - return rc; -} -#else -int -skip_some_packets( iobuf_t inp, unsigned n ) -{ - int skip, rc=0; - PACKET pkt; - - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 ); - } - return rc; -} -#endif - - -/**************** - * Parse packet. Set the variable skip points to 1 if the packet - * should be skipped; this is the case if either ONLYKEYPKTS is set - * and the parsed packet isn't one or the - * packet-type is 0, indicating deleted stuff. - * if OUT is not NULL, a special copymode is used. - */ -static int -parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, off_t *retpos, - int *skip, iobuf_t out, int do_skip -#ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l -#endif - ) -{ - int rc=0, c, ctb, pkttype, lenbytes; - unsigned long pktlen; - byte hdr[8]; - int hdrlen; - int new_ctb = 0; - int with_uid = (onlykeypkts == 2); - - *skip = 0; - assert( !pkt->pkt.generic ); - if( retpos ) - *retpos = iobuf_tell(inp); - - if( (ctb = iobuf_get(inp)) == -1 ) { - rc = -1; - goto leave; - } - hdrlen=0; - hdr[hdrlen++] = ctb; - if( !(ctb & 0x80) ) { - log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - pktlen = 0; - new_ctb = !!(ctb & 0x40); - if( new_ctb ) { - pkttype = ctb & 0x3f; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if (pkttype == PKT_COMPRESSED) { - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - } - else { - hdr[hdrlen++] = c; - if( c < 192 ) - pktlen = c; - else if( c < 224 ) { - pktlen = (c - 192) * 256; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 2nd length byte missing\n", - iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - hdr[hdrlen++] = c; - pktlen += c + 192; - } - else if( c == 255 ) { - pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 4 byte length invalid\n", - iobuf_where(inp) ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - pktlen |= (hdr[hdrlen++] = c ); - } - else { /* partial body length */ - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - } - } - } - else { - pkttype = (ctb>>2)&0xf; - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - if( !lenbytes ) { - pktlen = 0; /* don't know the value */ - switch (pkttype) { - case PKT_ENCRYPTED: - case PKT_PLAINTEXT: - /* These partial length encodings are from an very - early GnuPG release and deprecated. However we - still support them read-wise. Note, that we should - not allow them for any key related packets, because - this might render a keyring unusable if an errenous - packet indicated this mode but not complying to it - gets imported. */ - iobuf_set_block_mode(inp, 1); - break; - - case PKT_COMPRESSED: - break; /* the orginal pgp 2 way. */ - - default: - log_error ("%s: old style partial length " - "for invalid packet type\n", iobuf_where(inp) ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - } - else { - for( ; lenbytes; lenbytes-- ) { - pktlen <<= 8; - pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp); - } - } - } - - if (pktlen == 0xffffffff) { - /* with a some probability this is caused by a problem in the - * the uncompressing layer - in some error cases it just loops - * and spits out 0xff bytes. */ - log_error ("%s: garbled packet detected\n", iobuf_where(inp) ); - g10_exit (2); - } - - if( out && pkttype ) { - rc = iobuf_write( out, hdr, hdrlen ); - if (!rc) - rc = copy_packet(inp, out, pkttype, pktlen ); - goto leave; - } - - if (with_uid && pkttype == PKT_USER_ID) - ; - else if( do_skip - || !pkttype - || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY - && pkttype != PKT_PUBLIC_KEY - && pkttype != PKT_SECRET_SUBKEY - && pkttype != PKT_SECRET_KEY ) ) { - skip_rest(inp, pktlen); - *skip = 1; - rc = 0; - goto leave; - } - - if( DBG_PACKET ) { -#ifdef DEBUG_PARSE_PACKET - log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"", - dbg_w, dbg_f, dbg_l ); -#else - log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" ); -#endif - } - pkt->pkttype = pkttype; - rc = GPG_ERR_UNKNOWN_PACKET; /* default error */ - switch( pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = xcalloc (1,sizeof *pkt->pkt.public_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - pkt->pkt.secret_key = xcalloc (1,sizeof *pkt->pkt.secret_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SYMKEY_ENC: - rc = parse_symkeyenc( inp, pkttype, pktlen, pkt ); - break; - case PKT_PUBKEY_ENC: - rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt ); - break; - case PKT_SIGNATURE: - pkt->pkt.signature = xcalloc (1,sizeof *pkt->pkt.signature ); - rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature ); - break; - case PKT_ONEPASS_SIG: - pkt->pkt.onepass_sig = xcalloc (1,sizeof *pkt->pkt.onepass_sig ); - rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig ); - break; - case PKT_USER_ID: - rc = parse_user_id(inp, pkttype, pktlen, pkt ); - break; - case PKT_ATTRIBUTE: - pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */ - rc = parse_attribute(inp, pkttype, pktlen, pkt); - break; - case PKT_OLD_COMMENT: - case PKT_COMMENT: - rc = parse_comment(inp, pkttype, pktlen, pkt); - break; - case PKT_RING_TRUST: - parse_trust(inp, pkttype, pktlen, pkt); - rc = 0; - break; - case PKT_PLAINTEXT: - rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_COMPRESSED: - rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_MDC: - rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_GPG_CONTROL: - rc = parse_gpg_control(inp, pkttype, pktlen, pkt ); - break; - default: - skip_packet(inp, pkttype, pktlen); - break; - } - - leave: - if( !rc && iobuf_error(inp) ) - rc = GPG_ERR_INV_KEYRING; - return rc; -} - -static void -dump_hex_line( int c, int *i ) -{ - if( *i && !(*i%8) ) { - if( *i && !(*i%24) ) - printf("\n%4d:", *i ); - else - putchar(' '); - } - if( c == -1 ) - printf(" EOF" ); - else - printf(" %02x", c ); - ++*i; -} - - -static int -copy_packet( iobuf_t inp, iobuf_t out, int pkttype, unsigned long pktlen ) -{ - int rc, n; - char buf[100]; - - if( iobuf_in_block_mode(inp) ) { - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - else if( !pktlen && pkttype == PKT_COMPRESSED ) { - log_debug("copy_packet: compressed!\n"); - /* compressed packet, copy till EOF */ - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - else { - for( ; pktlen; pktlen -= n ) { - n = pktlen > 100 ? 100 : pktlen; - n = iobuf_read( inp, buf, n ); - if( n == -1 ) - return GPG_ERR_GENERAL; /* FIXME(gcrypt): read error*/; - if( (rc = iobuf_write(out, buf, n )) ) - return rc; /* write error */ - } - } - return 0; -} - - -static void -skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen ) -{ - if( list_mode ) { - if( pkttype == PKT_MARKER ) - fputs(":marker packet:\n", stdout ); - else - printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen); - if( pkttype ) { - int c, i=0 ; - if( pkttype != PKT_MARKER ) - fputs("dump:", stdout ); - if( iobuf_in_block_mode(inp) ) { - while( (c=iobuf_get(inp)) != -1 ) - dump_hex_line(c, &i); - } - else { - for( ; pktlen; pktlen-- ) - dump_hex_line(iobuf_get(inp), &i); - } - putchar('\n'); - return; - } - } - skip_rest(inp,pktlen); -} - -static void -skip_rest( iobuf_t inp, unsigned long pktlen ) -{ - if( iobuf_in_block_mode(inp) ) { - while( iobuf_get(inp) != -1 ) - ; - } - else { - for( ; pktlen; pktlen-- ) - if( iobuf_get(inp) == -1 ) - break; - } -} - - -static void * -read_rest( iobuf_t inp, size_t pktlen ) -{ - byte *p; - int i; - - if( iobuf_in_block_mode(inp) ) { - log_error("read_rest: can't store stream data\n"); - p = NULL; - } - else { - p = xmalloc ( pktlen ); - for(i=0; pktlen; pktlen--, i++ ) - p[i] = iobuf_get(inp); - } - return p; -} - - - -static int -parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - PKT_symkey_enc *k; - int rc = 0; - int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; - - if( pktlen < 4 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - version = iobuf_get_noeof(inp); pktlen--; - if( version != 4 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */ - log_error("packet(%d) too large\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - cipher_algo = iobuf_get_noeof(inp); pktlen--; - s2kmode = iobuf_get_noeof(inp); pktlen--; - hash_algo = iobuf_get_noeof(inp); pktlen--; - switch( s2kmode ) { - case 0: /* simple s2k */ - minlen = 0; - break; - case 1: /* salted s2k */ - minlen = 8; - break; - case 3: /* iterated+salted s2k */ - minlen = 9; - break; - default: - log_error("unknown S2K %d\n", s2kmode ); - goto leave; - } - if( minlen > pktlen ) { - log_error("packet with S2K %d too short\n", s2kmode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - seskeylen = pktlen - minlen; - k = packet->pkt.symkey_enc = xcalloc (1, sizeof *packet->pkt.symkey_enc - + seskeylen - 1 ); - k->version = version; - k->cipher_algo = cipher_algo; - k->s2k.mode = s2kmode; - k->s2k.hash_algo = hash_algo; - if( s2kmode == 1 || s2kmode == 3 ) { - for(i=0; i < 8 && pktlen; i++, pktlen-- ) - k->s2k.salt[i] = iobuf_get_noeof(inp); - } - if( s2kmode == 3 ) { - k->s2k.count = iobuf_get(inp); pktlen--; - } - k->seskeylen = seskeylen; - for(i=0; i < seskeylen && pktlen; i++, pktlen-- ) - k->seskey[i] = iobuf_get_noeof(inp); - assert( !pktlen ); - - if( list_mode ) { - printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n", - version, cipher_algo, s2kmode, hash_algo); - if( s2kmode == 1 || s2kmode == 3 ) { - printf("\tsalt "); - for(i=0; i < 8; i++ ) - printf("%02x", k->s2k.salt[i]); - if( s2kmode == 3 ) - printf(", count %lu\n", (ulong)k->s2k.count ); - printf("\n"); - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - -static int -parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - unsigned int n; - int rc = 0; - int i, ndata; - PKT_pubkey_enc *k; - - k = packet->pkt.pubkey_enc = xcalloc (1,sizeof *packet->pkt.pubkey_enc); - if( pktlen < 12 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - k->version = iobuf_get_noeof(inp); pktlen--; - if( k->version != 2 && k->version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, k->version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - k->keyid[0] = read_32(inp); pktlen -= 4; - k->keyid[1] = read_32(inp); pktlen -= 4; - k->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - k->throw_keyid = 0; /* only used as flag for build_packet */ - if( list_mode ) - printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n", - k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]); - - ndata = pubkey_get_nenc(k->pubkey_algo); - if( !ndata ) { - if( list_mode ) - printf("\tunsupported algorithm %d\n", k->pubkey_algo ); - unknown_pubkey_warning( k->pubkey_algo ); - k->data[0] = NULL; /* no need to store the encrypted data */ - } - else { - for( i=0; i < ndata; i++ ) { - n = pktlen; - k->data[i] = mpi_read(inp, &n, 0); pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, k->data[i], mpi_print_mode ); - putchar('\n'); - } - if (!k->data[i]) - rc = GPG_ERR_INV_PACKET; - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static void -dump_sig_subpkt( int hashed, int type, int critical, - const byte *buffer, size_t buflen, size_t length ) -{ - const char *p=NULL; - int i; - - /* The CERT has warning out with explains how to use GNUPG to - * detect the ARRs - we print our old message here when it is a faked - * ARR and add an additional notice */ - if ( type == SIGSUBPKT_ARR && !hashed ) { - printf("\tsubpkt %d len %u (additional recipient request)\n" - "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically " - "encrypt to this key and thereby reveal the plaintext to " - "the owner of this ARR key. Detailed info follows:\n", - type, (unsigned)length ); - } - - buffer++; - length--; - - printf("\t%s%ssubpkt %d len %u (", /*)*/ - critical ? "critical ":"", - hashed ? "hashed ":"", type, (unsigned)length ); - if( length > buflen ) { - printf("too short: buffer is only %u)\n", (unsigned)buflen ); - return; - } - switch( type ) { - case SIGSUBPKT_SIG_CREATED: - if( length >= 4 ) - printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_SIG_EXPIRE: - if( length >= 4 ) - printf("sig expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_EXPORTABLE: - if( length ) - printf("%sexportable", *buffer? "":"not "); - break; - case SIGSUBPKT_TRUST: - if(length!=2) - p="[invalid trust subpacket]"; - else - printf("trust signature of depth %d, value %d",buffer[0],buffer[1]); - break; - case SIGSUBPKT_REGEXP: - if(!length) - p="[invalid regexp subpacket]"; - else - printf("regular expression: \"%s\"",buffer); - break; - case SIGSUBPKT_REVOCABLE: - if( length ) - printf("%srevocable", *buffer? "":"not "); - break; - case SIGSUBPKT_KEY_EXPIRE: - if( length >= 4 ) - printf("key expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); - break; - case SIGSUBPKT_PREF_SYM: - fputs("pref-sym-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_REV_KEY: - fputs("revocation key: ", stdout ); - if( length < 22 ) - p = "[too short]"; - else { - printf("c=%02x a=%d f=", buffer[0], buffer[1] ); - for( i=2; i < length; i++ ) - printf("%02X", buffer[i] ); - } - break; - case SIGSUBPKT_ISSUER: - if( length >= 8 ) - printf("issuer key ID %08lX%08lX", - (ulong)buffer_to_u32(buffer), - (ulong)buffer_to_u32(buffer+4) ); - break; - case SIGSUBPKT_NOTATION: - { - fputs("notation: ", stdout ); - if( length < 8 ) - p = "[too short]"; - else { - const byte *s = buffer; - size_t n1, n2; - - n1 = (s[4] << 8) | s[5]; - n2 = (s[6] << 8) | s[7]; - s += 8; - if( 8+n1+n2 != length ) - p = "[error]"; - else { - print_string( stdout, s, n1, ')' ); - putc( '=', stdout ); - - if( *buffer & 0x80 ) - print_string( stdout, s+n1, n2, ')' ); - else - p = "[not human readable]"; - } - } - } - break; - case SIGSUBPKT_PREF_HASH: - fputs("pref-hash-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_PREF_COMPR: - fputs("pref-zip-algos:", stdout ); - for( i=0; i < length; i++ ) - printf(" %d", buffer[i] ); - break; - case SIGSUBPKT_KS_FLAGS: - fputs("key server preferences:",stdout); - for(i=0;i<length;i++) - printf(" %02X", buffer[i]); - break; - case SIGSUBPKT_PREF_KS: - fputs("preferred key server: ", stdout ); - print_string( stdout, buffer, length, ')' ); - break; - case SIGSUBPKT_PRIMARY_UID: - p = "primary user ID"; - break; - case SIGSUBPKT_POLICY: - fputs("policy: ", stdout ); - print_string( stdout, buffer, length, ')' ); - break; - case SIGSUBPKT_KEY_FLAGS: - fputs ( "key flags:", stdout ); - for( i=0; i < length; i++ ) - printf(" %02X", buffer[i] ); - break; - case SIGSUBPKT_SIGNERS_UID: - p = "signer's user ID"; - break; - case SIGSUBPKT_REVOC_REASON: - if( length ) { - printf("revocation reason 0x%02x (", *buffer ); - print_string( stdout, buffer+1, length-1, ')' ); - p = ")"; - } - break; - case SIGSUBPKT_ARR: - fputs("Big Brother's key (ignored): ", stdout ); - if( length < 22 ) - p = "[too short]"; - else { - printf("c=%02x a=%d f=", buffer[0], buffer[1] ); - for( i=2; i < length; i++ ) - printf("%02X", buffer[i] ); - } - break; - case SIGSUBPKT_FEATURES: - fputs ( "features:", stdout ); - for( i=0; i < length; i++ ) - printf(" %02x", buffer[i] ); - break; - default: - if(type>=100 && type<=110) - p="experimental / private subpacket"; - else - p = "?"; - break; - } - - printf("%s)\n", p? p: ""); -} - -/**************** - * Returns: >= 0 offset into buffer - * -1 unknown type - * -2 unsupported type - * -3 subpacket too short - */ -int -parse_one_sig_subpkt( const byte *buffer, size_t n, int type ) -{ - switch( type ) { - case SIGSUBPKT_REV_KEY: - if(n < 22) - break; - return 0; - case SIGSUBPKT_SIG_CREATED: - case SIGSUBPKT_SIG_EXPIRE: - case SIGSUBPKT_KEY_EXPIRE: - if( n < 4 ) - break; - return 0; - case SIGSUBPKT_KEY_FLAGS: - case SIGSUBPKT_KS_FLAGS: - case SIGSUBPKT_PREF_SYM: - case SIGSUBPKT_PREF_HASH: - case SIGSUBPKT_PREF_COMPR: - case SIGSUBPKT_POLICY: - case SIGSUBPKT_PREF_KS: - case SIGSUBPKT_FEATURES: - case SIGSUBPKT_REGEXP: - return 0; - case SIGSUBPKT_EXPORTABLE: - case SIGSUBPKT_REVOCABLE: - if( !n ) - break; - return 0; - case SIGSUBPKT_ISSUER: /* issuer key ID */ - if( n < 8 ) - break; - return 0; - case SIGSUBPKT_NOTATION: - if( n < 8 ) /* minimum length needed */ - break; - return 0; - case SIGSUBPKT_REVOC_REASON: - if( !n ) - break; - return 0; - case SIGSUBPKT_PRIMARY_UID: - if ( n != 1 ) - break; - return 0; - case SIGSUBPKT_TRUST: - if ( n != 2 ) - break; - return 0; - default: return -1; - } - return -3; -} - - -static int -can_handle_critical( const byte *buffer, size_t n, int type ) -{ - switch( type ) { - case SIGSUBPKT_NOTATION: - if( n >= 8 && (*buffer & 0x80) ) - return 1; /* human readable is handled */ - return 0; - - case SIGSUBPKT_SIG_CREATED: - case SIGSUBPKT_SIG_EXPIRE: - case SIGSUBPKT_KEY_EXPIRE: - case SIGSUBPKT_EXPORTABLE: - case SIGSUBPKT_REVOCABLE: - case SIGSUBPKT_REV_KEY: - case SIGSUBPKT_ISSUER:/* issuer key ID */ - case SIGSUBPKT_PREF_SYM: - case SIGSUBPKT_PREF_HASH: - case SIGSUBPKT_PREF_COMPR: - case SIGSUBPKT_KEY_FLAGS: - case SIGSUBPKT_PRIMARY_UID: - case SIGSUBPKT_FEATURES: - case SIGSUBPKT_TRUST: - case SIGSUBPKT_REGEXP: - /* Is it enough to show the policy or keyserver? */ - case SIGSUBPKT_POLICY: - case SIGSUBPKT_PREF_KS: - return 1; - - default: - return 0; - } -} - - -const byte * -enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype, - size_t *ret_n, int *start, int *critical ) -{ - const byte *buffer; - int buflen; - int type; - int critical_dummy; - int offset; - size_t n; - int seq = 0; - int reqseq = start? *start: 0; - - if(!critical) - critical=&critical_dummy; - - if( !pktbuf || reqseq == -1 ) { - /* return some value different from NULL to indicate that - * there is no critical bit we do not understand. The caller - * will never use the value. Yes I know, it is an ugly hack */ - return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL; - } - buffer = pktbuf->data; - buflen = pktbuf->len; - while( buflen ) { - n = *buffer++; buflen--; - if( n == 255 ) { /* 4 byte length header */ - if( buflen < 4 ) - goto too_short; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { /* 2 byte special encoded length header */ - if( buflen < 2 ) - goto too_short; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - goto too_short; - type = *buffer; - if( type & 0x80 ) { - type &= 0x7f; - *critical = 1; - } - else - *critical = 0; - if( !(++seq > reqseq) ) - ; - else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) { - if( *critical ) { - if( n-1 > buflen+1 ) - goto too_short; - if( !can_handle_critical(buffer+1, n-1, type ) ) - { - if(opt.verbose) - log_info(_("subpacket of type %d has " - "critical bit set\n"),type); - if( start ) - *start = seq; - return NULL; /* this is an error */ - } - } - } - else if( reqtype < 0 ) /* list packets */ - dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED, - type, *critical, buffer, buflen, n ); - else if( type == reqtype ) { /* found */ - buffer++; - n--; - if( n > buflen ) - goto too_short; - if( ret_n ) - *ret_n = n; - offset = parse_one_sig_subpkt(buffer, n, type ); - switch( offset ) { - case -3: - log_error("subpacket of type %d too short\n", type); - return NULL; - case -2: - return NULL; - case -1: - BUG(); /* not yet needed */ - default: - break; - } - if( start ) - *start = seq; - return buffer+offset; - } - buffer += n; buflen -=n; - } - if( reqtype == SIGSUBPKT_TEST_CRITICAL ) - return buffer; /* as value true to indicate that there is no */ - /* critical bit we don't understand */ - if( start ) - *start = -1; - return NULL; /* end of packets; not found */ - - too_short: - log_error("buffer shorter than subpacket\n"); - if( start ) - *start = -1; - return NULL; -} - - -const byte * -parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype, - size_t *ret_n) -{ - return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL ); -} - -const byte * -parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype, - size_t *ret_n ) -{ - const byte *p; - - p = parse_sig_subpkt (sig->hashed, reqtype, ret_n ); - if( !p ) - p = parse_sig_subpkt (sig->unhashed, reqtype, ret_n ); - return p; -} - -/* Find all revocation keys. Look in hashed area only. */ -void parse_revkeys(PKT_signature *sig) -{ - struct revocation_key *revkey; - int seq=0; - size_t len; - - if(sig->sig_class!=0x1F) - return; - - while((revkey= - (struct revocation_key *)enum_sig_subpkt(sig->hashed, - SIGSUBPKT_REV_KEY, - &len,&seq,NULL))) - { - if(len==sizeof(struct revocation_key) && - (revkey->class&0x80)) /* 0x80 bit must be set */ - { - sig->revkey=xrealloc(sig->revkey, - sizeof(struct revocation_key *)*(sig->numrevkeys+1)); - sig->revkey[sig->numrevkeys]=revkey; - sig->numrevkeys++; - } - } -} - -static int -parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_signature *sig ) -{ - int md5_len=0; - unsigned n; - int is_v4=0; - int rc=0; - int i, ndata; - - if( pktlen < 16 ) { - log_error("packet(%d) too short\n", pkttype); - goto leave; - } - sig->version = iobuf_get_noeof(inp); pktlen--; - if( sig->version == 4 ) - is_v4=1; - else if( sig->version != 2 && sig->version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, sig->version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( !is_v4 ) { - md5_len = iobuf_get_noeof(inp); pktlen--; - } - sig->sig_class = iobuf_get_noeof(inp); pktlen--; - if( !is_v4 ) { - sig->timestamp = read_32(inp); pktlen -= 4; - sig->keyid[0] = read_32(inp); pktlen -= 4; - sig->keyid[1] = read_32(inp); pktlen -= 4; - } - sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - sig->digest_algo = iobuf_get_noeof(inp); pktlen--; - sig->flags.exportable=1; - sig->flags.revocable=1; - if( is_v4 ) { /* read subpackets */ - n = read_16(inp); pktlen -= 2; /* length of hashed data */ - if( n > 10000 ) { - log_error("signature packet: hashed data too long\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( n ) { - sig->hashed = xmalloc (sizeof (*sig->hashed) + n - 1 ); - sig->hashed->size = n; - sig->hashed->len = n; - if( iobuf_read (inp, sig->hashed->data, n ) != n ) { - log_error ("premature eof while reading " - "hashed signature data\n"); - rc = -1; - goto leave; - } - pktlen -= n; - } - n = read_16(inp); pktlen -= 2; /* length of unhashed data */ - if( n > 10000 ) { - log_error("signature packet: unhashed data too long\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - if( n ) { - sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 ); - sig->unhashed->size = n; - sig->unhashed->len = n; - if( iobuf_read(inp, sig->unhashed->data, n ) != n ) { - log_error("premature eof while reading " - "unhashed signature data\n"); - rc = -1; - goto leave; - } - pktlen -= n; - } - } - - if( pktlen < 5 ) { /* sanity check */ - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--; - sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--; - - if( is_v4 && sig->pubkey_algo ) { /*extract required information */ - const byte *p; - size_t len; - - /* set sig->flags.unknown_critical if there is a - * critical bit set for packets which we do not understand */ - if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL) - || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL, - NULL) ) - { - sig->flags.unknown_critical = 1; - } - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL ); - if(p) - sig->timestamp = buffer_to_u32(p); - else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)) - log_error("signature packet without timestamp\n"); - - p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL ); - if( p ) - { - sig->keyid[0] = buffer_to_u32(p); - sig->keyid[1] = buffer_to_u32(p+4); - } - else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110)) - log_error("signature packet without keyid\n"); - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL); - if(p) - sig->expiredate=sig->timestamp+buffer_to_u32(p); - if(sig->expiredate && sig->expiredate<=make_timestamp()) - sig->flags.expired=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL); - if(p) - sig->flags.policy_url=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL); - if(p) - sig->flags.pref_ks=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL); - if(p) - sig->flags.notation=1; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL); - if(p && *p==0) - sig->flags.revocable=0; - - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len); - if(p && len==2) - { - sig->trust_depth=p[0]; - sig->trust_value=p[1]; - - /* Only look for a regexp if there is also a trust - subpacket. */ - sig->trust_regexp= - parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len); - - /* If the regular expression is of 0 length, there is no - regular expression. */ - if(len==0) - sig->trust_regexp=NULL; - } - - /* We accept the exportable subpacket from either the hashed - or unhashed areas as older versions of gpg put it in the - unhashed area. In theory, anyway, we should never see this - packet off of a local keyring. */ - - p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL); - if(p && *p==0) - sig->flags.exportable=0; - - /* Find all revocation keys. */ - if(sig->sig_class==0x1F) - parse_revkeys(sig); - } - - if( list_mode ) { - printf(":signature packet: algo %d, keyid %08lX%08lX\n" - "\tversion %d, created %lu, md5len %d, sigclass %02x\n" - "\tdigest algo %d, begin of digest %02x %02x\n", - sig->pubkey_algo, - (ulong)sig->keyid[0], (ulong)sig->keyid[1], - sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class, - sig->digest_algo, - sig->digest_start[0], sig->digest_start[1] ); - if( is_v4 ) { - parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL ); - parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL); - } - } - - ndata = pubkey_get_nsig(sig->pubkey_algo); - if( !ndata ) { - if( list_mode ) - printf("\tunknown algorithm %d\n", sig->pubkey_algo ); - unknown_pubkey_warning( sig->pubkey_algo ); - /* we store the plain material in data[0], so that we are able - * to write it back with build_packet() */ - sig->data[0] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - } - else { - for( i=0; i < ndata; i++ ) { - n = pktlen; - sig->data[i] = mpi_read(inp, &n, 0 ); - pktlen -=n; - if( list_mode ) { - printf("\tdata: "); - mpi_print(stdout, sig->data[i], mpi_print_mode ); - putchar('\n'); - } - if (!sig->data[i]) - rc = GPG_ERR_INV_PACKET; - } - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static int -parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen, - PKT_onepass_sig *ops ) -{ - int version; - int rc = 0; - - if( pktlen < 13 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - version = iobuf_get_noeof(inp); pktlen--; - if( version != 3 ) { - log_error("onepass_sig with unknown version %d\n", version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - ops->sig_class = iobuf_get_noeof(inp); pktlen--; - ops->digest_algo = iobuf_get_noeof(inp); pktlen--; - ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - ops->keyid[0] = read_32(inp); pktlen -= 4; - ops->keyid[1] = read_32(inp); pktlen -= 4; - ops->last = iobuf_get_noeof(inp); pktlen--; - if( list_mode ) - printf(":onepass_sig packet: keyid %08lX%08lX\n" - "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n", - (ulong)ops->keyid[0], (ulong)ops->keyid[1], - version, ops->sig_class, - ops->digest_algo, ops->pubkey_algo, ops->last ); - - - leave: - skip_rest(inp, pktlen); - return rc; -} - - -static gcry_mpi_t -read_protected_v3_mpi (iobuf_t inp, unsigned long *length) -{ - int c; - unsigned int nbits, nbytes; - unsigned char *buf, *p; - gcry_mpi_t val; - - if (*length < 2) - { - log_error ("mpi too small\n"); - return NULL; - } - - if ((c=iobuf_get (inp)) == -1) - return NULL; - --*length; - nbits = c << 8; - if ((c=iobuf_get(inp)) == -1) - return NULL; - --*length; - nbits |= c; - - if (nbits > 16384) - { - log_error ("mpi too large (%u bits)\n", nbits); - return NULL; - } - nbytes = (nbits+7) / 8; - buf = p = xmalloc (2 + nbytes); - *p++ = nbits >> 8; - *p++ = nbits; - for (; nbytes && length; nbytes--, --*length) - *p++ = iobuf_get (inp); - if (nbytes) - { - log_error ("packet shorter tham mpi\n"); - xfree (buf); - return NULL; - } - - /* convert buffer into an opaque gcry_mpi_t */ - val = gcry_mpi_set_opaque (NULL, buf, (p-buf)*8); - return val; -} - - -static int -parse_key( iobuf_t inp, int pkttype, unsigned long pktlen, - byte *hdr, int hdrlen, PACKET *pkt ) -{ - int i, version, algorithm; - unsigned n; - unsigned long timestamp, expiredate, max_expiredate; - int npkey, nskey; - int is_v4=0; - int rc=0; - - version = iobuf_get_noeof(inp); pktlen--; - if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) { - /* early versions of G10 use old PGP comments packets; - * luckily all those comments are started by a hash */ - if( list_mode ) { - printf(":rfc1991 comment packet: \"" ); - for( ; pktlen; pktlen-- ) { - int c; - c = iobuf_get_noeof(inp); - if( c >= ' ' && c <= 'z' ) - putchar(c); - else - printf("\\x%02x", c ); - } - printf("\"\n"); - } - skip_rest(inp, pktlen); - return 0; - } - else if( version == 4 ) - is_v4=1; - else if( version != 2 && version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, version); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( pktlen < 11 ) { - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - timestamp = read_32(inp); pktlen -= 4; - if( is_v4 ) { - expiredate = 0; /* have to get it from the selfsignature */ - max_expiredate = 0; - } - else { - unsigned short ndays; - ndays = read_16(inp); pktlen -= 2; - if( ndays ) - expiredate = timestamp + ndays * 86400L; - else - expiredate = 0; - - max_expiredate=expiredate; - } - algorithm = iobuf_get_noeof(inp); pktlen--; - if( list_mode ) - printf(":%s key packet:\n" - "\tversion %d, algo %d, created %lu, expires %lu\n", - pkttype == PKT_PUBLIC_KEY? "public" : - pkttype == PKT_SECRET_KEY? "secret" : - pkttype == PKT_PUBLIC_SUBKEY? "public sub" : - pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??", - version, algorithm, timestamp, expiredate ); - - if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = pkt->pkt.secret_key; - - sk->timestamp = timestamp; - sk->expiredate = expiredate; - sk->max_expiredate = max_expiredate; - sk->hdrbytes = hdrlen; - sk->version = version; - sk->is_primary = pkttype == PKT_SECRET_KEY; - sk->pubkey_algo = algorithm; - sk->req_usage = 0; - sk->pubkey_usage = 0; /* not yet used */ - } - else { - PKT_public_key *pk = pkt->pkt.public_key; - - pk->timestamp = timestamp; - pk->expiredate = expiredate; - pk->max_expiredate = max_expiredate; - pk->hdrbytes = hdrlen; - pk->version = version; - pk->is_primary = pkttype == PKT_PUBLIC_KEY; - pk->pubkey_algo = algorithm; - pk->req_usage = 0; - pk->pubkey_usage = 0; /* not yet used */ - pk->is_revoked = 0; - pk->is_disabled = 0; - pk->keyid[0] = 0; - pk->keyid[1] = 0; - } - nskey = pubkey_get_nskey( algorithm ); - npkey = pubkey_get_npkey( algorithm ); - if( !npkey ) { - if( list_mode ) - printf("\tunknown algorithm %d\n", algorithm ); - unknown_pubkey_warning( algorithm ); - } - - - if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) { - PKT_secret_key *sk = pkt->pkt.secret_key; - byte temp[16]; - size_t snlen = 0; - - if( !npkey ) { - sk->skey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - goto leave; - } - - for(i=0; i < npkey; i++ ) { - n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; - if( list_mode ) { - printf( "\tskey[%d]: ", i); - mpi_print(stdout, sk->skey[i], mpi_print_mode ); - putchar('\n'); - } - if (!sk->skey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) /* one of the MPIs were bad */ - goto leave; - sk->protect.algo = iobuf_get_noeof(inp); pktlen--; - sk->protect.sha1chk = 0; - if( sk->protect.algo ) { - sk->is_protected = 1; - sk->protect.s2k.count = 0; - if( sk->protect.algo == 254 || sk->protect.algo == 255 ) { - if( pktlen < 3 ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - sk->protect.sha1chk = (sk->protect.algo == 254); - sk->protect.algo = iobuf_get_noeof(inp); pktlen--; - /* Note that a sk->protect.algo > 110 is illegal, but - I'm not erroring on it here as otherwise there - would be no way to delete such a key. */ - sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--; - sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--; - /* check for the special GNU extension */ - if( is_v4 && sk->protect.s2k.mode == 101 ) { - for(i=0; i < 4 && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - if( i < 4 || memcmp( temp, "GNU", 3 ) ) { - if( list_mode ) - printf( "\tunknown S2K %d\n", - sk->protect.s2k.mode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - /* here we know that it is a gnu extension - * What follows is the GNU protection mode: - * All values have special meanings - * and they are mapped in the mode with a base of 1000. - */ - sk->protect.s2k.mode = 1000 + temp[3]; - } - switch( sk->protect.s2k.mode ) { - case 1: - case 3: - for(i=0; i < 8 && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - memcpy(sk->protect.s2k.salt, temp, 8 ); - break; - } - switch( sk->protect.s2k.mode ) { - case 0: if( list_mode ) printf( "\tsimple S2K" ); - break; - case 1: if( list_mode ) printf( "\tsalted S2K" ); - break; - case 3: if( list_mode ) printf( "\titer+salt S2K" ); - break; - case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" ); - break; - case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K"); - break; - default: - if( list_mode ) - printf( "\tunknown %sS2K %d\n", - sk->protect.s2k.mode < 1000? "":"GNU ", - sk->protect.s2k.mode ); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - - if( list_mode ) { - printf(", algo: %d,%s hash: %d", - sk->protect.algo, - sk->protect.sha1chk?" SHA1 protection," - :" simple checksum,", - sk->protect.s2k.hash_algo ); - if( sk->protect.s2k.mode == 1 - || sk->protect.s2k.mode == 3 ) { - printf(", salt: "); - for(i=0; i < 8; i++ ) - printf("%02x", sk->protect.s2k.salt[i]); - } - putchar('\n'); - } - - if( sk->protect.s2k.mode == 3 ) { - if( pktlen < 1 ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - sk->protect.s2k.count = iobuf_get(inp); - pktlen--; - if( list_mode ) - printf("\tprotect count: %lu\n", - (ulong)sk->protect.s2k.count); - } - else if( sk->protect.s2k.mode == 1002 ) { - /* Read the serial number. */ - if (pktlen < 1) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - snlen = iobuf_get (inp); - pktlen--; - if (pktlen < snlen || snlen == -1) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - } - } - /* Note that a sk->protect.algo > 110 is illegal, but I'm - not erroring on it here as otherwise there would be no - way to delete such a key. */ - else { /* old version; no S2K, so we set mode to 0, hash MD5 */ - sk->protect.s2k.mode = 0; - sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5; - if( list_mode ) - printf( "\tprotect algo: %d (hash algo: %d)\n", - sk->protect.algo, sk->protect.s2k.hash_algo ); - } - /* It is really ugly that we don't know the size - * of the IV here in cases we are not aware of the algorithm. - * so a - * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo); - * won't work. The only solution I see is to hardwire it here. - * NOTE: if you change the ivlen above 16, don't forget to - * enlarge temp. - */ - switch( sk->protect.algo ) { - case 7: case 8: case 9: /* reserved for AES */ - case 10: /* Twofish */ - sk->protect.ivlen = 16; - break; - default: - sk->protect.ivlen = 8; - } - if( sk->protect.s2k.mode == 1001 ) - sk->protect.ivlen = 0; - else if( sk->protect.s2k.mode == 1002 ) { - if (snlen > 16) - log_info ("WARNING: serial number of card truncated\n"); - sk->protect.ivlen = snlen < 16? snlen : 16; - - } - if( pktlen < sk->protect.ivlen ) { - rc = GPG_ERR_INV_PACKET; - goto leave; - } - for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- ) - temp[i] = iobuf_get_noeof(inp); - if( list_mode ) { - printf( sk->protect.s2k.mode == 1002? "\tserial-number: " - : "\tprotect IV: "); - for(i=0; i < sk->protect.ivlen; i++ ) - printf(" %02x", temp[i] ); - putchar('\n'); - } - memcpy(sk->protect.iv, temp, sk->protect.ivlen ); - } - else - sk->is_protected = 0; - /* It does not make sense to read it into secure memory. - * If the user is so careless, not to protect his secret key, - * we can assume, that he operates an open system :=(. - * So we put the key into secure memory when we unprotect it. */ - if( sk->protect.s2k.mode == 1001 - || sk->protect.s2k.mode == 1002 ) { - /* better set some dummy stuff here */ - sk->skey[npkey] = gcry_mpi_set_opaque(NULL, xstrdup ("dummydata"), - 10*8); - pktlen = 0; - } - else if( is_v4 && sk->is_protected ) { - /* ugly; the length is encrypted too, so we read all - * stuff up to the end of the packet into the first - * skey element */ - sk->skey[npkey] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - if( list_mode ) { - printf("\tencrypted stuff follows\n"); - } - } - else { /* v3 method: the mpi length is not encrypted */ - for(i=npkey; i < nskey; i++ ) { - if ( sk->is_protected ) { - sk->skey[i] = read_protected_v3_mpi (inp, &pktlen); - if( list_mode ) - printf( "\tskey[%d]: [encrypted]\n", i); - } - else { - n = pktlen; - sk->skey[i] = mpi_read(inp, &n, 0 ); - pktlen -=n; - if( list_mode ) { - printf( "\tskey[%d]: ", i); - mpi_print(stdout, sk->skey[i], mpi_print_mode ); - putchar('\n'); - } - } - - if (!sk->skey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) - goto leave; - - sk->csum = read_16(inp); pktlen -= 2; - if( list_mode ) { - printf("\tchecksum: %04hx\n", sk->csum); - } - } - } - else { - PKT_public_key *pk = pkt->pkt.public_key; - - if( !npkey ) { - pk->pkey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen), - pktlen*8 ); - pktlen = 0; - goto leave; - } - - for(i=0; i < npkey; i++ ) { - n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n; - if( list_mode ) { - printf( "\tpkey[%d]: ", i); - mpi_print(stdout, pk->pkey[i], mpi_print_mode ); - putchar('\n'); - } - if (!pk->pkey[i]) - rc = GPG_ERR_INV_PACKET; - } - if (rc) - goto leave; - } - - leave: - skip_rest(inp, pktlen); - return rc; -} - -/* Attribute subpackets have the same format as v4 signature - subpackets. This is not part of OpenPGP, but is done in several - versions of PGP nevertheless. */ -int -parse_attribute_subpkts(PKT_user_id *uid) -{ - size_t n; - int count=0; - struct user_attribute *attribs=NULL; - const byte *buffer=uid->attrib_data; - int buflen=uid->attrib_len; - byte type; - - xfree (uid->attribs); - - while(buflen) - { - n = *buffer++; buflen--; - if( n == 255 ) { /* 4 byte length header */ - if( buflen < 4 ) - goto too_short; - n = (buffer[0] << 24) | (buffer[1] << 16) - | (buffer[2] << 8) | buffer[3]; - buffer += 4; - buflen -= 4; - } - else if( n >= 192 ) { /* 2 byte special encoded length header */ - if( buflen < 2 ) - goto too_short; - n = (( n - 192 ) << 8) + *buffer + 192; - buffer++; - buflen--; - } - if( buflen < n ) - goto too_short; - - attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute)); - memset(&attribs[count],0,sizeof(struct user_attribute)); - - type=*buffer; - buffer++; - buflen--; - n--; - - attribs[count].type=type; - attribs[count].data=buffer; - attribs[count].len=n; - buffer+=n; - buflen-=n; - count++; - } - - uid->attribs=attribs; - uid->numattribs=count; - return count; - - too_short: - log_error("buffer shorter than attribute subpacket\n"); - uid->attribs=attribs; - uid->numattribs=count; - return count; -} - -static void setup_user_id(PACKET *packet) -{ - packet->pkt.user_id->ref = 1; - packet->pkt.user_id->attribs = NULL; - packet->pkt.user_id->attrib_data = NULL; - packet->pkt.user_id->attrib_len = 0; - packet->pkt.user_id->is_primary = 0; - packet->pkt.user_id->is_revoked = 0; - packet->pkt.user_id->is_expired = 0; - packet->pkt.user_id->expiredate = 0; - packet->pkt.user_id->created = 0; - packet->pkt.user_id->help_key_usage = 0; - packet->pkt.user_id->help_key_expire = 0; - packet->pkt.user_id->prefs = NULL; - packet->pkt.user_id->namehash = NULL; -} - -static int -parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - - packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id + pktlen); - packet->pkt.user_id->len = pktlen; - - setup_user_id(packet); - - p = packet->pkt.user_id->name; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - *p = 0; - - if( list_mode ) { - int n = packet->pkt.user_id->len; - printf(":user ID packet: \""); - /* fixme: Hey why don't we replace this with print_string?? */ - for(p=packet->pkt.user_id->name; n; p++, n-- ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\"\n"); - } - return 0; -} - - -void -make_attribute_uidname(PKT_user_id *uid, size_t max_namelen) -{ - assert ( max_namelen > 70 ); - if(uid->numattribs<=0) - sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len); - else if(uid->numattribs>1) - sprintf(uid->name,"[%d attributes of size %lu]", - uid->numattribs,uid->attrib_len); - else - { - /* Only one attribute, so list it as the "user id" */ - - if(uid->attribs->type==ATTRIB_IMAGE) - { - u32 len; - byte type; - - if(parse_image_header(uid->attribs,&type,&len)) - sprintf(uid->name,"[%.20s image of size %lu]", - image_type_to_string(type,1),(ulong)len); - else - sprintf(uid->name,"[invalid image]"); - } - else - sprintf(uid->name,"[unknown attribute of size %lu]", - (ulong)uid->attribs->len); - } - - uid->len = strlen(uid->name); -} - -static int -parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - -#define EXTRA_UID_NAME_SPACE 71 - packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id - + EXTRA_UID_NAME_SPACE); - - setup_user_id(packet); - - packet->pkt.user_id->attrib_data = xmalloc (pktlen); - packet->pkt.user_id->attrib_len = pktlen; - p = packet->pkt.user_id->attrib_data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - /* Now parse out the individual attribute subpackets. This is - somewhat pointless since there is only one currently defined - attribute type (jpeg), but it is correct by the spec. */ - parse_attribute_subpkts(packet->pkt.user_id); - - make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE); - - if( list_mode ) { - printf(":attribute packet: %s\n", packet->pkt.user_id->name ); - } - return 0; -} - - -static int -parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - - packet->pkt.comment = xmalloc (sizeof *packet->pkt.comment + pktlen - 1); - packet->pkt.comment->len = pktlen; - p = packet->pkt.comment->data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - if( list_mode ) { - int n = packet->pkt.comment->len; - printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT? - "OpenPGP draft " : "" ); - for(p=packet->pkt.comment->data; n; p++, n-- ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\"\n"); - } - return 0; -} - - -static void -parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt ) -{ - int c; - - if (pktlen) - { - c = iobuf_get_noeof(inp); - pktlen--; - pkt->pkt.ring_trust = xmalloc ( sizeof *pkt->pkt.ring_trust ); - pkt->pkt.ring_trust->trustval = c; - pkt->pkt.ring_trust->sigcache = 0; - if (!c && pktlen==1) - { - c = iobuf_get_noeof (inp); - pktlen--; - /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/ - if ( !(c & 0x80) ) - pkt->pkt.ring_trust->sigcache = c; - } - if( list_mode ) - printf(":trust packet: flag=%02x sigcache=%02x\n", - pkt->pkt.ring_trust->trustval, - pkt->pkt.ring_trust->sigcache); - } - else - { - if( list_mode ) - printf(":trust packet: empty\n"); - } - skip_rest (inp, pktlen); -} - - -static int -parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - int mode, namelen, partial=0; - PKT_plaintext *pt; - byte *p; - int c, i; - - if( pktlen && pktlen < 6 ) { - log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - /* A packet length of zero indicates partial body length. A zero - data length isn't a zero length packet due to the header (mode, - name, etc), so this is accurate. */ - if(pktlen==0) - partial=1; - mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--; - namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--; - pt = pkt->pkt.plaintext = xmalloc (sizeof *pkt->pkt.plaintext + namelen -1); - pt->new_ctb = new_ctb; - pt->mode = mode; - pt->namelen = namelen; - pt->is_partial = partial; - if( pktlen ) { - for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ ) - pt->name[i] = iobuf_get_noeof(inp); - } - else { - for( i=0; i < namelen; i++ ) - if( (c=iobuf_get(inp)) == -1 ) - break; - else - pt->name[i] = c; - } - pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4; - pt->len = pktlen; - pt->buf = inp; - pktlen = 0; - - if( list_mode ) { - printf(":literal data packet:\n" - "\tmode %c, created %lu, name=\"", - mode >= ' ' && mode <'z'? mode : '?', - (ulong)pt->timestamp ); - for(p=pt->name,i=0; i < namelen; p++, i++ ) { - if( *p >= ' ' && *p <= 'z' ) - putchar(*p); - else - printf("\\x%02x", *p ); - } - printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len ); - } - - leave: - return rc; -} - - -static int -parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - PKT_compressed *zd; - - /* pktlen is here 0, but data follows - * (this should be the last object in a file or - * the compress algorithm should know the length) - */ - zd = pkt->pkt.compressed = xmalloc (sizeof *pkt->pkt.compressed ); - zd->algorithm = iobuf_get_noeof(inp); - zd->len = 0; /* not used */ - zd->new_ctb = new_ctb; - zd->buf = inp; - if( list_mode ) - printf(":compressed packet: algo=%d\n", zd->algorithm); - return 0; -} - - -static int -parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - PKT_encrypted *ed; - unsigned long orig_pktlen = pktlen; - - ed = pkt->pkt.encrypted = xmalloc (sizeof *pkt->pkt.encrypted ); - ed->len = pktlen; - /* we don't know the extralen which is (cipher_blocksize+2) - because the algorithm ist not specified in this packet. - However, it is only important to know this for some sanity - checks on the packet length - it doesn't matter that we can't - do it */ - ed->extralen = 0; - ed->buf = NULL; - ed->new_ctb = new_ctb; - ed->mdc_method = 0; - if( pkttype == PKT_ENCRYPTED_MDC ) { - /* fixme: add some pktlen sanity checks */ - int version; - - version = iobuf_get_noeof(inp); - if (orig_pktlen) - pktlen--; - if( version != 1 ) { - log_error("encrypted_mdc packet with unknown version %d\n", - version); - /*skip_rest(inp, pktlen); should we really do this? */ - rc = GPG_ERR_INV_PACKET; - goto leave; - } - ed->mdc_method = DIGEST_ALGO_SHA1; - } - if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */ - log_error("packet(%d) too short\n", pkttype); - rc = GPG_ERR_INV_PACKET; - skip_rest(inp, pktlen); - goto leave; - } - if( list_mode ) { - if( orig_pktlen ) - printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen); - else - printf(":encrypted data packet:\n\tlength: unknown\n"); - if( ed->mdc_method ) - printf("\tmdc_method: %d\n", ed->mdc_method ); - } - - ed->buf = inp; - pktlen = 0; - - leave: - return rc; -} - - -static int -parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen, - PACKET *pkt, int new_ctb ) -{ - int rc = 0; - PKT_mdc *mdc; - byte *p; - - mdc = pkt->pkt.mdc= xmalloc (sizeof *pkt->pkt.mdc ); - if( list_mode ) - printf(":mdc packet: length=%lu\n", pktlen); - if( !new_ctb || pktlen != 20 ) { - log_error("mdc_packet with invalid encoding\n"); - rc = GPG_ERR_INV_PACKET; - goto leave; - } - p = mdc->hash; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - leave: - return rc; -} - - -/* - * This packet is internally generated by PGG (by armor.c) to - * transfer some information to the lower layer. To make sure that - * this packet is really a GPG faked one and not one comming from outside, - * we first check that tehre is a unique tag in it. - * The format of such a control packet is: - * n byte session marker - * 1 byte control type CTRLPKT_xxxxx - * m byte control data - */ - -static int -parse_gpg_control( iobuf_t inp, - int pkttype, unsigned long pktlen, PACKET *packet ) -{ - byte *p; - const byte *sesmark; - size_t sesmarklen; - int i; - - if ( list_mode ) - printf(":packet 63: length %lu ", pktlen); - - sesmark = get_session_marker ( &sesmarklen ); - if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */ - goto skipit; - for( i=0; i < sesmarklen; i++, pktlen-- ) { - if ( sesmark[i] != iobuf_get_noeof(inp) ) - goto skipit; - } - if ( list_mode ) - puts ("- gpg control packet"); - - packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control - + pktlen - 1); - packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--; - packet->pkt.gpg_control->datalen = pktlen; - p = packet->pkt.gpg_control->data; - for( ; pktlen; pktlen--, p++ ) - *p = iobuf_get_noeof(inp); - - return 0; - - skipit: - if ( list_mode ) { - int c; - - i=0; - printf("- private (rest length %lu)\n", pktlen); - if( iobuf_in_block_mode(inp) ) { - while( (c=iobuf_get(inp)) != -1 ) - dump_hex_line(c, &i); - } - else { - for( ; pktlen; pktlen-- ) - dump_hex_line(iobuf_get(inp), &i); - } - putchar('\n'); - } - skip_rest(inp,pktlen); - return GPG_ERR_INV_PACKET; -} - -/* create a gpg control packet to be used internally as a placeholder */ -PACKET * -create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen ) -{ - PACKET *packet; - byte *p; - - packet = xmalloc ( sizeof *packet ); - init_packet(packet); - packet->pkttype = PKT_GPG_CONTROL; - packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control - + datalen - 1); - packet->pkt.gpg_control->control = type; - packet->pkt.gpg_control->datalen = datalen; - p = packet->pkt.gpg_control->data; - for( ; datalen; datalen--, p++ ) - *p = *data++; - - return packet; -} diff --git a/g10/passphrase.c b/g10/passphrase.c deleted file mode 100644 index 986070a16..000000000 --- a/g10/passphrase.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* passphrase.c - Get a passphrase - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#if !defined(HAVE_DOSISH_SYSTEM) && !defined(__riscos__) -#include <sys/socket.h> -#include <sys/un.h> -#endif -#if defined (_WIN32) || defined (__CYGWIN32__) -# include <windows.h> -#endif -#include <errno.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "options.h" -#include "ttyio.h" -#include "cipher.h" -#include "keydb.h" -#include "main.h" -#include "i18n.h" -#include "status.h" - - -enum gpga_protocol_codes { - /* Request codes */ - GPGA_PROT_GET_VERSION = 1, - GPGA_PROT_GET_PASSPHRASE = 2, - GPGA_PROT_CLEAR_PASSPHRASE= 3, - GPGA_PROT_SHUTDOWN = 4, - GPGA_PROT_FLUSH = 5, - - /* Reply codes */ - GPGA_PROT_REPLY_BASE = 0x10000, - GPGA_PROT_OKAY = 0x10001, - GPGA_PROT_GOT_PASSPHRASE = 0x10002, - - /* Error codes */ - GPGA_PROT_ERROR_BASE = 0x20000, - GPGA_PROT_PROTOCOL_ERROR = 0x20001, - GPGA_PROT_INVALID_REQUEST= 0x20002, - GPGA_PROT_CANCELED = 0x20003, - GPGA_PROT_NO_PASSPHRASE = 0x20004, - GPGA_PROT_BAD_PASSPHRASE = 0x20005, - GPGA_PROT_INVALID_DATA = 0x20006, - GPGA_PROT_NOT_IMPLEMENTED= 0x20007, - GPGA_PROT_UI_PROBLEM = 0x20008 -}; - - -#define buftou32( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \ - (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3))) -#define u32tobuf( p, a ) do { \ - ((byte*)p)[0] = (byte)((a) >> 24); \ - ((byte*)p)[1] = (byte)((a) >> 16); \ - ((byte*)p)[2] = (byte)((a) >> 8); \ - ((byte*)p)[3] = (byte)((a) ); \ - } while(0) - -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - - -static char *fd_passwd = NULL; -static char *next_pw = NULL; -static char *last_pw = NULL; - -#if defined (_WIN32) -static int read_fd = 0; -static int write_fd = 0; -#endif - -static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ); - -int -have_static_passphrase() -{ - if ( opt.use_agent ) - return 0; - return !!fd_passwd; -} - -/**************** - * Set the passphrase to be used for the next query and only for the next - * one. - */ -void -set_next_passphrase( const char *s ) -{ - xfree (next_pw); - next_pw = NULL; - if( s ) { - next_pw = gcry_xmalloc_secure ( strlen(s)+1 ); - strcpy(next_pw, s ); - } -} - -/**************** - * Get the last passphrase used in passphrase_to_dek. - * Note: This removes the passphrase from this modules and - * the caller must free the result. May return NULL: - */ -char * -get_last_passphrase() -{ - char *p = last_pw; - last_pw = NULL; - return p; -} - - -void -read_passphrase_from_fd( int fd ) -{ - int i, len; - char *pw; - - if ( opt.use_agent ) - { /* Not used but we have to do a dummy read, so that it won't end - up at the begin of the message if the quite usual trick to - prepend the passphtrase to the message is used. */ - char buf[1]; - - while (!(read (fd, buf, 1) != 1 || *buf == '\n' )) - ; - *buf = 0; - return; - } - - if (!opt.batch ) - tty_printf("Reading passphrase from file descriptor %d ...", fd ); - for (pw = NULL, i = len = 100; ; i++ ) - { - if (i >= len-1 ) - { - char *pw2 = pw; - len += 100; - pw = gcry_xmalloc_secure ( len ); - if( pw2 ) - memcpy(pw, pw2, i ); - else - i=0; - } - if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' ) - break; - } - pw[i] = 0; - if (!opt.batch) - tty_printf("\b\b\b \n" ); - - xfree ( fd_passwd ); - fd_passwd = pw; -} - -static int -writen ( int fd, const void *buf, size_t nbytes ) -{ -#if defined (_WIN32) - DWORD nwritten, nleft = nbytes; - - while (nleft > 0) { - if ( !WriteFile( (HANDLE)write_fd, buf, nleft, &nwritten, NULL) ) { - log_error("write failed: ec=%d\n", (int)GetLastError()); - return -1; - } - /*log_info("** WriteFile fd=%d nytes=%d nwritten=%d\n", - write_fd, nbytes, (int)nwritten);*/ - Sleep(100); - - nleft -= nwritten; - buf = (const BYTE *)buf + nwritten; - } -#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ -#else - size_t nleft = nbytes; - int nwritten; - - while( nleft > 0 ) { - nwritten = write( fd, buf, nleft ); - if( nwritten < 0 ) { - if ( errno == EINTR ) - nwritten = 0; - else { - log_error ( "write() failed: %s\n", strerror (errno) ); - return -1; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } -#endif - - return 0; -} - - -static int -readn ( int fd, void *buf, size_t buflen, size_t *ret_nread ) -{ -#if defined (_WIN32) - DWORD nread, nleft = buflen; - - while (nleft > 0) { - if ( !ReadFile( (HANDLE)read_fd, buf, nleft, &nread, NULL) ) { - log_error("read() error: ec=%d\n", (int)GetLastError()); - return -1; - } - if (!nread || GetLastError() == ERROR_BROKEN_PIPE) - break; - /*log_info("** ReadFile fd=%d buflen=%d nread=%d\n", - read_fd, buflen, (int)nread);*/ - Sleep(100); - - nleft -= nread; - buf = (BYTE *)buf + nread; - } - if (ret_nread) - *ret_nread = buflen - nleft; - -#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ -#else - size_t nleft = buflen; - int nread; - char *p; - - p = buf; - while( nleft > 0 ) { - nread = read ( fd, buf, nleft ); - if( nread < 0 ) { - if (nread == EINTR) - nread = 0; - else { - log_error ( "read() error: %s\n", strerror (errno) ); - return -1; - } - } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - buf = (char*)buf + nread; - } - if( ret_nread ) - *ret_nread = buflen - nleft; -#endif - - return 0; -} - -/* read an entire line */ -static int -readline (int fd, char *buf, size_t buflen) -{ - size_t nleft = buflen; - char *p; - int nread = 0; - - while (nleft > 0) - { - int n = read (fd, buf, nleft); - if (n < 0) - { - if (errno == EINTR) - continue; - return -1; /* read error */ - } - else if (!n) - { - return -1; /* incomplete line */ - } - p = buf; - nleft -= n; - buf += n; - nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - break; /* at least one full line available - that's enough. - This function is just a temporary hack until we use - the assuna lib in gpg. So it is okay to forget - about pending bytes */ - } - } - - return nread; -} - - - -#if !defined (__riscos__) - -#if !defined (_WIN32) -/* For the new Assuan protocol we may have to send options */ -static int -agent_send_option (int fd, const char *name, const char *value) -{ - char buf[200]; - int nread; - char *line; - int i; - - line = xmalloc (7 + strlen (name) + 1 + strlen (value) + 2); - strcpy (stpcpy (stpcpy (stpcpy ( - stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - xfree (line); - if (i) - return -1; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 3) - return -1; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ - - return -1; -} - -static int -agent_send_all_options (int fd) -{ - char *dft_display = NULL; - const char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; - int rc = 0; - - dft_display = getenv ("DISPLAY"); - if (opt.display || dft_display) - { - if (agent_send_option (fd, "display", - opt.display ? opt.display : dft_display)) - return -1; - } - - if (!opt.ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && tty_get_ttyname ()) - dft_ttyname = tty_get_ttyname (); - } - if (opt.ttyname || dft_ttyname) - { - if (agent_send_option (fd, "ttyname", - opt.ttyname ? opt.ttyname : dft_ttyname)) - return -1; - } - - dft_ttytype = getenv ("TERM"); - if (opt.ttytype || (dft_ttyname && dft_ttytype)) - { - if (agent_send_option (fd, "ttytype", - opt.ttyname ? opt.ttytype : dft_ttytype)) - return -1; - } - -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - old_lc = xstrdup (old_lc); - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt.lc_ctype || (dft_ttyname && dft_lc)) - { - rc = agent_send_option (fd, "lc-ctype", - opt.lc_ctype ? opt.lc_ctype : dft_lc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - xfree (old_lc); - } -#endif - if (rc) - return rc; - -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - old_lc = xstrdup (old_lc); - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt.lc_messages || (dft_ttyname && dft_lc)) - { - rc = agent_send_option (fd, "lc-messages", - opt.lc_messages ? opt.lc_messages : dft_lc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - xfree (old_lc); - } -#endif - return rc; -} -#endif /*!_WIN32*/ - - -/* - * Open a connection to the agent and send the magic string - * Returns: -1 on error or an filedescriptor for urther processing - */ - -static int -agent_open (int *ret_prot) -{ -#if defined (_WIN32) - int fd; - char *infostr, *p; - HANDLE h; - char pidstr[128]; - - *ret_prot = 0; - if ( !(infostr = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentPID")) - || *infostr == '0') { - log_error( _("gpg-agent is not available in this session\n")); - return -1; - } - free(infostr); - - sprintf(pidstr, "%u", (unsigned int)GetCurrentProcessId()); - if (write_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentCID", pidstr)) { - log_error( _("can't set client pid for the agent\n") ); - return -1; - } - h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent"); - SetEvent(h); - Sleep(50); /* some time for the server */ - if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentReadFD")) ) { - log_error( _("can't get server read FD for the agent\n") ); - return -1; - } - read_fd = atol(p); - free(p); - if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG", - "agentWriteFD")) ) { - log_error ( _("can't get server write FD for the agent\n") ); - return -1; - } - write_fd = atol(p); - free(p); - fd = 0; - - if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) { - fd = -1; - } -#else /* Posix */ - - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - int prot; - - if (opt.gpg_agent_info) - infostr = xstrdup (opt.gpg_agent_info); - else - { - infostr = getenv ( "GPG_AGENT_INFO" ); - if ( !infostr || !*infostr ) { - log_error (_("gpg-agent is not available in this session\n")); - opt.use_agent = 0; - return -1; - } - infostr = xstrdup ( infostr ); - } - - if ( !(p = strchr ( infostr, ':')) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) { - log_error( _("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - *p++ = 0; - /* See whether this is the new gpg-agent using the Assuna protocl. - This agent identifies itself by have an info string with a - version number in the 3rd field. */ - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if ( prot < 0 || prot > 1) { - log_error (_("gpg-agent protocol version %d is not supported\n"),prot); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - *ret_prot = prot; - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) { - log_error ("can't create socket: %s\n", strerror(errno) ); - xfree (infostr ); - opt.use_agent = 0; - return -1; - } - - memset( &client_addr, 0, sizeof client_addr ); - client_addr.sun_family = AF_UNIX; - strcpy( client_addr.sun_path, infostr ); - len = offsetof (struct sockaddr_un, sun_path) - + strlen(client_addr.sun_path) + 1; - - if( connect( fd, (struct sockaddr*)&client_addr, len ) == -1 ) { - log_error ( _("can't connect to `%s': %s\n"), - infostr, strerror (errno) ); - xfree (infostr ); - close (fd ); - opt.use_agent = 0; - return -1; - } - xfree (infostr); - - if (!prot) { - if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) { - close (fd); - fd = -1; - } - } - else { /* assuan based gpg-agent */ - char line[200]; - int nread; - - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) { - log_error ( _("communication problem with gpg-agent\n")); - close (fd ); - opt.use_agent = 0; - return -1; - } - - if (agent_send_all_options (fd)) { - log_error (_("problem with the agent - disabling agent use\n")); - close (fd); - opt.use_agent = 0; - return -1; - } - - } -#endif - - return fd; -} - - -static void -agent_close ( int fd ) -{ -#if defined (_WIN32) - HANDLE h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent"); - ResetEvent(h); -#else - close (fd); -#endif -} -#endif /* !__riscos__ */ - - - -/* - * Ask the GPG Agent for the passphrase. - * Mode 0: Allow cached passphrase - * 1: No cached passphrase FIXME: Not really implemented - * 2: Ditto, but change the text to "repeat entry" - * - * Note that TRYAGAIN_TEXT must not be translated. If canceled is not - * NULL, the function does set it to 1 if the user canceled the - * operation. - */ -static char * -agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text, - int *canceled) -{ -#if defined(__riscos__) - return NULL; -#else - size_t n; - char *atext = NULL; - char buf[50]; - int fd = -1; - int nread; - u32 reply; - char *pw = NULL; - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - byte fpr[MAX_FINGERPRINT_LEN]; - int have_fpr = 0; - int prot; - char *orig_codeset = NULL; - - if (canceled) - *canceled = 0; - -#if MAX_FINGERPRINT_LEN < 20 -#error agent needs a 20 byte fingerprint -#endif - - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - if( keyid && get_pubkey( pk, keyid ) ) - { - free_public_key( pk ); - pk = NULL; /* oops: no key for some reason */ - } - -#ifdef ENABLE_NLS - /* The Assuan agent protocol requires us to transmit utf-8 strings */ - orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); -#ifdef HAVE_LANGINFO_CODESET - if (!orig_codeset) - orig_codeset = nl_langinfo (CODESET); -#endif - if (orig_codeset) - { /* We only switch when we are able to restore the codeset later. */ - orig_codeset = xstrdup (orig_codeset); - if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) - orig_codeset = NULL; - } -#endif - - if ( (fd = agent_open (&prot)) == -1 ) - goto failure; - - if ( !mode && pk && keyid ) - { - char *uid; - size_t uidlen; - const char *algo_name = gcry_pk_algo_name ( pk->pubkey_algo ); - const char *timestr; - char *maink; - - if ( !algo_name ) - algo_name = "?"; - - if( keyid[2] && keyid[3] && keyid[0] != keyid[2] - && keyid[1] != keyid[3] ) - maink = xasprintf ( _(" (main key ID %08lX)"), (ulong)keyid[3] ); - else - maink = NULL; - - uid = get_user_id ( keyid, &uidlen ); - timestr = strtimestamp (pk->timestamp); - atext = xasprintf ( - _("You need a passphrase to unlock the" - " secret key for user:\n" - "\"%.*s\"\n" - "%u-bit %s key, ID %08lX, created %s%s\n" ), - uidlen, uid, - nbits_from_pk (pk), algo_name, (ulong)keyid[1], timestr, - maink?maink:"" ); - xfree (uid); - xfree (maink); - - { - size_t dummy; - fingerprint_from_pk( pk, fpr, &dummy ); - have_fpr = 1; - } - - } - else if (mode == 2 ) - atext = xstrdup ( _("Repeat passphrase\n") ); - else - atext = xstrdup ( _("Enter passphrase\n") ); - - if (!prot) - { /* old style protocol */ - n = 4 + 20 + strlen (atext); - u32tobuf (buf, n ); - u32tobuf (buf+4, GPGA_PROT_GET_PASSPHRASE ); - memcpy (buf+8, fpr, 20 ); - if ( writen ( fd, buf, 28 ) || writen ( fd, atext, strlen (atext) ) ) - goto failure; - xfree (atext); atext = NULL; - - /* get response */ - if ( readn ( fd, buf, 12, &nread ) ) - goto failure; - - if ( nread < 8 ) - { - log_error ( "response from agent too short\n" ); - goto failure; - } - n = buftou32 ( buf ); - reply = buftou32 ( buf + 4 ); - if ( reply == GPGA_PROT_GOT_PASSPHRASE ) - { - size_t pwlen; - size_t nn; - - if ( nread < 12 || n < 8 ) - { - log_error ( "response from agent too short\n" ); - goto failure; - } - pwlen = buftou32 ( buf + 8 ); - nread -= 12; - n -= 8; - if ( pwlen > n || n > 1000 ) - { - log_error (_("passphrase too long\n")); - /* or protocol error */ - goto failure; - } - /* we read the whole block in one chunk to give no hints - * on how long the passhrase actually is - this wastes some bytes - * but because we already have this padding we should not loosen - * this by issuing 2 read calls */ - pw = xmalloc_secure ( n+1 ); - if ( readn ( fd, pw, n, &nn ) ) - goto failure; - if ( n != nn ) - { - log_error (_("invalid response from agent\n")); - goto failure; - } - pw[pwlen] = 0; /* make a C String */ - agent_close (fd); - free_public_key( pk ); -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - return pw; - } - else if ( reply == GPGA_PROT_CANCELED ) - { - log_info ( _("cancelled by user\n") ); - if (canceled) - *canceled = 1; - } - else - log_error ( _("problem with the agent: agent returns 0x%lx\n"), - (ulong)reply ); - } - else - { /* The new Assuan protocol */ - char *line, *p; - const unsigned char *s; - int i; - - if (!tryagain_text) - tryagain_text = "X"; - else - tryagain_text = _(tryagain_text); - - /* We allocate 2 time the needed space for atext so that there - is enough space for escaping */ - line = xmalloc (15 + 46 - + 3*strlen (tryagain_text) + 3*strlen (atext) + 2); - strcpy (line, "GET_PASSPHRASE "); - p = line+15; - if (!mode && have_fpr) - { - for (i=0; i < 20; i++, p +=2 ) - sprintf (p, "%02X", fpr[i]); - } - else - *p++ = 'X'; /* no caching */ - *p++ = ' '; - for (i=0, s=tryagain_text; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p++ = ' '; - *p++ = 'X'; /* Use the standard prompt */ - *p++ = ' '; - /* copy description */ - for (i=0, s= atext; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p++ = '\n'; - i = writen (fd, line, p - line); - xfree (line); - if (i) - goto failure; - xfree (atext); atext = NULL; - - /* get response */ - pw = xmalloc_secure (500); - nread = readline (fd, pw, 499); - if (nread < 3) - goto failure; - - if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') - { /* we got a passphrase - convert it back from hex */ - size_t pwlen = 0; - - for (i=3; i < nread && hexdigitp (pw+i); i+=2) - pw[pwlen++] = xtoi_2 (pw+i); - pw[pwlen] = 0; /* make a C String */ - agent_close (fd); - free_public_key( pk ); -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - return pw; - } - else if (nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - { - log_info (_("cancelled by user\n") ); - if (canceled) - *canceled = 1; - } - else - { - log_error (_("problem with the agent - disabling agent use\n")); - opt.use_agent = 0; - } - } - - - failure: -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (atext); - if ( fd != -1 ) - agent_close (fd); - xfree (pw ); - free_public_key( pk ); - - return NULL; -#endif /* Posix or W32 */ -} - -/* - * Clear the cached passphrase - */ -void -passphrase_clear_cache ( u32 *keyid, int algo ) -{ -#if defined(__riscos__) - return ; -#else - size_t n; - char buf[200]; - int fd = -1; - size_t nread; - u32 reply; - PKT_public_key *pk; - byte fpr[MAX_FINGERPRINT_LEN]; - int prot; - -#if MAX_FINGERPRINT_LEN < 20 -#error agent needs a 20 byte fingerprint -#endif - - if (!opt.use_agent) - return; - - pk = xcalloc (1, sizeof *pk ); - memset (fpr, 0, MAX_FINGERPRINT_LEN ); - if( !keyid || get_pubkey( pk, keyid ) ) - { - log_debug ("oops, no key in passphrase_clear_cache\n"); - goto failure; /* oops: no key for some reason */ - } - - { - size_t dummy; - fingerprint_from_pk( pk, fpr, &dummy ); - } - - if ( (fd = agent_open (&prot)) == -1 ) - goto failure; - - if (!prot) - { - n = 4 + 20; - u32tobuf (buf, n ); - u32tobuf (buf+4, GPGA_PROT_CLEAR_PASSPHRASE ); - memcpy (buf+8, fpr, 20 ); - if ( writen ( fd, buf, 28 ) ) - goto failure; - - /* get response */ - if ( readn ( fd, buf, 8, &nread ) ) - goto failure; - - if ( nread < 8 ) { - log_error ( "response from agent too short\n" ); - goto failure; - } - - reply = buftou32 ( buf + 4 ); - if ( reply != GPGA_PROT_OKAY && reply != GPGA_PROT_NO_PASSPHRASE ) - { - log_error ( _("problem with the agent: agent returns 0x%lx\n"), - (ulong)reply ); - } - } - else - { /* The assuan protocol */ - char *line, *p; - int i; - - line = xmalloc (17 + 40 + 2); - strcpy (line, "CLEAR_PASSPHRASE "); - p = line+17; - for (i=0; i < 20; i++, p +=2 ) - sprintf (p, "%02X", fpr[i]); - *p++ = '\n'; - i = writen (fd, line, p - line); - xfree (line); - if (i) - goto failure; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 3) - goto failure; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - ; - else - { - log_error (_("problem with the agent - disabling agent use\n")); - opt.use_agent = 0; - } - } - - failure: - if (fd != -1) - agent_close (fd); - free_public_key( pk ); -#endif /* Posix or W32 */ -} - - - - -/**************** - * Get a passphrase for the secret key with KEYID, display TEXT - * if the user needs to enter the passphrase. - * mode 0 = standard, 1 = same but don't show key info, - * 2 = create new passphrase - * Returns: a DEK with a session key; caller must free - * or NULL if the passphrase was not correctly repeated. - * (only for mode 2) - * a dek->keylen of 0 means: no passphrase entered. - * (only for mode 2) - * - * pubkey_algo is only informational. Note that TRYAGAIN_TEXT must - * not be translated as this is done within this function (required to - * switch to utf-8 when the agent is in use). If CANCELED is not - * NULL, it is set to 1 if the user choosed to cancel the operation, - * otherwise it will be set to 0. - */ -DEK * -passphrase_to_dek( u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled) -{ - char *pw = NULL; - DEK *dek; - STRING2KEY help_s2k; - - if (canceled) - *canceled = 0; - - if( !s2k ) { - /* This is used for the old rfc1991 mode - * Note: This must match the code in encode.c with opt.rfc1991 set */ - s2k = &help_s2k; - s2k->mode = 0; - s2k->hash_algo = opt.s2k_digest_algo; - } - - if( !next_pw && is_status_enabled() ) { - char buf[50]; - - if( keyid ) { - u32 used_kid[2]; - char *us; - - if( keyid[2] && keyid[3] ) { - used_kid[0] = keyid[2]; - used_kid[1] = keyid[3]; - } - else { - used_kid[0] = keyid[0]; - used_kid[1] = keyid[1]; - } - - us = get_long_user_id_string( keyid ); - write_status_text( STATUS_USERID_HINT, us ); - xfree (us); - - sprintf( buf, "%08lX%08lX %08lX%08lX %d 0", - (ulong)keyid[0], (ulong)keyid[1], - (ulong)used_kid[0], (ulong)used_kid[1], - pubkey_algo ); - - write_status_text( STATUS_NEED_PASSPHRASE, buf ); - } - else { - sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo ); - write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf ); - } - } - - if( keyid && !opt.batch && !next_pw && mode!=1 ) { - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - size_t n; - char *p; - - tty_printf(_("\nYou need a passphrase to unlock the secret key for\n" - "user: \"") ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - tty_printf("\"\n"); - - if( !get_pubkey( pk, keyid ) ) { - const char *s = gcry_pk_algo_name ( pk->pubkey_algo ); - tty_printf( _("%u-bit %s key, ID %08lX, created %s"), - nbits_from_pk( pk ), s?s:"?", (ulong)keyid[1], - strtimestamp(pk->timestamp) ); - if( keyid[2] && keyid[3] && keyid[0] != keyid[2] - && keyid[1] != keyid[3] ) - tty_printf( _(" (main key ID %08lX)"), (ulong)keyid[3] ); - tty_printf("\n"); - } - - tty_printf("\n"); - free_public_key( pk ); - } - - agent_died: - if( next_pw ) { - pw = next_pw; - next_pw = NULL; - } - else if ( opt.use_agent ) { - pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, - tryagain_text, canceled ); - if (!pw) - { - if (!opt.use_agent) - goto agent_died; - pw = xstrdup (""); - } - if( *pw && mode == 2 ) { - char *pw2 = agent_get_passphrase ( keyid, 2, NULL, canceled ); - if (!pw2) - { - if (!opt.use_agent) - { - xfree (pw); - pw = NULL; - goto agent_died; - } - pw2 = xstrdup (""); - } - if( strcmp(pw, pw2) ) { - xfree (pw2); - xfree (pw); - return NULL; - } - xfree (pw2); - } - } - else if( fd_passwd ) { - pw = xmalloc_secure ( strlen(fd_passwd)+1 ); - strcpy( pw, fd_passwd ); - } - else if( opt.batch ) { - log_error(_("can't query password in batchmode\n")); - pw = xstrdup ( "" ); /* return an empty passphrase */ - } - else { - pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") ); - tty_kill_prompt(); - if( mode == 2 && !cpr_enabled() ) { - char *pw2 = cpr_get_hidden("passphrase.repeat", - _("Repeat passphrase: ") ); - tty_kill_prompt(); - if( strcmp(pw, pw2) ) { - xfree (pw2); - xfree (pw); - return NULL; - } - xfree (pw2); - } - } - - if( !pw || !*pw ) - write_status( STATUS_MISSING_PASSPHRASE ); - - dek = xcalloc_secure (1, sizeof *dek ); - dek->algo = cipher_algo; - if( !*pw && mode == 2 ) - dek->keylen = 0; - else - hash_passphrase( dek, pw, s2k, mode==2 ); - xfree (last_pw); - last_pw = pw; - return dek; -} - - -/**************** - * Hash a passphrase using the supplied s2k. If create is true, create - * a new salt or what else must be filled into the s2k for a new key. - * always needs: dek->algo, s2k->mode, s2k->hash_algo. - */ -static void -hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) -{ - MD_HANDLE md; - int pass, i; - int used = 0; - int pwlen = strlen(pw); - - assert( s2k->hash_algo ); - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) - BUG(); - - gcry_md_open (&md, s2k->hash_algo, 1); - for(pass=0; used < dek->keylen ; pass++ ) { - if( pass ) { - gcry_md_reset(md); - for(i=0; i < pass; i++ ) /* preset the hash context */ - gcry_md_putc (md, 0 ); - } - - if( s2k->mode == 1 || s2k->mode == 3 ) { - int len2 = pwlen + 8; - ulong count = len2; - - if( create && !pass ) { - gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM ); - if( s2k->mode == 3 ) - s2k->count = 96; /* 65536 iterations */ - } - - if( s2k->mode == 3 ) { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - if( count < len2 ) - count = len2; - } - /* a little bit complicated because we need a ulong for count */ - while( count > len2 ) { /* maybe iterated+salted */ - gcry_md_write( md, s2k->salt, 8 ); - gcry_md_write( md, pw, pwlen ); - count -= len2; - } - if( count < 8 ) - gcry_md_write( md, s2k->salt, count ); - else { - gcry_md_write( md, s2k->salt, 8 ); - count -= 8; - gcry_md_write( md, pw, count ); - } - } - else - gcry_md_write( md, pw, pwlen ); - gcry_md_final ( md ); - i = gcry_md_get_algo_dlen (s2k->hash_algo); - if( i > dek->keylen - used ) - i = dek->keylen - used; - memcpy( dek->key+used, gcry_md_read (md, s2k->hash_algo), i ); - used += i; - } - gcry_md_close (md); -} - diff --git a/g10/photoid.c b/g10/photoid.c deleted file mode 100644 index 00cc7a273..000000000 --- a/g10/photoid.c +++ /dev/null @@ -1,333 +0,0 @@ -/* photoid.c - photo ID handling code - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#ifdef _WIN32 -# include <windows.h> -# ifndef VER_PLATFORM_WIN32_WINDOWS -# define VER_PLATFORM_WIN32_WINDOWS 1 -# endif -#endif -#include "packet.h" -#include "status.h" -#include "exec.h" -#include "keydb.h" -#include "util.h" -#include "i18n.h" -#include "iobuf.h" -#include "memory.h" -#include "options.h" -#include "main.h" -#include "photoid.h" - -/* Generate a new photo id packet, or return NULL if canceled */ -PKT_user_id *generate_photo_id(PKT_public_key *pk) -{ - PKT_user_id *uid; - int error=1,i; - unsigned int len; - char *filename=NULL; - byte *photo=NULL; - byte header[16]; - iobuf_t file; - - header[0]=0x10; /* little side of photo header length */ - header[1]=0; /* big side of photo header length */ - header[2]=1; /* 1 == version of photo header */ - header[3]=1; /* 1 == JPEG */ - - for(i=4;i<16;i++) /* The reserved bytes */ - header[i]=0; - -#define EXTRA_UID_NAME_SPACE 71 - uid=xcalloc (1,sizeof(*uid)+71); - - printf(_("\nPick an image to use for your photo ID. " - "The image must be a JPEG file.\n" - "Remember that the image is stored within your public key. " - "If you use a\n" - "very large picture, your key will become very large as well!\n" - "Keeping the image close to 240x288 is a good size to use.\n")); - - while(photo==NULL) - { - printf("\n"); - - xfree (filename); - - filename=cpr_get("photoid.jpeg.add", - _("Enter JPEG filename for photo ID: ")); - - if(strlen(filename)==0) - goto scram; - - file=iobuf_open(filename); - if(!file) - { - log_error(_("Unable to open photo \"%s\": %s\n"), - filename,strerror(errno)); - continue; - } - - len=iobuf_get_filelength(file); - if(len>6144) - { - printf("This JPEG is really large (%d bytes) !\n",len); - if(!cpr_get_answer_is_yes("photoid.jpeg.size", - _("Are you sure you want to use it (y/N)? "))) - { - iobuf_close(file); - continue; - } - } - - photo=xmalloc (len); - iobuf_read(file,photo,len); - iobuf_close(file); - - /* Is it a JPEG? */ - if(photo[0]!=0xFF || photo[1]!=0xD8 || - photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F') - { - log_error(_("\"%s\" is not a JPEG file\n"),filename); - xfree (photo); - photo=NULL; - continue; - } - - /* Build the packet */ - build_attribute_subpkt(uid,1,photo,len,header,16); - parse_attribute_subpkts(uid); - make_attribute_uidname(uid, EXTRA_UID_NAME_SPACE); - - /* Showing the photo is not safe when noninteractive since the - "user" may not be able to dismiss a viewer window! */ - if(opt.command_fd==-1) - { - show_photos(uid->attribs,uid->numattribs,pk,NULL); - switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay", - _("Is this photo correct (y/N/q)? "))) - { - case -1: - goto scram; - case 0: - free_attributes(uid); - xfree (photo); - photo=NULL; - continue; - } - } - } - - error=0; - uid->ref=1; - - scram: - xfree (filename); - xfree (photo); - - if(error) - { - free_attributes(uid); - xfree (uid); - return NULL; - } - - return uid; -} - -/* Returns 0 for error, 1 for valid */ -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) -{ - u16 headerlen; - - if(attr->len<3) - return 0; - - /* For historical reasons (i.e. "oops!"), the header length is - little endian. */ - headerlen=(attr->data[1]<<8) | attr->data[0]; - - if(headerlen>attr->len) - return 0; - - if(type && attr->len>=4) - { - if(attr->data[2]==1) /* header version 1 */ - *type=attr->data[3]; - else - *type=0; - } - - *len=attr->len-headerlen; - - if(*len==0) - return 0; - - return 1; -} - -/* style==0 for extension, 1 for name, 2 for MIME type. Remember that - the "name" style string could be used in a user ID name field, so - make sure it is not too big (see parse-packet.c:parse_attribute). - Extensions should be 3 characters long for the best cross-platform - compatibility. */ -char *image_type_to_string(byte type,int style) -{ - char *string; - - switch(type) - { - case 1: /* jpeg */ - if(style==0) - string="jpg"; - else if(style==1) - string="jpeg"; - else - string="image/jpeg"; - break; - - default: - if(style==0) - string="bin"; - else if(style==1) - string="unknown"; - else - string="image/x-unknown"; - break; - } - - return string; -} - -#if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER) -static const char *get_default_photo_command(void) -{ -#if defined(_WIN32) - OSVERSIONINFO osvi; - - memset(&osvi,0,sizeof(osvi)); - osvi.dwOSVersionInfoSize=sizeof(osvi); - GetVersionEx(&osvi); - - if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) - return "start /w %i"; - else - return "cmd /c start /w %i"; -#elif defined(__APPLE__) - /* OS X. This really needs more than just __APPLE__. */ - return "open %I"; -#elif defined(__riscos__) - return "Filer_Run %I"; -#else - return "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"; -#endif -} -#endif - -void show_photos(const struct user_attribute *attrs, - int count,PKT_public_key *pk,PKT_secret_key *sk) -{ -#ifndef DISABLE_PHOTO_VIEWER - int i; - struct expando_args args; - u32 len; - u32 kid[2]={0,0}; - - memset(&args,0,sizeof(args)); - args.pk=pk; - args.sk=sk; - - if(pk) - keyid_from_pk(pk,kid); - else if(sk) - keyid_from_sk(sk,kid); - - for(i=0;i<count;i++) - if(attrs[i].type==ATTRIB_IMAGE && - parse_image_header(&attrs[i],&args.imagetype,&len)) - { - char *command,*name; - struct exec_info *spawn; - int offset=attrs[i].len-len; - -#ifdef FIXED_PHOTO_VIEWER - opt.photo_viewer=FIXED_PHOTO_VIEWER; -#else - if(!opt.photo_viewer) - opt.photo_viewer=get_default_photo_command(); -#endif - - /* make command grow */ - command=pct_expando(opt.photo_viewer,&args); - if(!command) - goto fail; - - name=xmalloc (16+strlen(EXTSEP_S)+ - strlen(image_type_to_string(args.imagetype,0))+1); - - /* Make the filename. Notice we are not using the image - encoding type for more than cosmetics. Most external image - viewers can handle a multitude of types, and even if one - cannot understand a particular type, we have no way to know - which. The spec permits this, by the way. -dms */ - -#ifdef USE_ONLY_8DOT3 - sprintf(name,"%08lX" EXTSEP_S "%s",(ulong)kid[1], - image_type_to_string(args.imagetype,0)); -#else - sprintf(name,"%08lX%08lX" EXTSEP_S "%s",(ulong)kid[0],(ulong)kid[1], - image_type_to_string(args.imagetype,0)); -#endif - - if(exec_write(&spawn,NULL,command,name,1,1)!=0) - { - xfree (name); - goto fail; - } - -#ifdef __riscos__ - riscos_set_filetype_by_mimetype(spawn->tempfile_in, - image_type_to_string(args.imagetype,2)); -#endif - - xfree (name); - - fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild); - - if(exec_read(spawn)!=0) - { - exec_finish(spawn); - goto fail; - } - - if(exec_finish(spawn)!=0) - goto fail; - } - - return; - - fail: - log_error(_("unable to display photo ID!\n")); -#endif -} diff --git a/g10/photoid.h b/g10/photoid.h deleted file mode 100644 index 187ca5ba2..000000000 --- a/g10/photoid.h +++ /dev/null @@ -1,34 +0,0 @@ -/* photoid.h - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* Photo ID functions */ - -#ifndef _PHOTOID_H_ -#define _PHOTOID_H_ - -#include "packet.h" - -PKT_user_id *generate_photo_id(PKT_public_key *pk); -int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len); -char *image_type_to_string(byte type,int style); -void show_photos(const struct user_attribute *attrs, - int count,PKT_public_key *pk,PKT_secret_key *sk); - -#endif /* !_PHOTOID_H_ */ diff --git a/g10/pipemode.c b/g10/pipemode.c deleted file mode 100644 index 9f2ddfdb5..000000000 --- a/g10/pipemode.c +++ /dev/null @@ -1,317 +0,0 @@ -/* pipemode.c - pipemode handler - * Copyright (C) 1998, 1990, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "filter.h" - - -#define CONTROL_PACKET_SPACE 30 -#define FAKED_LITERAL_PACKET_SPACE (9+2+2) - - -enum pipemode_state_e { - STX_init = 0, - STX_wait_operation, - STX_begin, - STX_text, - STX_detached_signature, - STX_detached_signature_wait_text, - STX_signed_data, - STX_wait_init -}; - -struct pipemode_context_s { - enum pipemode_state_e state; - int operation; - int stop; - int block_mode; - UnarmorPump unarmor_ctx; -}; - - -static size_t -make_control ( byte *buf, int code, int operation ) -{ - const byte *sesmark; - size_t sesmarklen, n=0;; - - sesmark = get_session_marker( &sesmarklen ); - if ( sesmarklen > 20 ) - BUG(); - - buf[n++] = 0xff; /* new format, type 63, 1 length byte */ - n++; /* length will fixed below */ - memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen; - buf[n++] = CTRLPKT_PIPEMODE; - buf[n++] = code; - buf[n++] = operation; - buf[1] = n-2; - return n; -} - - - -static int -pipemode_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - struct pipemode_context_s *stx = opaque; - int rc=0; - size_t n = 0; - int esc = 0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - *ret_len = 0; - /* reserve some space for one control packet */ - if ( size <= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE ) - BUG(); - size -= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE; - - if ( stx->block_mode ) { - /* reserve 2 bytes for the block length */ - buf[n++] = 0; - buf[n++] = 0; - } - - - while ( n < size ) { - /* FIXME: we have to make sure that we have a large enough - * buffer for a control packet even after we already read - * something. The easest way to do this is probably by ungetting - * the control sequence and returning the buffer we have - * already assembled */ - int c = iobuf_get (a); - if (c == -1) { - if ( stx->state != STX_init ) { - log_error ("EOF encountered at wrong state\n"); - stx->stop = 1; - return -1; - } - break; - } - if ( esc ) { - switch (c) { - case '@': - if ( stx->state == STX_text ) { - buf[n++] = c; - break; - } - else if ( stx->state == STX_detached_signature ) { - esc = 0; - goto do_unarmor; /* not a very elegant solution */ - } - else if ( stx->state == STX_detached_signature_wait_text) { - esc = 0; - break; /* just ignore it in this state */ - } - log_error ("@@ not allowed in current state\n"); - return -1; - case '<': /* begin of stream part */ - if ( stx->state != STX_init ) { - log_error ("nested begin of stream\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_wait_operation; - stx->block_mode = 0; - unarmor_pump_release (stx->unarmor_ctx); - stx->unarmor_ctx = NULL; - break; - case '>': /* end of stream part */ - if ( stx->state != STX_wait_init ) { - log_error ("invalid state for @>\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_init; - break; - case 'V': /* operation = verify */ - case 'E': /* operation = encrypt */ - case 'S': /* operation = sign */ - case 'B': /* operation = detach sign */ - case 'C': /* operation = clearsign */ - case 'D': /* operation = decrypt */ - if ( stx->state != STX_wait_operation ) { - log_error ("invalid state for operation code\n"); - stx->stop = 1; - return -1; - } - stx->operation = c; - if ( stx->operation == 'B') { - stx->state = STX_detached_signature; - if ( !opt.no_armor ) - stx->unarmor_ctx = unarmor_pump_new (); - } - else - stx->state = STX_begin; - n += make_control ( buf+n, 1, stx->operation ); - /* must leave after a control packet */ - goto leave; - - case 't': /* plaintext text follows */ - if ( stx->state == STX_detached_signature_wait_text ) - stx->state = STX_detached_signature; - if ( stx->state == STX_detached_signature ) { - if ( stx->operation != 'B' ) { - log_error ("invalid operation for this state\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_signed_data; - n += make_control ( buf+n, 2, 'B' ); - /* and now we fake a literal data packet much the same - * as in armor.c */ - buf[n++] = 0xaf; /* old packet format, type 11, - var length */ - buf[n++] = 0; /* set the length header */ - buf[n++] = 6; - buf[n++] = 'b'; /* we ignore it anyway */ - buf[n++] = 0; /* namelength */ - memset(buf+n, 0, 4); /* timestamp */ - n += 4; - /* and return now so that we are sure to have - * more space in the bufer for the next control - * packet */ - stx->block_mode = 1; - goto leave2; - } - else { - log_error ("invalid state for @t\n"); - stx->stop = 1; - return -1; - } - break; - - case '.': /* ready */ - if ( stx->state == STX_signed_data ) { - if (stx->block_mode) { - buf[0] = (n-2) >> 8; - buf[1] = (n-2); - if ( buf[0] || buf[1] ) { - /* end of blocks marker */ - buf[n++] = 0; - buf[n++] = 0; - } - stx->block_mode = 0; - } - n += make_control ( buf+n, 3, 'B' ); - } - else { - log_error ("invalid state for @.\n"); - stx->stop = 1; - return -1; - } - stx->state = STX_wait_init; - goto leave; - - default: - log_error ("invalid escape sequence 0x%02x in stream\n", - c); - stx->stop = 1; - return -1; - } - esc = 0; - } - else if (c == '@') - esc = 1; - else if (stx->unarmor_ctx) { - do_unarmor: /* used to handle a @@ */ - c = unarmor_pump (stx->unarmor_ctx, c); - if ( !(c & ~255) ) - buf[n++] = c; - else if ( c < 0 ) { - /* end of armor or error - we don't care becuase - the armor can be modified anyway. The unarmored - stuff should stand for itself. */ - unarmor_pump_release (stx->unarmor_ctx); - stx->unarmor_ctx = NULL; - stx->state = STX_detached_signature_wait_text; - } - } - else if (stx->state == STX_detached_signature_wait_text) - ; /* just wait */ - else - buf[n++] = c; - } - - leave: - if ( !n ) { - stx->stop = 1; - rc = -1; /* eof */ - } - if ( stx->block_mode ) { - /* fixup the block length */ - buf[0] = (n-2) >> 8; - buf[1] = (n-2); - } - leave2: - /*log_hexdump ("pipemode:", buf, n );*/ - *ret_len = n; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "pipemode_filter"; - return rc; -} - - - -void -run_in_pipemode(void) -{ - iobuf_t fp; - armor_filter_context_t afx; - struct pipemode_context_s stx; - int rc; - - memset( &afx, 0, sizeof afx); - memset( &stx, 0, sizeof stx); - - fp = iobuf_open("-"); - iobuf_push_filter (fp, pipemode_filter, &stx ); - - do { - write_status (STATUS_BEGIN_STREAM); - rc = proc_packets( NULL, fp ); - write_status (STATUS_END_STREAM); - } while ( !stx.stop ); - -} - - - - - - diff --git a/g10/pkclist.c b/g10/pkclist.c deleted file mode 100644 index 71e6492e8..000000000 --- a/g10/pkclist.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* pkclist.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "trustdb.h" -#include "ttyio.h" -#include "status.h" -#include "photoid.h" -#include "i18n.h" - - -#define CONTROL_D ('D' - 'A' + 1) - - -/**************** - * Show the revocation reason as it is stored with the given signature - */ -static void -do_show_revocation_reason( PKT_signature *sig ) -{ - size_t n, nn; - const byte *p, *pp; - int seq = 0; - const char *text; - - while( (p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON, - &n, &seq, NULL )) ) { - if( !n ) - continue; /* invalid - just skip it */ - - if( *p == 0 ) - text = _("No reason specified"); - else if( *p == 0x01 ) - text = _("Key is superseded"); - else if( *p == 0x02 ) - text = _("Key has been compromised"); - else if( *p == 0x03 ) - text = _("Key is no longer used"); - else if( *p == 0x20 ) - text = _("User ID is no longer valid"); - else - text = NULL; - - log_info( _("reason for revocation: ") ); - if( text ) - fputs( text, log_get_stream () ); - else - fprintf( log_get_stream (), "code=%02x", *p ); - putc( '\n', log_get_stream () ); - n--; p++; - pp = NULL; - do { - /* We don't want any empty lines, so skip them */ - while( n && *p == '\n' ) { - p++; - n--; - } - if( n ) { - pp = memchr( p, '\n', n ); - nn = pp? pp - p : n; - log_info( _("revocation comment: ") ); - print_string( log_get_stream(), p, nn, 0 ); - putc( '\n', log_get_stream() ); - p += nn; n -= nn; - } - } while( pp ); - } -} - -/* Mode 0: try and find the revocation based on the pk (i.e. check - subkeys, etc.) Mode 1: use only the revocation on the main pk */ - -void -show_revocation_reason( PKT_public_key *pk, int mode ) -{ - /* Hmmm, this is not so easy becuase we have to duplicate the code - * used in the trustbd to calculate the keyflags. We need to find - * a clean way to check revocation certificates on keys and - * signatures. And there should be no duplicate code. Because we - * enter this function only when the trustdb told us that we have - * a revoked key, we could simply look for a revocation cert and - * display this one, when there is only one. Let's try to do this - * until we have a better solution. */ - KBNODE node, keyblock = NULL; - byte fingerprint[MAX_FINGERPRINT_LEN]; - size_t fingerlen; - int rc; - - /* get the keyblock */ - fingerprint_from_pk( pk, fingerprint, &fingerlen ); - rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen ); - if( rc ) { /* that should never happen */ - log_debug( "failed to get the keyblock\n"); - return; - } - - for( node=keyblock; node; node = node->next ) { - if( (mode && node->pkt->pkttype == PKT_PUBLIC_KEY) || - ( ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - && !cmp_public_keys( node->pkt->pkt.public_key, pk ) ) ) - break; - } - if( !node ) { - log_debug("Oops, PK not in keyblock\n"); - release_kbnode( keyblock ); - return; - } - /* now find the revocation certificate */ - for( node = node->next; node ; node = node->next ) { - if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - break; - if( node->pkt->pkttype == PKT_SIGNATURE - && (node->pkt->pkt.signature->sig_class == 0x20 - || node->pkt->pkt.signature->sig_class == 0x28 ) ) { - /* FIXME: we should check the signature here */ - do_show_revocation_reason ( node->pkt->pkt.signature ); - break; - } - } - - /* We didn't find it, so check if the whole key is revoked */ - if(!node && !mode) - show_revocation_reason(pk,1); - - release_kbnode( keyblock ); -} - - -static void -show_paths (const PKT_public_key *pk, int only_first ) -{ - log_debug("not yet implemented\n"); -#if 0 - void *context = NULL; - unsigned otrust, validity; - int last_level, level; - - last_level = 0; - while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){ - char *p; - int c, rc; - size_t n; - u32 keyid[2]; - PKT_public_key *pk ; - - if( level < last_level && only_first ) - break; - last_level = level; - - rc = keyid_from_lid( lid, keyid ); - - if( rc ) { - log_error("ooops: can't get keyid for lid %lu\n", lid); - return; - } - - pk = xcalloc (1, sizeof *pk ); - rc = get_pubkey( pk, keyid ); - if( rc ) { - log_error("key %08lX: public key not found: %s\n", - (ulong)keyid[1], gpg_strerror (rc) ); - return; - } - - tty_printf("%*s%4u%c/%08lX.%lu %s \"", - level*2, "", - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], lid, datestr_from_pk( pk ) ); - - c = trust_letter(otrust); - if( c ) - putchar( c ); - else - printf( "%02x", otrust ); - putchar('/'); - c = trust_letter(validity); - if( c ) - putchar( c ); - else - printf( "%02x", validity ); - putchar(' '); - - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ), - xfree (p); - tty_printf("\"\n"); - free_public_key( pk ); - } - enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */ -#endif - tty_printf("\n"); -} - - - - -/**************** - * mode: 0 = standard - * 1 = Without key info and additional menu option 'm' - * this does also add an option to set the key to ultimately trusted. - * Returns: - * -2 = nothing changed - caller should show some additional info - * -1 = quit operation - * 0 = nothing changed - * 1 = new ownertrust now in new_trust - */ -static int -do_edit_ownertrust (PKT_public_key *pk, int mode, - unsigned *new_trust, int defer_help ) -{ - char *p; - size_t n; - u32 keyid[2]; - int changed=0; - int quit=0; - int show=0; - int min_num; - int did_help=defer_help; - unsigned int minimum=get_min_ownertrust(pk); - - switch(minimum) - { - default: min_num=0; break; - case TRUST_UNDEFINED: min_num=1; break; - case TRUST_NEVER: min_num=2; break; - case TRUST_MARGINAL: min_num=3; break; - case TRUST_FULLY: min_num=4; break; - } - - keyid_from_pk (pk, keyid); - for(;;) { - /* a string with valid answers */ - const char *ans = _("iImMqQsS"); - - if( !did_help ) - { - if( !mode ) - { - KBNODE keyblock, un; - - tty_printf(_("No trust value assigned to:\n" - "%4u%c/%08lX %s \""), - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ), - xfree (p); - tty_printf("\"\n"); - - keyblock = get_pubkeyblock (keyid); - if (!keyblock) - BUG (); - for (un=keyblock; un; un = un->next) { - if (un->pkt->pkttype != PKT_USER_ID ) - continue; - if (un->pkt->pkt.user_id->is_revoked ) - continue; - if (un->pkt->pkt.user_id->is_expired ) - continue; - /* Only skip textual primaries */ - if (un->pkt->pkt.user_id->is_primary && - !un->pkt->pkt.user_id->attrib_data ) - continue; - - if((opt.verify_options&VERIFY_SHOW_PHOTOS) - && un->pkt->pkt.user_id->attrib_data) - show_photos(un->pkt->pkt.user_id->attribs, - un->pkt->pkt.user_id->numattribs,pk,NULL); - - tty_printf (" %s", _(" aka \"")); - tty_print_utf8_string (un->pkt->pkt.user_id->name, - un->pkt->pkt.user_id->len ); - tty_printf("\"\n"); - } - - print_fingerprint (pk, NULL, 2); - tty_printf("\n"); - } - /* This string also used in keyedit.c:sign_uids */ - tty_printf (_( - "Please decide how far you trust this user to correctly\n" - "verify other users' keys (by looking at passports,\n" - "checking fingerprints from different sources...)?\n\n")); - if(min_num<=1) - tty_printf (_(" %d = I don't know\n"), 1); - if(min_num<=2) - tty_printf (_(" %d = I do NOT trust\n"), 2); - if(min_num<=3) - tty_printf (_(" %d = I trust marginally\n"), 3); - if(min_num<=4) - tty_printf (_(" %d = I trust fully\n"), 4); - if (mode) - tty_printf (_(" %d = I trust ultimately\n"), 5); -#if 0 - /* not yet implemented */ - tty_printf (_(" i = please show me more information\n") ); -#endif - if( mode ) - tty_printf(_(" m = back to the main menu\n")); - else - { - tty_printf(_(" s = skip this key\n")); - tty_printf(_(" q = quit\n")); - } - tty_printf("\n"); - if(minimum) - tty_printf(_("The minimum trust level for this key is: %s\n\n"), - trust_value_to_string(minimum)); - did_help = 1; - } - if( strlen(ans) != 8 ) - BUG(); - p = cpr_get("edit_ownertrust.value",_("Your decision? ")); - trim_spaces(p); - cpr_kill_prompt(); - if( !*p ) - did_help = 0; - else if( *p && p[1] ) - ; - else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) ) - { - unsigned int trust; - switch( *p ) - { - case '1': trust = TRUST_UNDEFINED; break; - case '2': trust = TRUST_NEVER ; break; - case '3': trust = TRUST_MARGINAL ; break; - case '4': trust = TRUST_FULLY ; break; - case '5': trust = TRUST_ULTIMATE ; break; - default: BUG(); - } - if (trust == TRUST_ULTIMATE - && !cpr_get_answer_is_yes ("edit_ownertrust.set_ultimate.okay", - _("Do you really want to set this key" - " to ultimate trust? "))) - ; /* no */ - else - { - *new_trust = trust; - changed = 1; - break; - } - } -#if 0 - /* not yet implemented */ - else if( *p == ans[0] || *p == ans[1] ) - { - tty_printf(_("Certificates leading to an ultimately trusted key:\n")); - show = 1; - break; - } -#endif - else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) - { - break ; /* back to the menu */ - } - else if( !mode && (*p == ans[6] || *p == ans[7] ) ) - { - break; /* skip */ - } - else if( !mode && (*p == ans[4] || *p == ans[5] ) ) - { - quit = 1; - break ; /* back to the menu */ - } - xfree (p); p = NULL; - } - xfree (p); - return show? -2: quit? -1 : changed; -} - -/* - * Display a menu to change the ownertrust of the key PK (which should - * be a primary key). - * For mode values see do_edit_ownertrust () - */ -int -edit_ownertrust (PKT_public_key *pk, int mode ) -{ - unsigned int trust; - int no_help = 0; - - for(;;) - { - switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) ) - { - case -1: /* quit */ - return -1; - case -2: /* show info */ - show_paths(pk, 1); - no_help = 1; - break; - case 1: /* trust value set */ - trust &= ~TRUST_FLAG_DISABLED; - trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED; - update_ownertrust (pk, trust ); - return 1; - default: - return 0; - } - } -} - - -/**************** - * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL - * Returns: true if we trust. - */ -static int -do_we_trust( PKT_public_key *pk, unsigned int *trustlevel ) -{ - unsigned int trustmask = 0; - - /* FIXME: get_pubkey_byname already checks the validity and won't - * return keys which are either expired or revoked - so these - * question here won't get triggered. We have to find a solution - * for this. It might make sense to have a function in getkey.c - * which does only the basic checks and returns even revoked and - * expired keys. This fnction could then also returhn a list of - * keys if the speicified name is ambiguous - */ - if( (*trustlevel & TRUST_FLAG_REVOKED) ) { - log_info(_("key %08lX: key has been revoked!\n"), - (ulong)keyid_from_pk( pk, NULL) ); - show_revocation_reason( pk, 0 ); - if( opt.batch ) - return 0; /* no */ - - if( !cpr_get_answer_is_yes("revoked_key.override", - _("Use this key anyway? ")) ) - return 0; /* no */ - trustmask |= TRUST_FLAG_REVOKED; - } - if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) { - log_info(_("key %08lX: subkey has been revoked!\n"), - (ulong)keyid_from_pk( pk, NULL) ); - show_revocation_reason( pk, 0 ); - if( opt.batch ) - return 0; - - if( !cpr_get_answer_is_yes("revoked_key.override", - _("Use this key anyway? ")) ) - return 0; - trustmask |= TRUST_FLAG_SUB_REVOKED; - } - *trustlevel &= ~trustmask; - - if( opt.trust_model==TM_ALWAYS ) { - if( opt.verbose ) - log_info("No trust check due to --trust-model always option\n"); - return 1; - } - - switch( (*trustlevel & TRUST_MASK) ) { - case TRUST_EXPIRED: - log_info(_("%08lX: key has expired\n"), - (ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - default: - log_error ("invalid trustlevel %u returned from validation layer\n", - *trustlevel); - /* fall thru */ - case TRUST_UNKNOWN: - case TRUST_UNDEFINED: - log_info(_("%08lX: There is no assurance this key belongs " - "to the named user\n"),(ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - /* No way to get here? */ - case TRUST_NEVER: - log_info(_("%08lX: We do NOT trust this key\n"), - (ulong)keyid_from_pk( pk, NULL) ); - return 0; /* no */ - - case TRUST_MARGINAL: - log_info(_("%08lX: There is limited assurance this key belongs " - "to the named user\n"),(ulong)keyid_from_pk(pk,NULL)); - return 1; /* yes */ - - case TRUST_FULLY: - if( opt.verbose ) - log_info(_("This key probably belongs to the named user\n")); - return 1; /* yes */ - - case TRUST_ULTIMATE: - if( opt.verbose ) - log_info(_("This key belongs to us\n")); - return 1; /* yes */ - } - - return 1; /* yes */ -} - - - -/**************** - * wrapper around do_we_trust, so we can ask whether to use the - * key anyway. - */ -static int -do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel ) -{ - int rc; - - rc = do_we_trust( pk, &trustlevel ); - - if( (trustlevel & TRUST_FLAG_REVOKED) && !rc ) - return 0; - if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc ) - return 0; - - if( !opt.batch && !rc ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid); - tty_printf( "%4u%c/%08lX %s \"", - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - /* If the pk was chosen by a particular user ID, this is the - one to ask about. */ - if(pk->user_id) - tty_print_utf8_string(pk->user_id->name,pk->user_id->len); - else - { - size_t n; - char *p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - } - tty_printf("\"\n"); - print_fingerprint (pk, NULL, 2); - tty_printf("\n"); - - tty_printf(_( -"It is NOT certain that the key belongs to the person named\n" -"in the user ID. If you *really* know what you are doing,\n" -"you may answer the next question with yes\n\n")); - - if( cpr_get_answer_is_yes("untrusted_key.override", - _("Use this key anyway? ")) ) - rc = 1; - - /* Hmmm: Should we set a flag to tell the user about - * his decision the next time he encrypts for this recipient? - */ - } - else if( opt.trust_model==TM_ALWAYS && !rc ) { - if( !opt.quiet ) - log_info(_("WARNING: Using untrusted key!\n")); - rc = 1; - } - return rc; -} - - - -/**************** - * Check whether we can trust this signature. - * Returns: Error if we shall not trust this signatures. - */ -int -check_signatures_trust( PKT_signature *sig ) -{ - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - unsigned int trustlevel; - int rc=0; - - rc = get_pubkey( pk, sig->keyid ); - if (rc) - { /* this should not happen */ - log_error("Ooops; the key vanished - can't check the trust\n"); - rc = GPG_ERR_NO_PUBKEY; - goto leave; - } - - if ( opt.trust_model==TM_ALWAYS ) - { - if( !opt.quiet ) - log_info(_("WARNING: Using untrusted key!\n")); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - goto leave; - } - - trustlevel = get_validity (pk, NULL); - - if ( (trustlevel & TRUST_FLAG_REVOKED) ) - { - write_status( STATUS_KEYREVOKED ); - log_info(_("WARNING: This key has been revoked by its owner!\n")); - log_info(_(" This could mean that the signature is forgery.\n")); - show_revocation_reason( pk, 0 ); - } - else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) - { - write_status( STATUS_KEYREVOKED ); - log_info(_("WARNING: This subkey has been revoked by its owner!\n")); - show_revocation_reason( pk, 0 ); - } - - if ((trustlevel & TRUST_FLAG_DISABLED)) - log_info (_("Note: This key has been disabled.\n")); - - switch ( (trustlevel & TRUST_MASK) ) - { - case TRUST_EXPIRED: - log_info(_("Note: This key has expired!\n")); - print_fingerprint (pk, NULL, 1); - break; - - default: - log_error ("invalid trustlevel %u returned from validation layer\n", - trustlevel); - /* fall thru */ - case TRUST_UNKNOWN: - case TRUST_UNDEFINED: - write_status( STATUS_TRUST_UNDEFINED ); - log_info(_("WARNING: This key is not certified with" - " a trusted signature!\n")); - log_info(_(" There is no indication that the " - "signature belongs to the owner.\n" )); - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_NEVER: - /* currently we won't get that status */ - write_status( STATUS_TRUST_NEVER ); - log_info(_("WARNING: We do NOT trust this key!\n")); - log_info(_(" The signature is probably a FORGERY.\n")); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - break; - - case TRUST_MARGINAL: - write_status( STATUS_TRUST_MARGINAL ); - log_info(_("WARNING: This key is not certified with" - " sufficiently trusted signatures!\n")); - log_info(_(" It is not certain that the" - " signature belongs to the owner.\n" )); - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_FULLY: - write_status( STATUS_TRUST_FULLY ); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - break; - - case TRUST_ULTIMATE: - write_status( STATUS_TRUST_ULTIMATE ); - if (opt.with_fingerprint) - print_fingerprint (pk, NULL, 1); - break; - } - - leave: - free_public_key( pk ); - return rc; -} - - -void -release_pk_list( PK_LIST pk_list ) -{ - PK_LIST pk_rover; - - for( ; pk_list; pk_list = pk_rover ) { - pk_rover = pk_list->next; - free_public_key( pk_list->pk ); - xfree ( pk_list ); - } -} - - -static int -key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk) -{ - for( ; pk_list; pk_list = pk_list->next) - if (cmp_public_keys(pk_list->pk, pk) == 0) - return 0; - - return -1; -} - - -/**************** - * Return a malloced string with a default reciepient if there is any - */ -static char * -default_recipient(void) -{ - PKT_secret_key *sk; - byte fpr[MAX_FINGERPRINT_LEN+1]; - size_t n; - char *p; - int i; - - if( opt.def_recipient ) - return xstrdup ( opt.def_recipient ); - if( !opt.def_recipient_self ) - return NULL; - sk = xcalloc (1, sizeof *sk ); - i = get_seckey_byname( sk, NULL, 0 ); - if( i ) { - free_secret_key( sk ); - return NULL; - } - n = MAX_FINGERPRINT_LEN; - fingerprint_from_sk( sk, fpr, &n ); - free_secret_key( sk ); - p = xmalloc ( 2*n+3 ); - *p++ = '0'; - *p++ = 'x'; - for(i=0; i < n; i++ ) - sprintf( p+2*i, "%02X", fpr[i] ); - p -= 2; - return p; -} - -static int -expand_id(const char *id,STRLIST *into,unsigned int flags) -{ - struct groupitem *groups; - int count=0; - - for(groups=opt.grouplist;groups;groups=groups->next) - { - /* need strcasecmp() here, as this should be localized */ - if(strcasecmp(groups->name,id)==0) - { - STRLIST each,sl; - - /* this maintains the current utf8-ness */ - for(each=groups->values;each;each=each->next) - { - sl=add_to_strlist(into,each->d); - sl->flags=flags; - count++; - } - - break; - } - } - - return count; -} - -/* For simplicity, and to avoid potential loops, we only expand once - - you can't make an alias that points to an alias. */ -static STRLIST -expand_group(STRLIST input) -{ - STRLIST sl,output=NULL,rover; - - for(rover=input;rover;rover=rover->next) - if(expand_id(rover->d,&output,rover->flags)==0) - { - /* Didn't find any groups, so use the existing string */ - sl=add_to_strlist(&output,rover->d); - sl->flags=rover->flags; - } - - return output; -} - -int -build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) -{ - PK_LIST pk_list = NULL; - PKT_public_key *pk=NULL; - int rc=0; - int any_recipients=0; - STRLIST rov,remusr; - char *def_rec = NULL; - - if(opt.grouplist) - remusr=expand_group(rcpts); - else - remusr=rcpts; - - /* check whether there are any recipients in the list and build the - * list of the encrypt-to ones (we always trust them) */ - for( rov = remusr; rov; rov = rov->next ) { - if( !(rov->flags & 1) ) - { - any_recipients = 1; - - if((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--hidden-recipient", - compliance_option_string()); - - compliance_failure(); - } - } - else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - /* We can encrypt-to a disabled key */ - if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL, 1 )) ) { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - rov->d, strlen (rov->d), -1); - goto fail; - } - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) { - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - rov->d); - } - else { - PK_LIST r; - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = (rov->flags&2)?1:0; - pk_list = r; - - if(r->flags&1 && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--hidden-encrypt-to", - compliance_option_string()); - - compliance_failure(); - } - } - } - else { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - rov->d, strlen (rov->d), -1); - goto fail; - } - } - } - - if( !any_recipients && !opt.batch ) { /* ask */ - int have_def_rec; - char *answer=NULL; - STRLIST backlog=NULL; - - def_rec = default_recipient(); - have_def_rec = !!def_rec; - if( !have_def_rec ) - tty_printf(_( - "You did not specify a user ID. (you may use \"-r\")\n")); - for(;;) { - rc = 0; - xfree (answer); - if( have_def_rec ) { - answer = def_rec; - def_rec = NULL; - } - else if (backlog) { - answer = strlist_pop (&backlog); - } - else { - answer = cpr_get_utf8("pklist.user_id.enter", - _("\nEnter the user ID. End with an empty line: ")); - trim_spaces(answer); - cpr_kill_prompt(); - } - if( !answer || !*answer ) { - xfree (answer); - break; - } - if(expand_id(answer,&backlog,0)) - continue; - if( pk ) - free_public_key( pk ); - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 ); - if( rc ) - tty_printf(_("No such user ID.\n")); - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) { - if( have_def_rec ) { - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("skipped: public key " - "already set as default recipient\n") ); - } - else { - PK_LIST r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing default ids */ - pk_list = r; - } - any_recipients = 1; - continue; - } - else { - int trustlevel; - - trustlevel = get_validity (pk, pk->user_id); - if( (trustlevel & TRUST_FLAG_DISABLED) ) { - tty_printf(_("Public key is disabled.\n") ); - } - else if( do_we_trust_pre( pk, trustlevel ) ) { - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("skipped: public key already set\n") ); - } - else { - PK_LIST r; - u32 keyid[2]; - - keyid_from_pk( pk, keyid); - tty_printf("Added %4u%c/%08lX %s \"", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], - datestr_from_pk( pk ) ); - if(pk->user_id) - tty_print_utf8_string(pk->user_id->name, - pk->user_id->len); - else - { - size_t n; - char *p = get_user_id( keyid, &n ); - tty_print_utf8_string( p, n ); - xfree (p); - } - tty_printf("\"\n"); - - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing interactive ids */ - pk_list = r; - } - any_recipients = 1; - continue; - } - } - } - xfree (def_rec); def_rec = NULL; - have_def_rec = 0; - } - if( pk ) { - free_public_key( pk ); - pk = NULL; - } - } - else if( !any_recipients && (def_rec = default_recipient()) ) { - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - /* The default recipient may be disabled */ - rc = get_pubkey_byname( pk, def_rec, NULL, NULL, 1 ); - if( rc ) - log_error(_("unknown default recipient `%s'\n"), def_rec ); - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) { - /* Mark any_recipients here since the default recipient - would have been used if it wasn't already there. It - doesn't really matter if we got this key from the default - recipient or an encrypt-to. */ - any_recipients = 1; - if (key_present_in_pk_list(pk_list, pk) == 0) - log_info(_("skipped: public key already set as default recipient\n")); - else { - PK_LIST r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = 0; /* no throwing default ids */ - pk_list = r; - } - } - if( pk ) { - free_public_key( pk ); - pk = NULL; - } - xfree (def_rec); def_rec = NULL; - } - else { - any_recipients = 0; - for(; remusr; remusr = remusr->next ) { - if( (remusr->flags & 1) ) - continue; /* encrypt-to keys are already handled */ - - pk = xcalloc (1, sizeof *pk ); - pk->req_usage = use; - if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) { - free_public_key( pk ); pk = NULL; - log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) ); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, strlen (remusr->d), - -1); - goto fail; - } - else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) { - int trustlevel; - - trustlevel = get_validity (pk, pk->user_id); - if( (trustlevel & TRUST_FLAG_DISABLED) ) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key is disabled\n"), - remusr->d); - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, - strlen (remusr->d), - -1); - rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); - goto fail; - } - else if( do_we_trust_pre( pk, trustlevel ) ) { - /* note: do_we_trust may have changed the trustlevel */ - - /* We have at least one valid recipient. It doesn't matters - * if this recipient is already present. */ - any_recipients = 1; - - /* Skip the actual key if the key is already present - * in the list */ - if (key_present_in_pk_list(pk_list, pk) == 0) { - free_public_key(pk); pk = NULL; - log_info(_("%s: skipped: public key already present\n"), - remusr->d); - } - else { - PK_LIST r; - r = xmalloc ( sizeof *r ); - r->pk = pk; pk = NULL; - r->next = pk_list; - r->flags = (remusr->flags&2)?1:0; - pk_list = r; - } - } - else { /* we don't trust this pk */ - free_public_key( pk ); pk = NULL; - write_status_text_and_buffer (STATUS_INV_RECP, "10 ", - remusr->d, - strlen (remusr->d), - -1); - rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY); - goto fail; - } - } - else { - free_public_key( pk ); pk = NULL; - write_status_text_and_buffer (STATUS_INV_RECP, "0 ", - remusr->d, - strlen (remusr->d), - -1); - log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) ); - goto fail; - } - } - } - - if( !rc && !any_recipients ) { - log_error(_("no valid addressees\n")); - write_status_text (STATUS_NO_RECP, "0"); - rc = GPG_ERR_NO_USER_ID; - } - - fail: - - if( rc ) - release_pk_list( pk_list ); - else - *ret_pk_list = pk_list; - if(opt.grouplist) - free_strlist(remusr); - return rc; -} - - -/* In pgp6 mode, disallow all ciphers except IDEA (1), 3DES (2), and - CAST5 (3), all hashes except MD5 (1), SHA1 (2), and RIPEMD160 (3), - and all compressions except none (0) and ZIP (1). pgp7 and pgp8 - mode expands the cipher list to include AES128 (7), AES192 (8), - AES256 (9), and TWOFISH (10). pgp8 adds the SHA-256 hash (8). For - a true PGP key all of this is unneeded as they are the only items - present in the preferences subpacket, but checking here covers the - weird case of encrypting to a key that had preferences from a - different implementation which was then used with PGP. I am not - completely comfortable with this as the right thing to do, as it - slightly alters the list of what the user is supposedly requesting. - It is not against the RFC however, as the preference chosen will - never be one that the user didn't specify somewhere ("The - implementation may use any mechanism to pick an algorithm in the - intersection"), and PGP has no mechanism to fix such a broken - preference list, so I'm including it. -dms */ - -int -algo_available( preftype_t preftype, int algo, void *hint ) -{ - if( preftype == PREFTYPE_SYM ) - { - if(PGP6 && (algo != CIPHER_ALGO_IDEA - && algo != CIPHER_ALGO_3DES - && algo != CIPHER_ALGO_CAST5)) - return 0; - - if((PGP7 || PGP8) && (algo != CIPHER_ALGO_IDEA - && algo != CIPHER_ALGO_3DES - && algo != CIPHER_ALGO_CAST5 - && algo != CIPHER_ALGO_AES - && algo != CIPHER_ALGO_AES192 - && algo != CIPHER_ALGO_AES256 - && algo != CIPHER_ALGO_TWOFISH)) - return 0; - - return algo && !gcry_cipher_test_algo (algo); - } - else if( preftype == PREFTYPE_HASH ) - { - if(hint && ((*(int *)hint) != gcry_md_get_algo_dlen (algo))) - return 0; - - if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5 - && algo != DIGEST_ALGO_SHA1 - && algo != DIGEST_ALGO_RMD160)) - return 0; - - - if(PGP8 && (algo != DIGEST_ALGO_MD5 - && algo != DIGEST_ALGO_SHA1 - && algo != DIGEST_ALGO_RMD160 - && algo != DIGEST_ALGO_SHA256)) - return 0; - - return algo && !gcry_md_test_algo( algo ); - } - else if( preftype == PREFTYPE_ZIP ) - { - if((PGP6 || PGP7 || PGP8) && (algo != COMPRESS_ALGO_NONE - && algo != COMPRESS_ALGO_ZIP)) - return 0; - - return !check_compress_algo( algo ); - } - else - return 0; -} - - - -/**************** - * Return -1 if we could not find an algorithm. - */ -int -select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint) -{ - PK_LIST pkr; - u32 bits[8]; - const prefitem_t *prefs; - int i, j; - int compr_hack=0; - int any; - - if( !pk_list ) - return -1; - - memset( bits, ~0, 8 * sizeof *bits ); - for( pkr = pk_list; pkr; pkr = pkr->next ) { - u32 mask[8]; - - memset( mask, 0, 8 * sizeof *mask ); - if( preftype == PREFTYPE_SYM ) { - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys - with v3 selfsigs (rfc2440:12.1) if - --pgp2 mode is on. This doesn't - mean it's actually available, of - course. */ - else - mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */ - } - else if( preftype == PREFTYPE_HASH ) { - /* While I am including this code for completeness, note - that currently --pgp2 mode locks the hash at MD5, so this - function will never even be called. Even if the hash - wasn't locked at MD5, we don't support sign+encrypt in - --pgp2 mode, and that's the only time PREFTYPE_HASH is - used anyway. -dms */ - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3 - selfsigs when --pgp2 is on. */ - else - mask[0] |= (1<<2); /* SHA1 is there for everyone else */ - } - else if( preftype == PREFTYPE_ZIP ) - mask[0] |= (1<<0); /* Uncompressed is implicit */ - - if (pkr->pk->user_id) /* selected by user ID */ - prefs = pkr->pk->user_id->prefs; - else - prefs = pkr->pk->prefs; - - any = 0; - if( prefs ) { - for (i=0; prefs[i].type; i++ ) { - if( prefs[i].type == preftype ) { - mask[prefs[i].value/32] |= 1 << (prefs[i].value%32); - any = 1; - } - } - } - - if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) { - mask[0] |= 3; /* asume no_compression and old pgp */ - compr_hack = 1; - } - -#if 0 - log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4], - (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]); -#endif - for(i=0; i < 8; i++ ) - bits[i] &= mask[i]; -#if 0 - log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4], - (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]); -#endif - } - /* usable algorithms are now in bits - * We now use the last key from pk_list to select - * the algorithm we want to use. there are no - * preferences for the last key, we select the one - * corresponding to first set bit. - */ - i = -1; - any = 0; - - /* Can we use the requested algorithm? */ - if(request>-1 && (bits[request/32] & (1<<(request%32))) && - algo_available(preftype,request,hint)) - return request; - - /* If we have personal prefs set, use them instead of the last key */ - if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) - prefs=opt.personal_cipher_prefs; - else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) - prefs=opt.personal_digest_prefs; - else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) - prefs=opt.personal_compress_prefs; - - if( prefs ) { - for(j=0; prefs[j].type; j++ ) { - if( prefs[j].type == preftype ) { - if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) { - if( algo_available( preftype, prefs[j].value, hint ) ) { - any = 1; - i = prefs[j].value; - break; - } - } - } - } - } - if( !prefs || !any ) { - for(j=0; j < 256; j++ ) - if( (bits[j/32] & (1<<(j%32))) ) { - if( algo_available( preftype, j, hint ) ) { - i = j; - break; - } - } - } - -#if 0 - log_debug("prefs of type %d: selected %d\n", preftype, i ); -#endif - if( compr_hack && !i ) { - /* selected no compression, but we should check whether - * algorithm 1 is also available (the ordering is not relevant - * in this case). */ - if( bits[0] & (1<<1) ) - i = 1; /* yep; we can use compression algo 1 */ - } - - /* "If you are building an authentication system, the recipient - may specify a preferred signing algorithm. However, the signer - would be foolish to use a weak algorithm simply because the - recipient requests it." RFC2440:13. If we settle on MD5, and - SHA1 is also available, use SHA1 instead. Of course, if the - user intentionally chose MD5 (by putting it in their personal - prefs), then we should do what they say. */ - - if(preftype==PREFTYPE_HASH && - i==DIGEST_ALGO_MD5 && (bits[0] & (1<<DIGEST_ALGO_SHA1))) - { - i=DIGEST_ALGO_SHA1; - - if(opt.personal_digest_prefs) - for(j=0; prefs[j].type; j++ ) - if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH && - opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5) - { - i=DIGEST_ALGO_MD5; - break; - } - } - - return i; -} - -/* - * Select the MDC flag from the pk_list. We can only use MDC if all recipients - * support this feature - */ -int -select_mdc_from_pklist (PK_LIST pk_list) -{ - PK_LIST pkr; - - if( !pk_list ) - return 0; - - for (pkr = pk_list; pkr; pkr = pkr->next) { - int mdc; - - if (pkr->pk->user_id) /* selected by user ID */ - mdc = pkr->pk->user_id->mdc_feature; - else - mdc = pkr->pk->mdc_feature; - if (!mdc) - return 0; /* at least one recipient does not support it */ - } - return 1; /* can be used */ -} diff --git a/g10/pkglue.c b/g10/pkglue.c deleted file mode 100644 index f062d8366..000000000 --- a/g10/pkglue.c +++ /dev/null @@ -1,342 +0,0 @@ -/* pkglue.c - public key operations glue code - * Copyright (C) 2000, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "pkglue.h" - - -static gcry_mpi_t -mpi_from_sexp (gcry_sexp_t sexp, const char * item) -{ - gcry_sexp_t list; - gcry_mpi_t data; - - list = gcry_sexp_find_token (sexp, item, 0); - assert (list); - data = gcry_sexp_nth_mpi (list, 1, 0); - assert (data); - gcry_sexp_release (list); - return data; -} - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) -{ - gcry_sexp_t s_sig, s_hash, s_skey; - int rc; - - /* make a sexp from skey */ - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put hash into a S-Exp s_hash */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); - - rc = gcry_pk_sign (&s_sig, s_hash, s_skey); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_skey); - - if (rc) - ; - else if (algo == GCRY_PK_RSA) - data[0] = mpi_from_sexp (s_sig, "s"); - else - { - data[0] = mpi_from_sexp (s_sig, "r"); - data[1] = mpi_from_sexp (s_sig, "s"); - } - - gcry_sexp_release (s_sig); - return rc; -} - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) -{ - gcry_sexp_t s_sig, s_hash, s_pkey; - int rc; - - /* make a sexp from pkey */ - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2], pkey[3]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put hash into a S-Exp s_hash */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); - - /* put data into a S-Exp s_sig */ - if (algo == GCRY_PK_DSA) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(elg(r%m)(s%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_RSA) - { - if (!data[0]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]); - } - else - BUG (); - - if (rc) - BUG (); - - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) -{ - gcry_sexp_t s_ciph, s_data, s_pkey; - int rc; - - /* make a sexp from pkey */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", - pkey[0], pkey[1]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", data)) - BUG (); - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - if (rc) - ; - else - { /* add better error handling or make gnupg use S-Exp directly */ - resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA) - resarr[1] = mpi_from_sexp (s_ciph, "b"); - } - - gcry_sexp_release (s_ciph); - return rc; -} - - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, - gcry_mpi_t * skey) -{ - gcry_sexp_t s_skey, s_data, s_plain; - int rc; - - *result = NULL; - /* make a sexp from skey */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put data into a S-Exp s_data */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, - "(enc-val(elg(a%m)(b%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_RSA) - { - if (!data[0]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]); - } - else - BUG (); - - if (rc) - BUG (); - - rc = gcry_pk_decrypt (&s_plain, s_data, s_skey); - gcry_sexp_release (s_skey); - gcry_sexp_release (s_data); - if (rc) - return rc; - - *result = gcry_sexp_nth_mpi (s_plain, 0, 0); - gcry_sexp_release (s_plain); - if (!*result) - return -1; /* oops */ - - return 0; -} - - -/* Check whether SKEY is a suitable secret key. */ -int -pk_check_secret_key (int algo, gcry_mpi_t *skey) -{ - gcry_sexp_t s_skey; - int rc; - - if (algo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4]); - } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (algo == GCRY_PK_RSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (!rc) - { - rc = gcry_pk_testkey (s_skey); - gcry_sexp_release (s_skey); - } - return rc; -} diff --git a/g10/pkglue.h b/g10/pkglue.h deleted file mode 100644 index 43b82785b..000000000 --- a/g10/pkglue.h +++ /dev/null @@ -1,35 +0,0 @@ -/* pkglue.h - public key operations definitions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_G10_PKGLUE_H -#define GNUPG_G10_PKGLUE_H - -int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash, - gcry_mpi_t *skey); -int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, - gcry_mpi_t *pkey); -int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, - gcry_mpi_t *pkey); -int pk_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, - gcry_mpi_t *skey); -int pk_check_secret_key (int algo, gcry_mpi_t *skey); - - -#endif /*GNUPG_G10_PKGLUE_H*/ diff --git a/g10/plaintext.c b/g10/plaintext.c deleted file mode 100644 index d84a523fe..000000000 --- a/g10/plaintext.c +++ /dev/null @@ -1,458 +0,0 @@ -/* plaintext.c - process plaintext packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#ifdef HAVE_DOSISH_SYSTEM -#include <fcntl.h> /* for setmode() */ -#endif - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "options.h" -#include "packet.h" -#include "ttyio.h" -#include "filter.h" -#include "main.h" -#include "status.h" -#include "i18n.h" - - - -/**************** - * Handle a plaintext packet. If MFX is not NULL, update the MDs - * Note: we should use the filter stuff here, but we have to add some - * easy mimic to set a read limit, so we calculate only the - * bytes from the plaintext. - */ -int -handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, - int nooutput, int clearsig, int *create_failed ) -{ - char *fname = NULL; - FILE *fp = NULL; - int rc = 0; - int c; - int convert = pt->mode == 't'; -#ifdef __riscos__ - int filetype = 0xfff; -#endif - int dummy_create_failed; - - if (!create_failed) - create_failed = &dummy_create_failed; - *create_failed = 0; - - /* create the filename as C string */ - if( nooutput ) - ; - else if( opt.outfile ) { - fname = xmalloc ( strlen( opt.outfile ) + 1); - strcpy(fname, opt.outfile ); - } - else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) { - log_info(_("data not saved; use option \"--output\" to save it\n")); - nooutput = 1; - } - else if( !opt.use_embedded_filename ) { - fname = make_outfile_name( iobuf_get_real_fname(pt->buf) ); - if( !fname ) - fname = ask_outfile_name( pt->name, pt->namelen ); - if( !fname ) { - *create_failed = 1; - rc = GPG_ERR_GENERAL; - goto leave; - } - } - else { - fname = make_printable_string( pt->name, pt->namelen, 0 ); - } - - if( nooutput ) - ; - else if( !*fname || (*fname=='-' && !fname[1])) { - /* no filename or "-" given; write to stdout */ - fp = stdout; -#ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); -#endif - } - else { - while( !overwrite_filep (fname) ) { - char *tmp = ask_outfile_name (NULL, 0); - if ( !tmp || !*tmp ) { - xfree (tmp); - *create_failed = 1; - rc = GPG_ERR_GENERAL; - goto leave; - } - xfree (fname); - fname = tmp; - } - } - -#ifndef __riscos__ - if( fp || nooutput ) - ; - else if( !(fp = fopen(fname,"wb")) ) { - rc = gpg_error_from_errno (errno); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - *create_failed = 1; - goto leave; - } -#else /* __riscos__ */ - /* Convert all '.' in fname to '/' -- we don't create directories! */ - for( c=0; fname[c]; ++c ) - if( fname[c] == '.' ) - fname[c] = '/'; - - if( fp || nooutput ) - ; - else { - fp = fopen(fname,"wb"); - if( !fp ) { - rc == gpg_error_from_errno (errno); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - *create_failed = 1; - if (errno == 106) - log_info("Do output file and input file have the same name?\n"); - goto leave; - } - - /* If there's a ,xxx extension in the embedded filename, - use that, else check whether the user input (in fname) - has a ,xxx appended, then use that in preference */ - if( (c = riscos_get_filetype_from_string( pt->name, - pt->namelen )) != -1 ) - filetype = c; - if( (c = riscos_get_filetype_from_string( fname, - strlen(fname) )) != -1 ) - filetype = c; - riscos_set_filetype_by_number(fname, filetype); - } -#endif /* __riscos__ */ - - if( !pt->is_partial ) { - /* we have an actual length (which might be zero). */ - assert( !clearsig ); - if( convert ) { /* text mode */ - for( ; pt->len; pt->len-- ) { - if( (c = iobuf_get(pt->buf)) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error("Problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - goto leave; - } - if( mfx->md ) - gcry_md_putc (mfx->md, c ); -#ifndef HAVE_DOSISH_SYSTEM - if( c == '\r' ) /* convert to native line ending */ - continue; /* fixme: this hack might be too simple */ -#endif - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - } - } - else { /* binary mode */ - byte *buffer = xmalloc ( 32768 ); - while( pt->len ) { - int len = pt->len > 32768 ? 32768 : pt->len; - len = iobuf_read( pt->buf, buffer, len ); - if( len == -1 ) { - rc = gpg_error_from_errno (errno); - log_error("Problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - xfree ( buffer ); - goto leave; - } - if( mfx->md ) - gcry_md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree ( buffer ); - goto leave; - } - } - pt->len -= len; - } - xfree ( buffer ); - } - } - else if( !clearsig ) { - if( convert ) { /* text mode */ - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( mfx->md ) - gcry_md_putc (mfx->md, c ); -#ifndef HAVE_DOSISH_SYSTEM - if( convert && c == '\r' ) - continue; /* fixme: this hack might be too simple */ -#endif - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - } - } - else { /* binary mode */ - byte *buffer = xmalloc ( 32768 ); - int eof; - for( eof=0; !eof; ) { - /* Why do we check for len < 32768: - * If we won't, we would practically read 2 EOFs but - * the first one has already popped the block_filter - * off and therefore we don't catch the boundary. - * So, always assume EOF if iobuf_read returns less bytes - * then requested */ - int len = iobuf_read( pt->buf, buffer, 32768 ); - if( len == -1 ) - break; - if( len < 32768 ) - eof = 1; - if( mfx->md ) - gcry_md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree ( buffer ); - goto leave; - } - } - } - xfree ( buffer ); - } - pt->buf = NULL; - } - else { /* clear text signature - don't hash the last cr,lf */ - int state = 0; - - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( fp ) { - if( putc( c, fp ) == EOF ) { - rc = gpg_error_from_errno (errno); - log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - if( !mfx->md ) - continue; - if( state == 2 ) { - gcry_md_putc (mfx->md, '\r' ); - gcry_md_putc (mfx->md, '\n' ); - state = 0; - } - if( !state ) { - if( c == '\r' ) - state = 1; - else if( c == '\n' ) - state = 2; - else - gcry_md_putc (mfx->md, c ); - } - else if( state == 1 ) { - if( c == '\n' ) - state = 2; - else { - gcry_md_putc (mfx->md, '\r' ); - if( c == '\r' ) - state = 1; - else { - state = 0; - gcry_md_putc (mfx->md, c ); - } - } - } - } - pt->buf = NULL; - } - - if( fp && fp != stdout && fclose(fp) ) { - rc = gpg_error_from_errno (errno); - log_error("Error closing `%s': %s\n", fname, strerror(errno) ); - fp = NULL; - goto leave; - } - fp = NULL; - - leave: - if( fp && fp != stdout ) - fclose(fp); - xfree (fname); - return rc; -} - -static void -do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode ) -{ - text_filter_context_t tfx; - int c; - - if( textmode ) { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( fp, text_filter, &tfx ); - } - if( md2 ) { /* work around a strange behaviour in pgp2 */ - /* It seems that at least PGP5 converts a single CR to a CR,LF too */ - int lc = -1; - while( (c = iobuf_get(fp)) != -1 ) { - if( c == '\n' && lc == '\r' ) - gcry_md_putc (md2, c); - else if( c == '\n' ) { - gcry_md_putc (md2, '\r'); - gcry_md_putc (md2, c); - } - else if( c != '\n' && lc == '\r' ) { - gcry_md_putc (md2, '\n'); - gcry_md_putc (md2, c); - } - else - gcry_md_putc (md2, c); - - if( md ) - gcry_md_putc (md, c ); - lc = c; - } - } - else { - while( (c = iobuf_get(fp)) != -1 ) { - if( md ) - gcry_md_putc (md, c ); - } - } -} - - -/**************** - * Ask for the detached datafile and calculate the digest from it. - * INFILE is the name of the input file. - */ -int -ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2, - const char *inname, int textmode ) -{ - progress_filter_context_t pfx; - char *answer = NULL; - iobuf_t fp; - int rc = 0; - - fp = open_sigfile( inname, &pfx ); /* open default file */ - - if( !fp && !opt.batch ) { - int any=0; - tty_printf(_("Detached signature.\n")); - do { - xfree (answer); - answer = cpr_get("detached_signature.filename", - _("Please enter name of data file: ")); - cpr_kill_prompt(); - if( any && !*answer ) { - rc = GPG_ERR_GENERAL; - goto leave; - } - fp = iobuf_open(answer); - if( !fp && errno == ENOENT ) { - tty_printf("No such file, try again or hit enter to quit.\n"); - any++; - } - else if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error("can't open `%s': %s\n", answer, strerror(errno) ); - goto leave; - } - } while( !fp ); - } - - if( !fp ) { - if( opt.verbose ) - log_info(_("reading stdin ...\n")); - fp = iobuf_open( NULL ); - assert(fp); - } - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - - leave: - xfree (answer); - return rc; -} - - - -/**************** - * Hash the given files and append the hash to hash context md. - * If FILES is NULL, hash stdin. - */ -int -hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files, - const char *sigfilename, int textmode ) -{ - progress_filter_context_t pfx; - iobuf_t fp; - STRLIST sl; - - if( !files ) { - /* check whether we can open the signed material */ - fp = open_sigfile( sigfilename, &pfx ); - if( fp ) { - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - return 0; - } - log_error (_("no signed data\n")); - return GPG_ERR_NO_DATA; - } - - - for (sl=files; sl; sl = sl->next ) { - fp = iobuf_open( sl->d ); - if( !fp ) { - int tmperr = gpg_error_from_errno (errno); - log_error(_("can't open signed data `%s'\n"), - print_fname_stdin(sl->d)); - return tmperr; - } - handle_progress (&pfx, fp, sl->d); - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - } - - return 0; -} diff --git a/g10/progress.c b/g10/progress.c deleted file mode 100644 index 9d9805065..000000000 --- a/g10/progress.c +++ /dev/null @@ -1,118 +0,0 @@ -/* progress.c - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> - -#include "gpg.h" -#include "iobuf.h" -#include "filter.h" -#include "status.h" -#include "util.h" -#include "options.h" - -/**************** - * The filter is used to report progress to the user. - */ -int -progress_filter (void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - int rc = 0; - progress_filter_context_t *pfx = opaque; - - if (control == IOBUFCTRL_INIT) - { - char buffer[50]; - - pfx->last = 0; - pfx->offset = 0; - pfx->last_time = make_timestamp (); - - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); - } - else if (control == IOBUFCTRL_UNDERFLOW) - { - u32 timestamp = make_timestamp (); - int len = iobuf_read (a, buf, *ret_len); - - if (len >= 0) - { - pfx->offset += len; - *ret_len = len; - } - else - { - *ret_len = 0; - rc = -1; - } - if ((len == -1 && pfx->offset != pfx->last) - || timestamp - pfx->last_time > 0) - { - char buffer[50]; - - sprintf (buffer, "%.20s ? %lu %lu", - pfx->what? pfx->what : "?", - pfx->offset, - pfx->total); - write_status_text (STATUS_PROGRESS, buffer); - - pfx->last = pfx->offset; - pfx->last_time = timestamp; - } - } - else if (control == IOBUFCTRL_FREE) - { - /* Note, that we must always dealloc resources of a filter - within the filter handler and not anywhere else. (We set it - to NULL and check all uses just in case.) */ - xfree (pfx->what); - pfx->what = NULL; - } - else if (control == IOBUFCTRL_DESC) - *(char**)buf = "progress_filter"; - return rc; -} - -void -handle_progress (progress_filter_context_t *pfx, iobuf_t inp, const char *name) -{ - off_t filesize = 0; - - if (!opt.enable_progress_filter) - return; - - if (!is_status_enabled ()) - return; - - if (name && *name && !(*name == '-' && !name[1])) - filesize = iobuf_get_filelength (inp); - else if (opt.set_filesize) - filesize = opt.set_filesize; - - /* register the progress filter */ - pfx->what = xstrdup (name ? name : "stdin"); - pfx->total = filesize; - iobuf_push_filter (inp, progress_filter, pfx); -} diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c deleted file mode 100644 index 4b45b9f5c..000000000 --- a/g10/pubkey-enc.c +++ /dev/null @@ -1,345 +0,0 @@ -/* pubkey-enc.c - public key encoded packet handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "keydb.h" -#include "trustdb.h" -#include "cipher.h" -#include "status.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "pkglue.h" -#include "call-agent.h" - -static int get_it( PKT_pubkey_enc *k, - DEK *dek, PKT_secret_key *sk, u32 *keyid ); - - -/* check that the given algo is mentioned in one of the valid user IDs */ -static int -is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo ) -{ - KBNODE k; - - for (k=keyblock; k; k=k->next) { - if (k->pkt->pkttype == PKT_USER_ID) { - PKT_user_id *uid = k->pkt->pkt.user_id; - prefitem_t *prefs = uid->prefs; - - if (uid->created && prefs && - !uid->is_revoked && !uid->is_expired ) { - for (; prefs->type; prefs++ ) - if (prefs->type == type && prefs->value == algo) - return 1; - } - } - } - return 0; -} - - -/**************** - * Get the session key from a pubkey enc packet and return - * it in DEK, which should have been allocated in secure memory. - */ -int -get_session_key( PKT_pubkey_enc *k, DEK *dek ) -{ - PKT_secret_key *sk = NULL; - int rc; - - rc = openpgp_pk_test_algo (k->pubkey_algo, PUBKEY_USAGE_ENC); - if( rc ) - goto leave; - - if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) { - sk = xcalloc (1, sizeof *sk ); - sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ - if( !(rc = get_seckey( sk, k->keyid )) ) - rc = get_it( k, dek, sk, k->keyid ); - } - else { /* anonymous receiver: Try all available secret keys */ - void *enum_context = NULL; - u32 keyid[2]; - char *p; - - for(;;) { - if( sk ) - free_secret_key( sk ); - sk = xcalloc (1, sizeof *sk ); - rc=enum_secret_keys( &enum_context, sk, 1, 0); - if( rc ) { - rc = GPG_ERR_NO_SECKEY; - break; - } - if( sk->pubkey_algo != k->pubkey_algo ) - continue; - keyid_from_sk( sk, keyid ); - log_info(_("anonymous recipient; trying secret key %08lX ...\n"), - (ulong)keyid[1] ); - - if(!opt.try_all_secrets && !is_status_enabled()) - { - p=get_last_passphrase(); - set_next_passphrase(p); - xfree (p); - } - - rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask - only - once */ - if( !rc ) - rc = get_it( k, dek, sk, keyid ); - if( !rc ) { - log_info(_("okay, we are the anonymous recipient.\n") ); - break; - } - } - enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */ - } - - leave: - if( sk ) - free_secret_key( sk ); - return rc; -} - - -static int -get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) -{ - int rc; - gcry_mpi_t plain_dek = NULL; - byte *frame = NULL; - unsigned n, nframe; - u16 csum, csum2; - int card = 0; - - if (sk->is_protected && sk->protect.s2k.mode == 1002) - { /* FIXME: Note that we do only support RSA for now. */ - char *rbuf; - size_t rbuflen; - char *snbuf; - unsigned char *indata = NULL; - unsigned int indatalen; - - snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); - - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen, - enc->data[0])) - BUG(); - - rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen); - xfree (snbuf); - xfree (indata); - if (rc) - goto leave; - - frame = rbuf; - nframe = rbuflen; - card = 1; - } - else - { - rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey); - if( rc ) - goto leave; - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek)) - BUG(); - gcry_mpi_release (plain_dek); plain_dek = NULL; - } - - - /* Now get the DEK (data encryption key) from the frame - * - * Old versions encode the DEK in in this format (msb is left): - * - * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2 - * - * Later versions encode the DEK like this: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (mpi_get_buffer already removed the leading zero). - * - * RND are non-zero randow bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) with length k - * CSUM - */ - if( DBG_CIPHER ) - log_printhex ("DEK frame:", frame, nframe ); - n=0; - if (!card) - { - if( n + 7 > nframe ) - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - if( frame[n] == 1 && frame[nframe-1] == 2 ) { - log_info(_("old encoding of the DEK is not supported\n")); - rc = GPG_ERR_CIPHER_ALGO; - goto leave; - } - if( frame[n] != 2 ) /* somethink is wrong */ - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */ - ; - n++; /* and the zero byte */ - } - - if( n + 4 > nframe ) - { rc = GPG_ERR_WRONG_SECKEY; goto leave; } - dek->keylen = nframe - (n+1) - 2; - dek->algo = frame[n++]; - if( dek->algo == CIPHER_ALGO_IDEA ) - write_status(STATUS_RSA_OR_IDEA); - rc = openpgp_cipher_test_algo (dek->algo); - if( rc ) { - if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) { - log_info(_("cipher algorithm %d%s is unknown or disabled\n"), - dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":""); - if(dek->algo==CIPHER_ALGO_IDEA) - idea_cipher_warn(0); - } - dek->algo = 0; - goto leave; - } - if( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) { - rc = GPG_ERR_WRONG_SECKEY; - goto leave; - } - - /* copy the key to DEK and compare the checksum */ - csum = frame[nframe-2] << 8; - csum |= frame[nframe-1]; - memcpy( dek->key, frame+n, dek->keylen ); - for( csum2=0, n=0; n < dek->keylen; n++ ) - csum2 += dek->key[n]; - if( csum != csum2 ) { - rc = GPG_ERR_WRONG_SECKEY; - goto leave; - } - if( DBG_CIPHER ) - log_printhex ("DEK is:", dek->key, dek->keylen ); - /* check that the algo is in the preferences and whether it has expired */ - { - PKT_public_key *pk = NULL; - KBNODE pkb = get_pubkeyblock (keyid); - - if( !pkb ) { - rc = -1; - log_error("oops: public key not found for preference check\n"); - } - else if( pkb->pkt->pkt.public_key->selfsigversion > 3 - && dek->algo != CIPHER_ALGO_3DES - && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) { - /* Don't print a note while we are not on verbose mode, - * the cipher is blowfish and the preferences have twofish - * listed */ - if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH - || !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH)) - log_info(_( - "NOTE: cipher algorithm %d not found in preferences\n"), - dek->algo ); - } - - if (!rc) { - KBNODE k; - - for (k=pkb; k; k = k->next) { - if (k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){ - u32 aki[2]; - keyid_from_pk(k->pkt->pkt.public_key, aki); - - if (aki[0]==keyid[0] && aki[1]==keyid[1]) { - pk = k->pkt->pkt.public_key; - break; - } - } - } - if (!pk) - BUG (); - if ( pk->expiredate && pk->expiredate <= make_timestamp() ) { - log_info(_("NOTE: secret key %08lX expired at %s\n"), - (ulong)keyid[1], asctimestamp( pk->expiredate) ); - } - } - - if ( pk && pk->is_revoked ) { - log_info( _("NOTE: key has been revoked") ); - putc( '\n', log_get_stream() ); - show_revocation_reason( pk, 1 ); - } - - release_kbnode (pkb); - rc = 0; - } - - - leave: - gcry_mpi_release (plain_dek); - xfree (frame); - return rc; -} - - -/**************** - * Get the session key from the given string. - * String is supposed to be formatted as this: - * <algo-id>:<even-number-of-hex-digits> - */ -int -get_override_session_key( DEK *dek, const char *string ) -{ - const char *s; - int i; - - if ( !string ) - return GPG_ERR_BAD_KEY; - dek->algo = atoi(string); - if ( dek->algo < 1 ) - return GPG_ERR_BAD_KEY; - if ( !(s = strchr ( string, ':' )) ) - return GPG_ERR_BAD_KEY; - s++; - for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) { - int c = hextobyte ( s ); - if (c == -1) - return GPG_ERR_BAD_KEY; - dek->key[i] = c; - } - if ( *s ) - return GPG_ERR_BAD_KEY; - dek->keylen = i; - return 0; -} - diff --git a/g10/pubring.asc b/g10/pubring.asc deleted file mode 100644 index 09b099bfe..000000000 --- a/g10/pubring.asc +++ /dev/null @@ -1,458 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.0e (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBDVBlNMRBADeX96LvyNiop30YPeeCBJZzeqQuQ3yQ+SK3AHoXLQ1qsGHrdoi -HfHbVV2GfulRq+H/z97vUtA3APE2NZ7HuvBJzhXZCOE93wT59OZV8Pp5ir6TAEYm -dvPCgvjYmwQvKgvaF0hG4eyvQst7SaevFUGV+jEz5DQhniy+/a2/W7nC/QCg/2SE -nBeZNJnZauf9cXQ34GnXV68D/1BspMcbrpY/YFXsdLUSbroG0EXGma4jY9UlcRV8 -8cIftxl2jh04l91bvzzCFgSGvFdxVbHWnIgbQ+PQ1cme7SsS3ZFFI3B3zykXGOi8 -shhOT/Gip1Tk4O6MwTyOWdTdnEGSjk+qoVwEMxhY/ZZDd3bbUkymrPK5jtfumreB -JjqwA/wL5fOdCzLWBev4/Xks2YENg0HVwN3a3iypNNGZOYCWTZKnFX5yel/mqiT0 -uEn1CJ5w29GKxRax/Ua9kr7ftMhpQ8lZdyy4Z/Br0NiU9fgvmWF/2WvOMx+hHf/k -LRUYewxzOSLfapiM1SOQs/L+29tnu4wfAsezSuFfKjKVZHlx4rQnQnJpYW4gV2Fy -bmVyIChob21lKSA8d2FybmVyQGxvdGhhci5jb20+iF0EExECAB0FAjZYxf4FCQPf -GysDCwQDBRUDAgYBAxYCAQIXgAAKCRCQOaC/0TnMTJJUAKC0jAhA3fXI2UCbfZ6J -Ti3CL0bcMQCgpA7pEUYM7edUlxqFJfWYtBblS5u5Ag0ENUGU1BAIAPZCV7cIfwgX -cqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyD -vWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5 -u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98 -iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlA -GBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqr -ol7DVekyCzsAAgIH/AlcnP6QSKd67ad/1lQpzMEBNyIX0X7//lns6XAGl/+U5Iqx -i+8sd+oJikFlgVH+n0JD6vq4dO8XCBzUgIi3xV2cuJqj16zVp7JdMXKqIxkDu5Q/ -By3/IL7WWkc06FxyDraigP1Hu3W78l0lySK8yEW+fVlkyzK6irkJ7EFWkSDaZqT2 -IrPd94hoGFEyQOIgkYdy2DHoK00nUd9FzIbhrrz2ZDJIfCMVp2go4oCu6Zk0LxJX -qTFU7K3SxVNN5jWsOCsPzWLyhKNrgnv8WzVaPKgqgMNdmdykAvC0iSTNat51p8Ad -4mGtY1nW0aOAiufjBTMUtILfHKsknItj/P2D4seITAQYEQIADAUCNljGDQUJA98b -OQAKCRCQOaC/0TnMTHKtAJsHojLJup9Niwsutt68U02uyl13BwCgpovl3ebeH41a -k2Kp37si/9RsdICZAaIENt243BEEAOCNfiVnzetemJ2DpFA51QnnGUihYs0beBQ2 -ptJP47uLlxsZbix2Gg3wDCP7HNgcEWlXc29vrd2oiA9nanKLcJzLYVL0lBBbPVX4 -8PGvRFKvJVHI17LWqpq3aOF8kOSf/4QyRIafWdGzxvAFycAiq2Bs1/B7BeUqmhWO -3FXs6VNLAKDqqMUc7apbVRFSV6/kbQ8PLTYw0QP/dRwVX9NtBEogFNoSU4jw1sRg -+nqGQplE9OXESMQO3fiszBkCWghsKk+/O+HcFrIiSAxRPR3y8nXCsaLQEf4WfrD7 -nKFeGWDIqPvi3KJOzuaqZP3DMf4LdfltmM/zHifZo4aBkkIQd6703vBFAYA0lONH -+W5qyx0ZnYr7XunDqkMD/2JC3cogap2H6IzaHl9oQegGKGwrCErBuJxCeL9i7h/+ -5Wg8ou6TE8kAGf1oMeeWwrWOBxub4xsUqfYk+mKM//O2OkCMfVFQgQQtjy5CtFQx -X5AErQ4Ukoy8XmNGOAi9ipWpL0450XwNvusaeff4D1ztJbCb+LMkqI9gYEQWSwxF -tCNKLiBNaWNoYWVsIEFzaGxleSA8amFzaGxleUBhY20ub3JnPohVBBMRAgAVBQI3 -RcCEAwsKAwMVAwIDFgIBAheAAAoJEAcDKpaJBMjiiuQAni3iUNjDvqvOQOlIgz1d -5ibjHrA8AKDWPy7kZN+W3Leptp3FYTIMTbDpU7kBDQQ23bjuEAQAl1Txo5tRemsP -8mNmoBlGQx/4EmN61ga/V8iBS7u7MvzI1zktNuHaK7rJItE4ilyGeivXitZ74eGV -7P2/rbNhWnOo1fMlvLvl8mDNmLD2nJovu4LVFXGhoYdGb75d2YbCCBN5Q/BSYh+l -b2wd6VewnqMy6A9iGULaAWz10G2IOYMAAwYD/iooRihzfIC6rw6K2kASGRiy/dts -3w0L9Iu5DsxLFH2tHUpv8fPVDuvGkRfwPuKaTHAvq90/I46/3BBTOOneMaW1+RAL -hM5f4ytsYNlDDerhRiuGyEjoGtXVjXye/3SwIxISrg0EO7UHNtr4rObQEfF69RcT -gjzKdO2n2WlP+7/qiEwEGBECAAwFAjdVLZwFCQHwga4ACgkQBwMqlokEyOIEvwCe -IHFkUaLTPmaZhAOs3yfwDtAC33gAn3f2BoDALaHL1uqu/unWQA1JZRTYmQGiBDfj -Y5kRBADMfdIcB6LbzfMZAe9+3GMqLgx5fUEhX9GVZIxb3w+ZBGbJGrERMtEigd+S -Y2xR9TWyhd/eVh80qcgGzA9Fyb6IOdVwN6HxtYdIz4CZP6ZmtSM8jecfbbKsf/Ol -BJQ6RZlAWNjE6F2r1D/gHpw1ZEl+lSlW3ObCEkeXBC/er/fIowCgwia77SmSgm3b -GgHEqfFQ8MID6lsD/0h45kDwi3K8WhI6lnZP0zpnNfA6753QaA9NqB8MY36YCVtx -OhBm7GUCgKyfh9zrTpZWwcBcAQyyB8Ld3K7cWi0uLy+gO2169cRApR0S1l6BlkbO -9wlv1zoRR1VT2gQCMGw6mjyne99v4Hst7UXV/nXvOsdrxdS5tTkAEL7Alzz0BACc -imFIsBD1CKqqN0fTdZooVrBZzpn6ZjTgzX1hKr61fuFyPgMkhzutN2jXy8tweCZw -FmN5XZ9cu7mxAdN9Xmwk7Kl0EGChwZdm7Sx9UTvu9kJnGOQvqtOkWB86Ts+r4fVb -w65BqcrZZzuMQrUqliM/YVUGazN/w2uyApNPByJUzbQ4TWljaGFlbCBSb3RoIChV -c2VkIGZvciBrZXkgc2lnbmF0dXJlcykgPG1yb3RoQGdudXBnLm9yZz6IVQQTEQIA -FQUCN+NjmQMLCgMDFQMCAxYCAQIXgAAKCRDKFfq6GxOtQUZWAJ40vGK1b1f2KN7u -BHOHLDAHvnuPLwCfXHyq3wGapWGDw6txlP9LMec1jf2JAJQDBRA342hqcwhlf6d9 -2r0BAenKA/d9luNiVpPciTyfM9W4GybmWSlLt0qxrY34WSNL5IOG6P2H335skdAC -xSUlwBSkD2IzoaQ0LAyGw0jsk8yWhfQqgjWxjZ0zcmKHZJZsMLwtvA4FeOSQuscf -kYsbA3vZWotYO1o9jyfAZTj0MeALzGEmxBeGUNiKUEnbBU0Lg+c8iEYEEBECAAYF -AjfjadIACgkQAJxC28xc8YI7iQCfboS4b2tqYvml31ouMT6XPHhTsYMAnRGQId+W -7mOHlWHvrddjwu8JHms6mQGiBDbYl60RBACxaonXMHpbmyzoQyxn7wYXGpEJZnKc -IWRc/sE++XSebUZMJOk09qkKhtg1TQ8D0Siv1/EjuqjoKP2f9+EOIW55+55vQsti -XwevF6pJBFYGGRluQPoFbUilDzCDmismFv0xwIEoOLftxvyvlmmw4Upx3/8TY83f -dQGzxSDvNbPEtwCguK4ARxZub/SQgLMy6S9/7itEfHcD/RXRVGmz3dDxXtgdAqwV -mY7RI+FOPQdn+DiFaaTjmqgP+NR6w5v72+jE5cdn/OnYmXQcERXc/4nZgWHdKmso -eLvLs0hpk9zFhgHkSufCWlo0ZYemaWRYrRI5mukGFIMbPdPEaySNQEqC78Rgj2wm -FJ2ttbAQlSRi332xTwFbzY4XA/9RppZOE9hGCh+2P4FgtHMgf7L8JUJVgR9tIKUv -GXjDkSWEqIMeyKeXFoPk5QdxNVM5sRYf6gmV6U3zHUOfEzlOf5GUJyPkmwl9RADE -6uyk4ySlW2d6+glsM0/Fd9Pyyzb0v6xfAPDFyTYU1X6vUDp0FyzPUijhbrdj4Fwm -fAVf3LQeTWljaGFlbCBSb3RoIDxtcm90aEBnbnVwZy5vcmc+iFsEExECABsFAjfi -yIQFCQlnNJ8DCwoDAxUDAgMWAgECF4AACgkQAJxC28xc8YKnHACeMFOdlg4xjXgE -FzyA7MQFxyXmyuoAnRCcbQ4bvEm/fxaaBFRnJgavm25LiQCVAwUQN+NpSnMIZX+n -fdq9AQF72gP7ByZG6W8yTz+1nv+CMvGIGLa4otN812X5lXvvIpH7bNgoWWD70xvH -5GP/Q5e3yUh4aGGN59uOVVQ5uoa3VFYl1ufWt2LvxaSW2q7f0FcvEref/5biu3gx -2O296DWENYPP3xZtaD+htaDP4h18RFBIvbZz9Ryp9C8myGEPQGcOxw+IRgQQEQIA -BgUCN+NqjQAKCRDKFfq6GxOtQfhaAJ9bMyNoYhAf3jkeMy1cnXoyr9ZbwQCfeWjK -xnAa+++nbYVEnuPP2gUdume0Hk1pY2hhZWwgUm90aCA8bXJvdGhAbmVzc2llLmRl -PohbBBMRAgAbBQI34siUBQkJZzSfAwsKAwMVAwIDFgIBAheAAAoJEACcQtvMXPGC -iF4AniaC76L0oLBvc0jA40NCXMDz4PX2AJ9RGPnHKf0XmaRXcTOlR8MiH1CeoLkB -zQQ22JgDEAcAqtpFls8cnLDIh1r6gSRf8sYiv5qd+a8CDd/LWHveWeGCeuBiVbwv -SG0q9ci13ZRIEtHXi0BVWLBpz/YqQCHJX4Vk2iV6yY7rCo0rFOEzyco+Glssjg1G -/ZCuVkGo4rpLKqOn6oXq92ojwBNjdYeBOOoZ78jp65gJ3OC0ckYanrRUe3J9bc0W -lAA+to/Dus91Ivkggu/iH5DEPrf/PQY14t7jxCcxBJCa8XaC04LrXVphPuuRziVe -gINTU02fdyrZlAyWf+0KZq5rMza1N+NwSxjkxBOzM+lbhA5PSekqHp8AAwUG/12f -DRpOtZ/GrKoUgkML8urMjxKFD4Hh6l1Wb5NCEe4tIm38yI+C/AwMCY5cDlf03YOZ -0ThTVjpvQfYT8EJuPbZ+2dGYEroY3OBLetcg6DDh4saKsVU2XSLHyCh2xPzOiusB -xNPrmvqd63S7JnRSSsEfgwYpKpA/GNMSJyyFpT4vtvK3jOON0v7uobYOBTLRuwj3 -OJMJfyQDa6WyiTJxUvsuQL0MK5cZG7oLUWTK9ZrFPuqzLeZAcpIgJ/QMJ/PnrRnZ -gUnXEbsnCVZ33NVBtiK/ktS2RTQKcvCNPtnimRqsiEwEGBECAAwFAjbYmAMFCQlm -AYAACgkQAJxC28xc8YJTTACgmUYdFZGR8pk9NbB4lpnKnum15WUAoIgDLWQA+qb1 -EPtpywwRBvqGOVUPmQGiBDgf7uARBADdNye00iQMSe4RULS0hDKVGNl1CFGzeol+ -AoNkW9bqXD3f9KNrWD11r9tef6C4OMN2fILO7cpD+YZwuHjXv6xSDAoZ31bmsxQn -N51YhwFhZRh8K/XheaULO9gedCZaXndQ8dvXGC/doKKOo/CNGK8gct+cPPr0N6cu -FztlgRpbqwCgm8u3ylalEvlWhXOjVYoTnEs04aMEAJVK0ZcYjHUdXWXi+TaDZCJq -ktk/r2E4M4/EsBTIkuAuy6RvPediVShRQ/CZl0MCQHM17ywdC+PXgOmQLeGbR8m8 -flK9HROJQebHB23/MK2knm/yKgqSJbtoDv23QRfZjNd1aox50uFLvv36CDMhAMQ4 -ENHrBzuj5bMZo8nMELVaBACPlGKAcAO2FP6DpmcJIXDnO+oVHvs4QMzADn+/aBQp -H3UQASAbu7aH/84SLBUH0h1Z9QNkKLuMtpC0rVHqRsw4d4FmOxoxvOF8hQnICiQr -2XRMDKZwR/+gH9Vh2XFRi4j/xHH2h787C6bKoOPd6UPJM1HdxNPQlG89fb4hgv/e -WbQ+TmlpYmUgWXV0YWthIChHTlUvTGludXggb24gU3VwZXJIIFByb2plY3QpIDxn -bmlpYmVAY2hyb290Lm9yZz6IWwQTEQIAGwUCOB/u4AUJA8JnAAMLCgMDFQMCAxYC -AQIXgAAKCRDj8lhUEo8OeTsQAJ96XKYFFJuwup2Mce9mDk6EOnEEdACdFp6gwm6x -T6Hm1FD53oKNgrnafhqIRgQQEQIABgUCOB/w/QAKCRC+6Lh52/bl/+myAJ0UubvN -9ydWvrdgkKbfokKJTrOC0wCgooxVzceD44Oo/C1kaHjXv5yFQeKIRgQQEQIABgUC -OClPHgAKCRBd4kmWWwNYol/nAJ0YXC3/sGqBaddoLqoLpo1kapcthACglrEi6n5z -6OcQO+II4Fe6wFOisYu5AQ0EOB/u8RAEALec6/ux2Py+0Wv/w5J/VmDzUNDOHQJM -kxTEQbp+vZ80Quf8FoMy8i9PciekoDl+oB8/zQDs92SgqGVD0+y8K9UPIEvmifjr -oPn+EsIrXf8M7dGGotCtwaiEwDxwmetlQMYLd84XqLj0LgGzdT3/7dMurhUiGZH7 -dpWMfUZAVNjHAAMFA/9iLg3F0Bqi1dVDeCMqOVCOcWKhulFG80il3TwS9Q7SpvJX -/4yZyoEdyJ/VYm4PakvDUyiy4MuhsvGSwCEyXD4IskEkmlf97jDoBiiktexkjlKI -vmp7P0XNQMURXFLqDilI9YY2jVAu4XNw+G0G1ImGgzbadbraUl1J1uJtvg+NOYhM -BBgRAgAMBQI4H+7xBQkDwmcAAAoJEOPyWFQSjw55J58An1UbKjszsK+9Awtz3a+5 -gNiuzdo5AKCE5Pv3w56DMeZLH8GyZkVqo1QsrZkBogQ3KcaNEQQAsRxnSrRpASl8 -e0lOtR3C7I1MoCuivlawh48JzC9WXgA/Pgn+VOLiDDob/zjQoNbBEoG+BHrwq+AC -CVBQFAiMMNur8u7qY+R4eLWD/KDKaNcydchdKehw0eiy7d9mv0hTHSmkUIgIpy4k -d+XvsbozP40+/G+yNjGEHvJf3tsO8ocAoP4wWPnUPNwWkuKn41tR3cb2m+ZlA/0Q -lIn4E3Na3o0AhhuLC3YrJ4X4rHJmUJg+i2mS3lJCM3HPJRCdz/eIlU4WiaBpNPve -PMEeg5KSluqdYOsCvBa6XsAGm8gxQ2Wzf6ZqsXdBxztjwXqcLeuBKFfuDUlwloYI -Rie+naIgPasYwu3ABG4peRJmc8aRXJCg39rE8MK4BAP+Pt+NqJQw9S9ykLDDIXDD -ucH7YOBxfvUo18lPr+iNuPcbXh3fQQoibk4qK0w699YLGD25KizP+FTiCrD2fy9i -knUplevJkGDTdeDLrAPYVYTM2hryLPcisSP55Yf0GW6SnkFbE5LKYHo5YQF+9rvp -yUCR4xXm6CXo9m9FKBuuk5i0Hk5pa2xhcyBIZXJuYWV1cyA8bmhAZGYubHRoLnNl -PohbBBMRAgAbBQI3KcaNBQklmAYAAwsKAwMVAwIDFgIBAheAAAoJEHUPZJXInZM+ -i40AoIykcWzV7PpBoEG4MbTXTNpKBeTIAJ9tJcXW7S/ox+iJGOrBXgSlB7bXnIhG -BBARAgAGBQI3NDnLAAoJEF3iSZZbA1iipZEAoKm4vkXn0/4KC0aZp5o2U5zyErZe -AKDF3mdMyHEumx4xSWJyX4TvDZ+3ybkCDQQ3Kc4MEAgAsgkRCXJQLlHgk4Fu1Jk+ -UKEDdMZYufSOGR0D57WxbRtArPqDMox1NqFHGi8Sg88TtDwH6/BnGkYCOuBQidaE -BPQtl7jeU6fQhXL4kRY3KB50/ChzzUB/G+LsT8COCUIsNDiBQxwEiLTEOMFAqbRA -ugQhZnUKrf0auZKnB53RPhAuIdGozC+k9+vJl0l76e+JcVr8AL6wWBQO00UbKgp+ -MKiWjFDSYIFtMNrXO9rfHW1n3jW79bvAVyFl9rwEbL0gbSWmaZKXIWI7D11J8aYF -3ppDk5UsCc0Cs70okV9d58s0PjnTqwAcVxZcyoO81qJVOPesRVJ4jURdGeSBTqNM -rwADBwgArjJRLMSTveaC2tELGSr7qBioUJ9FbFk0A5D8vH3Xcr34E/m0sgNGJSD3 -qWQNXN0OpH7hKdeiwEPLE8gR/Tnxwgb+r3S0dBViktQPMajdW5S/dJfusTdqBzo2 -LgdZ24lVl1O0ZKci+6SVWt5SBxbAYYtgSEjiGhbWUDdQoC52yNGUQvG9wL5OD1BK -y94wzKQZi9WV/NdNfJPMjZv+tx3pezfGYTPDnUpP1CoLXY/gre+APwr9yHAg46Hz -F+DQT+KAWQDTxahEUk9OE86nR3gO0zNN2KzGKb297ikcLWYusW9QQ46X3uIBTYmK -PZP9l/bR7322tj88GPaKPesZE8rR2ohMBBgRAgAMBQI3Kc4MBQklmAYAAAoJEHUP -ZJXInZM+GUwAn2qcZ8hOcrD1Bw7zZofZ+xm8wDL/AJ9DJQbxAae5kKnBDG1O28B4 -J0wF45kBogQ14HkWEQQA1qRbEQxVQzxv1QAvAgFoW3nT+BbWAs5fenhmvkWIMunk -xhB8cIeYaImzmdDK0YioSgQ03ER5O4x5AcVKXiUJKUWqIermAqSCk6W0z8iWD0Vu -boP8JrAJ6hd5WCWPpzb41OJumi5Xy3RzWdYWq2IOXOVZM2Wt1gnXA7p2PxS+ZqMA -oKLnKFiDGdQPqKH5zwG488A95X9lA/4mkc0LBxfBIipWEE3HzgkcmNRb0zdxzUGY -TGrHIYK3i7TZrfq09+jTA1dMbs2tX/nbUdd1oMaKefCqBw3hD50E685bla17TPFh -NXhBRCCGhH8IGGAg0o6P3B0+QQHJsp7eof/VKgIFN6NeXga+621vkal5eU6jHQ44 -sHHkkkk0fQQAu8a0B2kf4VFHIE4kDraDPgIkhWV2r7efsLJj671NOKBHOMzWB+PK -0eh0b6Tc34n44lyH6Cmc2F9xUzk7POa/uEi8aPB1z2/NdYeFg6nKTrkN4nYnQtYr -GG4oPgeX0+DoNHmlRJto+pYMU8PwJA9fCT1K+szRr5p072LImZ7lsk20LlBldGVy -IEdlcndpbnNraSAoRWxHL0RTQSkgPHBldGVyQGdlcndpbnNraS5kZT6IVwQTEQIA -FwUCNmGXiwMLBAMFFQMCBgEDFgIBAheAAAoJEJg0ZdshQ5Qir60An1Zl/jBAU7Cx -XINEaZupk1TmkdiDAKCFGR9orHjfKgw+xEA+idd/Ls0lDohGBBARAgAGBQI3pyH0 -AAoJEF3iSZZbA1iiXRAAnRCydbPV/ipvi0NfEzV9+RC8lBxNAJ9jQwXwCKt0HVc8 -/Y3OVY/WI1LnTbkCDQQ14Hp8EAgAoz58r9ogDLeyaL8NoMXoMhJ0ogHqC0jzt6xa -zw/h6t0AJE1He5tMF1yVkenXo+sah2oTjrm38fRVXODbACvmn1oP+WLcK7/bG82V -Ol4Zv0Iu+8X1KzXz2JGae+h0ogNcwyW7CXfPSEVhrCBTY7i7mdnAoyGFoW0yFSvt -8YcRXdN7GU16tdATfruMV276MuStGwNIWYYfjFtqwFBdaVOpwMfJs2golT7PLEIj -O2l1u1ZtAI6WvuEzQH4ftzzihmHQXMf4YsvtL5g/8TSJfmfUEFbbKFbU5bIbHzG4 -yj/O8uEBBj7u01oGpu/5UVFTgslvTIEAWx54sfT/oA06PvhsDwADBQf/VWZUn/wC -/gktKZfh6Aq7RRI2K5bJEXhXE5p0rPWLMQy+v4DPGcuDF3nLg1IZT5mbLUGEh+7n -zEgUsmLGPqBz54DgjhBxO1DfAfV3HVnYYpL7DO1u4ceCUh2O9PwLnp1+4W2XmND5 -nFrQ6gGChCgwb79/PxQdLEgj9dlf+vrv5SfajmTydiFCZ0+0GZRFDytdIda08TWv -DabV/41F3T0TSbCMGPWr/TgrfQ6yeyOUpO9lmVbS0u9gKWGAedVOofMYi7Lqp+Pt -zNQTwd9PKCP/HSjUxmm4xX3yVZuUxUV97ckucB8TOlr9deNnq32jnMuP9DeWpBz4 -05uwoBLYvOGNAYhGBBgRAgAGBQI14Hp8AAoJEJg0ZdshQ5QitJcAn0sn+TIAlbNC -3YS5YxlYbExg6UnxAJwM+TJoHjFG8+rZ0nW7/vVq6+hHl5kBogQ3zBNgEQQA7vY0 -FBndb1BOSmisOzqCtcqwzP7iMKF+hwEKDqRKrO/oZ7zqMXigROEDb+ar95oSh2EX -7tETk2b8ga9LA0UxT8nZ8e4eCOOchNggLyX4ZpsyrVTMGwahnjf8KsepIaKqfEnQ -lzE4KsnLsuC+LKodhDUoInZIn/9bC6cRrCfe/xMAoJdLRTMDNe0+ruy2LtnwQg14 -vRp7BADm9fBrVW89COBepWr/xVQ89mDA23oiAaLrKjiJb8LQg9NpmGa5AFuWBym2 -Y5MzjremPeqmjMfXGyXIu5o+9e1k5DQ72NB/m24FdrYkCW38sinIVVghDtvzLniG -fOwBL+c0iA0BweBCNuouoJjJegPQbzaliTgcV8ZjuCq4juyp4AQApBN45mj8JIwZ -wbsNnAmZ4mtv3gR03k20Tk4uCurktNjd0HvU28HOyg/ZehxeoKMd14R/8NZBE39W -vzJHnAVzfcsmNV1SQS7fSxD2f0FsWYxfF2ErBhwhK3GIuKAujPnlzjT57ZnhzBuH -cALohJ1izyVOcBwFIAc+mwZSBRAKILq0OFJpY2hhcmQgR3V5IEJyaWdncyAoZ3Bn -LWxhcCkgPHJnYkBjb25zY29vcC5vdHRhd2Eub24uY2E+iFsEExECABsFAjfME2AF -CQPCZwADCwoDAxUDAgMWAgECF4AACgkQNmdg8X0u14ixOACfcmzB1f4YZ2yC0jyX -efVFtbIZ/fMAn35OwFji+uU6/BFLYXnsMlsJMsOMuQENBDfME3QQBADQcXxUkW/f -6s6S7RXOUIIV9CgHiZpHPV7T23wQhQOOtVjO2akFLryNI6Z6a66JRhS6fRa3+eiL -9TB0umC8e297dHrzObs43bf5h7sTJB8xHTUI9v4rlMwC8Bk3oghnoCJ820MADttR -p+CUWMkPaBQoDTJJhyfju66lgxZoycLVMwADBgQApLUhOmpHB+zGMvluBUJgBEja -Z553bU/gLzRsTCvt1gnIXLjxYXkiKjLyXfym47mXNaGUGWC7b7yaMVjhfnF3bJ5t -xeIiL7/p3ei17aYOlzXx3MhmuPRhS1IJbXfXChPc7toCqDeSFmnGmVWJZ+zuleTm -OITYkgt5Lshp/N1NZXKITAQYEQIADAUCN8wTdAUJA8JnAAAKCRA2Z2DxfS7XiApb -AJ94BeAKtqsshjVPWijCZ/8SBcJogwCggQjLX5KwZzhHASEXQ/oMvAgS6OKZAaIE -Nuv2vBEEAJttf93iMoIaranZOJ8AR0V0ax+4bTo61nQ392tjaRiPv+9lWuY1O3rv -pHTzTtXP5Qtz1Uw51jn5rDAA43mwz0+cR93g873ecb41/9LRKF8I9CbmZO6N70Re -mLdGb4R1FQ2gMHAwIz+Z54esABLQgq1qUZ66k1+TL/3EZRLnRSk3AKD8fayzCfyw -Vxgy8C67Z35FdBsVGwP9HLfVXrDoAkl3St52A9cIqYKCjWk7Hbv3mdNZIz8pEuhY -7BlpPeMwP9p5cEqlTMjaQHfefHwm1K7GthihkGAHyWM2iZLZSQzIFPG1ER+feTCA -VjSSbvoDGyhHbW+uhGYaNwSLQC36+NrC6ULoTq6Uh86Klpa7mJzLAq+b/6XKhR8D -/jzTElA97kUJEzdpbm5YtqDsu9H16Zdlf+jO59MNi2rcElt3w+thNfucNHVo8fm0 -FGgTpXwNss0Ej4cBXKc8m1ujAWG/hC9s9MMaa1uUgbqngGhZrOvcXXFCJZwoWteW -K4rqucRx7BAl3hyQwl3KK8TY60Te329VBIcKJyVvb7TFtDFVbHJpayBEaWNrb3cg -KG9ubGluZSBHbnVQRyB0ZXN0KSA8dWtkQGthbXBzYXguZGs+iQCVAwUQNuwRdSDu -hu1tZgc9AQEAzwP9HnvIc9zYRmjQEsB44Aik6/pQvrBsSpLNzAWelEaMw6bFHaQT -1PtMnpFmGxbJR6MBBsWku2armlC8G4EUVn9AR07BtXGVGfn8xsHs4MK77QPO7C/I -eqOdotrEYr/OmpXMjBHTfB3B/9vu1p4+ubA8jrY/9DKxRLeWtoJcT19Pe/+JARUD -BRA2744i2gTMWm1DVDsBAQohCACL7/fi/RR7eZc6c0aXEqdytMmAoIg/056jdhwe -OiJITmXxDwNzaDbofOMWGm2IbDb3XfAU52WmKRsnlUFZFWEmHQurUaApx6xGqQiG -wJC38sBS+CfbMmhbvWBeu0XI4V/F/wfzpxYCbELULEHsAeDMXCa4TLhKfmZdrde5 -1RJgK+bNZx/HVCwwU5YtGHbyJ/lYDlg8FxxRCPAAb31mSviRJLLrdEwPWWdi9lGr -G8kp10nnDsfl3mxlItWKAa7ey7ntYi/1glIxSdqgXhfKiXCgZLRC98cQMyj0J3fY -HXF19fkugPCCx5itawmWLeS7sKAkMKBmsqcWKaYp3oy8WnR7iFsEExECABsFAjbr -9rwFCQF+UwADCwoDAxUDAgMWAgECF4AACgkQ9u7fIBhLxNmwfgCg6vEPiWfYZ4Bt -tUvCbLqw7qxl354AoMzEob55S7m8YjrkDP0iimJfHsKliEYEEBECAAYFAjc0ONQA -CgkQXeJJllsDWKKeoACbB7pifCZOprEAEwLyaJmaSvYOvUkAn1CaMjj9cxhwQxLg -7X1Db3FTm3PbuQINBDbr92cQCACHpMcXbJWET55YL4vcHhgZnlzdthEHunAp0EG4 -RznS4ESJX7D2Ll2jO74fD25XFQ/6HsvZl+ITZhMMDW5p8lTfniVBPRWRQaVSzjzw -A0UykQVSf093unT7bSIsGZAMmUymD1ucG5Jh0eHGQq4REmBuvSm6CKh6JRmAJbyk -TKWhfagX5TN0+mHD+CcFKzsgorYRh7KNlFLB6idtAZxFqdhHXkI64kysMVFt6ZlA -2CV5LCQy8m1lLc0WuXM58tWDZ84UeBCJfO+5N8EwkS1S4dRWouOxFWx8nJpje0NP -tb/vyZRQ+JMClVaKOLjmC017k4F8XxVYNqZ7Y5TWmr6sl2WnAAQLB/9iaLQ3eGPG -9GWv9pp/wAYIYzMiDsokdHXf7gOifZXG1DT3Gn1gXqgJmYP3DQN1l6b7NboH+ekB -Ua4D1Y9glIf4/HbdCtv6fGFGv2JWDwNWkU1H88ZrDmwAxcOS9vu9D78ElnACrV46 -OOfmc0PnDseZCgGSuAscXU8YM/zLIGFMvmeALzHxPVOLrLp/Ep0+kGNKdEEDV5ht -5F81uOpTMNkacASAdUqS5iseSjITYbo1sk4j5Fn8pTTn0U9445b/KjKiEH+jbn4x -fPcC03FaXvMnFP+1nAqLbgFmVJ2ljjgEBbgkDPumsrjIuU2ZgSN9CZZ4tQke/FU0 -7RttYHde48eziEwEGBECAAwFAjbr92cFCQF+UwAACgkQ9u7fIBhLxNmnUACgrtAG -GLWPUQbGR/6OQa9AZ6xLhnMAn0SZudBARwp97yCM3Wcm433S6xVDmQGiBDWiHh4R -BAD+l0rg5p9rW4M3sKvmeyzhs2mDxhRKDTVVUnTwpMIR2kIA9pT43No/coPajDvh -ZTaDM/vSz25IZDZWJ7gEu86RpoEdtr/eK8GuDcgsWvFs5+YpCDwWG2dx39ME7DN+ -SRvEE1xUm4E9G2Nnd2UNtLgg82wgi/ZK4Ih9CYDyo0a9awCgisn3RvZ/MREJmQq1 -+SjJgDx+c2sEAOEnxGYisqIKcOTdPOTTie7o7x+nem2uac7uOW68N+wRWxhGPIxs -OdueMIa7U94Wg/Ydn4f2WngJpBvKNaHYmW8j1Q5zvZXXpIWRXSvyTR641BceGHNd -YiR/PiDBJsGQ3ac7n7pwhV4qex3IViRDJWz5Dzr88x+Oju63KtxYurUIBACi7d1r -UlHr4ok7iBRlWHYXU2hpUIQ8C+UOE1XXT+HB7mZLSRONQnWMyXnqbAAW+EUUX2xp -b54CevAg4eOilt0es8GZMmU6c0wdUsnMWWqOKHBFFlDIvyI27aZ9quf0yvby63kF -CanQKc0QnqGXQKzuXbFqBYW2UQrYgjXji8rd8bQnV2VybmVyIEtvY2ggKGdudXBn -IHNpZykgPGRkOWpuQGdudS5vcmc+iF0EExECAB0FAjZVoKYFCQhtDIgDCwQDBRUD -AgYBAxYCAQIXgAAKCRBot6uJV1SNzS4+AKCHdeYHMmKQV9mC7REE5Vz6d5rRBgCf -VMcyRP7dxBwhytmwCDpAcCFvCLSJAV8DBRA1oh5DA28RuP8+qgsQA2MyBR0eiPUo -vYMz0DUXBbNs5606eaVeTJOn9WqkYGcS9xOKlGd8Xj0IcAKN30st5AsC5hRqr82r -rUjB5/CuVdbvk+Qkh6ixWCqo+RRrbgf8cKCg1x+lDj9PpeSD/B9UU45ntxYamoXn -PszxtzU+e73Nkbtrej5rgMK8tgTLkhTAbO8M15Mgtw2yOeDFfiCj4xzDkYryvLiP -I5p2vYXTVcgYnwpNRnMZBwUghb1PMSXj7AP0P/8wnpb656yIjH2OAkE5is5HvTEs -2wGUCEXXYKxgLIl9bRPGd2DHfJQ6broxy1RHVmaOrOeDibspx67RRTm3WqbtLiK0 -/nRF0gEjFGxLjQiy92gp6xLRiQsMQdkz0Lwgr0dgSs6JejBlsQPp5nXXkIm9q/hl -6Cly3Zx3KbAIwO5ZF5NyBciezCxSurg64xmxibNhSknblI0vyG+IRgQQEQIABgUC -NaInPAAKCRBsfuG4YhzAE37WAJ9Xzmig1DrfnUt/KwfgidkPohJViQCg0T6afKuR -spWzPAz5TKQpVjd02KmIRgQQEQIABgUCNu1ObAAKCRBd4kmWWwNYomq2AJ9+alN2 -TpVRAhCxP91eqvfEN9HgGgCgrTvpWnB9EKtROr+AT//cujKCyIaZAaIENaIg8xEE -ALYPe0XNsPjx+inTQ+Izz527ZJnoc6BhWik/4a2bZYENSOQXAMKTDQMv2lLeI0i6 -ceB967MNubhHeVdNeOWYHFSM1UGRfhmZERISho3bp+wVZvVG8GBVwpw34PJjgYU/ -0tDwnJaJ8BzX6j0ecTSTjQPnaUEtdJ/u/gmG9j0218TzAKDihdNoKJEU9IKUiSjd -GomSuem/VwQArHfaucSiDmY8+zyZbVLLnK6UJMqtsIv1LvAg20xwXoUk2bY8H3tX -L4UZ8YcoSXYozwALq3cIo5UZJ0q9Of71mI8WLK2iFSYVplpTX0WMClAdkGt3HgVb -7xtOhGt1mEKeRQjNZ2LteUQrRDD9MTQ+XxcvEN0IpAj4kBJe9bR6HzAD/iecCmGw -SlHUZZrgqWzv78o79XxDdcuLdl4i2fL7kwEOf9jsDe7hGs27yrdJEmAG9QF9TOF9 -LJFmE1CqkgW+EpKxsY01Wjm0BFJB1R7iPUaUtFRZxYqfgXarmPjql2iBi+cVjLzG -u+4BSojVAPgP/hhcnIowf4M4edPiICMP1GVjtCFXZXJuZXIgS29jaCA8d2VybmVy -LmtvY2hAZ3V1Zy5kZT6IWwQTEQIAGwUCNs8JNwUJCCCxRAMLCgMDFQMCAxYCAQIX -gAAKCRBsfuG4YhzAE2kgAJ92JKU+YcYHoRhX51+4s3fnPIyNEgCfaiWeoyb15xgd -O6etGiD2MYCWy5mJAHUDBRA1o3cUHRn0wQyYV6UBAT3zAv9HMaPuMWFQKZRTtJyG -Mo0ID+w/DtLn8z7CMBd5L2+2+RTTY36fgwITehtBziIJC9xrFrQnx+VB2pYvprTR -SCg6U7a/hf5T6WT9zj887C2UuIWE6pjLNTvwAqvGsSoAIpWJAV8DBRA1oicOA28R -uP8+qgsQAwfcBR9Iuppp+q1mChXqSYV8oROMFqkTyQJ736IllJ7Q6eGiEMrOpTkY -oFVyFqOJOEivxR+fWJ8xe+e/Kq02Vv0XANGyKias6mqrDnU2BBWuPXAo7y5wVuDn -myZS01LP555lNBVilvDsMC/qQrvHe3y0kp4IAbK1EMG3qbsNHCaHLRTwM+U9Z0CY -nkClbB2gjcC9nbtF3nzoBebowdYytat6eFMrBfYRHAUfZbRN0x6/or+I7WV5gtT+ -GrfVuSxVrGLsK9FN8iXGikiqdL/8BhFntif4BUGdIQdft+UawmT4IlrBL/Owh2hu -l7UPtx4YqwQibGIZjopFSqBGp+j4VFUdapVxMraQLd/PUwZ78nHgF/IXBzhN3Yrh -ryCxIGHrN4MN7OWZjO21F945tga1/FnIXsVBVECLiltnC9+/TBV0fE28aVca7EWB -P+Ix2QWIRgQQEQIABgUCNu1OCwAKCRBd4kmWWwNYonyaAKCxLBsteoVfwn5g5Lug -9QgVCMV76QCfRgQKXQv9zl4oO7Aa1Qljm9zEM3C5AY0ENs8HCBAGAPc1hCpuXmaT -DAUbIqS9CFHkihMnilIwAV+L2Dbq5eOPtoemPKx5+6xtZfzzY9/VCVwZCxY9Y5PE -N9r/twUA478L/FOXv5E4BpX+4R91klt/EZGcNfDl2Ar56FpGJ3iLg4+vxx9m1TV5 -k2nNOUZAVD1L+MoapWhaZFXLMChrhDUcbo7/1Fr1Rfv9j/LkkIJJhqf3G8HzE5Av -CQVSywUayYZdbmqdiY2bklZJVFAXs1X9zSTGoFc8eOxz6i1ZeMq+GwADBgX/T7o5 -R+SOTlJ72ac/g121f1kFX1dbRkQq2pCI95qTehp1AxdSwG3ur2slFCfi8ZDNUqkF -XJrsv5mh1yfqq7zS5T6lGT5lOXCDZbAO2wqNZY1VKeeCdcvD2VMeh8XxJfy8y1ZK -/iE1p8qnokYpA3nFH+JIsdrXk5ceiN3nKk+aDamUkV1sJzeEm5F7QHe60oBKbVGI -UF4EhGq6daVyeCeK4KhWuPYyiEgyaq5/xJZbR3uRcdW6X5AiGJWJOOQoGvWziEwE -GBECAAwFAjbPBwgFCQbzyQAACgkQbH7huGIcwBN5FQCggakIOYzLX3lNq2WWgcAk -SNm7kpoAnA69b3z2E5vxyD3bhggVUDX7j8hruQGNBDWiITwUBgCRCYCU5eLFvzCt -rzesTWLssIQ0vOW8FlYoFc3g416VkCeeQ6bsipGMyG0pEk3vnOpXIpRpTAMqOl/0 -nkra3vmZLEG2ds1Govdeh2Mcr3c5wBSTPdyLuK4L9vbgkjarhd5Ab+/hhHVWh0zT -MRDUgLQkKrg+Xf1BnJcl1kKtQW8xxermu41KV3O0GpMUVSIVuTDUW6D9nJcm97YV -VxuxFcWsHsQS7L6KJT+Rn81WIqTQvhPopEdWwSKuI2UKKJtbX18AAwUF/1Nu/rso -UwOsupBqf/ShJKh2MNAoMaq2iHspBggo9ep+pPxx533J3kwsXA8p/e3sBYbW5xbb -HXXwA1iQ9JTXbZROd0+xrHRxjheRofFo3Ck0UKi0ZDRRFKHEo2lypt1+/L7V3ymk -Rq+A7LGdXUk6QuNkkvArxuDEV1s9ZywkmeO64fc/DPzsLNOA5JhDEw+cjBBzHlu5 -khXk14Qsm1xtt3dFW5or8ZCG3xAmm5dKOLw2XUWKFgOMAJHxNpGUCHnQaYhGBCgR -AgAGBQI4K/uDAAoJEGx+4bhiHMAT2FMAn1xEe77uraGTGkV+eiTiZGKyh8JOAKDO -g+M0i5iKJXr7AsHmjXXsw1Y9kIhMBBgRAgAMBQI1oiE8BQkHhM4AAAoJEGx+4bhi -HMATDfUAoLstR8cg5QtHwSQ3nFCOKEREUFIwAKDID3K3hM+b6jW1o+tNX9dnjb+Y -MZkAbQIwbYOUAAABAwC7ltmO5vdKssohwzXEZeYvDW2ll3CYD2I+ruiNq0ybxkfF -Bopq9cxta0OvVML4LK/TH+60f/Fqx9wg2yk9APXyaomdLrXfWyfZ91YtNCfj3ElC -4XB4qqm0HRn0wQyYV6UABRG0IVdlcm5lciBLb2NoIDx3ZXJuZXIua29jaEBndXVn -LmRlPokAlQMFEDRfoOmOB31Gi6BmjQEBzwgD/2fHcdDXuRRY+SHvIVESweijstB+ -2/sVRp+FCDjR74Kg576sJHfTJCxtSSmzpaVpelb5z4URGJ/Byi5L9AU7hC75S1Zn -J+MjBT6VePyk/r0uBrMkU/lMG7lk/y2By3Hll+edjzJsdwn6aoNPiyen4Ch4UGTE -guxYsLq0HES/UvojiQEVAwUTNECE2gnp+QqKck5FAQH+1Af/QMlYPlLG+5E19qP6 -AilKQUzNkd1TWMenXTS66hGIVwkLVQDi6RCimhnLMq/F7ENA8bSbyyMuncaBz5dH -4kjfiDp1o64LULcTmN1LW9ctpTAIeLLJZnwxoJLkUbLUYKADKqIBXHMt2B0zRmhF -OqEjRN+PhI7XCcHeHWHiDeUB58QKMyeoJ/QG/7zLwnNgDN2PVqq2E72C3ye5FOkY -LcHfWKyBRrn6BdUphAB0LxZujSGk8ohZFbia+zxpWdE8xSBhZbjVGlwLurmS2UTj -jxByBNiheUD6IC3u5P6psld0OfqnpriZofP0CBP2oTk65r529f/1lsy2kfWrVPYI -FJXEnIkAlQMFEDQyneGkWMS9SnJfMQEBMBMD/1ADuhhuY9kyN7Oj6DPrDt5SpPQD -GS0Jtw3yuIPoed+xyzlrEuL2HeaOj1O9urpn8XLN7V21ajkzlqsxnGkOuifbE9UT -67o2b2vCldCcY4nV5n+U1snMDwNv+RkcEgNa8ANiWkm03UItd7/FpHDQP0FIgbPE -PwRoBN87I4gaebfRiQCVAwUQNDUSwxRNm5Suj3z1AQGMTAP/UaXXMhPzcjjLxBW0 -AccTdHUtLi+K+rS5PNxxef2nnasEhCdK4GkM9nwJgsP0EZxCG3ZSAIlWIgQ3MK3Z -AV1Au5pLKolRjFyEZF420wAtiE7V+4lw3FCqNoXDJEFC3BW431kx1wAhDk9VaIHH -adYcof4ddmMLQOW2cJ7LDEEBW/WJAJUDBRA0M/VQImbGhU33abUBARcoA/9eerDB -ZGPCuGyEmQBcr24KPJHWv/EZIKl5DM/Ynz1YZZbzLcvEFww34mvY0jCfoVcCKIeF -FBMKiSKrOMtoVC6cQMKpmhE9hYRStw4E0bcf0BD/stepdVtpwRnG8SDP2Zbmtgyj -YT/7T4Yt6/0f6N/0NC7E9qfq4ZlpU3uCGGu/44kAlQMFEDQz8kp2sPVxuCQEdQEB -c5YD/RixvFcLTO1HznbblrO0WMzQc+R4qQ50CmCpWcFMwvVeQHo/bxoxGggNMmuV -T0bqf7MolZDSJNS96IAN32uf25tYHgERnQaMhmi1aSHvRDh4jxFu8gGVgL6lWit/ -vBDW/BiFBCH6sZJJrGSuSdpecTtaWC8OJGDoKTO9PqAA/HQRiQB1AwUQNDJSx011 -eFs7VOAZAQGdKQL/ea3qD2OP3wVTzXvfjQL1CosX4wyKusBBhdt9u2vOT+KWkiRk -1o35nIOGuZLHtSFQDY8CVDOkqg6g4sVbOcTl8QUwHA+A4AVDInwTm1m4Bk4oeCIw -k4Bp6mDdW11g28k/iQEVAgUSNDIWPm/Y4wPDeaMxAQGvBQgAqGhzA/21K7oL/L5S -5Xz//eO7J8hgvqqGXWd13drNy3bHbKPn7TxilkA3ca24st+6YPZDdSUHLMCqg16Y -OMyQF8gEkX7ZHWPacVoUpCmSz1uQ3p6W3+u5UCkRpgQN8wBbJx5ZpBBqeq5q/31o -kaoNjzA2ghEWyR5Ll+U0C87MY7pc7PlNHGCr0ZNOhhtf1jU+H9ag5UyT6exIYim3 -QqWYruiCLSUcim0l3wK7LMW1w/7Q6cWfAFQvl3rGjt3rg6OWg9J4H2h5ukf5JNiR -ybkupmatUM+OVMRkf93jzU62kbyZpJBHiQZuxxJaLkhpv2RgWib9pbkftwEy/Znm -jkxlIIkAlQMFEDQvWjh4313xYR8/NQEB37QEAIi9vR9h9ennz8Vi7RNU413h1ZoZ -jxfEbOpkQAjE/LrZ/L5WiWdoStSiyqCLPoyPpQafiU8nTOr1KmY4RgceJNgxIW4O -iSMoSvrhc2kqP+skb8A2B4+47Aqjr5fSAVfVfrDMqDGireOguhQ/hf9BOYsM0gs+ -ROdtyLWPtMjRnFlviD8DBRAz8qQSj6lRT5YOKXIRAntSAJ9StSEMBoFvk8iRWpXb -6+LDNLUWzACfT8iY3IxwvMF6jjCHrbuxQkL7chSJARUDBRA0MMO7569NIyeqD3EB -ATIAB/4tCPZ1sLWO07g2ZCpiP1HlYpf5PENaXtaasFvhWch7eUe3DksuMEPzB5Gn -auoQZAkuhEGkoEfrfL3AXtXH+WMm2t7dIcTBD4p3XkeZ+PgJpKiASXDyul9rumXX -vMxSL4KV7ar+F1ZJ0ycCx2r2au0prPao70hDAzLTy16hrWgvdHSK7+wwaYO5TPCL -5JDmcB+dHKW72qNUOD0pxbe0uCkkb+gDxeVX28pZEkIIOMMV/eAs5bs/smV+eJqW -T/EyfVBDo7heF2aeyJj5ecxNOODr88xKF7qEpqazCQ4xhvFY+Yn6+vNCcYfkoZbO -n0XQAvqfa2Vab9woVIVSaDji/mlPiQB1AwUQNDC233FfeD4HYGBJAQFh6QL/XCgm -5O3q9kWpgts1MHKoHoh7vxSSQGSP2k7flNP1UB2nv4sKvyGM8eJKApuROIodcTkc -cM4qXaBuXunMr5kJlvDJPm+NLzKyhtQP2fWI7xGYwiCiB29gm1GFMjdur4amiQEV -AwUQNDBR9fjDdqGixRdJAQE+mAf+JyqJZEVFwNwZ2hSIMewekC1r7N97p924nqfZ -Knzn6weFpE80KIJSWtEVzI0XvHlVCOnS+WRxn7zxwrOTbrcEOy0goVbNgUsP5ypZ -a2/EM546uyyJTvgD0nwA45Q4bP5sGhjh0G63r9Vwov7itFe4RDBGM8ibGnZTr9hH -o469jpomHSNeavcaUYyEqcr4GbpQmdpJTnn/H0A+fMl7ZHRoaclNx9ZksxihuCRr -kQvUOb3uRD9lFIhCvNwEardN62dKOKJXmn1TOtyanZvnmWigU5AmGuk6FpsClm3p -5vvlid64i49fZt9vW5krs2XfUevR4oL0IyUl+qW2HN0DIlDiAYkAlQMFEDQvbv2w -cgJwUPMhJQEBVBID/iOtS8CQfMxtG0EmrfaeVUU8R/pegBmVWDBULAp8CLTtdfxj -Vzs/6DXw0RogXMRRl2aFfu1Yp0xhBYjII6Kque/FzAFXY9VNF1peqnPt7ADdeptY -MppZa8sGn9BBRu9Fsw69z6JkyqvMiVxGcKy3XEpVGr0JHx8Xt6BYdrULiKr2iQB1 -AwUQNC68n6jZR/ntlUftAQFaYgL+NUYEj/sX9M5xq1ORX0SsVPMpNamHO3JBSmZS -Izjiox5MAqoFOCigAkonuzk5aBy/bRHy1cmDBOxf4mNhzrH8N6IkGvPE70cimDnb -Fvr+hoZSjIqxtELNZsLuLVavLPAXiQCVAwUQNC6vWocCuHlnLQXBAQHb1gQAugp6 -2aVzDCuz4ntfXsmlGbLY7o5oZXYIKdPP4riOj4imcJh6cSgYFL6OMzeIp9VW/PHo -2mk8kkdkz5uif5LqOkEuIxgra7p1Yq/LL4YVhWGQeD8hwpmu+ulYoPOw40dVYS36 -PwrHIH9afNhl8Or5O2VIHIWnoQ++9r6gwngFQOyJAJUDBRAzHnkh1sNKtX1rroUB -AWphBACdhuqm7GHoiXptQ/Y5F6BivCjxr9ch+gPSjaLMhq0kBHVO+TbXyVefVVGV -gCYvFPjozM8PEVykQAtY//eJ475aGXjF+BOAhl2z0IMkQKCJMExoEDHbcj0jIIMZ -2/+ptgtbFSyJ2DQ3vvCdbw/1kyPHTPfP+L2u40GWMIYVBbyouokAlQMFEDMe7+UZ -symln7HG2QEBzMED/3L0DyPK/u6PyAd1AdpjUODTkWTZjZ6XA2ubc6IXXsZWpmCg -B/24v8jsJ3DIsvUD3Ke55kTr6xV+au+mAkwOQqWUTUWfQCkSrSDlbUJ1VPBzhyTp -uzjBopte7o3R6XXfcLiC5jY6eCX0QtLGhKpLjTr5uRhf1fYODGsAGXmCByDviQB1 -AgUQMy6UMB0Z9MEMmFelAQHV4AMAjdFUIyFtpTr5jkyZSd3y//0JGO0z9U9hLVxe -BBCwvdEQxsrpeTtVdqpeKZxHN1GhPCYvgLFZAQlcPh/Gc8u9uO7wVSgJc3zYKFTh -KpQevdF/rzjTCHfgigf5Iui0qiqBiQCVAwUQMx22bAtzgG/ED06dAQFi0gQAkosq -TMWy+1eUXbi2azFK3RX5ERf9wlN7mqh7TvwcPXvVWzUARnwRv+4kk3uOWI18q5UP -is7KH3KYOVeRrPd8bbp6SjhBh82ourTEQUXLBDQiI1V1cZZmwwEdlnAnhFnkXgMB -NM2q7oBefRHADfYDfGo90wXyrVVL+GihDNpzUwOJAJUDBRAzHUFnOWvfULwOR3EB -AbOYA/90JIrKmxhwP6quaheFOjjPoxDGEZpGJEOwejEByYj+AgONCRmQS3Bydtub -A+nm/32DFeG8pe/dnFvGc+QgNW560hK21C2KJj72mhjRlg/na7jz4/MmBAv5k61Q -7roWi0rwx+R9NSHxpshC8A92zmvo8w/XzVSogC8pJ04jcnY6YokAlQMFEDMdPtta -9LwlvuSC3QEBvPMD/3TJGroHhHYjHhiEpDZZVszeRQ0cvVI/uLLi5yq3W4F6Jy47 -DF8VckA7mw0bXrOMNACN7Je7uyaU85qvJC2wgoQpFGdFlkjmkAwDAjR+koEysiE8 -FomiOHhvEpEY/SjSS4jj4IPmgV8Vq66XjPw+i7Z0RsPLOIf67yZHxypNiBiYiQCV -AwUQMxxwpKrq6G7/78D5AQHo2QQAjnp6KxOl6Vvv5rLQ/4rj3OemvF7IUUq34xb2 -5i/BSvGBUpDQVUmhv/qIfWvDqWGZedyM+AlNSfUWPWnP41S8OH+lcERH2g2dGKGl -7kH1F2BxByZlqREHm2q624wPPA35RLXtXIx06yYjLtJ7b+FCAX6PUgZktZYk5gwj -doAGrC2JAJUDBRAzGvcCKC6c7f53PGUBAUozA/9l/qKmcqbi8RtLsKQSh3vHds9d -22zcbkuJPBSoOv2D7i2VLshaQFjq+62uYZGE6nU1WP5sZcBDuWjoX4t4NrffnOG/ -1R9D0t1t9F47D77HJzjvo+J52SN520YHcbT8VoHdPRoEOXPN4tzhvn2GapVVdaAl -WM0MLlohNH3I9jap9okAdQMFEDMZlUAnyXglSykrxQEBnuwC/jXbFL+jzs2HQCuo -4gyVrPlUksQCLYZjNnZtw1ca697GV3NhBhSXR9WHLQH+ZWnpTzg2iL3WYSdi9tbP -s78iY1FSd4EG8H9V700oQG8dlICF5W2VjzR7fByNosKM70WSXYkBFQMFEDMWBsGC -y1t9eckWHQEBHzMH/jmrsHwSPrA5R055VCTuDzdS0AJ+tuWkqIyqQQpqbost89Hx -per3MmjLJas/VJv8EheuU3vQ9a8sG2SnlWKLtzFqpk7TCkyq/H3blub0agREbNnY -hHHTGQFCYJb4lWjWvMjfP+N5jvlLcnDqQPloXfAOgy7W90POoqFrsvhxdpnXgoLr -zyNNja1O1NRj+Cdv/GmJYNi6sQe43zmXWeA7syLKMw6058joDqEJFKndgSp3Zy/y -XmObOZ/HC2OJwA3gzEaAu8Pqd1svwGIGznqtTNCn9k1+rMvJPaxglg7PXIJS282h -mBl9AcJlwmh2GUCswl9/sj+REWTb8SgJUbkFcp6JAJUDBRAwdboVMPfsgxioXMEB -AQ/LA/9BFTZ9T95P/TtsxeC7lm9imk2mpNQCBEvXk286FQnGFtDodGfBfcH5SeKH -aUNxFaXr39rDGUtoTE98iAX3qgCElf4V2rzgoHLpuQzCg3U35dfs1rIxlpcSDk5i -vaHpPV3Sv+mlqWL049y+3bGaZeAnwM6kvGMP2uccS9U6cbhpw4hGBBARAgAGBQI3 -GtRfAAoJEF3iSZZbA1iikWUAoIpSuXzuN/CI63dZtT7RL7c/KtWUAJ929SAtTr9S -lpSgxMC8Vk1T1i5/SYkBFQMFEzccnFnSJilEzmrGwQEBJxwH/2oauG+JlUC3zBUs -oWhRQwqo7DdqaPl7sH5oCGDKS4x4CRA23U15NicDI7ox6EizkwCjk0dRr1EeRK+R -qL1b/2T42B6nynOLhRG2A0BPHRRJLcoL4nKfoPSo/6dIC+3iVliGEl90KZZD5bnO -NrVJQkRjZL8Ao+9IpmoYh8XjS5xMLEF9oAQqAkA93nVBm56lKmaL1kl+M3dJFtNK -tVB8de1ZXifDs8HykD42qYVtcseCKxZXhC3UTG5YLNhPvgZKH8WBCr3zcR13hFDx -uecUmu0MVhvEzoKyBYYt0rrqnyWrxwbv4gSTUWH5ZbgsTjc1SYKZxz6hrPQnfYWz -NkznlFWJARUDBRM0xL43CdxwOTnzf10BATOCB/0Q6WrpzwPMofjHj54MiGLKVP++ -YfwzdvnsHxVpTZLZ5Ux8ErDsnLmvUGphnLVELZwEkEGRjln7a19h9oL8UYZaV+Ic -R6tQ06Fb1ldR+q+3nXtBYzGhleXdgJQSKLJkzPF72tvY0DHUB//GUV9IBLQMvfG8 -If/AFsih4iXi96DOtUAbeuIhnMlWwLJFeGjLLsX1u6HSX33xy4bGX6v/UcHbTSSY -axzb92GR/xpP2Xt332hOFRkDZL52g27HS0UrEJWdAVZbh25KbZEl7C6zX/82OZ5n -TEziHo20eOS6Nrt2+gLSeA9X5h/+qUx30kTPz2LUPBQyIqLCJkHM8+0q5j9ciQCi -AwUTNMS+HZFeTizbCJMJAQFrGgRlEAkG1FYU4ufTxsaxhFZy7xv18527Yxpls6mS -Ci1HL55nJoce6TI+Z34MrLOaiZljeQP3EUgzA+cs1sFRago4qz2wS8McmQ9w0FNQ -QMz4vVg9CVi1JUVd4EWYvJpA8swDd5b9+AodYFEsfxt9Z3aP+AcWFb10RlVVsNw9 -EhObc6IMnwAOHCEI9vp5FzzFiQCVAwUQNxyr6UyjTSyISdw9AQHf+wP+K+q6hIQ0 -9tkgaYaDLlWKLbuxePXqM4oO72qi70Gkg0PV5nU4l368R6W5xgR8ZkxlQlg85sJ0 -bL6wW/SjMz7pP9hkhNwk0x3IFkGMTYG8i6Gt8Nm7x70dzJoiC+A496PryYC0rvGV -f+Om8j5uTexBBjb/jpJhAQ/SGqeDeCHheOC0Lldlcm5lciBLb2NoIChtZWluIGFs -dGVyIGtleSkgPHdrQGNvbXB1dGVyLm9yZz6JAHUDBRM2G2MyHRn0wQyYV6UBASKK -Av4wzmK7a9Z+g0KH+6W8ffIhzrQo8wDAU9X1WJKzJjS205tx4mmdnAt58yReBc/+ -5HXTI8IKR8IgF+LVXKWAGv5P5AqGhnPMeQSCs1JYdf9MPvbe34jD8wA1LTWFXn9e -/cWIRgQQEQIABgUCNxrUaQAKCRBd4kmWWwNYovRiAJ9dJBVfjx9lGARoFXmAieYr -MGDrmwCZAQyO4Wo0ntQ+iq4do9M3/FTFjiCZAaIENu1I6REEAJRGEqcYgXJch5fr -UYBj2EkDkWAbhRqVXnmiF3PjCEGAPMMYsTddiU7wcKfiCAqKWWXow7BjTJl6Do8R -T1jdKpPOlBJXqqPYzsyBxLzE6mLps0K7SLJlSKTQqSVRcx0jx78JWYGlAlP0Kh9s -PV2w/rPh0LrPeOKXT7lZt/DrIhfPAKDL/sVqCrmY3QfvrT8kSKJcgtLWfQP/cfbq -VNrGjW8am631N3UVA3tWfpgM/T9OjmKmw44NE5XfPJTAXlCV5j7zNMUkDeoPkrFF -8DvbpYQs4XWYHozDjhR2Q+eI6gZ0wfmhLHqqc2eVVkEG7dT57Wp9DAtCMe7RZfhn -arTQMqlYtOEa/suiHk0qLo59NsyF8eh68IDNCeYD/Apzonwaq2EQ1OEpfFlp6LcS -nS34+UGZtTO4BgJdmEjr/QrIPp6bJDstgho+/2oR8yQwuHGJwbS/8ADA4IFEpLdu -SpzrABho7RuNQcm96bceRY+7Hza3zf7pg/JGdWOb+bC3S4TIpK+3sx3YNWs7eURw -pGREeJi5/Seic+GXlGzltBpXZXJuZXIgS29jaCA8d2tAZ251cGcub3JnPohbBBMR -AgAbBQI3Gs+QBQkMyXyAAwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iiXcIAnjv7 -ON5AiwzCLBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhGBBARAgAG -BQI3GtE9AAoJEGx+4bhiHMAThfQAnjcDvBthtHotN89IP590GSKY287xAJ0WhKl9 -j7gWwpVqCD+ofcq0ZQBG1IkAdQMFEDca0WMdGfTBDJhXpQEB0a4C/0AzSj1eSYFs -4ss2x7xCn0yMPxML+hJdjGnVb0CPJGzzeKpD69pmVsD87nPa53gj0NXi/ADnQvPm -csVs8dr7K5PxXFOXaJzDm72tnLeJKiTesZfMY7MQ0yYQUhUWogSY8YhGBBARAgAG -BQI3GtGjAAoJEGi3q4lXVI3NLfgAoISt+x9r02Hl14njSfGmZIjyUrXuAJ9FhxTq -LUHU1uDZmSSvlKpOcG1pYIhGBBARAgAGBQI3Tx9dAAoJEPbu3yAYS8TZLb4Ani50 -OXjsQCc/gr5G+xZy/yqOqnOWAJ44VlluXNaN6J7yhB9iXtsEGvE+oohGBBARAgAG -BQI3pyb+AAoJEJg0ZdshQ5QifskAn0stcy37RHy7iB2bFB4rPVNDJaizAJ9hCH+0 -yNTOTisrEHLhS0QufAn3H4hFBBARAgAGBQI34UEzAAoJEDZnYPF9LteIeecAn3eT -mQldy/AIYuEFvyaF1FPmQdDNAJj3trsO1mAyzs7+PB++rZunMveeiEYEEBECAAYF -AjgqYg8ACgkQ4/JYVBKPDnkbHQCfRR7qUYmwTxtrf+Fw6hfsYjCy//AAn1eRdkkd -CExOJPwvrHEtZydSmVA1tAtXZXJuZXIgS29jaIhbBBMRAgAbBQI27UjqBQkMyXyA -AwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iitdYAn1IJbSJ46kvsBjq8X44hoybD -ZlbWAKCS2jR5Z+CmMC5WDqNepHXAe3alA4kCHgQQFAMABgUCNy9Z1AAKCRBsTDGl -sdUVZw3FB/9uDXhYYnQZYw1K6445HRZjNRo23NimItJXIuut5e2jwsE3DNuDOPat -qZbtGL61gkAcuG25rxmBJ6JuaAG5lqwXx1vWbk03VlwcFcZPKwCOn4qeJxNn06uP -vkP2jehKYzJFyKwSGv6CSPS1WEZ84A4Lp4pu59W7JgUNUjI7JQEaVbsCl6bMDNh6 -Z+zcN2MefzuWSMcxURI7h8zmu0u5JztwF8v97qWNpZBzlbxLSAgO/RW0vf2kxbgG -WkprbmvXignLC5Sm9YJm6y8Obtkmepn9aaA4dBSzJi51NE6kYhuWw2DyKoLqG5ak -ZIFF27ehFBGGSql9V2zPPoEH+cDHTWrbB/9D5T1ch3WPLPFQvVIaBpgx/pB3KMdD -WjG4Us3HMzoL8zTr23Bs2BcnvVGwMNdXEVl9JONKIfXTQA/372FvmbJxpctQ5dgO -85IXMcF38uyMU1WusVsOzlfD5wsZUc4iBHkhYB+C7l3U8BlT25BWB0adB+ZmDfzd -FI/G9Hd+dnPWsc1QaZLrDvHoVVvFrVBTa3fyA1pwjAcBMA9wGnIkt9ejOdumDcAN -uAIbIOMHCe49ARCRjBFqRtzNGuB7who9lu3Ydg+hSx25cxnIkjzPm2+7ulQPCznW -dXURfXkFw3f75pjmlTIDUi1poPKZBWagVtALQE0zMw7nd0ycWSjiLjaSiEYEEBEC -AAYFAjc6+aMACgkQdQ9klcidkz6GiwCdGe0KSP/vSyEZM/GClQXvjMD4RvMAoJwy -TIdcjPZbQizDeAO3btn2CCwTiEYEEBECAAYFAjc3I8UACgkQ9u7fIBhLxNmHZQCg -lWbPDznIcnOxdDW+k7YgA9+/n00An1ZjSiJipverUxLEFHAbSBWI0IntiQEVAwUQ -N0Pe01KAV0R2U0AdAQHIcQf/Ykx+DvUaCLIYlMrEIDKZ3J/aPbJ8frAjvzYkrgFZ -XhzQT9Xfyr6OkhiyWKFX23yzzDVcrmeIxovCUI7IFY6QM/d5yHr4Y8+18HdyaUva -FLz3o9ZnVp1AeAJ5CkHzfufnrKPRpOzgvXFqttJVPbaVTAyJTo/Bh0fZGHyeHwW8 -3QhmxuWfac6PveoA1DM1+Wax5QoXVeHhyTzIutF3ivpqaHEBUB9xgVEk3jN0svdy -aGCS3QANmXMDBecSPB0cfLtK8AmTV5w04D2kWw4lu+fO593Vp+z8Jsbvwj7QkOGD -vlnY3Crx4qOwqqI7TPP+8bnJZKd1m9aRNbPcPdvXGvUh3YhGBBARAgAGBQI4KmIe -AAoJEOPyWFQSjw55D5AAoJs5OxzJSdYdKsOjh8jLQxOESOE6AJ4vgpvtNaR384dB -JxUE7yxNTPT7aA== -=gKwz ------END PGP PUBLIC KEY BLOCK----- diff --git a/g10/revoke.c b/g10/revoke.c deleted file mode 100644 index 161bd2b82..000000000 --- a/g10/revoke.c +++ /dev/null @@ -1,690 +0,0 @@ -/* revoke.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "ttyio.h" -#include "status.h" -#include "i18n.h" - - -struct revocation_reason_info { - int code; - char *desc; -}; - - -int -revocation_reason_build_cb( PKT_signature *sig, void *opaque ) -{ - struct revocation_reason_info *reason = opaque; - char *ud = NULL; - byte *buffer; - size_t buflen = 1; - - if(!reason) - return 0; - - if( reason->desc ) { - ud = native_to_utf8( reason->desc ); - buflen += strlen(ud); - } - buffer = xmalloc ( buflen ); - *buffer = reason->code; - if( ud ) { - memcpy(buffer+1, ud, strlen(ud) ); - xfree ( ud ); - } - - build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen ); - xfree ( buffer ); - return 0; -} - -/* Outputs a minimal pk (as defined by 2440) from a keyblock. A - minimal pk consists of the public key packet and a user ID. We try - and pick a user ID that has a uid signature, and include it if - possible. */ -static int -export_minimal_pk(iobuf_t out,KBNODE keyblock, - PKT_signature *revsig,PKT_signature *revkey) -{ - KBNODE node; - PACKET pkt; - PKT_user_id *uid=NULL; - PKT_signature *selfsig=NULL; - u32 keyid[2]; - int rc; - - node=find_kbnode(keyblock,PKT_PUBLIC_KEY); - if(!node) - { - log_error(_("key incomplete\n")); - return GPG_ERR_GENERAL; - } - - keyid_from_pk(node->pkt->pkt.public_key,keyid); - - pkt=*node->pkt; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - - init_packet(&pkt); - pkt.pkttype=PKT_SIGNATURE; - - /* the revocation itself, if any. 2440 likes this to come first. */ - if(revsig) - { - pkt.pkt.signature=revsig; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - /* If a revkey in a 1F sig is present, include it too */ - if(revkey) - { - pkt.pkt.signature=revkey; - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - while(!selfsig) - { - KBNODE signode; - - node=find_next_kbnode(node,PKT_USER_ID); - if(!node) - { - /* We're out of user IDs - none were self-signed. */ - if(uid) - break; - else - { - log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]); - return GPG_ERR_GENERAL; - } - } - - if(node->pkt->pkt.user_id->attrib_data) - continue; - - uid=node->pkt->pkt.user_id; - signode=node; - - while((signode=find_next_kbnode(signode,PKT_SIGNATURE))) - { - if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && - keyid[1]==signode->pkt->pkt.signature->keyid[1] && - IS_UID_SIG(signode->pkt->pkt.signature)) - { - selfsig=signode->pkt->pkt.signature; - break; - } - } - } - - pkt.pkttype=PKT_USER_ID; - pkt.pkt.user_id=uid; - - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - - if(selfsig) - { - pkt.pkttype=PKT_SIGNATURE; - pkt.pkt.signature=selfsig; - - rc=build_packet(out,&pkt); - if(rc) - { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} - -/**************** - * Generate a revocation certificate for UNAME via a designated revoker - */ -int -gen_desig_revoke( const char *uname ) -{ - int rc = 0; - armor_filter_context_t afx; - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - PKT_signature *sig = NULL; - iobuf_t out = NULL; - struct revocation_reason_info *reason = NULL; - KEYDB_HANDLE kdbhd; - KEYDB_SEARCH_DESC desc; - KBNODE keyblock=NULL,node; - u32 keyid[2]; - int i,any=0; - - if( opt.batch ) { - log_error(_("sorry, can't do this in batch mode\n")); - return GPG_ERR_GENERAL; - } - - memset( &afx, 0, sizeof afx); - - kdbhd = keydb_new (0); - classify_user_id (uname, &desc); - rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("key `%s' not found: %s\n"),uname, gpg_strerror (rc)); - goto leave; - } - - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* To parse the revkeys */ - merge_keys_and_selfsig(keyblock); - - /* get the key from the keyblock */ - node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); - if( !node ) - BUG (); - - pk=node->pkt->pkt.public_key; - - keyid_from_pk(pk,keyid); - - /* Are we a designated revoker for this key? */ - - if(!pk->revkey && pk->numrevkeys) - BUG(); - - for(i=0;i<pk->numrevkeys;i++) - { - if(sk) - free_secret_key(sk); - - sk=xcalloc (1,sizeof(*sk)); - - rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN); - - /* We have the revocation key */ - if(!rc) - { - PKT_signature *revkey = NULL; - - any = 1; - - print_pubkey_info (NULL, pk); - tty_printf ("\n"); - - tty_printf (_("To be revoked by:\n")); - print_seckey_info (sk); - - if(pk->revkey[i].class&0x40) - tty_printf(_("(This is a sensitive revocation key)\n")); - tty_printf("\n"); - - if( !cpr_get_answer_is_yes("gen_desig_revoke.okay", - _("Create a revocation certificate for this key? ")) ) - continue; - - /* get the reason for the revocation (this is always v4) */ - reason = ask_revocation_reason( 1, 0, 1 ); - if( !reason ) - continue; - - rc = check_secret_key( sk, 0 ); - if( rc ) - continue; - - if( !opt.armor ) - tty_printf(_("ASCII armored output forced.\n")); - - if( (rc = open_outfile( NULL, 0, &out )) ) - goto leave; - - afx.what = 1; - afx.hdrlines = "Comment: A revocation certificate should follow\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - /* create it */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, - 0, 0, 0, - revocation_reason_build_cb, reason ); - if( rc ) { - log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - /* Spit out a minimal pk as well, since otherwise there is - no way to know which key to attach this revocation to. - Also include the direct key signature that contains - this revocation key. We're allowed to include - sensitive revocation keys along with a revocation, as - this may be the only time the recipient has seen it. - Note that this means that if we have multiple different - sensitive revocation keys in a given direct key - signature, we're going to include them all here. This - is annoying, but the good outweighs the bad, since - without including this a sensitive revoker can't really - do their job. People should not include multiple - sensitive revocation keys in one signature: 2440 says - "Note that it may be appropriate to isolate this - subpacket within a separate signature so that it is not - combined with other subpackets that need to be - exported." -dms */ - - while(!revkey) - { - KBNODE signode; - - signode=find_next_kbnode(node,PKT_SIGNATURE); - if(!signode) - break; - - node=signode; - - if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && - keyid[1]==signode->pkt->pkt.signature->keyid[1] && - IS_KEY_SIG(signode->pkt->pkt.signature)) - { - int j; - - for(j=0;j<signode->pkt->pkt.signature->numrevkeys;j++) - { - if(pk->revkey[i].class== - signode->pkt->pkt.signature->revkey[j]->class && - pk->revkey[i].algid== - signode->pkt->pkt.signature->revkey[j]->algid && - memcmp(pk->revkey[i].fpr, - signode->pkt->pkt.signature->revkey[j]->fpr, - MAX_FINGERPRINT_LEN)==0) - { - revkey=signode->pkt->pkt.signature; - break; - } - } - } - } - - if(!revkey) - BUG(); - - rc=export_minimal_pk(out,keyblock,sig,revkey); - if(rc) - goto leave; - - /* and issue a usage notice */ - tty_printf(_("Revocation certificate created.\n")); - break; - } - } - - if(!any) - log_error(_("no revocation keys found for `%s'\n"),uname); - - leave: - if( pk ) - free_public_key( pk ); - if( sk ) - free_secret_key( sk ); - if( sig ) - free_seckey_enc( sig ); - - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - release_revocation_reason_info( reason ); - return rc; -} - - -/**************** - * Generate a revocation certificate for UNAME - */ -int -gen_revoke( const char *uname ) -{ - int rc = 0; - armor_filter_context_t afx; - PACKET pkt; - PKT_secret_key *sk; /* used as pointer into a kbnode */ - PKT_public_key *pk = NULL; - PKT_signature *sig = NULL; - u32 sk_keyid[2]; - iobuf_t out = NULL; - KBNODE keyblock = NULL, pub_keyblock = NULL; - KBNODE node; - KEYDB_HANDLE kdbhd; - struct revocation_reason_info *reason = NULL; - KEYDB_SEARCH_DESC desc; - - if( opt.batch ) { - log_error(_("sorry, can't do this in batch mode\n")); - return GPG_ERR_GENERAL; - } - - memset( &afx, 0, sizeof afx); - init_packet( &pkt ); - - /* search the userid: - * We don't want the whole getkey stuff here but the entire keyblock - */ - kdbhd = keydb_new (1); - classify_user_id (uname, &desc); - rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID; - if (rc) { - log_error (_("secret key `%s' not found: %s\n"), - uname, gpg_strerror (rc)); - goto leave; - } - - rc = keydb_get_keyblock (kdbhd, &keyblock ); - if( rc ) { - log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, PKT_SECRET_KEY ); - if( !node ) - BUG (); - - /* fixme: should make a function out of this stuff, - * it's used all over the source */ - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, sk_keyid ); - print_seckey_info (sk); - - pk = xcalloc (1, sizeof *pk ); - - /* FIXME: We should get the public key direct from the secret one */ - - pub_keyblock=get_pubkeyblock(sk_keyid); - if(!pub_keyblock) - { - log_error(_("no corresponding public key: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY); - if(!node) - BUG(); - - pk=node->pkt->pkt.public_key; - - if( cmp_public_secret_key( pk, sk ) ) { - log_error(_("public key does not match secret key!\n") ); - rc = GPG_ERR_GENERAL; - goto leave; - } - - tty_printf("\n"); - if( !cpr_get_answer_is_yes("gen_revoke.okay", - _("Create a revocation certificate for this key? ")) ){ - rc = 0; - goto leave; - } - - if(sk->version>=4 || opt.force_v4_certs) { - /* get the reason for the revocation */ - reason = ask_revocation_reason( 1, 0, 1 ); - if( !reason ) { /* user decided to cancel */ - rc = 0; - goto leave; - } - } - - switch( is_secret_key_protected( sk ) ) { - case -1: - log_error(_("unknown protection algorithm\n")); - rc = GPG_ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf(_("NOTE: This key is not protected!\n")); - break; - default: - rc = check_secret_key( sk, 0 ); - break; - } - if( rc ) - goto leave; - - - if( !opt.armor ) - tty_printf(_("ASCII armored output forced.\n")); - - if( (rc = open_outfile( NULL, 0, &out )) ) - goto leave; - - afx.what = 1; - afx.hdrlines = "Comment: A revocation certificate should follow\n"; - iobuf_push_filter( out, armor_filter, &afx ); - - /* create it */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, - opt.force_v4_certs?4:0, 0, 0, - revocation_reason_build_cb, reason ); - if( rc ) { - log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc)); - goto leave; - } - - if(PGP2 || PGP6 || PGP7 || PGP8) - { - /* Use a minimal pk for PGPx mode, since PGP can't import bare - revocation certificates. */ - rc=export_minimal_pk(out,pub_keyblock,sig,NULL); - if(rc) - goto leave; - } - else - { - init_packet( &pkt ); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) ); - goto leave; - } - } - - /* and issue a usage notice */ - tty_printf(_("Revocation certificate created.\n\n" -"Please move it to a medium which you can hide away; if Mallory gets\n" -"access to this certificate he can use it to make your key unusable.\n" -"It is smart to print this certificate and store it away, just in case\n" -"your media become unreadable. But have some caution: The print system of\n" -"your machine might store the data and make it available to others!\n")); - - leave: - if( sig ) - free_seckey_enc( sig ); - release_kbnode( keyblock ); - release_kbnode( pub_keyblock ); - keydb_release (kdbhd); - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - release_revocation_reason_info( reason ); - return rc; -} - - - -struct revocation_reason_info * -ask_revocation_reason( int key_rev, int cert_rev, int hint ) -{ - int code=-1; - char *description = NULL; - struct revocation_reason_info *reason; - const char *text_0 = _("No reason specified"); - const char *text_1 = _("Key has been compromised"); - const char *text_2 = _("Key is superseded"); - const char *text_3 = _("Key is no longer used"); - const char *text_4 = _("User ID is no longer valid"); - const char *code_text = NULL; - - do { - code=-1; - xfree (description); - description = NULL; - - tty_printf(_("Please select the reason for the revocation:\n")); - tty_printf( " 0 = %s\n", text_0 ); - if( key_rev ) - tty_printf(" 1 = %s\n", text_1 ); - if( key_rev ) - tty_printf(" 2 = %s\n", text_2 ); - if( key_rev ) - tty_printf(" 3 = %s\n", text_3 ); - if( cert_rev ) - tty_printf(" 4 = %s\n", text_4 ); - tty_printf( " Q = %s\n", _("Cancel") ); - if( hint ) - tty_printf(_("(Probably you want to select %d here)\n"), hint ); - - while(code==-1) { - int n; - char *answer = cpr_get("ask_revocation_reason.code", - _("Your decision? ")); - trim_spaces( answer ); - cpr_kill_prompt(); - if( *answer == 'q' || *answer == 'Q') - return NULL; /* cancel */ - if( hint && !*answer ) - n = hint; - else if(!digitp( answer ) ) - n = -1; - else - n = atoi(answer); - xfree (answer); - if( n == 0 ) { - code = 0x00; /* no particular reason */ - code_text = text_0; - } - else if( key_rev && n == 1 ) { - code = 0x02; /* key has been compromised */ - code_text = text_1; - } - else if( key_rev && n == 2 ) { - code = 0x01; /* key is superseded */ - code_text = text_2; - } - else if( key_rev && n == 3 ) { - code = 0x03; /* key is no longer used */ - code_text = text_3; - } - else if( cert_rev && n == 4 ) { - code = 0x20; /* uid is no longer valid */ - code_text = text_4; - } - else - tty_printf(_("Invalid selection.\n")); - } - - tty_printf(_("Enter an optional description; " - "end it with an empty line:\n") ); - for(;;) { - char *answer = cpr_get("ask_revocation_reason.text", "> " ); - trim_trailing_ws( answer, strlen(answer) ); - cpr_kill_prompt(); - if( !*answer ) { - xfree (answer); - break; - } - - { - char *p = make_printable_string( answer, strlen(answer), 0 ); - xfree (answer); - answer = p; - } - - if( !description ) - description = xstrdup (answer); - else { - char *p = xmalloc ( strlen(description) + strlen(answer) + 2 ); - strcpy(stpcpy(stpcpy( p, description),"\n"),answer); - xfree (description); - description = p; - } - xfree (answer); - } - - tty_printf(_("Reason for revocation: %s\n"), code_text ); - if( !description ) - tty_printf(_("(No description given)\n") ); - else - tty_printf("%s\n", description ); - - } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay", - _("Is this okay? ")) ); - - reason = xmalloc ( sizeof *reason ); - reason->code = code; - reason->desc = description; - return reason; -} - -void -release_revocation_reason_info( struct revocation_reason_info *reason ) -{ - if( reason ) { - xfree ( reason->desc ); - xfree ( reason ); - } -} diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c deleted file mode 100644 index 7356cb224..000000000 --- a/g10/seckey-cert.c +++ /dev/null @@ -1,452 +0,0 @@ -/* seckey-cert.c - secret key certificate packet handling - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "memory.h" -#include "packet.h" -#include "mpi.h" -#include "keydb.h" -#include "cipher.h" -#include "main.h" -#include "options.h" -#include "i18n.h" -#include "status.h" -#include "pkglue.h" - -static int -do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, - int *canceled ) -{ - byte *buffer; - u16 csum=0; - int i, res; - unsigned nbytes; - gpg_error_t rc; - - if( sk->is_protected ) { /* remove the protection */ - DEK *dek = NULL; - u32 keyid[4]; /* 4! because we need two of them */ - CIPHER_HANDLE cipher_hd=NULL; - PKT_secret_key *save_sk; - - if( sk->protect.s2k.mode == 1001 ) { - log_info(_("secret key parts are not available\n")); - return GPG_ERR_GENERAL; - } - if( sk->protect.algo == CIPHER_ALGO_NONE ) - BUG(); - if( openpgp_cipher_test_algo( sk->protect.algo ) ) { - log_info(_("protection algorithm %d%s is not supported\n"), - sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" ); - if (sk->protect.algo==CIPHER_ALGO_IDEA) - { - write_status (STATUS_RSA_OR_IDEA); - idea_cipher_warn (0); - } - return GPG_ERR_CIPHER_ALGO; - } - keyid_from_sk( sk, keyid ); - keyid[2] = keyid[3] = 0; - if( !sk->is_primary ) { - keyid[2] = sk->main_keyid[0]; - keyid[3] = sk->main_keyid[1]; - } - dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo, - &sk->protect.s2k, mode, - tryagain_text, canceled ); - if (!dek && canceled && *canceled) - return GPG_ERR_GENERAL; - - rc = gcry_cipher_open (&cipher_hd, sk->protect.algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | (sk->protect.algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC)); - if (rc) - log_fatal ("cipher open failed: %s\n", gpg_strerror (rc) ); - - rc = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen); - if (rc) - log_fatal ("set key failed: %s\n", gpg_strerror (rc) ); - - xfree (dek); - save_sk = copy_secret_key( NULL, sk ); - gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen); - csum = 0; - if( sk->version >= 4 ) { - int ndata; - unsigned int ndatabits; - byte *p, *data; - u16 csumc = 0; - - i = pubkey_get_npkey(sk->pubkey_algo); - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE )); - p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits ); - ndata = (ndatabits+7)/8; - if ( ndata > 1 ) - csumc = p[ndata-2] << 8 | p[ndata-1]; - data = gcry_xmalloc_secure ( ndata ); - gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata ); - gcry_mpi_release ( sk->skey[i] ); sk->skey[i] = NULL ; - p = data; - if (sk->protect.sha1chk) { - /* This is the new SHA1 checksum method to detect - tampering with the key as used by the Klima/Rosa - attack */ - sk->csum = 0; - csum = 1; - if( ndata < 20 ) - log_error("not enough bytes for SHA-1 checksum\n"); - else { - gcry_md_hd_t h; - - if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1)) - BUG(); /* algo not available */ - gcry_md_write (h, data, ndata - 20); - gcry_md_final (h); - if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1), - data + ndata - 20, 20) ) { - /* digest does match. We have to keep the old - style checksum in sk->csum, so that the - test used for unprotected keys does work. - This test gets used when we are adding new - keys. */ - sk->csum = csum = checksum (data, ndata-20); - } - gcry_md_close (h); - } - } - else { - if( ndata < 2 ) { - log_error("not enough bytes for checksum\n"); - sk->csum = 0; - csum = 1; - } - else { - csum = checksum( data, ndata-2); - sk->csum = data[ndata-2] << 8 | data[ndata-1]; - if ( sk->csum != csum ) { - /* This is a PGP 7.0.0 workaround */ - sk->csum = csumc; /* take the encrypted one */ - } - } - } - - /* must check it here otherwise the mpi_read_xx would fail - because the length may have an arbitrary value */ - if( sk->csum == csum ) { - for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - assert( gcry_is_secure( p ) ); - res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP, - p, ndata, &nbytes); - if( res ) - log_bug ("gcry_mpi_scan failed in do_check: %s\n", - gpg_strerror (res)); - ndata -= nbytes; - p += nbytes; - } - /* Note: at this point ndata should be 2 for a simple - checksum or 20 for the sha1 digest */ - } - xfree (data); - } - else { - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - byte *p; - int ndata; - unsigned int ndatabits; - - assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE)); - p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits ); - ndata = (ndatabits+7)/8; - assert (ndata >= 2); - assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2); - buffer = gcry_xmalloc_secure (ndata); - gcry_cipher_sync (cipher_hd); - buffer[0] = p[0]; - buffer[1] = p[1]; - gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, - p+2, ndata-2); - csum += checksum (buffer, ndata); - gcry_mpi_release (sk->skey[i]); - res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG, - buffer, ndata, &ndata ); - if( res ) - log_bug ("gcry_mpi_scan failed in do_check: %s\n", - gpg_strerror (res)); - - assert (sk->skey[i]); - xfree (buffer); -/* csum += checksum_mpi (sk->skey[i]); */ - } - } - gcry_cipher_close (cipher_hd); - /* now let's see whether we have used the right passphrase */ - if( csum != sk->csum ) { - copy_secret_key( sk, save_sk ); - passphrase_clear_cache ( keyid, sk->pubkey_algo ); - free_secret_key( save_sk ); - return gpg_error (GPG_ERR_BAD_PASSPHRASE); - } - /* the checksum may fail, so we also check the key itself */ - res = pk_check_secret_key (sk->pubkey_algo, sk->skey); - if (res) { - copy_secret_key( sk, save_sk ); - passphrase_clear_cache ( keyid, sk->pubkey_algo ); - free_secret_key( save_sk ); - return gpg_error (GPG_ERR_BAD_PASSPHRASE); - } - free_secret_key( save_sk ); - sk->is_protected = 0; - } - else { /* not protected, assume it is okay if the checksum is okay */ - csum = 0; - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - csum += checksum_mpi( sk->skey[i] ); - } - if( csum != sk->csum ) - return GPG_ERR_CHECKSUM; - } - - return 0; -} - - - -/**************** - * Check the secret key - * Ask up to 3 (or n) times for a correct passphrase - * If n is negative, disable the key info prompt and make n=abs(n) - */ -int -check_secret_key( PKT_secret_key *sk, int n ) -{ - int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE); - int i,mode; - - if (sk && sk->is_protected && sk->protect.s2k.mode == 1002) - return 0; /* Let the scdaemon handle it. */ - - if(n<0) - { - n=abs(n); - mode=1; - } - else - mode=0; - - if( n < 1 ) - n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */ - - for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) { - int canceled = 0; - const char *tryagain = NULL; - if (i) { - tryagain = N_("Invalid passphrase; please try again"); - log_info (_("%s ...\n"), _(tryagain)); - } - rc = do_check( sk, tryagain, mode, &canceled ); - if( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - && is_status_enabled() ) { - u32 kid[2]; - char buf[50]; - - keyid_from_sk( sk, kid ); - sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]); - write_status_text( STATUS_BAD_PASSPHRASE, buf ); - } - if( have_static_passphrase() || canceled) - break; - } - - if( !rc ) - write_status( STATUS_GOOD_PASSPHRASE ); - - return rc; -} - -/**************** - * check whether the secret key is protected. - * Returns: 0 not protected, -1 on error or the protection algorithm - * -2 indicates a card stub. - */ -int -is_secret_key_protected( PKT_secret_key *sk ) -{ - return sk->is_protected? - sk->protect.s2k.mode == 1002? -2 - : sk->protect.algo : 0; -} - - - -/**************** - * Protect the secret key with the passphrase from DEK - */ -int -protect_secret_key( PKT_secret_key *sk, DEK *dek ) -{ - int i,j, rc = 0; - byte *buffer; - unsigned nbytes; - u16 csum; - - if( !dek ) - return 0; - - if( !sk->is_protected ) { /* okay, apply the protection */ - gcry_cipher_hd_t cipher_hd=NULL; - - if( openpgp_cipher_test_algo( sk->protect.algo ) ) - { - rc = gpg_error (GPG_ERR_CIPHER_ALGO); /* unsupport - protection - algorithm */ - } - else { - print_cipher_algo_note( sk->protect.algo ); - rc = gcry_cipher_open (&cipher_hd, sk->protect.algo, - GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_SECURE - | (sk->protect.algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC) ); - if (rc) - BUG(); - if( gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen ) ) - log_info(_("WARNING: Weak key detected" - " - please change passphrase again.\n")); - sk->protect.ivlen = gcry_cipher_get_algo_blklen(sk->protect.algo); - assert( sk->protect.ivlen <= DIM(sk->protect.iv) ); - if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 ) - BUG(); /* yes, we are very careful */ - gcry_create_nonce (sk->protect.iv, sk->protect.ivlen); - gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen ); - if( sk->version >= 4 ) { - unsigned char *bufarr[PUBKEY_MAX_NSKEY]; - unsigned narr[PUBKEY_MAX_NSKEY]; - unsigned nbits[PUBKEY_MAX_NSKEY]; - int ndata=0; - byte *p, *data; - - for(j=0, i = pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) { - assert( !gcry_mpi_get_flag( sk->skey[i], - GCRYMPI_FLAG_OPAQUE )); - - if( gcry_mpi_aprint( GCRYMPI_FMT_USG, bufarr+j, - narr+j, sk->skey[i])) - BUG(); - - nbits[j] = gcry_mpi_get_nbits( sk->skey[i] ); - ndata += narr[j] + 2; - } - for( ; j < PUBKEY_MAX_NSKEY; j++ ) - bufarr[j] = NULL; - ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */ - - data = xmalloc_secure ( ndata ); - p = data; - for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) { - p[0] = nbits[j] >> 8 ; - p[1] = nbits[j]; - p += 2; - memcpy(p, bufarr[j], narr[j] ); - p += narr[j]; - xfree (bufarr[j]); - } - - if (opt.simple_sk_checksum) { - log_info (_("generating the deprecated 16-bit checksum" - " for secret key protection\n")); - csum = checksum( data, ndata-2); - sk->csum = csum; - *p++ = csum >> 8; - *p++ = csum; - sk->protect.sha1chk = 0; - } - else { - gcry_md_hd_t h; - - if (gcry_md_open (&h, GCRY_MD_SHA1, 1)) - BUG(); /* algo not available */ - gcry_md_write (h, data, ndata - 20); - gcry_md_final (h); - memcpy (p, gcry_md_read (h, GCRY_MD_SHA1), 20); - p += 20; - gcry_md_close (h); - sk->csum = csum = 0; - sk->protect.sha1chk = 1; - } - assert( p == data+ndata ); - - gcry_cipher_encrypt( cipher_hd, data, ndata, NULL, 0 ); - for(i = pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - gcry_mpi_release ( sk->skey[i] ); - sk->skey[i] = NULL; - } - i = pubkey_get_npkey(sk->pubkey_algo); - sk->skey[i] = gcry_mpi_set_opaque(NULL, data, ndata*8); - } - else { - csum = 0; - for(i=pubkey_get_npkey(sk->pubkey_algo); - i < pubkey_get_nskey(sk->pubkey_algo); i++ ) { - byte *data; - unsigned int nbits; - - csum += checksum_mpi (sk->skey[i]); - if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &buffer, - &nbytes, sk->skey[i] ) ) - BUG(); - gcry_cipher_sync (cipher_hd); - assert (!gcry_mpi_get_flag( sk->skey[i], - GCRYMPI_FLAG_OPAQUE )); - data = xmalloc (nbytes+2); - nbits = gcry_mpi_get_nbits (sk->skey[i]); - assert (nbytes == (nbits + 7)/8); - data[0] = nbits >> 8; - data[1] = nbits; - gcry_cipher_encrypt (cipher_hd, data+2, nbytes, - buffer, nbytes); - xfree ( buffer ); - - gcry_mpi_release (sk->skey[i]); - sk->skey[i] = gcry_mpi_set_opaque (NULL, data, - (nbytes+2)*8); - } - sk->csum = csum; - } - sk->is_protected = 1; - gcry_cipher_close( cipher_hd ); - } - } - return rc; -} diff --git a/g10/seskey.c b/g10/seskey.c deleted file mode 100644 index be2535ace..000000000 --- a/g10/seskey.c +++ /dev/null @@ -1,244 +0,0 @@ -/* seskey.c - make sesssion keys etc. - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "cipher.h" -#include "mpi.h" -#include "main.h" -#include "i18n.h" -#include "options.h" - -/**************** - * Make a session key and put it into DEK - */ -void -make_session_key( DEK *dek ) -{ - gcry_cipher_hd_t chd; - int i, rc; - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - - if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB, - (GCRY_CIPHER_SECURE - | (dek->algo >= 100 ? - 0 : GCRY_CIPHER_ENABLE_SYNC))) ) - BUG(); - - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - for (i=0; i < 16; i++ ) - { - rc = gcry_cipher_setkey (chd, dek->key, dek->keylen); - if (!rc) - { - gcry_cipher_close (chd); - return; - } - if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY) - BUG(); - log_info (_("weak key created - retrying\n") ); - /* Renew the session key until we get a non-weak key. */ - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - } - - log_fatal (_("cannot avoid weak key for symmetric cipher; " - "tried %d times!\n"), i); -} - - -/**************** - * Encode the session key. NBITS is the number of bits which should be used - * for packing the session key. - * returns: A mpi with the session key (caller must free) - */ -gcry_mpi_t -encode_session_key (DEK *dek, unsigned int nbits) -{ - int nframe = (nbits+7) / 8; - byte *p; - byte *frame; - int i,n; - u16 csum; - gcry_mpi_t a; - - /* the current limitation is that we can only use a session key - * whose length is a multiple of BITS_PER_MPI_LIMB - * I think we can live with that. - */ - if( dek->keylen + 7 > nframe || !nframe ) - log_bug("can't encode a %d bit key in a %d bits frame\n", - dek->keylen*8, nbits ); - - /* We encode the session key in this way: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (But how can we store the leading 0 - the external representaion - * of MPIs doesn't allow leading zeroes =:-) - * - * RND are non-zero random bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) length k depends on the - * cipher algorithm (20 is used with blowfish160). - * CSUM is the 16 bit checksum over the DEK - */ - csum = 0; - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; - - frame = gcry_xmalloc_secure ( nframe ); - n = 0; - frame[n++] = 0; - frame[n++] = 2; - i = nframe - 6 - dek->keylen; - assert( i > 0 ); - p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); - /* replace zero bytes by new values */ - for(;;) { - int j, k; - byte *pp; - - /* count the zero bytes */ - for(j=k=0; j < i; j++ ) - if( !p[j] ) - k++; - if( !k ) - break; /* okay: no zero bytes */ - k += k/128; /* better get some more */ - pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM); - for(j=0; j < i && k ; j++ ) - if( !p[j] ) - p[j] = pp[--k]; - xfree (pp); - } - memcpy( frame+n, p, i ); - xfree (p); - n += i; - frame[n++] = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - assert (n == nframe); - - if (DBG_CIPHER) - log_printhex ("encoded session key:", frame, nframe ); - - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) - BUG(); - xfree (frame); - return a; -} - - -static gcry_mpi_t -do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, - const byte *asn, size_t asnlen, int v3compathack ) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i,n; - gcry_mpi_t a; - - if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); - - /* We encode the MD in this way: - * - * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) - * - * PAD consists of FF bytes. - */ - frame = gcry_md_is_secure (md)? xmalloc_secure (nframe): xmalloc (nframe); - n = 0; - frame[n++] = 0; - frame[n++] = v3compathack? algo : 1; /* block type */ - i = nframe - len - asnlen -3 ; - assert( i > 1 ); - memset( frame+n, 0xff, i ); n += i; - frame[n++] = 0; - memcpy( frame+n, asn, asnlen ); n += asnlen; - memcpy( frame+n, gcry_md_read (md, algo), len ); n += len; - assert( n == nframe ); - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe )) - BUG(); - xfree (frame); - return a; -} - - -/**************** - * Encode a message digest into an MPI. - * v3compathack is used to work around a bug in old GnuPG versions - * which did put the algo identifier inseatd of the block type 1 into - * the encoded value. Setting this flag forces the old behaviour. - */ -gcry_mpi_t -encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo, - unsigned int nbits, int v3compathack ) -{ - int algo = hash_algo? hash_algo : gcry_md_get_algo (md); - gcry_mpi_t frame; - - if (pubkey_algo == GCRY_PK_DSA) - { - size_t n = gcry_md_get_algo_dlen(hash_algo); - if (n != 20) - { - log_error (_("DSA requires the use of a 160 bit hash algorithm\n")); - return NULL; - } - if (gcry_mpi_scan( &frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), n, &n ) ) - BUG(); - } - else - { - gpg_error_t rc; - byte *asn; - size_t asnlen; - - rc = gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, NULL, &asnlen); - if (rc) - log_fatal("can't get OID of algo %d: %s\n", - algo, gpg_strerror (rc)); - asn = xmalloc (asnlen); - if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) ) - BUG(); - frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ), - nbits, asn, asnlen, v3compathack ); - xfree (asn); - } - return frame; -} - - - - - - diff --git a/g10/sig-check.c b/g10/sig-check.c deleted file mode 100644 index b0c89cba3..000000000 --- a/g10/sig-check.c +++ /dev/null @@ -1,575 +0,0 @@ -/* sig-check.c - Check a signature - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "gpg.h" -#include "util.h" -#include "packet.h" -#include "memory.h" -#include "mpi.h" -#include "keydb.h" -#include "cipher.h" -#include "main.h" -#include "status.h" -#include "i18n.h" -#include "options.h" -#include "pkglue.h" - -struct cmp_help_context_s { - PKT_signature *sig; - MD_HANDLE md; -}; - - -static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk); - -/**************** - * Check the signature which is contained in SIG. - * The MD_HANDLE should be currently open, so that this function - * is able to append some data, before finalizing the digest. - */ -int -signature_check( PKT_signature *sig, MD_HANDLE digest ) -{ - return signature_check2( sig, digest, NULL, NULL, NULL, NULL ); -} - -int -signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ) -{ - PKT_public_key *pk = xcalloc (1, sizeof *pk ); - int rc=0; - - /* Sanity check that the md has a context for the hash that the - sig is expecting. This can happen if a onepass sig header does - not match the actual sig, and also if the clearsign "Hash:" - header is missing or does not match the actual sig. */ - - if(!gcry_md_is_enabled (digest,sig->digest_algo)) { - log_info(_("WARNING: signature digest conflict in message\n")); - rc=GPG_ERR_GENERAL; - } - else if( get_pubkey( pk, sig->keyid ) ) - rc = GPG_ERR_NO_PUBKEY; - else if(!pk->is_valid && !pk->is_primary) - rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an - invalid subkey */ - else { - if (r_expiredate) - *r_expiredate = pk->expiredate; - rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk ); - } - - free_public_key( pk ); - - if( !rc && sig->sig_class < 2 && is_status_enabled() ) { - /* This signature id works best with DLP algorithms because - * they use a random parameter for every signature. Instead of - * this sig-id we could have also used the hash of the document - * and the timestamp, but the drawback of this is, that it is - * not possible to sign more than one identical document within - * one second. Some remote batch processing applications might - * like this feature here */ - gcry_md_hd_t md; - u32 a = sig->timestamp; - int i, nsig = pubkey_get_nsig( sig->pubkey_algo ); - byte *p, *buffer; - - gcry_md_open (&md, GCRY_MD_RMD160, 0); - gcry_md_putc( digest, sig->pubkey_algo ); - gcry_md_putc( digest, sig->digest_algo ); - gcry_md_putc( digest, (a >> 24) & 0xff ); - gcry_md_putc( digest, (a >> 16) & 0xff ); - gcry_md_putc( digest, (a >> 8) & 0xff ); - gcry_md_putc( digest, a & 0xff ); - for(i=0; i < nsig; i++ ) { - size_t n; - unsigned char *tmp; - - if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i])) - BUG(); - - gcry_md_write (md, tmp, n); - xfree (tmp); - } - gcry_md_final( md ); - p = make_radix64_string( gcry_md_read( md, 0 ), 20 ); - buffer = xmalloc ( strlen(p) + 60 ); - sprintf( buffer, "%s %s %lu", - p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp ); - write_status_text( STATUS_SIG_ID, buffer ); - xfree (buffer); - xfree (p); - gcry_md_close(md); - } - - return rc; -} - - -static int -do_check_messages( PKT_public_key *pk, PKT_signature *sig, - int *r_expired, int *r_revoked ) -{ - u32 cur_time; - - if (r_expired) - *r_expired = 0; - if (r_revoked) - *r_revoked = 0; - if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info(_("key %08lX: this is a PGP generated " - "ElGamal key which is NOT secure for signatures!\n"), - (ulong)keyid_from_pk(pk,NULL)); - return GPG_ERR_PUBKEY_ALGO; - } - - if( pk->timestamp > sig->timestamp ) { - ulong d = pk->timestamp - sig->timestamp; - log_info( d==1 - ? _("public key %08lX is %lu second newer than the signature\n") - : _("public key %08lX is %lu seconds newer than the signature\n"), - (ulong)keyid_from_pk(pk,NULL),d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */ - } - - cur_time = make_timestamp(); - if( pk->timestamp > cur_time ) { - ulong d = pk->timestamp - cur_time; - log_info( d==1 ? _("key %08lX has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key %08lX has been created %lu seconds " - "in future (time warp or clock problem)\n"), - (ulong)keyid_from_pk(pk,NULL),d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; - } - - if( pk->expiredate && pk->expiredate < cur_time ) { - char buf[11]; - if (opt.verbose) { - u32 tmp_kid[2]; - - keyid_from_pk( pk, tmp_kid ); - log_info(_("NOTE: signature key %08lX expired %s\n"), - (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) ); - } - /* SIGEXPIRED is deprecated. Use KEYEXPIRED. */ - sprintf(buf,"%lu",(ulong)pk->expiredate); - write_status_text(STATUS_KEYEXPIRED,buf); - write_status(STATUS_SIGEXPIRED); - if (r_expired) - *r_expired = 1; - } - - if(pk->is_revoked && r_revoked) - *r_revoked=1; - - return 0; -} - - -static int -do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, - int *r_expired, int *r_revoked, PKT_public_key *ret_pk ) -{ - gcry_mpi_t result = NULL; - int rc=0; - struct cmp_help_context_s ctx; - - if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) ) - return rc; - if( (rc=gcry_md_test_algo(sig->digest_algo)) ) - return rc; - if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) ) - return rc; - - /* make sure the digest algo is enabled (in case of a detached - signature)*/ - gcry_md_enable( digest, sig->digest_algo ); - - /* complete the digest */ - if( sig->version >= 4 ) - gcry_md_putc( digest, sig->version ); - gcry_md_putc( digest, sig->sig_class ); - if( sig->version < 4 ) { - u32 a = sig->timestamp; - gcry_md_putc( digest, (a >> 24) & 0xff ); - gcry_md_putc( digest, (a >> 16) & 0xff ); - gcry_md_putc( digest, (a >> 8) & 0xff ); - gcry_md_putc( digest, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - gcry_md_putc( digest, sig->pubkey_algo ); - gcry_md_putc( digest, sig->digest_algo ); - if( sig->hashed ) { - n = sig->hashed->len; - gcry_md_putc (digest, (n >> 8) ); - gcry_md_putc (digest, n ); - gcry_md_write (digest, sig->hashed->data, n); - n += 6; - } - else { - /* Two octets for the (empty) length of the hashed - section. */ - gcry_md_putc (digest, 0); - gcry_md_putc (digest, 0); - n = 6; - } - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - gcry_md_write( digest, buf, 6 ); - } - gcry_md_final (digest); - - result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), 0 ); - if (!result) - return GPG_ERR_GENERAL; - ctx.sig = sig; - ctx.md = digest; - rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey); - gcry_mpi_release ( result ); - if( (opt.emulate_bugs & EMUBUG_MDENCODE) - && gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE - && is_ELGAMAL(pk->pubkey_algo) ) { - /* In this case we try again because old GnuPG versions didn't encode - * the hash right. There is no problem with DSA however */ - result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), (sig->version < 5) ); - if (!result) - rc = GPG_ERR_GENERAL; - else { - ctx.sig = sig; - ctx.md = digest; - rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey); - } - } - - if( !rc && sig->flags.unknown_critical ) { - log_info(_("assuming bad signature from key %08lX " - "due to an unknown critical bit\n"), - (ulong)keyid_from_pk(pk,NULL)); - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - } - - if(!rc && ret_pk) - copy_public_key(ret_pk,pk); - - return rc; -} - - -static void -hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig ) -{ - PKT_user_id *uid = unode->pkt->pkt.user_id; - - assert( unode->pkt->pkttype == PKT_USER_ID ); - if( uid->attrib_data ) { - if( sig->version >=4 ) { - byte buf[5]; - buf[0] = 0xd1; /* packet of type 17 */ - buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */ - buf[2] = uid->attrib_len >> 16; - buf[3] = uid->attrib_len >> 8; - buf[4] = uid->attrib_len; - gcry_md_write( md, buf, 5 ); - } - gcry_md_write( md, uid->attrib_data, uid->attrib_len ); - } - else { - if( sig->version >=4 ) { - byte buf[5]; - buf[0] = 0xb4; /* indicates a userid packet */ - buf[1] = uid->len >> 24; /* always use 4 length bytes */ - buf[2] = uid->len >> 16; - buf[3] = uid->len >> 8; - buf[4] = uid->len; - gcry_md_write( md, buf, 5 ); - } - gcry_md_write( md, uid->name, uid->len ); - } -} - -static void -cache_sig_result ( PKT_signature *sig, int result ) -{ - if ( !result ) { - sig->flags.checked = 1; - sig->flags.valid = 1; - } - else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) { - sig->flags.checked = 1; - sig->flags.valid = 0; - } - else { - sig->flags.checked = 0; - sig->flags.valid = 0; - } -} - - -/* Check the revocation keys to see if any of them have revoked our - pk. sig is the revocation sig. pk is the key it is on. This code - will need to be modified if gpg ever becomes multi-threaded. Note - that this guarantees that a designated revocation sig will never be - considered valid unless it is actually valid, as well as being - issued by a revocation key in a valid direct signature. Note that - this is written so that a revoked revoker can still issue - revocations: i.e. If A revokes B, but A is revoked, B is still - revoked. I'm not completely convinced this is the proper behavior, - but it matches how PGP does it. -dms */ - -/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not - revoked */ -int -check_revocation_keys(PKT_public_key *pk,PKT_signature *sig) -{ - static int busy=0; - int i,rc=GPG_ERR_GENERAL; - - assert(IS_KEY_REV(sig)); - assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1])); - - if(busy) - { - /* return -1 (i.e. not revoked), but mark the pk as uncacheable - as we don't really know its revocation status until it is - checked directly. */ - - pk->dont_cache=1; - return rc; - } - - busy=1; - - /* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1], - (ulong)sig->keyid[1]); */ - - /* is the issuer of the sig one of our revokers? */ - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - for(i=0;i<pk->numrevkeys;i++) - { - u32 keyid[2]; - - keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid); - - if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1]) - { - gcry_md_hd_t md; - - gcry_md_open (&md, sig->digest_algo,0); - hash_public_key(md,pk); - rc=signature_check(sig,md); - cache_sig_result(sig,rc); - break; - } - } - - busy=0; - - return rc; -} - -/**************** - * check the signature pointed to by NODE. This is a key signature. - * If the function detects a self-signature, it uses the PK from - * ROOT and does not read any public key. - */ -int -check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) -{ - return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL); -} - -/* If check_pk is set, then use it to check the signature in node - rather than getting it from root or the keydb. If ret_pk is set, - fill in the public key that was used to verify the signature. - ret_pk is only meaningful when the verification was successful. */ -/* TODO: add r_revoked here as well. It has the same problems as - r_expiredate and r_expired and the cache. */ -int -check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, - PKT_public_key *ret_pk, int *is_selfsig, - u32 *r_expiredate, int *r_expired ) -{ - MD_HANDLE md; - PKT_public_key *pk; - PKT_signature *sig; - int algo; - int rc; - - if( is_selfsig ) - *is_selfsig = 0; - if( r_expiredate ) - *r_expiredate = 0; - if( r_expired ) - *r_expired = 0; - assert( node->pkt->pkttype == PKT_SIGNATURE ); - assert( root->pkt->pkttype == PKT_PUBLIC_KEY ); - - pk = root->pkt->pkt.public_key; - sig = node->pkt->pkt.signature; - algo = sig->digest_algo; - - /* check whether we have cached the result of a previous signature check.*/ - if ( !opt.no_sig_cache ) { - if (sig->flags.checked) { /*cached status available*/ - if( is_selfsig ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; - } - /* BUG: This is wrong for non-self-sigs. Needs to be the - actual pk */ - if((rc=do_check_messages(pk,sig,r_expired,NULL))) - return rc; - return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE); - } - } - - if( (rc=gcry_md_test_algo(algo)) ) - return rc; - - if( sig->sig_class == 0x20 ) { /* key revocation */ - u32 keyid[2]; - keyid_from_pk( pk, keyid ); - - /* is it a designated revoker? */ - if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1]) - rc=check_revocation_keys(pk,sig); - else - { - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - } - else if( sig->sig_class == 0x28 ) { /* subkey revocation */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); - - if( snode ) { - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (opt.verbose) - log_info (_("key %08lX: no subkey for subkey " - "revocation signature\n"), - (ulong)keyid_from_pk (pk, NULL)); - rc = GPG_ERR_SIG_CLASS; - } - } - else if( sig->sig_class == 0x18 ) { /* key binding */ - KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY ); - - if( snode ) { - if( is_selfsig ) { /* does this make sense????? */ - u32 keyid[2]; /* it should always be a selfsig */ - - keyid_from_pk( pk, keyid ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - *is_selfsig = 1; - } - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_public_key( md, snode->pkt->pkt.public_key ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (opt.verbose) - log_info(_("key %08lX: no subkey for subkey " - "binding signature\n"), - (ulong)keyid_from_pk (pk, NULL)); - rc = GPG_ERR_SIG_CLASS; - } - } - else if( sig->sig_class == 0x1f ) { /* direct key signature */ - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { /* all other classes */ - KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID ); - - if( unode ) { - u32 keyid[2]; - - keyid_from_pk( pk, keyid ); - gcry_md_open (&md, algo, 0 ); - hash_public_key( md, pk ); - hash_uid_node( unode, md, sig ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) - { - if( is_selfsig ) - *is_selfsig = 1; - rc = do_check( pk, sig, md, r_expired, NULL, ret_pk ); - } - else if (check_pk) - rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk); - else - rc = signature_check2( sig, md, r_expiredate, r_expired, - NULL, ret_pk); - - cache_sig_result ( sig, rc ); - gcry_md_close(md); - } - else { - if (!opt.quiet) - log_info ("key %08lX: no user ID for key signature packet " - "of class %02x\n", - (ulong)keyid_from_pk (pk, NULL), sig->sig_class ); - rc = GPG_ERR_SIG_CLASS; - } - } - - return rc; -} diff --git a/g10/sign.c b/g10/sign.c deleted file mode 100644 index cd7615c00..000000000 --- a/g10/sign.c +++ /dev/null @@ -1,1412 +0,0 @@ -/* sign.c - sign data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> /* need sleep() */ - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "filter.h" -#include "ttyio.h" -#include "trustdb.h" -#include "status.h" -#include "i18n.h" -#include "pkglue.h" -#include "call-agent.h" - - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -void __stdcall Sleep(ulong); -#define sleep(a) Sleep((a)*1000) -#else -#define LF "\n" -#endif - -static int recipient_digest_algo=0; - -/**************** - * Create a notation. We assume thIt is assumed that the strings in - * the STRLISTs of the opt struct are already checked to contain only - * printable data and have a valid NAME=VALUE format. - */ -static void -mk_notation_policy_etc( PKT_signature *sig, - PKT_public_key *pk, PKT_secret_key *sk ) -{ - const char *string; - char *s=NULL; - byte *buf; - unsigned n1, n2; - STRLIST nd=NULL,pu=NULL; - struct expando_args args; - - memset(&args,0,sizeof(args)); - args.pk=pk; - args.sk=sk; - - /* It is actually impossible to get here when making a v3 key - signature since keyedit.c:sign_uids will automatically bump a - signature with a notation or policy url up to v4, but it is - good to do these checks anyway. */ - - /* notation data */ - if(IS_SIG(sig) && opt.sig_notation_data) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "signatures\n")); - else - nd=opt.sig_notation_data; - } - else if( IS_CERT(sig) && opt.cert_notation_data ) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "key signatures\n")); - else - nd=opt.cert_notation_data; - } - - for( ; nd; nd = nd->next ) { - char *expanded; - - string = nd->d; - s = strchr( string, '=' ); - if( !s ) - BUG(); /* we have already parsed this */ - n1 = s - string; - s++; - - expanded=pct_expando(s,&args); - if(!expanded) - { - log_error(_("WARNING: unable to %%-expand notation " - "(too large). Using unexpanded.\n")); - expanded=xstrdup (s); - } - - n2 = strlen(expanded); - buf = xmalloc ( 8 + n1 + n2 ); - buf[0] = 0x80; /* human readable */ - buf[1] = buf[2] = buf[3] = 0; - buf[4] = n1 >> 8; - buf[5] = n1; - buf[6] = n2 >> 8; - buf[7] = n2; - memcpy(buf+8, string, n1 ); - memcpy(buf+8+n1, expanded, n2 ); - build_sig_subpkt( sig, SIGSUBPKT_NOTATION - | ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0), - buf, 8+n1+n2 ); - xfree (expanded); - xfree (buf); - } - - /* set policy URL */ - if( IS_SIG(sig) && opt.sig_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 (PGP 2.x style) " - "signatures\n")); - else - pu=opt.sig_policy_url; - } - else if( IS_CERT(sig) && opt.cert_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 key (PGP 2.x style) " - "signatures\n")); - else - pu=opt.cert_policy_url; - } - - for(;pu;pu=pu->next) - { - string = pu->d; - - s=pct_expando(string,&args); - if(!s) - { - log_error(_("WARNING: unable to %%-expand policy url " - "(too large). Using unexpanded.\n")); - s=xstrdup (string); - } - - build_sig_subpkt(sig,SIGSUBPKT_POLICY| - ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0), - s,strlen(s)); - - xfree (s); - } - - /* preferred keyserver URL */ - if( IS_SIG(sig) && opt.sig_keyserver_url ) - { - if(sig->version<4) - log_info (_("can't put a preferred keyserver URL " - "into v3 signatures\n")); - else - pu=opt.sig_keyserver_url; - } - - for(;pu;pu=pu->next) - { - string = pu->d; - - s=pct_expando(string,&args); - if(!s) - { - log_error(_("WARNING: unable to %%-expand preferred keyserver URL" - " (too large). Using unexpanded.\n")); - s=xstrdup(string); - } - - build_sig_subpkt(sig,SIGSUBPKT_PREF_KS| - ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0), - s,strlen(s)); - - xfree(s); - } -} - - -/* - * Helper to hash a user ID packet. - */ -static void -hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid) -{ - if ( sigversion >= 4 ) { - byte buf[5]; - - if(uid->attrib_data) { - buf[0] = 0xd1; /* indicates an attribute packet */ - buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */ - buf[2] = uid->attrib_len >> 16; - buf[3] = uid->attrib_len >> 8; - buf[4] = uid->attrib_len; - } - else { - buf[0] = 0xb4; /* indicates a userid packet */ - buf[1] = uid->len >> 24; /* always use 4 length bytes */ - buf[2] = uid->len >> 16; - buf[3] = uid->len >> 8; - buf[4] = uid->len; - } - gcry_md_write( md, buf, 5 ); - } - - if(uid->attrib_data) - gcry_md_write (md, uid->attrib_data, uid->attrib_len ); - else - gcry_md_write (md, uid->name, uid->len ); -} - - -/* - * Helper to hash some parts from the signature - */ -static void -hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig) -{ - if (sig->version >= 4) - gcry_md_putc (md, sig->version); - gcry_md_putc (md, sig->sig_class); - if (sig->version < 4) { - u32 a = sig->timestamp; - gcry_md_putc (md, (a >> 24) & 0xff ); - gcry_md_putc (md, (a >> 16) & 0xff ); - gcry_md_putc (md, (a >> 8) & 0xff ); - gcry_md_putc (md, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - - gcry_md_putc (md, sig->pubkey_algo); - gcry_md_putc (md, sig->digest_algo); - if (sig->hashed) { - n = sig->hashed->len; - gcry_md_putc (md, (n >> 8) ); - gcry_md_putc (md, n ); - gcry_md_write (md, sig->hashed->data, n ); - n += 6; - } - else { - gcry_md_putc (md, 0); /* always hash the length of the subpacket*/ - gcry_md_putc (md, 0); - n = 6; - } - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - gcry_md_write (md, buf, 6); - } -} - - -static int -do_sign( PKT_secret_key *sk, PKT_signature *sig, - MD_HANDLE md, int digest_algo ) -{ - gcry_mpi_t frame; - byte *dp; - int rc; - - if( sk->timestamp > sig->timestamp ) { - ulong d = sk->timestamp - sig->timestamp; - log_info( d==1 ? _("key has been created %lu second " - "in future (time warp or clock problem)\n") - : _("key has been created %lu seconds " - "in future (time warp or clock problem)\n"), d ); - if( !opt.ignore_time_conflict ) - return GPG_ERR_TIME_CONFLICT; - } - - print_pubkey_algo_note(sk->pubkey_algo); - - if( !digest_algo ) - digest_algo = gcry_md_get_algo(md); - - print_digest_algo_note( digest_algo ); - dp = gcry_md_read ( md, digest_algo ); - sig->digest_algo = digest_algo; - sig->digest_start[0] = dp[0]; - sig->digest_start[1] = dp[1]; - if (sk->is_protected && sk->protect.s2k.mode == 1002) - { /* FIXME: Note that we do only support RSA for now. */ - char *rbuf; - size_t rbuflen; - char *snbuf; - - snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk); - rc = agent_scd_pksign (snbuf, digest_algo, - gcry_md_read (md, digest_algo), - gcry_md_get_algo_dlen (digest_algo), - &rbuf, &rbuflen); - xfree (snbuf); - if (!rc) - { - if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG, - rbuf, rbuflen, NULL)) - BUG (); - } - } - else - { - frame = encode_md_value( sk->pubkey_algo, md, - digest_algo, mpi_get_nbits(sk->skey[0]), 0 ); - if (!frame) - return GPG_ERR_GENERAL; - rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); - gcry_mpi_release (frame); - } - if (!rc && !opt.no_sig_create_check) { - /* check that the signature verification worked and nothing is - * fooling us e.g. by a bug in the signature create - * code or by deliberately introduced faults. */ - PKT_public_key *pk = xcalloc (1,sizeof *pk); - - if( get_pubkey( pk, sig->keyid ) ) - rc = GPG_ERR_NO_PUBKEY; - else { - frame = encode_md_value (pk->pubkey_algo, md, - sig->digest_algo, - mpi_get_nbits(pk->pkey[0]), 0); - if (!frame) - rc = GPG_ERR_GENERAL; - else - rc = pk_verify (pk->pubkey_algo, frame, - sig->data, pk->pkey); - gcry_mpi_release (frame); - } - if (rc) - log_error (_("checking created signature failed: %s\n"), - gpg_strerror (rc)); - free_public_key (pk); - } - if( rc ) - log_error(_("signing failed: %s\n"), gpg_strerror (rc) ); - else { - if( opt.verbose ) { - char *ustr = get_user_id_string_printable (sig->keyid); - log_info(_("%s/%s signature from: \"%s\"\n"), - gcry_pk_algo_name (sk->pubkey_algo), - gcry_md_algo_name (sig->digest_algo), - ustr ); - xfree (ustr); - } - } - return rc; -} - - - -int -complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md ) -{ - int rc=0; - - if( !(rc=check_secret_key( sk, 0 )) ) - rc = do_sign( sk, sig, md, 0 ); - return rc; -} - -static int -hash_for(int pubkey_algo, int packet_version ) -{ - if( opt.def_digest_algo ) - return opt.def_digest_algo; - else if( recipient_digest_algo ) - return recipient_digest_algo; - else if(PGP2 && pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 ) - { - /* Old-style PGP only understands MD5 */ - return DIGEST_ALGO_MD5; - } - else if( pubkey_algo == PUBKEY_ALGO_DSA ) - { - /* We need a 160-bit hash for DSA, so we can't just take the first - in the pref list */ - - if(opt.personal_digest_prefs) - { - prefitem_t *prefs; - - for(prefs=opt.personal_digest_prefs;prefs->type;prefs++) - if(gcry_md_get_algo_dlen (prefs->value) == 20) - return prefs->value; - } - - return DIGEST_ALGO_SHA1; - } - else if( opt.personal_digest_prefs ) - { - /* It's not DSA, so we can use whatever the first hash algorithm - is in the pref list */ - return opt.personal_digest_prefs[0].value; - } - else - return DEFAULT_DIGEST_ALGO; -} - -static int -only_old_style( SK_LIST sk_list ) -{ - SK_LIST sk_rover = NULL; - int old_style = 0; - - /* if there are only old style capable key we use the old sytle */ - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 ) - old_style = 1; - else - return 0; - } - return old_style; -} - - -static void -print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what ) -{ - byte array[MAX_FINGERPRINT_LEN], *p; - char buf[100+MAX_FINGERPRINT_LEN*2]; - size_t i, n; - - sprintf(buf, "%c %d %d %02x %lu ", - what, sig->pubkey_algo, sig->digest_algo, sig->sig_class, - (ulong)sig->timestamp ); - - fingerprint_from_sk( sk, array, &n ); - p = buf + strlen(buf); - for(i=0; i < n ; i++ ) - sprintf(p+2*i, "%02X", array[i] ); - - write_status_text( STATUS_SIG_CREATED, buf ); -} - - -/* - * Loop over the secret certificates in SK_LIST and build the one pass - * signature packets. OpenPGP says that the data should be bracket by - * the onepass-sig and signature-packet; so we build these onepass - * packet here in reverse order - */ -static int -write_onepass_sig_packets (SK_LIST sk_list, iobuf_t out, int sigclass ) -{ - int skcount; - SK_LIST sk_rover; - - for (skcount=0, sk_rover=sk_list; sk_rover; sk_rover = sk_rover->next) - skcount++; - - for (; skcount; skcount--) { - PKT_secret_key *sk; - PKT_onepass_sig *ops; - PACKET pkt; - int i, rc; - - for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - if (++i == skcount) - break; - } - - sk = sk_rover->sk; - ops = xcalloc (1,sizeof *ops); - ops->sig_class = sigclass; - ops->digest_algo = hash_for (sk->pubkey_algo, sk->version); - ops->pubkey_algo = sk->pubkey_algo; - keyid_from_sk (sk, ops->keyid); - ops->last = (skcount == 1); - - init_packet(&pkt); - pkt.pkttype = PKT_ONEPASS_SIG; - pkt.pkt.onepass_sig = ops; - rc = build_packet (out, &pkt); - free_packet (&pkt); - if (rc) { - log_error ("build onepass_sig packet failed: %s\n", - gpg_strerror (rc)); - return rc; - } - } - - return 0; -} - -/* - * Helper to write the plaintext (literal data) packet - */ -static int -write_plaintext_packet (iobuf_t out, iobuf_t inp, const char *fname, int ptmode) -{ - PKT_plaintext *pt = NULL; - u32 filesize; - int rc = 0; - - if (!opt.no_literal) { - if (fname || opt.set_filename) { - char *s = make_basename (opt.set_filename? opt.set_filename - : fname - /*, iobuf_get_real_fname(inp)*/); - pt = xmalloc (sizeof *pt + strlen(s) - 1); - pt->namelen = strlen (s); - memcpy (pt->name, s, pt->namelen); - xfree (s); - } - else { /* no filename */ - pt = xmalloc (sizeof *pt - 1); - pt->namelen = 0; - } - } - - /* try to calculate the length of the data */ - if (fname && *fname && !(*fname=='-' && !fname[1])) { - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info (_("WARNING: `%s' is an empty file\n"), fname); - - /* we can't yet encode the length of very large files, - * so we switch to partial length encoding in this case */ - if (filesize >= IOBUF_FILELENGTH_LIMIT) - filesize = 0; - - /* because the text_filter modifies the length of the - * data, it is not possible to know the used length - * without a double read of the file - to avoid that - * we simple use partial length packets. - */ - if ( ptmode == 't' ) - filesize = 0; - } - else { - filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */ - } - - if (!opt.no_literal) { - PACKET pkt; - - pt->timestamp = make_timestamp (); - pt->mode = ptmode; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - init_packet(&pkt); - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - /*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/ - if( (rc = build_packet (out, &pkt)) ) - log_error ("build_packet(PLAINTEXT) failed: %s\n", - gpg_strerror (rc) ); - pt->buf = NULL; - } - else { - byte copy_buffer[4096]; - int bytes_copied; - - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied) )) { - log_error ("copying input to output failed: %s\n", - gpg_strerror (rc)); - break; - } - wipememory(copy_buffer,4096); /* burn buffer */ - } - /* fixme: it seems that we never freed pt/pkt */ - - return rc; -} - -/* - * Write the signatures from the SK_LIST to OUT. HASH must be a non-finalized - * hash which will not be changes here. - */ -static int -write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash, - int sigclass, u32 timestamp, u32 duration, - int status_letter) -{ - SK_LIST sk_rover; - - /* loop over the secret certificates */ - for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) { - PKT_secret_key *sk; - PKT_signature *sig; - MD_HANDLE md; - int rc; - - sk = sk_rover->sk; - - /* build the signature packet */ - sig = xcalloc (1,sizeof *sig); - if(opt.force_v3_sigs || RFC1991) - sig->version=3; - else if(duration || opt.sig_policy_url - || opt.sig_notation_data || opt.sig_keyserver_url) - sig->version=4; - else - sig->version=sk->version; - keyid_from_sk (sk, sig->keyid); - sig->digest_algo = hash_for (sk->pubkey_algo, sk->version); - sig->pubkey_algo = sk->pubkey_algo; - if(timestamp) - sig->timestamp = timestamp; - else - sig->timestamp = make_timestamp(); - if(duration) - sig->expiredate = sig->timestamp+duration; - sig->sig_class = sigclass; - - gcry_md_copy (&md, hash); - - if (sig->version >= 4) - build_sig_subpkt_from_sig (sig); - mk_notation_policy_etc (sig, NULL, sk); - - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = do_sign( sk, sig, md, hash_for (sig->pubkey_algo, sk->version) ); - gcry_md_close (md); - - if( !rc ) { /* and write it */ - PACKET pkt; - - init_packet(&pkt); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - rc = build_packet (out, &pkt); - if (!rc && is_status_enabled()) { - print_status_sig_created ( sk, sig, status_letter); - } - free_packet (&pkt); - if (rc) - log_error ("build signature packet failed: %s\n", - gpg_strerror (rc) ); - } - if( rc ) - return rc;; - } - - return 0; -} - -/**************** - * Sign the files whose names are in FILENAME. - * If DETACHED has the value true, - * make a detached signature. If FILENAMES->d is NULL read from stdin - * and ignore the detached mode. Sign the file with all secret keys - * which can be taken from LOCUSR, if this is NULL, use the default one - * If ENCRYPTFLAG is true, use REMUSER (or ask if it is NULL) to encrypt the - * signed data for these users. - * If OUTFILE is not NULL; this file is used for output and the function - * does not ask for overwrite permission; output is then always - * uncompressed, non-armored and in binary mode. - */ -int -sign_file( STRLIST filenames, int detached, STRLIST locusr, - int encryptflag, STRLIST remusr, const char *outfile ) -{ - const char *fname; - armor_filter_context_t afx; - compress_filter_context_t zfx; - md_filter_context_t mfx; - text_filter_context_t tfx; - progress_filter_context_t pfx; - encrypt_filter_context_t efx; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - int rc = 0; - PK_LIST pk_list = NULL; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int multifile = 0; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &mfx, 0, sizeof mfx); - memset( &efx, 0, sizeof efx); - init_packet( &pkt ); - - if( filenames ) { - fname = filenames->d; - multifile = !!filenames->next; - } - else - fname = NULL; - - if( fname && filenames->next && (!detached || encryptflag) ) - log_bug("multiple files can only be detached signed"); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) - goto leave; - - if(PGP2 && !only_old_style(sk_list)) - { - log_info(_("you can only detach-sign with PGP 2.x style keys " - "while in --pgp2 mode\n")); - compliance_failure(); - } - - if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC ))) - goto leave; - - /* prepare iobufs */ - if( multifile ) /* have list of filenames */ - inp = NULL; /* we do it later */ - else { - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - - handle_progress (&pfx, inp, fname); - } - - if( outfile ) { - if( !(out = iobuf_create( outfile )) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't create %s: %s\n"), outfile, strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), outfile ); - } - else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out ))) - goto leave; - - /* prepare to calculate the MD over the input */ - if( opt.textmode && !outfile && !multifile ) - { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( inp, text_filter, &tfx ); - } - - gcry_md_open (&mfx.md, 0, 0); - - /* If we're encrypting and signing, it is reasonable to pick the - hash algorithm to use out of the recepient key prefs. */ - if(pk_list) - { - if(opt.def_digest_algo) - { - if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_HASH, - opt.def_digest_algo, - NULL)!=opt.def_digest_algo) - log_info(_("forcing digest algorithm %s (%d) " - "violates recipient preferences\n"), - gcry_md_algo_name (opt.def_digest_algo), - opt.def_digest_algo); - } - else - { - int hashlen=0,algo; - - /* Of course, if the recipient asks for something - unreasonable (like a non-160-bit hash for DSA, for - example), then don't do it. Check all sk's - if any - are DSA, then the hash must be 160-bit. In the future - this can be more complex with different hashes for each - sk, but so long as there is only one signing algorithm - with hash restrictions, this is ok. -dms */ - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) - if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA) - hashlen=20; - - if((algo= - select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1, - hashlen?&hashlen:NULL))>0) - recipient_digest_algo=algo; - } - } - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (mfx.md, hash_for(sk->pubkey_algo, sk->version )); - } - - if( !multifile ) - iobuf_push_filter( inp, md_filter, &mfx ); - - if( detached && !encryptflag && !RFC1991 ) - afx.what = 2; - - if( opt.armor && !outfile ) - iobuf_push_filter( out, armor_filter, &afx ); - - if( encryptflag ) { - efx.pk_list = pk_list; - /* fixme: set efx.cfx.datalen if known */ - iobuf_push_filter( out, encrypt_filter, &efx ); - } - - if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) - { - int compr_algo=opt.def_compress_algo; - - /* If not forced by user */ - if(compr_algo==-1) - { - /* If we're not encrypting, then select_algo_from_prefs - will fail and we'll end up with the default. If we are - encrypting, select_algo_from_prefs cannot fail since - there is an assumed preference for uncompressed data. - Still, if it did fail, we'll also end up with the - default. */ - - if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) - compr_algo=default_compress_algo(); - } - else if(!opt.expert && pk_list - && select_algo_from_prefs(pk_list,PREFTYPE_ZIP, - compr_algo,NULL)!=compr_algo) - log_info(_("forcing compression algorithm %s (%d) " - "violates recipient preferences\n"), - compress_algo_to_string(compr_algo),compr_algo); - - /* algo 0 means no compression */ - if( compr_algo ) - { - zfx.algo = compr_algo; - iobuf_push_filter( out, compress_filter, &zfx ); - } - } - - /* Write the one-pass signature packets if needed */ - if (!detached && !RFC1991) { - rc = write_onepass_sig_packets (sk_list, out, - opt.textmode && !outfile ? 0x01:0x00); - if (rc) - goto leave; - } - - /* setup the inner packet */ - if( detached ) { - if( multifile ) { - STRLIST sl; - - if( opt.verbose ) - log_info(_("signing:") ); - /* must walk reverse trough this list */ - for( sl = strlist_last(filenames); sl; - sl = strlist_prev( filenames, sl ) ) { - if( !(inp = iobuf_open(sl->d)) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open %s: %s\n"), - sl->d, strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, sl->d); - if( opt.verbose ) - fprintf(stderr, " `%s'", sl->d ); - if(opt.textmode) - { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( inp, text_filter, &tfx ); - } - iobuf_push_filter( inp, md_filter, &mfx ); - while( iobuf_get(inp) != -1 ) - ; - iobuf_close(inp); inp = NULL; - } - if( opt.verbose ) - putc( '\n', stderr ); - } - else { - /* read, so that the filter can calculate the digest */ - while( iobuf_get(inp) != -1 ) - ; - } - } - else { - rc = write_plaintext_packet (out, inp, fname, - opt.textmode && !outfile ? 't':'b'); - } - - /* catch errors from above */ - if (rc) - goto leave; - - /* write the signatures */ - rc = write_signature_packets (sk_list, out, mfx.md, - opt.textmode && !outfile? 0x01 : 0x00, - 0, duration, detached ? 'D':'S'); - if( rc ) - goto leave; - - - leave: - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); - if (encryptflag) - write_status( STATUS_END_ENCRYPTION ); - } - iobuf_close(inp); - gcry_md_close ( mfx.md ); - release_sk_list( sk_list ); - release_pk_list( pk_list ); - recipient_digest_algo=0; - return rc; -} - - - -/**************** - * make a clear signature. note that opt.armor is not needed - */ -int -clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) -{ - armor_filter_context_t afx; - progress_filter_context_t pfx; - MD_HANDLE textmd = NULL; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int old_style = RFC1991; - int only_md5 = 0; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - init_packet( &pkt ); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) - goto leave; - - if( !old_style && !duration ) - old_style = only_old_style( sk_list ); - - if(PGP2 && !only_old_style(sk_list)) - { - log_info(_("you can only clearsign with PGP 2.x style keys " - "while in --pgp2 mode\n")); - compliance_failure(); - } - - /* prepare iobufs */ - if( !(inp = iobuf_open(fname)) ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, fname); - - if( outfile ) { - if( !(out = iobuf_create( outfile )) ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't create %s: %s\n"), outfile, strerror(errno) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("writing to `%s'\n"), outfile ); - } - else if( (rc = open_outfile( fname, 1, &out )) ) - goto leave; - - iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF ); - - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - if( hash_for(sk->pubkey_algo, sk->version) == DIGEST_ALGO_MD5 ) - only_md5 = 1; - else { - only_md5 = 0; - break; - } - } - - if( !(old_style && only_md5) ) { - const char *s; - int any = 0; - byte hashs_seen[256]; - - memset( hashs_seen, 0, sizeof hashs_seen ); - iobuf_writestr(out, "Hash: " ); - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - int i = hash_for(sk->pubkey_algo, sk->version); - - if( !hashs_seen[ i & 0xff ] ) { - s = gcry_md_algo_name (i); - if( s ) { - hashs_seen[ i & 0xff ] = 1; - if( any ) - iobuf_put(out, ',' ); - iobuf_writestr(out, s ); - any = 1; - } - } - } - assert(any); - iobuf_writestr(out, LF ); - } - - if( opt.not_dash_escaped ) - iobuf_writestr( out, - "NotDashEscaped: You need GnuPG to verify this message" LF ); - iobuf_writestr(out, LF ); - - gcry_md_open (&textmd, 0, 0); - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (textmd, hash_for(sk->pubkey_algo, sk->version)); - } - if ( DBG_HASHING ) - gcry_md_start_debug ( textmd, "clearsign" ); - copy_clearsig_text( out, inp, textmd, !opt.not_dash_escaped, - opt.escape_from, (old_style && only_md5) ); - /* fixme: check for read errors */ - - /* now write the armor */ - afx.what = 2; - iobuf_push_filter( out, armor_filter, &afx ); - - /* write the signatures */ - rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C'); - if( rc ) - goto leave; - - leave: - if( rc ) - iobuf_cancel(out); - else - iobuf_close(out); - iobuf_close(inp); - gcry_md_close ( textmd ); - release_sk_list( sk_list ); - return rc; -} - -/* - * Sign and conventionally encrypt the given file. - * FIXME: Far too much code is duplicated - revamp the whole file. - */ -int -sign_symencrypt_file (const char *fname, STRLIST locusr) -{ - armor_filter_context_t afx; - progress_filter_context_t pfx; - compress_filter_context_t zfx; - md_filter_context_t mfx; - text_filter_context_t tfx; - cipher_filter_context_t cfx; - iobuf_t inp = NULL, out = NULL; - PACKET pkt; - STRING2KEY *s2k = NULL; - int rc = 0; - SK_LIST sk_list = NULL; - SK_LIST sk_rover = NULL; - int algo; - u32 duration=0; - - memset( &afx, 0, sizeof afx); - memset( &zfx, 0, sizeof zfx); - memset( &mfx, 0, sizeof mfx); - memset( &tfx, 0, sizeof tfx); - memset( &cfx, 0, sizeof cfx); - init_packet( &pkt ); - - if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991) - duration=ask_expire_interval(1); - - rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG); - if (rc) - goto leave; - - /* prepare iobufs */ - inp = iobuf_open(fname); - if( !inp ) { - rc = gpg_error_from_errno (errno); - log_error("can't open %s: %s\n", fname? fname: "[stdin]", - strerror(errno) ); - goto leave; - } - handle_progress (&pfx, inp, fname); - - /* prepare key */ - s2k = xcalloc (1, sizeof *s2k ); - s2k->mode = RFC1991? 0:opt.s2k_mode; - s2k->hash_algo = opt.s2k_digest_algo; - - algo = default_cipher_algo(); - if (!opt.quiet || !opt.batch) - log_info (_("%s encryption will be used\n"), - gcry_cipher_algo_name (algo) ); - cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, NULL); - - if (!cfx.dek || !cfx.dek->keylen) { - rc = gpg_error (GPG_ERR_INV_PASSPHRASE); - log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) ); - goto leave; - } - - /* now create the outfile */ - rc = open_outfile (fname, opt.armor? 1:0, &out); - if (rc) - goto leave; - - /* prepare to calculate the MD over the input */ - if (opt.textmode) - iobuf_push_filter (inp, text_filter, &tfx); - gcry_md_open (&mfx.md, 0, 0); - - for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) { - PKT_secret_key *sk = sk_rover->sk; - gcry_md_enable (mfx.md, hash_for (sk->pubkey_algo, sk->version )); - } - - iobuf_push_filter (inp, md_filter, &mfx); - - /* Push armor output filter */ - if (opt.armor) - iobuf_push_filter (out, armor_filter, &afx); - - /* Write the symmetric key packet */ - /*(current filters: armor)*/ - if (!RFC1991) { - PKT_symkey_enc *enc = xcalloc (1, sizeof *enc ); - enc->version = 4; - enc->cipher_algo = cfx.dek->algo; - enc->s2k = *s2k; - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - if( (rc = build_packet( out, &pkt )) ) - log_error("build symkey packet failed: %s\n", gpg_strerror (rc) ); - xfree (enc); - } - - /* Push the encryption filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); - - /* Push the Zip filter */ - if (opt.compress && default_compress_algo()) - { - zfx.algo = default_compress_algo(); - iobuf_push_filter( out, compress_filter, &zfx ); - } - - /* Write the one-pass signature packets */ - /*(current filters: zip - encrypt - armor)*/ - if (!RFC1991) { - rc = write_onepass_sig_packets (sk_list, out, - opt.textmode? 0x01:0x00); - if (rc) - goto leave; - } - - /* Pipe data through all filters; i.e. write the signed stuff */ - /*(current filters: zip - encrypt - armor)*/ - rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b'); - if (rc) - goto leave; - - /* Write the signatures */ - /*(current filters: zip - encrypt - armor)*/ - rc = write_signature_packets (sk_list, out, mfx.md, - opt.textmode? 0x01 : 0x00, - 0, duration, 'S'); - if( rc ) - goto leave; - - - leave: - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); - write_status( STATUS_END_ENCRYPTION ); - } - iobuf_close(inp); - release_sk_list( sk_list ); - gcry_md_close ( mfx.md ); - xfree (cfx.dek); - xfree (s2k); - return rc; -} - - -/**************** - * Create a signature packet for the given public key certificate and - * the user id and return it in ret_sig. User signature class SIGCLASS - * user-id is not used (and may be NULL if sigclass is 0x20) If - * DIGEST_ALGO is 0 the function selects an appropriate one. - * SIGVERSION gives the minimal required signature packet version; - * this is needed so that special properties like local sign are not - * applied (actually: dropped) when a v3 key is used. TIMESTAMP is - * the timestamp to use for the signature. 0 means "now". */ -int -make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, - PKT_user_id *uid, PKT_public_key *subpk, - PKT_secret_key *sk, - int sigclass, int digest_algo, - int sigversion, u32 timestamp, u32 duration, - int (*mksubpkt)(PKT_signature *, void *), void *opaque - ) -{ - PKT_signature *sig; - int rc=0; - MD_HANDLE md; - - assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F - || sigclass == 0x20 || sigclass == 0x18 - || sigclass == 0x30 || sigclass == 0x28 ); - - if (opt.force_v4_certs) - sigversion = 4; - - if (sigversion < sk->version) - sigversion = sk->version; - - /* If you are making a signature on a v4 key using your v3 key, it - doesn't make sense to generate a v3 sig. After all, no v3-only - PGP implementation could understand the v4 key in the first - place. Note that this implies that a signature on an attribute - uid is usually going to be v4 as well, since they are not - generally found on v3 keys. */ - if (sigversion < pk->version) - sigversion = pk->version; - - if( !digest_algo ) - { - /* Basically, this means use SHA1 always unless it's a v3 RSA - key making a v3 cert (use MD5), or the user specified - something (use whatever they said). They still must use a - 160-bit hash with DSA, or the signature will fail. Note - that this still allows the caller of make_keysig_packet to - override the user setting if it must. */ - - if(opt.cert_digest_algo) - digest_algo=opt.cert_digest_algo; - else if((sk->pubkey_algo==PUBKEY_ALGO_RSA || - sk->pubkey_algo==PUBKEY_ALGO_RSA_S) && - pk->version<4 && sigversion < 4) - digest_algo = DIGEST_ALGO_MD5; - else - digest_algo = DIGEST_ALGO_SHA1; - } - - gcry_md_open (&md, digest_algo, 0 ); - - /* hash the public key certificate and the user id */ - hash_public_key( md, pk ); - if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/ - hash_public_key( md, subpk ); - } - else if( sigclass != 0x1F && sigclass != 0x20 ) { - hash_uid (md, sigversion, uid); - } - /* and make the signature packet */ - sig = xcalloc (1, sizeof *sig ); - sig->version = sigversion; - sig->flags.exportable=1; - sig->flags.revocable=1; - keyid_from_sk( sk, sig->keyid ); - sig->pubkey_algo = sk->pubkey_algo; - sig->digest_algo = digest_algo; - if(timestamp) - sig->timestamp=timestamp; - else - sig->timestamp=make_timestamp(); - if(duration) - sig->expiredate=sig->timestamp+duration; - sig->sig_class = sigclass; - if( sig->version >= 4 ) - build_sig_subpkt_from_sig( sig ); - mk_notation_policy_etc ( sig, pk, sk ); - - /* Crucial that the call to mksubpkt comes LAST before the calls - to finalize the sig as that makes it possible for the mksubpkt - function to get a reliable pointer to the subpacket area. */ - if( sig->version >= 4 && mksubpkt ) - rc = (*mksubpkt)( sig, opaque ); - - if( !rc ) { - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = complete_sig( sig, sk, md ); - } - - gcry_md_close ( md ); - if( rc ) - free_seckey_enc( sig ); - else - *ret_sig = sig; - return rc; -} - - - -/**************** - * Create a new signature packet based on an existing one. - * Only user ID signatures are supported for now. - * TODO: Merge this with make_keysig_packet. - */ -int -update_keysig_packet( PKT_signature **ret_sig, - PKT_signature *orig_sig, - PKT_public_key *pk, - PKT_user_id *uid, - PKT_public_key *subpk, - PKT_secret_key *sk, - int (*mksubpkt)(PKT_signature *, void *), - void *opaque - ) -{ - PKT_signature *sig; - int rc=0; - MD_HANDLE md; - - if ((!orig_sig || !pk || !sk) - || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid) - || (orig_sig->sig_class == 0x18 && !subpk)) - return GPG_ERR_GENERAL; - - gcry_md_open (&md, orig_sig->digest_algo, 0); - - /* hash the public key certificate and the user id */ - hash_public_key( md, pk ); - - if( orig_sig->sig_class == 0x18 ) - hash_public_key( md, subpk ); - else - hash_uid (md, orig_sig->version, uid); - - /* create a new signature packet */ - sig = copy_signature (NULL, orig_sig); - - /* We need to create a new timestamp so that new sig expiration - calculations are done correctly... */ - sig->timestamp=make_timestamp(); - - /* ... but we won't make a timestamp earlier than the existing - one. */ - while(sig->timestamp<=orig_sig->timestamp) - { - sleep(1); - sig->timestamp=make_timestamp(); - } - - /* Note that already expired sigs will remain expired (with a - duration of 0) since build-packet.c:build_sig_subpkt_from_sig - detects this case. */ - - if( sig->version >= 4 ) - { - /* Put the updated timestamp into the sig. Note that this - will automagically lower any sig expiration dates to - correctly correspond to the differences in the timestamps - (i.e. the duration will shrink). */ - build_sig_subpkt_from_sig( sig ); - - if (mksubpkt) - rc = (*mksubpkt)(sig, opaque); - } - - if (!rc) { - hash_sigversion_to_magic (md, sig); - gcry_md_final (md); - - rc = complete_sig( sig, sk, md ); - } - - gcry_md_close (md); - if( rc ) - free_seckey_enc (sig); - else - *ret_sig = sig; - return rc; -} diff --git a/g10/signal.c b/g10/signal.c deleted file mode 100644 index 9f50fbe3a..000000000 --- a/g10/signal.c +++ /dev/null @@ -1,226 +0,0 @@ -/* signal.c - signal handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "ttyio.h" - - -static volatile int caught_fatal_sig = 0; -static volatile int caught_sigusr1 = 0; - -static void -init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) -{ -#ifndef HAVE_DOSISH_SYSTEM -#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION) - struct sigaction oact, nact; - - if (check_ign) { - /* we don't want to change an IGN handler */ - sigaction (sig, NULL, &oact ); - if (oact.sa_handler == SIG_IGN ) - return; - } - - nact.sa_handler = handler; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - sigaction ( sig, &nact, NULL); -#else - RETSIGTYPE (*ohandler)(int); - - ohandler = signal (sig, handler); - if (check_ign && ohandler == SIG_IGN) { - /* Change it back if it was already set to IGN */ - signal (sig, SIG_IGN); - } -#endif -#endif /*!HAVE_DOSISH_SYSTEM*/ -} - -static const char * -get_signal_name( int signum ) -{ -#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG) - return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?"; -#else - return "some signal"; -#endif -} - - -static RETSIGTYPE -got_fatal_signal( int sig ) -{ - const char *s; - - if( caught_fatal_sig ) - raise( sig ); - caught_fatal_sig = 1; - - gcry_control (GCRYCTL_TERM_SECMEM ); - /* better don't transtale these messages */ - write(2, "\n", 1 ); - s = "?" /* FIXME: log_get_name()*/; if( s ) write(2, s, strlen(s) ); - write(2, ": ", 2 ); - s = get_signal_name(sig); write(2, s, strlen(s) ); - write(2, " caught ... exiting\n", 20 ); - - /* reset action to default action and raise signal again */ - init_one_signal (sig, SIG_DFL, 0); - dotlock_remove_lockfiles (); -#ifdef __riscos__ - riscos_close_fds (); -#endif /* __riscos__ */ - raise( sig ); -} - - -static RETSIGTYPE -got_usr_signal( int sig ) -{ - caught_sigusr1 = 1; -} - - -void -init_signals() -{ -#ifndef HAVE_DOSISH_SYSTEM - init_one_signal (SIGINT, got_fatal_signal, 1 ); - init_one_signal (SIGHUP, got_fatal_signal, 1 ); - init_one_signal (SIGTERM, got_fatal_signal, 1 ); - init_one_signal (SIGQUIT, got_fatal_signal, 1 ); - init_one_signal (SIGSEGV, got_fatal_signal, 1 ); - init_one_signal (SIGUSR1, got_usr_signal, 0 ); - init_one_signal (SIGPIPE, SIG_IGN, 0 ); -#endif -} - - -void -pause_on_sigusr( int which ) -{ -#ifndef HAVE_DOSISH_SYSTEM -#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T) - sigset_t mask, oldmask; - - assert( which == 1 ); - sigemptyset( &mask ); - sigaddset( &mask, SIGUSR1 ); - - sigprocmask( SIG_BLOCK, &mask, &oldmask ); - while( !caught_sigusr1 ) - sigsuspend( &oldmask ); - caught_sigusr1 = 0; - sigprocmask( SIG_UNBLOCK, &mask, NULL ); -#else - assert (which == 1); - sighold (SIGUSR1); - while (!caught_sigusr1) - sigpause(SIGUSR1); - caught_sigusr1 = 0; - sigrelse(SIGUSR1); -#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/ -#endif -} - - -static void -do_block( int block ) -{ -#ifndef HAVE_DOSISH_SYSTEM - static int is_blocked; -#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T) - static sigset_t oldmask; - - if( block ) { - sigset_t newmask; - - if( is_blocked ) - log_bug("signals are already blocked\n"); - sigfillset( &newmask ); - sigprocmask( SIG_BLOCK, &newmask, &oldmask ); - is_blocked = 1; - } - else { - if( !is_blocked ) - log_bug("signals are not blocked\n"); - sigprocmask( SIG_SETMASK, &oldmask, NULL ); - is_blocked = 0; - } -#else /*!HAVE_SIGPROCMASK*/ - -#if defined(NSIG) -# define SIGSMAX (NSIG) -#elif defined(MAXSIG) -# define SIGSMAX (MAXSIG+1) -#else -# error "define SIGSMAX to the number of signals on your platform plus one" -#endif - - static void (*disposition[SIGSMAX])(int); - int sig; - - if( block ) { - if( is_blocked ) - log_bug("signals are already blocked\n"); - for (sig=1; sig < SIGSMAX; sig++) { - disposition[sig] = sigset (sig, SIG_HOLD); - } - is_blocked = 1; - } - else { - if( !is_blocked ) - log_bug("signals are not blocked\n"); - for (sig=1; sig < SIGSMAX; sig++) { - sigset (sig, disposition[sig]); - } - is_blocked = 0; - } -#endif /*!HAVE_SIGPROCMASK*/ -#endif /*HAVE_DOSISH_SYSTEM*/ -} - - -void -block_all_signals() -{ - do_block(1); -} - -void -unblock_all_signals() -{ - do_block(0); -} diff --git a/g10/skclist.c b/g10/skclist.c deleted file mode 100644 index 67d9eb2f9..000000000 --- a/g10/skclist.c +++ /dev/null @@ -1,176 +0,0 @@ -/* skclist.c - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cipher.h" - - -void -release_sk_list( SK_LIST sk_list ) -{ - SK_LIST sk_rover; - - for( ; sk_list; sk_list = sk_rover ) { - sk_rover = sk_list->next; - free_secret_key( sk_list->sk ); - xfree ( sk_list ); - } -} - - - -static int -key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk) -{ - for (; sk_list; sk_list = sk_list->next) { - if ( !cmp_secret_keys(sk_list->sk, sk) ) - return 0; - } - return -1; -} - -static int -is_duplicated_entry (STRLIST list, STRLIST item) -{ - for(; list && list != item; list = list->next) { - if ( !strcmp (list->d, item->d) ) - return 1; - } - return 0; -} - - -int -build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, - int unlock, unsigned int use ) -{ - SK_LIST sk_list = NULL; - int rc; - - if( !locusr ) { /* use the default one */ - PKT_secret_key *sk; - - sk = xcalloc (1, sizeof *sk ); - sk->req_usage = use; - if( (rc = get_seckey_byname( sk, NULL, unlock )) ) { - free_secret_key( sk ); sk = NULL; - log_error("no default secret key: %s\n", gpg_strerror (rc) ); - } - else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) { - SK_LIST r; - - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info("this is a PGP generated " - "ElGamal key which is NOT secure for signatures!\n"); - free_secret_key( sk ); sk = NULL; - } - else { - r = xmalloc ( sizeof *r ); - r->sk = sk; sk = NULL; - r->next = sk_list; - r->mark = 0; - sk_list = r; - } - } - else { - free_secret_key( sk ); sk = NULL; - log_error("invalid default secret key: %s\n", gpg_strerror (rc) ); - } - } - else { - STRLIST locusr_orig = locusr; - for(; locusr; locusr = locusr->next ) { - PKT_secret_key *sk; - - rc = 0; - /* Do an early check agains duplicated entries. However this - * won't catch all duplicates because the user IDs may be - * specified in different ways. - */ - if ( is_duplicated_entry ( locusr_orig, locusr ) ) { - log_error(_("skipped `%s': duplicated\n"), locusr->d ); - continue; - } - sk = xcalloc (1, sizeof *sk ); - sk->req_usage = use; - if( (rc = get_seckey_byname( sk, locusr->d, 0 )) ) { - free_secret_key( sk ); sk = NULL; - log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) ); - } - else if ( key_present_in_sk_list(sk_list, sk) == 0) { - free_secret_key(sk); sk = NULL; - log_info(_("skipped: secret key already present\n")); - } - else if ( unlock && (rc = check_secret_key( sk, 0 )) ) { - free_secret_key( sk ); sk = NULL; - log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) ); - } - else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) { - SK_LIST r; - - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info(_("skipped `%s': this is a PGP generated " - "ElGamal key which is not secure for signatures!\n"), - locusr->d ); - free_secret_key( sk ); sk = NULL; - } - else { - r = xmalloc ( sizeof *r ); - r->sk = sk; sk = NULL; - r->next = sk_list; - r->mark = 0; - sk_list = r; - } - } - else { - free_secret_key( sk ); sk = NULL; - log_error("skipped `%s': %s\n", locusr->d, gpg_strerror (rc) ); - } - } - } - - - if( !rc && !sk_list ) { - log_error("no valid signators\n"); - rc = GPG_ERR_NO_USER_ID; - } - - if( rc ) - release_sk_list( sk_list ); - else - *ret_sk_list = sk_list; - return rc; -} - diff --git a/g10/status.c b/g10/status.c deleted file mode 100644 index aa55020be..000000000 --- a/g10/status.c +++ /dev/null @@ -1,472 +0,0 @@ -/* status.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> - -#include "gpg.h" -#include "util.h" -#include "status.h" -#include "ttyio.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "cipher.h" /* for progress functions */ - -#define CONTROL_D ('D' - 'A' + 1) - - - -static FILE *statusfp; - - -static void -progress_cb (void *ctx, const char *what, int printchar, int current, int total) -{ - char buf[150]; - - if (printchar == '\n') - printchar = 'X'; - - sprintf (buf, "%.20s %c %d %d", what, printchar, current, total); - write_status_text (STATUS_PROGRESS, buf); -} - -static const char * -get_status_string ( int no ) -{ - const char *s; - - switch( no ) { - case STATUS_ENTER : s = "ENTER"; break; - case STATUS_LEAVE : s = "LEAVE"; break; - case STATUS_ABORT : s = "ABORT"; break; - case STATUS_GOODSIG: s = "GOODSIG"; break; - case STATUS_KEYEXPIRED: s = "KEYEXPIRED"; break; - case STATUS_KEYREVOKED: s = "KEYREVOKED"; break; - case STATUS_BADSIG : s = "BADSIG"; break; - case STATUS_ERRSIG : s = "ERRSIG"; break; - case STATUS_BADARMOR : s = "BADARMOR"; break; - case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break; - case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break; - case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break; - case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break; - case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break; - case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break; - case STATUS_GET_BOOL : s = "GET_BOOL"; break; - case STATUS_GET_LINE : s = "GET_LINE"; break; - case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break; - case STATUS_GOT_IT : s = "GOT_IT"; break; - case STATUS_SHM_INFO : s = "SHM_INFO"; break; - case STATUS_SHM_GET : s = "SHM_GET"; break; - case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break; - case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break; - case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break; - case STATUS_VALIDSIG : s = "VALIDSIG"; break; - case STATUS_SIG_ID : s = "SIG_ID"; break; - case STATUS_ENC_TO : s = "ENC_TO"; break; - case STATUS_NODATA : s = "NODATA"; break; - case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break; - case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break; - case STATUS_NO_SECKEY : s = "NO_SECKEY"; break; - case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break; - case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break; - case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break; - case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break; - case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break; - case STATUS_GOODMDC : s = "GOODMDC"; break; - case STATUS_BADMDC : s = "BADMDC"; break; - case STATUS_ERRMDC : s = "ERRMDC"; break; - case STATUS_IMPORTED : s = "IMPORTED"; break; - case STATUS_IMPORT_OK : s = "IMPORT_OK"; break; - case STATUS_IMPORT_CHECK : s = "IMPORT_CHECK"; break; - case STATUS_IMPORT_RES : s = "IMPORT_RES"; break; - case STATUS_FILE_START : s = "FILE_START"; break; - case STATUS_FILE_DONE : s = "FILE_DONE"; break; - case STATUS_FILE_ERROR : s = "FILE_ERROR"; break; - case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break; - case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break; - case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break; - case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break; - case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break; - case STATUS_PROGRESS : s = "PROGRESS"; break; - case STATUS_SIG_CREATED : s = "SIG_CREATED"; break; - case STATUS_SESSION_KEY : s = "SESSION_KEY"; break; - case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break; - case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break; - case STATUS_POLICY_URL : s = "POLICY_URL" ; break; - case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break; - case STATUS_END_STREAM : s = "END_STREAM"; break; - case STATUS_KEY_CREATED : s = "KEY_CREATED"; break; - case STATUS_USERID_HINT : s = "USERID_HINT"; break; - case STATUS_UNEXPECTED : s = "UNEXPECTED"; break; - case STATUS_INV_RECP : s = "INV_RECP"; break; - case STATUS_NO_RECP : s = "NO_RECP"; break; - case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break; - case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break; - case STATUS_EXPSIG : s = "EXPSIG"; break; - case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; - case STATUS_REVKEYSIG : s = "REVKEYSIG"; break; - case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break; - default: s = "?"; break; - } - return s; -} - -void -set_status_fd ( int fd ) -{ - static int last_fd = -1; - - if ( fd != -1 && last_fd == fd ) - return; - - if ( statusfp && statusfp != stdout && statusfp != stderr ) - fclose (statusfp); - statusfp = NULL; - if ( fd == -1 ) - return; - - if( fd == 1 ) - statusfp = stdout; - else if( fd == 2 ) - statusfp = stderr; - else - statusfp = fdopen( fd, "w" ); - if( !statusfp ) { - log_fatal("can't open fd %d for status output: %s\n", - fd, strerror(errno)); - } - last_fd = fd; - gcry_set_progress_handler (progress_cb, NULL); -} - -int -is_status_enabled() -{ - return !!statusfp; -} - -void -write_status ( int no ) -{ - write_status_text( no, NULL ); -} - -void -write_status_text ( int no, const char *text) -{ - if( !statusfp ) - return; /* not enabled */ - - fputs ( "[GNUPG:] ", statusfp ); - fputs ( get_status_string (no), statusfp ); - if( text ) { - putc ( ' ', statusfp ); - for (; *text; text++) { - if (*text == '\n') - fputs ( "\\n", statusfp ); - else if (*text == '\r') - fputs ( "\\r", statusfp ); - else - putc ( *(const byte *)text, statusfp ); - } - } - putc ('\n',statusfp); - fflush (statusfp); -} - - -/* - * Write a status line with a buffer using %XX escapes. If WRAP is > - * 0 wrap the line after this length. If STRING is not NULL it will - * be prepended to the buffer, no escaping is done for string. - * A wrap of -1 forces spaces not to be encoded as %20. - */ -void -write_status_text_and_buffer ( int no, const char *string, - const char *buffer, size_t len, int wrap ) -{ - const char *s, *text; - int esc, first; - int lower_limit = ' '; - size_t n, count, dowrap; - - if( !statusfp ) - return; /* not enabled */ - - if (wrap == -1) { - lower_limit--; - wrap = 0; - } - - text = get_status_string (no); - count = dowrap = first = 1; - do { - if (dowrap) { - fprintf (statusfp, "[GNUPG:] %s ", text ); - count = dowrap = 0; - if (first && string) { - fputs (string, statusfp); - count += strlen (string); - } - first = 0; - } - for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { - if ( *s == '%' || *(const byte*)s <= lower_limit - || *(const byte*)s == 127 ) - esc = 1; - if ( wrap && ++count > wrap ) { - dowrap=1; - break; - } - } - if (esc) { - s--; n++; - } - if (s != buffer) - fwrite (buffer, s-buffer, 1, statusfp ); - if ( esc ) { - fprintf (statusfp, "%%%02X", *(const byte*)s ); - s++; n--; - } - buffer = s; - len = n; - if ( dowrap && len ) - putc ( '\n', statusfp ); - } while ( len ); - - putc ('\n',statusfp); - fflush (statusfp); -} - -void -write_status_buffer ( int no, const char *buffer, size_t len, int wrap ) -{ - write_status_text_and_buffer (no, NULL, buffer, len, wrap); -} - - - -static int -myread(int fd, void *buf, size_t count) -{ - int rc; - do { - rc = read( fd, buf, count ); - } while ( rc == -1 && errno == EINTR ); - if ( !rc && count ) { - static int eof_emmited=0; - if ( eof_emmited < 3 ) { - *(char*)buf = CONTROL_D; - rc = 1; - eof_emmited++; - } - else { /* Ctrl-D not caught - do something reasonable */ -#ifdef HAVE_DOSISH_SYSTEM - raise (SIGINT); /* nothing to hangup under DOS */ -#else - raise (SIGHUP); /* no more input data */ -#endif - } - } - return rc; -} - - - -/**************** - * Request a string from the client over the command-fd - * If bool, returns static string on true (do not free) or NULL for false - */ -static char * -do_get_from_fd( const char *keyword, int hidden, int bool ) -{ - int i, len; - char *string; - - write_status_text( bool? STATUS_GET_BOOL : - hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword ); - - for( string = NULL, i = len = 200; ; i++ ) { - if( i >= len-1 ) { - char *save = string; - len += 100; - string = hidden? xmalloc_secure ( len ) : xmalloc ( len ); - if( save ) - memcpy(string, save, i ); - else - i=0; - } - /* Hmmm: why not use our read_line function here */ - if( myread( opt.command_fd, string+i, 1) != 1 || string[i] == '\n' ) - break; - else if ( string[i] == CONTROL_D ) { - /* found ETX - cancel the line and return a sole ETX */ - string[0] = CONTROL_D; - i=1; - break; - } - } - string[i] = 0; - - write_status( STATUS_GOT_IT ); - - if( bool ) /* Fixme: is this correct??? */ - return (string[0] == 'Y' || string[0] == 'y') ? "" : NULL; - - return string; -} - - - -int -cpr_enabled() -{ - if( opt.command_fd != -1 ) - return 1; - return 0; -} - -char * -cpr_get_no_help( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 0, 0 ); - for(;;) { - p = tty_get( prompt ); - return p; - } -} - -char * -cpr_get( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 0, 0 ); - for(;;) { - p = tty_get( prompt ); - if( *p=='?' && !p[1] && !(keyword && !*keyword)) { - xfree (p); - display_online_help( keyword ); - } - else - return p; - } -} - - -char * -cpr_get_utf8( const char *keyword, const char *prompt ) -{ - char *p; - p = cpr_get( keyword, prompt ); - if( p ) { - char *utf8 = native_to_utf8( p ); - xfree ( p ); - p = utf8; - } - return p; -} - -char * -cpr_get_hidden( const char *keyword, const char *prompt ) -{ - char *p; - - if( opt.command_fd != -1 ) - return do_get_from_fd ( keyword, 1, 0 ); - for(;;) { - p = tty_get_hidden( prompt ); - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else - return p; - } -} - -void -cpr_kill_prompt(void) -{ - if( opt.command_fd != -1 ) - return; - tty_kill_prompt(); - return; -} - -int -cpr_get_answer_is_yes( const char *keyword, const char *prompt ) -{ - int yes; - char *p; - - if( opt.command_fd != -1 ) - return !!do_get_from_fd ( keyword, 0, 1 ); - for(;;) { - p = tty_get( prompt ); - trim_spaces(p); /* it is okay to do this here */ - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else { - tty_kill_prompt(); - yes = answer_is_yes(p); - xfree (p); - return yes; - } - } -} - -int -cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ) -{ - int yes; - char *p; - - if( opt.command_fd != -1 ) - return !!do_get_from_fd ( keyword, 0, 1 ); - for(;;) { - p = tty_get( prompt ); - trim_spaces(p); /* it is okay to do this here */ - if( *p == '?' && !p[1] ) { - xfree (p); - display_online_help( keyword ); - } - else { - tty_kill_prompt(); - yes = answer_is_yes_no_quit(p); - xfree (p); - return yes; - } - } -} diff --git a/g10/status.h b/g10/status.h deleted file mode 100644 index d8de81080..000000000 --- a/g10/status.h +++ /dev/null @@ -1,124 +0,0 @@ -/* status.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_STATUS_H -#define G10_STATUS_H - - -#define STATUS_ENTER 1 -#define STATUS_LEAVE 2 -#define STATUS_ABORT 3 - -#define STATUS_GOODSIG 4 -#define STATUS_BADSIG 5 -#define STATUS_ERRSIG 6 - - -#define STATUS_BADARMOR 7 - -#define STATUS_RSA_OR_IDEA 8 -#define STATUS_KEYEXPIRED 9 -#define STATUS_KEYREVOKED 10 - -#define STATUS_TRUST_UNDEFINED 11 -#define STATUS_TRUST_NEVER 12 -#define STATUS_TRUST_MARGINAL 13 -#define STATUS_TRUST_FULLY 14 -#define STATUS_TRUST_ULTIMATE 15 - -#define STATUS_SHM_INFO 16 -#define STATUS_SHM_GET 17 -#define STATUS_SHM_GET_BOOL 18 -#define STATUS_SHM_GET_HIDDEN 19 - -#define STATUS_NEED_PASSPHRASE 20 -#define STATUS_VALIDSIG 21 -#define STATUS_SIG_ID 22 -#define STATUS_ENC_TO 23 -#define STATUS_NODATA 24 -#define STATUS_BAD_PASSPHRASE 25 -#define STATUS_NO_PUBKEY 26 -#define STATUS_NO_SECKEY 27 -#define STATUS_NEED_PASSPHRASE_SYM 28 -#define STATUS_DECRYPTION_FAILED 29 -#define STATUS_DECRYPTION_OKAY 30 -#define STATUS_MISSING_PASSPHRASE 31 -#define STATUS_GOOD_PASSPHRASE 32 -#define STATUS_GOODMDC 33 -#define STATUS_BADMDC 34 -#define STATUS_ERRMDC 35 -#define STATUS_IMPORTED 36 -#define STATUS_IMPORT_RES 37 -#define STATUS_FILE_START 38 -#define STATUS_FILE_DONE 39 -#define STATUS_FILE_ERROR 40 - -#define STATUS_BEGIN_DECRYPTION 41 -#define STATUS_END_DECRYPTION 42 -#define STATUS_BEGIN_ENCRYPTION 43 -#define STATUS_END_ENCRYPTION 44 - -#define STATUS_DELETE_PROBLEM 45 -#define STATUS_GET_BOOL 46 -#define STATUS_GET_LINE 47 -#define STATUS_GET_HIDDEN 48 -#define STATUS_GOT_IT 49 -#define STATUS_PROGRESS 50 -#define STATUS_SIG_CREATED 51 -#define STATUS_SESSION_KEY 52 -#define STATUS_NOTATION_NAME 53 -#define STATUS_NOTATION_DATA 54 -#define STATUS_POLICY_URL 55 -#define STATUS_BEGIN_STREAM 56 -#define STATUS_END_STREAM 57 -#define STATUS_KEY_CREATED 58 -#define STATUS_USERID_HINT 59 -#define STATUS_UNEXPECTED 60 -#define STATUS_INV_RECP 61 -#define STATUS_NO_RECP 62 -#define STATUS_ALREADY_SIGNED 63 -#define STATUS_SIGEXPIRED 64 -#define STATUS_EXPSIG 65 -#define STATUS_EXPKEYSIG 66 -#define STATUS_ATTRIBUTE 67 -#define STATUS_IMPORT_OK 68 -#define STATUS_IMPORT_CHECK 69 -#define STATUS_REVKEYSIG 70 - -/*-- status.c --*/ -void set_status_fd ( int fd ); -int is_status_enabled ( void ); -void write_status ( int no ); -void write_status_text ( int no, const char *text ); -void write_status_buffer ( int no, - const char *buffer, size_t len, int wrap ); -void write_status_text_and_buffer ( int no, const char *text, - const char *buffer, size_t len, int wrap ); - -int cpr_enabled(void); -char *cpr_get( const char *keyword, const char *prompt ); -char *cpr_get_no_help( const char *keyword, const char *prompt ); -char *cpr_get_utf8( const char *keyword, const char *prompt ); -char *cpr_get_hidden( const char *keyword, const char *prompt ); -void cpr_kill_prompt(void); -int cpr_get_answer_is_yes( const char *keyword, const char *prompt ); -int cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ); - - -#endif /*G10_STATUS_H*/ diff --git a/g10/tdbdump.c b/g10/tdbdump.c deleted file mode 100644 index 5eb482959..000000000 --- a/g10/tdbdump.c +++ /dev/null @@ -1,223 +0,0 @@ -/* tdbdump.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "trustdb.h" -#include "options.h" -#include "packet.h" -#include "main.h" -#include "i18n.h" -#include "tdbio.h" - - -#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \ - (x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10)) - - -/**************** - * Wirte a record but die on error - */ -static void -write_record( TRUSTREC *rec ) -{ - int rc = tdbio_write_record( rec ); - if( !rc ) - return; - log_error(_("trust record %lu, type %d: write failed: %s\n"), - rec->recnum, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); -} - - -/**************** - * Dump the entire trustdb or only the entries of one key. - */ -void -list_trustdb( const char *username ) -{ - TRUSTREC rec; - - init_trustdb(); - /* for now we ignore the user ID */ - if (1) { - ulong recnum; - int i; - - printf("TrustDB: %s\n", tdbio_get_dbname() ); - for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- ) - putchar('-'); - putchar('\n'); - for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) - tdbio_dump_record( &rec, stdout ); - } -} - - - - - -/**************** - * Print a list of all defined owner trust value. - */ -void -export_ownertrust() -{ - TRUSTREC rec; - ulong recnum; - int i; - byte *p; - - init_trustdb(); - printf(_("# List of assigned trustvalues, created %s\n" - "# (Use \"gpg --import-ownertrust\" to restore them)\n"), - asctimestamp( make_timestamp() ) ); - for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) { - if( rec.rectype == RECTYPE_TRUST ) { - if( !rec.r.trust.ownertrust ) - continue; - p = rec.r.trust.fingerprint; - for(i=0; i < 20; i++, p++ ) - printf("%02X", *p ); - printf(":%u:\n", (unsigned int)rec.r.trust.ownertrust ); - } - } -} - - -void -import_ownertrust( const char *fname ) -{ - FILE *fp; - int is_stdin=0; - char line[256]; - char *p; - size_t n, fprlen; - unsigned int otrust; - byte fpr[20]; - int any = 0; - int rc; - - init_trustdb(); - if( !fname || (*fname == '-' && !fname[1]) ) { - fp = stdin; - fname = "[stdin]"; - is_stdin = 1; - } - else if( !(fp = fopen( fname, "r" )) ) { - log_error ( _("can't open `%s': %s\n"), fname, strerror(errno) ); - return; - } - - while( fgets( line, DIM(line)-1, fp ) ) { - TRUSTREC rec; - - if( !*line || *line == '#' ) - continue; - n = strlen(line); - if( line[n-1] != '\n' ) { - log_error (_("\b%s: line too long\n"), fname ); - /* ... or last line does not have a LF */ - break; /* can't continue */ - } - for(p = line; *p && *p != ':' ; p++ ) - if( !hexdigitp (p) ) - break; - if( *p != ':' ) { - log_error (_("\b%s: error: missing colon\n"), fname ); - continue; - } - fprlen = p - line; - if( fprlen != 32 && fprlen != 40 ) { - log_error (_("\b%s: error: invalid fingerprint\n"), fname ); - continue; - } - if( sscanf(p, ":%u:", &otrust ) != 1 ) { - log_error (_("\b%s: error: no ownertrust value\n"), fname ); - continue; - } - if( !otrust ) - continue; /* no otrust defined - no need to update or insert */ - /* convert the ascii fingerprint to binary */ - for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 ) - fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); - while (fprlen < 20) - fpr[fprlen++] = 0; - - rc = tdbio_search_trust_byfpr (fpr, &rec); - if( !rc ) { /* found: update */ - if (rec.r.trust.ownertrust != otrust) - { - if( rec.r.trust.ownertrust ) - log_info("changing ownertrust from %u to %u\n", - rec.r.trust.ownertrust, otrust ); - else - log_info("setting ownertrust to %u\n", otrust ); - rec.r.trust.ownertrust = otrust; - write_record (&rec ); - any = 1; - } - } - else if( rc == -1 ) { /* not found: insert */ - log_info("inserting ownertrust of %u\n", otrust ); - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - memcpy (rec.r.trust.fingerprint, fpr, 20); - rec.r.trust.ownertrust = otrust; - write_record (&rec ); - any = 1; - } - else /* error */ - log_error (_("\b%s: error finding trust record: %s\n"), - fname, gpg_strerror (rc)); - } - if( ferror(fp) ) - log_error (_("\b%s: read error: %s\n"), fname, strerror(errno) ); - if( !is_stdin ) - fclose(fp); - - if (any) - { - revalidation_mark (); - rc = tdbio_sync (); - if (rc) - log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) ); - } - -} - - diff --git a/g10/tdbio.c b/g10/tdbio.c deleted file mode 100644 index 75687a3b0..000000000 --- a/g10/tdbio.c +++ /dev/null @@ -1,1636 +0,0 @@ -/* tdbio.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "options.h" -#include "main.h" -#include "i18n.h" -#include "trustdb.h" -#include "tdbio.h" - -#if defined(HAVE_DOSISH_SYSTEM) -#define ftruncate chsize -#endif - -#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) -#define MY_O_BINARY O_BINARY -#else -#define MY_O_BINARY 0 -#endif - - -/**************** - * Yes, this is a very simple implementation. We should really - * use a page aligned buffer and read complete pages. - * To implement a simple trannsaction system, this is sufficient. - */ -typedef struct cache_ctrl_struct *CACHE_CTRL; -struct cache_ctrl_struct { - CACHE_CTRL next; - struct { - unsigned used:1; - unsigned dirty:1; - } flags; - ulong recno; - char data[TRUST_RECORD_LEN]; -}; - -#define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */ -#define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */ -static CACHE_CTRL cache_list; -static int cache_entries; -static int cache_is_dirty; - -/* a type used to pass infomation to cmp_krec_fpr */ -struct cmp_krec_fpr_struct { - int pubkey_algo; - const char *fpr; - int fprlen; -}; - -/* a type used to pass infomation to cmp_[s]dir */ -struct cmp_xdir_struct { - int pubkey_algo; - u32 keyid[2]; -}; - - -static char *db_name; -static DOTLOCK lockhandle; -static int is_locked; -static int db_fd = -1; -static int in_transaction; - -static void open_db(void); -static void migrate_from_v2 (void); - - - -/************************************* - ************* record cache ********** - *************************************/ - -/**************** - * Get the data from therecord cache and return a - * pointer into that cache. Caller should copy - * the return data. NULL is returned on a cache miss. - */ -static const char * -get_record_from_cache( ulong recno ) -{ - CACHE_CTRL r; - - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->recno == recno ) - return r->data; - } - return NULL; -} - - -static int -write_cache_item( CACHE_CTRL r ) -{ - int n; - gpg_error_t rc; - - if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: lseek failed: %s\n"), - r->recno, strerror(errno) ); - return rc; - } - n = write( db_fd, r->data, TRUST_RECORD_LEN); - if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"), - r->recno, n, strerror(errno) ); - return rc; - } - r->flags.dirty = 0; - return 0; -} - -/**************** - * Put data into the cache. This function may flush the - * some cache entries if there is not enough space available. - */ -int -put_record_into_cache( ulong recno, const char *data ) -{ - CACHE_CTRL r, unused; - int dirty_count = 0; - int clean_count = 0; - - /* see whether we already cached this one */ - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( !r->flags.used ) { - if( !unused ) - unused = r; - } - else if( r->recno == recno ) { - if( !r->flags.dirty ) { - /* Hmmm: should we use a a copy and compare? */ - if( memcmp(r->data, data, TRUST_RECORD_LEN ) ) { - r->flags.dirty = 1; - cache_is_dirty = 1; - } - } - memcpy( r->data, data, TRUST_RECORD_LEN ); - return 0; - } - if( r->flags.used ) { - if( r->flags.dirty ) - dirty_count++; - else - clean_count++; - } - } - /* not in the cache: add a new entry */ - if( unused ) { /* reuse this entry */ - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* see whether we reached the limit */ - if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */ - r = xmalloc ( sizeof *r ); - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - r->next = cache_list; - cache_list = r; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* cache is full: discard some clean entries */ - if( clean_count ) { - int n = clean_count / 3; /* discard a third of the clean entries */ - if( !n ) - n = 1; - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( r->flags.used && !r->flags.dirty ) { - if( !unused ) - unused = r; - r->flags.used = 0; - cache_entries--; - if( !--n ) - break; - } - } - assert( unused ); - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - /* no clean entries: have to flush some dirty entries */ - if( in_transaction ) { - /* but we can't do this while in a transaction - * we increase the cache size instead */ - if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */ - if( opt.debug && !(cache_entries % 100) ) - log_debug("increasing tdbio cache size\n"); - r = xmalloc ( sizeof *r ); - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - r->next = cache_list; - cache_list = r; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - log_info(_("trustdb transaction too large\n")); - return GPG_ERR_RESOURCE_LIMIT; - } - if( dirty_count ) { - int n = dirty_count / 5; /* discard some dirty entries */ - if( !n ) - n = 1; - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - } - for( unused = NULL, r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - int rc = write_cache_item( r ); - if( rc ) - return rc; - if( !unused ) - unused = r; - r->flags.used = 0; - cache_entries--; - if( !--n ) - break; - } - } - if( !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - assert( unused ); - r = unused; - r->flags.used = 1; - r->recno = recno; - memcpy( r->data, data, TRUST_RECORD_LEN ); - r->flags.dirty = 1; - cache_is_dirty = 1; - cache_entries++; - return 0; - } - BUG(); -} - - -int -tdbio_is_dirty() -{ - return cache_is_dirty; -} - - -/**************** - * Flush the cache. This cannot be used while in a transaction. - */ -int -tdbio_sync() -{ - CACHE_CTRL r; - int did_lock = 0; - - if( db_fd == -1 ) - open_db(); - if( in_transaction ) - log_bug("tdbio: syncing while in transaction\n"); - - if( !cache_is_dirty ) - return 0; - - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - did_lock = 1; - } - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - int rc = write_cache_item( r ); - if( rc ) - return rc; - } - } - cache_is_dirty = 0; - if( did_lock && !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - - return 0; -} - - -#if 0 -/* The transaction code is disabled in the 1.2.x branch, as it is not - yet used. It will be enabled in 1.3.x. */ - -/**************** - * Simple transactions system: - * Everything between begin_transaction and end/cancel_transaction - * is not immediatly written but at the time of end_transaction. - * - */ -int -tdbio_begin_transaction() -{ - int rc; - - if( in_transaction ) - log_bug("tdbio: nested transactions\n"); - /* flush everything out */ - rc = tdbio_sync(); - if( rc ) - return rc; - in_transaction = 1; - return 0; -} - -int -tdbio_end_transaction() -{ - int rc; - - if( !in_transaction ) - log_bug("tdbio: no active transaction\n"); - if( !is_locked ) { - if( make_dotlock( lockhandle, -1 ) ) - log_fatal("can't acquire lock - giving up\n"); - else - is_locked = 1; - } -#warning block_all_signals is not yet available in ../common/signals.c - /* block_all_signals(); */ - in_transaction = 0; - rc = tdbio_sync(); -/* unblock_all_signals(); */ - if( !opt.lock_once ) { - if( !release_dotlock( lockhandle ) ) - is_locked = 0; - } - return rc; -} - -int -tdbio_cancel_transaction() -{ - CACHE_CTRL r; - - if( !in_transaction ) - log_bug("tdbio: no active transaction\n"); - - /* remove all dirty marked entries, so that the original ones - * are read back the next time */ - if( cache_is_dirty ) { - for( r = cache_list; r; r = r->next ) { - if( r->flags.used && r->flags.dirty ) { - r->flags.used = 0; - cache_entries--; - } - } - cache_is_dirty = 0; - } - - in_transaction = 0; - return 0; -} - -#endif /* transaction code */ - - - -/******************************************************** - **************** cached I/O functions ****************** - ********************************************************/ - -static void -cleanup(void) -{ - if( is_locked ) { - if( !release_dotlock(lockhandle) ) - is_locked = 0; - } -} - -/* Caller must sync */ -int -tdbio_update_version_record (void) -{ - TRUSTREC rec; - int rc; - - memset( &rec, 0, sizeof rec ); - - rc=tdbio_read_record( 0, &rec, RECTYPE_VER); - if(rc==0) - { - rec.r.ver.created = make_timestamp(); - rec.r.ver.marginals = opt.marginals_needed; - rec.r.ver.completes = opt.completes_needed; - rec.r.ver.cert_depth = opt.max_cert_depth; - rec.r.ver.trust_model = opt.trust_model; - rc=tdbio_write_record(&rec); - } - - return rc; -} - -static int -create_version_record (void) -{ - TRUSTREC rec; - int rc; - - memset( &rec, 0, sizeof rec ); - rec.r.ver.version = 3; - rec.r.ver.created = make_timestamp(); - rec.r.ver.marginals = opt.marginals_needed; - rec.r.ver.completes = opt.completes_needed; - rec.r.ver.cert_depth = opt.max_cert_depth; - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - rec.r.ver.trust_model = opt.trust_model; - else - rec.r.ver.trust_model = TM_PGP; - rec.rectype = RECTYPE_VER; - rec.recnum = 0; - rc = tdbio_write_record( &rec ); - if( !rc ) - tdbio_sync(); - return rc; -} - - - -int -tdbio_set_dbname( const char *new_dbname, int create ) -{ - char *fname; - static int initialized = 0; - - if( !initialized ) { - atexit( cleanup ); - initialized = 1; - } - - if(new_dbname==NULL) - fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL); - else if (*new_dbname != DIRSEP_C ) - { - if (strchr(new_dbname, DIRSEP_C) ) - fname = make_filename (new_dbname, NULL); - else - fname = make_filename (opt.homedir, new_dbname, NULL); - } - else - fname = xstrdup (new_dbname); - - if( access( fname, R_OK ) ) { - if( errno != ENOENT ) { - log_error( _("%s: can't access: %s\n"), fname, strerror(errno) ); - xfree (fname); - return GPG_ERR_TRUSTDB; - } - if( create ) { - FILE *fp; - TRUSTREC rec; - int rc; - char *p = strrchr( fname, DIRSEP_C ); - mode_t oldmask; - - assert(p); - *p = 0; - if( access( fname, F_OK ) ) { - try_make_homedir( fname ); - log_fatal( _("%s: directory does not exist!\n"), fname ); - } - *p = DIRSEP_C; - - xfree (db_name); - db_name = fname; -#ifdef __riscos__ - if( !lockhandle ) - lockhandle = create_dotlock( db_name ); - if( !lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); - if( make_dotlock( lockhandle, -1 ) ) - log_fatal( _("%s: can't make lock\n"), db_name ); -#endif /* __riscos__ */ - oldmask=umask(077); - fp =fopen( fname, "wb" ); - umask(oldmask); - if( !fp ) - log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) ); - fclose(fp); - db_fd = open( db_name, O_RDWR | MY_O_BINARY ); - if( db_fd == -1 ) - log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); - -#ifndef __riscos__ - if( !lockhandle ) - lockhandle = create_dotlock( db_name ); - if( !lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); -#endif /* !__riscos__ */ - - rc = create_version_record (); - if( rc ) - log_fatal( _("%s: failed to create version record: %s"), - fname, gpg_strerror (rc)); - /* and read again to check that we are okay */ - if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb created\n"), db_name ); - - if( !opt.quiet ) - log_info(_("%s: trustdb created\n"), db_name); - - return 0; - } - } - xfree (db_name); - db_name = fname; - return 0; -} - - -const char * -tdbio_get_dbname() -{ - return db_name; -} - - - -static void -open_db() -{ - byte buf[10]; - int n; - TRUSTREC rec; - - assert( db_fd == -1 ); - - if (!lockhandle ) - lockhandle = create_dotlock( db_name ); - if (!lockhandle ) - log_fatal( _("%s: can't create lock\n"), db_name ); -#ifdef __riscos__ - if (make_dotlock( lockhandle, -1 ) ) - log_fatal( _("%s: can't make lock\n"), db_name ); -#endif /* __riscos__ */ - db_fd = open (db_name, O_RDWR | MY_O_BINARY ); - if (db_fd == -1 && errno == EACCES) { - db_fd = open (db_name, O_RDONLY | MY_O_BINARY ); - if (db_fd != -1) - log_info (_("NOTE: trustdb not writable\n")); - } - if ( db_fd == -1 ) - log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); - - /* check whether we need to do a version migration */ - do - n = read (db_fd, buf, 5); - while (n==-1 && errno == EINTR); - if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5)) - { - migrate_from_v2 (); - } - - /* read the version record */ - if (tdbio_read_record (0, &rec, RECTYPE_VER ) ) - log_fatal( _("%s: invalid trustdb\n"), db_name ); -} - - -/**************** - * Make a hashtable: type 0 = trust hash - */ -static void -create_hashtable( TRUSTREC *vr, int type ) -{ - TRUSTREC rec; - off_t offset; - ulong recnum; - int i, n, rc; - - offset = lseek( db_fd, 0, SEEK_END ); - if( offset == -1 ) - log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) ); - recnum = offset / TRUST_RECORD_LEN; - assert(recnum); /* this is will never be the first record */ - - if( !type ) - vr->r.ver.trusthashtbl = recnum; - - /* Now write the records */ - n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD; - for(i=0; i < n; i++, recnum++ ) { - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HTBL; - rec.recnum = recnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_fatal( _("%s: failed to create hashtable: %s\n"), - db_name, gpg_strerror (rc)); - } - /* update the version record */ - rc = tdbio_write_record( vr ); - if( !rc ) - rc = tdbio_sync(); - if( rc ) - log_fatal( _("%s: error updating version record: %s\n"), - db_name, gpg_strerror (rc)); -} - - -int -tdbio_db_matches_options() -{ - static int yes_no = -1; - - if( yes_no == -1 ) - { - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - yes_no = vr.r.ver.marginals == opt.marginals_needed - && vr.r.ver.completes == opt.completes_needed - && vr.r.ver.cert_depth == opt.max_cert_depth - && vr.r.ver.trust_model == opt.trust_model; - } - - return yes_no; -} - -byte -tdbio_read_model(void) -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - return vr.r.ver.trust_model; -} - -/**************** - * Return the nextstamp value. - */ -ulong -tdbio_read_nextcheck () -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - return vr.r.ver.nextcheck; -} - -/* Return true when the stamp was actually changed. */ -int -tdbio_write_nextcheck (ulong stamp) -{ - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - if (vr.r.ver.nextcheck == stamp) - return 0; - - vr.r.ver.nextcheck = stamp; - rc = tdbio_write_record( &vr ); - if( rc ) - log_fatal( _("%s: error writing version record: %s\n"), - db_name, gpg_strerror (rc) ); - return 1; -} - - - -/**************** - * Return the record number of the trusthash tbl or create a new one. - */ -static ulong -get_trusthashrec(void) -{ - static ulong trusthashtbl; /* record number of the trust hashtable */ - - if( !trusthashtbl ) { - TRUSTREC vr; - int rc; - - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - if( !vr.r.ver.trusthashtbl ) - create_hashtable( &vr, 0 ); - - trusthashtbl = vr.r.ver.trusthashtbl; - } - return trusthashtbl; -} - - - -/**************** - * Update a hashtable. - * table gives the start of the table, key and keylen is the key, - * newrecnum is the record number to insert. - */ -static int -upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum ) -{ - TRUSTREC lastrec, rec; - ulong hashrec, item; - int msb; - int level=0; - int rc, i; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("upd_hashtable in `%s': read failed: %s\n", db_name, - gpg_strerror (rc) ); - return rc; - } - - item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) { /* insert a new item into the hash table */ - rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error ("upd_hashtable in `%s': write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - } - else if( item != newrecnum ) { /* must do an update */ - lastrec = rec; - rc = tdbio_read_record( item, &rec, 0 ); - if( rc ) { - log_error( "upd_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - - if( rec.rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error( "hashtable has invalid indirections.\n"); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - else if( rec.rectype == RECTYPE_HLST ) { /* extend list */ - /* see whether the key is already in this list */ - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec.r.hlst.rnum[i] == newrecnum ) { - return 0; /* okay, already in the list */ - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST); - if( rc ) { - log_error( "upd_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - break; /* not there */ - } - /* find the next free entry and put it in */ - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( !rec.r.hlst.rnum[i] ) { - rec.r.hlst.rnum[i] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error( "upd_hashtable: write hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; /* done */ - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST ); - if( rc ) { - log_error( "upd_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else { /* add a new list record */ - rec.r.hlst.next = item = tdbio_new_recnum(); - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error( "upd_hashtable: write hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HLST; - rec.recnum = item; - rec.r.hlst.rnum[0] = newrecnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error( "upd_hashtable: write ext hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; /* done */ - } - } /* end loop over hlst slots */ - } - else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */ - if( rec.recnum == newrecnum ) { - return 0; - } - item = rec.recnum; /* save number of key record */ - memset( &rec, 0, sizeof rec ); - rec.rectype = RECTYPE_HLST; - rec.recnum = tdbio_new_recnum(); - rec.r.hlst.rnum[0] = item; /* old keyrecord */ - rec.r.hlst.rnum[1] = newrecnum; /* and new one */ - rc = tdbio_write_record( &rec ); - if( rc ) { - log_error( "upd_hashtable: write new hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - /* update the hashtable record */ - lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum; - rc = tdbio_write_record( &lastrec ); - if( rc ) - log_error( "upd_hashtable: update htbl failed: %s\n", - gpg_strerror (rc) ); - return rc; /* ready */ - } - else { - log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n", - table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item); - list_trustdb(NULL); - return GPG_ERR_TRUSTDB; - } - } - - return 0; -} - - -/**************** - * Drop an entry from a hashtable - * table gives the start of the table, key and keylen is the key, - */ -static int -drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum ) -{ - TRUSTREC rec; - ulong hashrec, item; - int msb; - int level=0; - int rc, i; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("drop_from_hashtable `%s': read failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) /* not found - forget about it */ - return 0; - - if( item == recnum ) { /* tables points direct to the record */ - rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0; - rc = tdbio_write_record( &rec ); - if( rc ) - log_error ("drop_from_hashtable `%s': write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - rc = tdbio_read_record( item, &rec, 0 ); - if( rc ) { - log_error( "drop_from_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - - if( rec.rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error( "hashtable has invalid indirections.\n"); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - - if( rec.rectype == RECTYPE_HLST ) { - for(;;) { - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec.r.hlst.rnum[i] == recnum ) { - rec.r.hlst.rnum[i] = 0; /* drop */ - rc = tdbio_write_record( &rec ); - if( rc ) - log_error ("drop_from_hashtable `%s': " - "write htbl failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - } - if( rec.r.hlst.next ) { - rc = tdbio_read_record( rec.r.hlst.next, - &rec, RECTYPE_HLST); - if( rc ) { - log_error( "drop_from_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - return 0; /* key not in table */ - } - } - - log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n", - table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item); - return GPG_ERR_TRUSTDB; -} - - - -/**************** - * Lookup a record via the hashtable tablewith key/keylen and return the - * result in rec. cmp() should return if the record is the desired one. - * Returns -1 if not found, 0 if found or another errocode - */ -static int -lookup_hashtable( ulong table, const byte *key, size_t keylen, - int (*cmpfnc)(void*, const TRUSTREC *), void *cmpdata, - TRUSTREC *rec ) -{ - int rc; - ulong hashrec, item; - int msb; - int level=0; - - hashrec = table; - next_level: - msb = key[level]; - hashrec += msb / ITEMS_PER_HTBL_RECORD; - rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL ); - if( rc ) { - log_error ("lookup_hashtable in `%s' failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - - item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD]; - if( !item ) - return -1; /* not found */ - - rc = tdbio_read_record( item, rec, 0 ); - if( rc ) { - log_error ("hashtable `%s' read failed: %s\n", - db_name, gpg_strerror (rc) ); - return rc; - } - if( rec->rectype == RECTYPE_HTBL ) { - hashrec = item; - level++; - if( level >= keylen ) { - log_error ("hashtable `%s' has invalid indirections\n", db_name); - return GPG_ERR_TRUSTDB; - } - goto next_level; - } - else if( rec->rectype == RECTYPE_HLST ) { - for(;;) { - int i; - - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - if( rec->r.hlst.rnum[i] ) { - TRUSTREC tmp; - - rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 ); - if( rc ) { - log_error( "lookup_hashtable: read item failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - if( (*cmpfnc)( cmpdata, &tmp ) ) { - *rec = tmp; - return 0; - } - } - } - if( rec->r.hlst.next ) { - rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST ); - if( rc ) { - log_error( "lookup_hashtable: read hlst failed: %s\n", - gpg_strerror (rc) ); - return rc; - } - } - else - return -1; /* not found */ - } - } - - - if( (*cmpfnc)( cmpdata, rec ) ) - return 0; /* really found */ - - return -1; /* no: not found */ -} - - -/**************** - * Update the trust hashtbl or create the table if it does not exist - */ -static int -update_trusthashtbl( TRUSTREC *tr ) -{ - return upd_hashtable( get_trusthashrec(), - tr->r.trust.fingerprint, 20, tr->recnum ); -} - - - -void -tdbio_dump_record( TRUSTREC *rec, FILE *fp ) -{ - int i; - ulong rnum = rec->recnum; - - fprintf(fp, "rec %5lu, ", rnum ); - - switch( rec->rectype ) { - case 0: fprintf(fp, "blank\n"); - break; - case RECTYPE_VER: fprintf(fp, - "version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d nc=%lu (%s)\n", - rec->r.ver.trusthashtbl, - rec->r.ver.firstfree, - rec->r.ver.marginals, - rec->r.ver.completes, - rec->r.ver.cert_depth, - rec->r.ver.trust_model, - rec->r.ver.nextcheck, - strtimestamp(rec->r.ver.nextcheck) - ); - break; - case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next ); - break; - case RECTYPE_HTBL: - fprintf(fp, "htbl,"); - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) - fprintf(fp, " %lu", rec->r.htbl.item[i] ); - putc('\n', fp); - break; - case RECTYPE_HLST: - fprintf(fp, "hlst, next=%lu,", rec->r.hlst.next ); - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) - fprintf(fp, " %lu", rec->r.hlst.rnum[i] ); - putc('\n', fp); - break; - case RECTYPE_TRUST: - fprintf(fp, "trust "); - for(i=0; i < 20; i++ ) - fprintf(fp, "%02X", rec->r.trust.fingerprint[i] ); - fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust, - rec->r.trust.depth, rec->r.trust.validlist); - break; - case RECTYPE_VALID: - fprintf(fp, "valid "); - for(i=0; i < 20; i++ ) - fprintf(fp, "%02X", rec->r.valid.namehash[i] ); - fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity, - rec->r.valid.next); - break; - default: - fprintf(fp, "unknown type %d\n", rec->rectype ); - break; - } -} - -/**************** - * read the record with number recnum - * returns: -1 on error, 0 on success - */ -int -tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) -{ - byte readbuf[TRUST_RECORD_LEN]; - const byte *buf, *p; - int rc = 0; - int n, i; - - if( db_fd == -1 ) - open_db(); - buf = get_record_from_cache( recnum ); - if( !buf ) { - if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) ); - return rc; - } - n = read( db_fd, readbuf, TRUST_RECORD_LEN); - if( !n ) { - return -1; /* eof */ - } - else if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb: read failed (n=%d): %s\n"), n, - strerror(errno) ); - return rc; - } - buf = readbuf; - } - rec->recnum = recnum; - rec->dirty = 0; - p = buf; - rec->rectype = *p++; - if( expected && rec->rectype != expected ) { - log_error("%lu: read expected rec type %d, got %d\n", - recnum, expected, rec->rectype ); - return GPG_ERR_TRUSTDB; - } - p++; /* skip reserved byte */ - switch( rec->rectype ) { - case 0: /* unused (free) record */ - break; - case RECTYPE_VER: /* version record */ - if( memcmp(buf+1, "gpg", 3 ) ) { - log_error( _("%s: not a trustdb file\n"), db_name ); - rc = GPG_ERR_TRUSTDB; - } - p += 2; /* skip "gpg" */ - rec->r.ver.version = *p++; - rec->r.ver.marginals = *p++; - rec->r.ver.completes = *p++; - rec->r.ver.cert_depth = *p++; - rec->r.ver.trust_model = *p++; - p += 3; - rec->r.ver.created = buftoulong(p); p += 4; - rec->r.ver.nextcheck = buftoulong(p); p += 4; - p += 4; - p += 4; - rec->r.ver.firstfree =buftoulong(p); p += 4; - p += 4; - rec->r.ver.trusthashtbl =buftoulong(p); p += 4; - if( recnum ) { - log_error( _("%s: version record with recnum %lu\n"), db_name, - (ulong)recnum ); - rc = GPG_ERR_TRUSTDB; - } - else if( rec->r.ver.version != 3 ) { - log_error( _("%s: invalid file version %d\n"), db_name, - rec->r.ver.version ); - rc = GPG_ERR_TRUSTDB; - } - break; - case RECTYPE_FREE: - rec->r.free.next = buftoulong(p); p += 4; - break; - case RECTYPE_HTBL: - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { - rec->r.htbl.item[i] = buftoulong(p); p += 4; - } - break; - case RECTYPE_HLST: - rec->r.hlst.next = buftoulong(p); p += 4; - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - rec->r.hlst.rnum[i] = buftoulong(p); p += 4; - } - break; - case RECTYPE_TRUST: - memcpy( rec->r.trust.fingerprint, p, 20); p+=20; - rec->r.trust.ownertrust = *p++; - rec->r.trust.depth = *p++; - rec->r.trust.min_ownertrust = *p++; - p++; - rec->r.trust.validlist = buftoulong(p); p += 4; - break; - case RECTYPE_VALID: - memcpy( rec->r.valid.namehash, p, 20); p+=20; - rec->r.valid.validity = *p++; - rec->r.valid.next = buftoulong(p); p += 4; - rec->r.valid.full_count = *p++; - rec->r.valid.marginal_count = *p++; - break; - default: - log_error( "%s: invalid record type %d at recnum %lu\n", - db_name, rec->rectype, (ulong)recnum ); - rc = GPG_ERR_TRUSTDB; - break; - } - - return rc; -} - -/**************** - * Write the record at RECNUM - */ -int -tdbio_write_record( TRUSTREC *rec ) -{ - byte buf[TRUST_RECORD_LEN], *p; - int rc = 0; - int i; - ulong recnum = rec->recnum; - - if( db_fd == -1 ) - open_db(); - - memset(buf, 0, TRUST_RECORD_LEN); - p = buf; - *p++ = rec->rectype; p++; - switch( rec->rectype ) { - case 0: /* unused record */ - break; - case RECTYPE_VER: /* version record */ - if( recnum ) - BUG(); - memcpy(p-1, "gpg", 3 ); p += 2; - *p++ = rec->r.ver.version; - *p++ = rec->r.ver.marginals; - *p++ = rec->r.ver.completes; - *p++ = rec->r.ver.cert_depth; - *p++ = rec->r.ver.trust_model; - p += 3; - ulongtobuf(p, rec->r.ver.created); p += 4; - ulongtobuf(p, rec->r.ver.nextcheck); p += 4; - p += 4; - p += 4; - ulongtobuf(p, rec->r.ver.firstfree ); p += 4; - p += 4; - ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4; - break; - - case RECTYPE_FREE: - ulongtobuf(p, rec->r.free.next); p += 4; - break; - - - case RECTYPE_HTBL: - for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { - ulongtobuf( p, rec->r.htbl.item[i]); p += 4; - } - break; - - case RECTYPE_HLST: - ulongtobuf( p, rec->r.hlst.next); p += 4; - for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { - ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4; - } - break; - - case RECTYPE_TRUST: - memcpy( p, rec->r.trust.fingerprint, 20); p += 20; - *p++ = rec->r.trust.ownertrust; - *p++ = rec->r.trust.depth; - *p++ = rec->r.trust.min_ownertrust; - p++; - ulongtobuf( p, rec->r.trust.validlist); p += 4; - break; - - case RECTYPE_VALID: - memcpy( p, rec->r.valid.namehash, 20); p += 20; - *p++ = rec->r.valid.validity; - ulongtobuf( p, rec->r.valid.next); p += 4; - *p++ = rec->r.valid.full_count; - *p++ = rec->r.valid.marginal_count; - break; - - default: - BUG(); - } - - rc = put_record_into_cache( recnum, buf ); - if( rc ) - ; - else if( rec->rectype == RECTYPE_TRUST ) - rc = update_trusthashtbl( rec ); - - return rc; -} - -int -tdbio_delete_record( ulong recnum ) -{ - TRUSTREC vr, rec; - int rc; - - /* Must read the record fist, so we can drop it from the hash tables */ - rc = tdbio_read_record( recnum, &rec, 0 ); - if( rc ) - ; - else if( rec.rectype == RECTYPE_TRUST ) { - rc = drop_from_hashtable( get_trusthashrec(), - rec.r.trust.fingerprint, 20, rec.recnum ); - } - - if( rc ) - return rc; - - /* now we can chnage it to a free record */ - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - - rec.recnum = recnum; - rec.rectype = RECTYPE_FREE; - rec.r.free.next = vr.r.ver.firstfree; - vr.r.ver.firstfree = recnum; - rc = tdbio_write_record( &rec ); - if( !rc ) - rc = tdbio_write_record( &vr ); - return rc; -} - -/**************** - * create a new record and return its record number - */ -ulong -tdbio_new_recnum() -{ - off_t offset; - ulong recnum; - TRUSTREC vr, rec; - int rc; - - /* look for unused records */ - rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); - if( rc ) - log_fatal( _("%s: error reading version record: %s\n"), - db_name, gpg_strerror (rc) ); - if( vr.r.ver.firstfree ) { - recnum = vr.r.ver.firstfree; - rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE ); - if( rc ) { - log_error( _("%s: error reading free record: %s\n"), - db_name, gpg_strerror (rc) ); - return rc; - } - /* update dir record */ - vr.r.ver.firstfree = rec.r.free.next; - rc = tdbio_write_record( &vr ); - if( rc ) { - log_error( _("%s: error writing dir record: %s\n"), - db_name, gpg_strerror (rc) ); - return rc; - } - /*zero out the new record */ - memset( &rec, 0, sizeof rec ); - rec.rectype = 0; /* unused record */ - rec.recnum = recnum; - rc = tdbio_write_record( &rec ); - if( rc ) - log_fatal(_("%s: failed to zero a record: %s\n"), - db_name, gpg_strerror (rc)); - } - else { /* not found, append a new record */ - offset = lseek( db_fd, 0, SEEK_END ); - if( offset == -1 ) - log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) ); - recnum = offset / TRUST_RECORD_LEN; - assert(recnum); /* this is will never be the first record */ - /* we must write a record, so that the next call to this function - * returns another recnum */ - memset( &rec, 0, sizeof rec ); - rec.rectype = 0; /* unused record */ - rec.recnum = recnum; - rc = 0; - if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: lseek failed: %s\n"), - recnum, strerror(errno) ); - } - else { - int n = write( db_fd, &rec, TRUST_RECORD_LEN); - if( n != TRUST_RECORD_LEN ) { - rc = gpg_error_from_errno (errno); - log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"), - recnum, n, strerror(errno) ); - } - } - - if( rc ) - log_fatal(_("%s: failed to append a record: %s\n"), - db_name, gpg_strerror (rc)); - } - return recnum ; -} - - - -static int -cmp_trec_fpr ( void *fpr, const TRUSTREC *rec ) -{ - return rec->rectype == RECTYPE_TRUST - && !memcmp( rec->r.trust.fingerprint, fpr, 20); -} - - -int -tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec ) -{ - int rc; - - /* locate the trust record using the hash table */ - rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20, - cmp_trec_fpr, (void*)fingerprint, rec ); - return rc; -} - -int -tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec) -{ - byte fingerprint[MAX_FINGERPRINT_LEN]; - size_t fingerlen; - - fingerprint_from_pk( pk, fingerprint, &fingerlen ); - for (; fingerlen < 20; fingerlen++ ) - fingerprint[fingerlen] = 0; - return tdbio_search_trust_byfpr (fingerprint, rec); -} - - - -void -tdbio_invalid(void) -{ - log_error(_( - "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") ); - g10_exit(2); -} - -/* - * Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2) - * to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs - * only to scan the tdb and insert new the new trust records. The old ones are - * obsolte from now on - */ -static void -migrate_from_v2 () -{ - TRUSTREC rec; - int i, n; - struct { - ulong keyrecno; - byte ot; - byte okay; - byte fpr[20]; - } *ottable; - int ottable_size, ottable_used; - byte oldbuf[40]; - ulong recno; - int rc, count; - - ottable_size = 5; - ottable = xmalloc (ottable_size * sizeof *ottable); - ottable_used = 0; - - /* We have some restrictions here. We can't use the version record - * and we can't use any of the old hashtables because we dropped the - * code. So we first collect all ownertrusts and then use a second - * pass fo find the associated keys. We have to do this all without using - * the regular record read functions. - */ - - /* get all the ownertrusts */ - if (lseek (db_fd, 0, SEEK_SET ) == -1 ) - log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno)); - for (recno=0;;recno++) - { - do - n = read (db_fd, oldbuf, 40); - while (n==-1 && errno == EINTR); - if (!n) - break; /* eof */ - if (n != 40) - log_fatal ("migrate_vfrom_v2: read error or short read\n"); - - if (*oldbuf != 2) - continue; - - /* v2 dir record */ - if (ottable_used == ottable_size) - { - ottable_size += 1000; - ottable = xrealloc (ottable, ottable_size * sizeof *ottable); - } - ottable[ottable_used].keyrecno = buftoulong (oldbuf+6); - ottable[ottable_used].ot = oldbuf[18]; - ottable[ottable_used].okay = 0; - memset (ottable[ottable_used].fpr,0, 20); - if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot) - ottable_used++; - } - log_info ("found %d ownertrust records\n", ottable_used); - - /* Read again and find the fingerprints */ - if (lseek (db_fd, 0, SEEK_SET ) == -1 ) - log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno)); - for (recno=0;;recno++) - { - do - n = read (db_fd, oldbuf, 40); - while (n==-1 && errno == EINTR); - if (!n) - break; /* eof */ - if (n != 40) - log_fatal ("migrate_from_v2: read error or short read\n"); - - if (*oldbuf != 3) - continue; - - /* v2 key record */ - for (i=0; i < ottable_used; i++) - { - if (ottable[i].keyrecno == recno) - { - memcpy (ottable[i].fpr, oldbuf+20, 20); - ottable[i].okay = 1; - break; - } - } - } - - /* got everything - create the v3 trustdb */ - if (ftruncate (db_fd, 0)) - log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) ); - if (create_version_record ()) - log_fatal ("failed to recreate version record of `%s'\n", db_name); - - /* access the hash table, so it is store just after the version record, - * this is not needed put a dump is more pretty */ - get_trusthashrec (); - - /* And insert the old ownertrust values */ - count = 0; - for (i=0; i < ottable_used; i++) - { - if (!ottable[i].okay) - continue; - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20); - rec.r.trust.ownertrust = ottable[i].ot; - if (tdbio_write_record (&rec)) - log_fatal ("failed to write trust record of `%s'\n", db_name); - count++; - } - - revalidation_mark (); - rc = tdbio_sync (); - if (rc) - log_fatal ("failed to sync `%s'\n", db_name); - log_info ("migrated %d version 2 ownertrusts\n", count); - xfree (ottable); -} diff --git a/g10/tdbio.h b/g10/tdbio.h deleted file mode 100644 index 708e06d2b..000000000 --- a/g10/tdbio.h +++ /dev/null @@ -1,117 +0,0 @@ -/* tdbio.h - Trust database I/O functions - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TDBIO_H -#define G10_TDBIO_H - -#include "host2net.h" - -#define TRUST_RECORD_LEN 40 -#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5) -#define ITEMS_PER_HTBL_RECORD ((TRUST_RECORD_LEN-2)/4) -#define ITEMS_PER_HLST_RECORD ((TRUST_RECORD_LEN-6)/5) -#define ITEMS_PER_PREF_RECORD (TRUST_RECORD_LEN-10) -#if ITEMS_PER_PREF_RECORD % 2 -#error ITEMS_PER_PREF_RECORD must be even -#endif -#define MAX_LIST_SIGS_DEPTH 20 - - -#define RECTYPE_VER 1 -#define RECTYPE_HTBL 10 -#define RECTYPE_HLST 11 -#define RECTYPE_TRUST 12 -#define RECTYPE_VALID 13 -#define RECTYPE_FREE 254 - - -struct trust_record { - int rectype; - int mark; - int dirty; /* for now only used internal by functions */ - struct trust_record *next; /* help pointer to build lists in memory */ - ulong recnum; - union { - struct { /* version record: */ - byte version; /* should be 3 */ - byte marginals; - byte completes; - byte cert_depth; - byte trust_model; - ulong created; /* timestamp of trustdb creation */ - ulong nextcheck; /* timestamp of next scheduled check */ - ulong reserved; - ulong reserved2; - ulong firstfree; - ulong reserved3; - ulong trusthashtbl; - } ver; - struct { /* free record */ - ulong next; - } free; - struct { - ulong item[ITEMS_PER_HTBL_RECORD]; - } htbl; - struct { - ulong next; - ulong rnum[ITEMS_PER_HLST_RECORD]; /* of another record */ - } hlst; - struct { - byte fingerprint[20]; - byte ownertrust; - byte depth; - ulong validlist; - byte min_ownertrust; - } trust; - struct { - byte namehash[20]; - ulong next; - byte validity; - byte full_count; - byte marginal_count; - } valid; - } r; -}; -typedef struct trust_record TRUSTREC; - -/*-- tdbio.c --*/ -int tdbio_update_version_record(void); -int tdbio_set_dbname( const char *new_dbname, int create ); -const char *tdbio_get_dbname(void); -void tdbio_dump_record( TRUSTREC *rec, FILE *fp ); -int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); -int tdbio_write_record( TRUSTREC *rec ); -int tdbio_db_matches_options(void); -byte tdbio_read_model(void); -ulong tdbio_read_nextcheck (void); -int tdbio_write_nextcheck (ulong stamp); -int tdbio_is_dirty(void); -int tdbio_sync(void); -int tdbio_begin_transaction(void); -int tdbio_end_transaction(void); -int tdbio_cancel_transaction(void); -int tdbio_delete_record( ulong recnum ); -ulong tdbio_new_recnum(void); -int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec ); -int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec ); - -void tdbio_invalid(void); - -#endif /*G10_TDBIO_H*/ diff --git a/g10/textfilter.c b/g10/textfilter.c deleted file mode 100644 index a3ea4b138..000000000 --- a/g10/textfilter.c +++ /dev/null @@ -1,235 +0,0 @@ -/* textfilter.c - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "filter.h" -#include "i18n.h" -#include "options.h" - -#ifdef HAVE_DOSISH_SYSTEM -#define LF "\r\n" -#else -#define LF "\n" -#endif - -#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */ - /* to make sure that a warning is displayed while */ - /* creating a message */ - -static unsigned -len_without_trailing_chars( byte *line, unsigned len, const char *trimchars ) -{ - byte *p, *mark; - unsigned n; - - for(mark=NULL, p=line, n=0; n < len; n++, p++ ) { - if( strchr( trimchars, *p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - return mark? (mark - line) : len; -} - -unsigned -len_without_trailing_ws( byte *line, unsigned len ) -{ - return len_without_trailing_chars( line, len, " \t\r\n" ); -} - - - - -static int -standard( text_filter_context_t *tfx, iobuf_t a, - byte *buf, size_t size, size_t *ret_len) -{ - int rc=0; - size_t len = 0; - unsigned maxlen; - - assert( size > 10 ); - size -= 2; /* reserve 2 bytes to append CR,LF */ - while( !rc && len < size ) { - int lf_seen; - - while( len < size && tfx->buffer_pos < tfx->buffer_len ) - buf[len++] = tfx->buffer[tfx->buffer_pos++]; - if( len >= size ) - continue; - - /* read the next line */ - maxlen = MAX_LINELEN; - tfx->buffer_pos = 0; - tfx->buffer_len = iobuf_read_line( a, &tfx->buffer, - &tfx->buffer_size, &maxlen ); - if( !maxlen ) - tfx->truncated++; - if( !tfx->buffer_len ) { - if( !len ) - rc = -1; /* eof */ - break; - } - lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n'; - tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len ); - if( lf_seen ) { - tfx->buffer[tfx->buffer_len++] = '\r'; - tfx->buffer[tfx->buffer_len++] = '\n'; - } - } - *ret_len = len; - return rc; -} - - - - -/**************** - * The filter is used to make canonical text: Lines are terminated by - * CR, LF, trailing white spaces are removed. - */ -int -text_filter( void *opaque, int control, - iobuf_t a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - text_filter_context_t *tfx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { - rc = standard( tfx, a, buf, size, ret_len ); - } - else if( control == IOBUFCTRL_FREE ) { - if( tfx->truncated ) - log_error(_("can't handle text lines longer than %d characters\n"), - MAX_LINELEN ); - xfree ( tfx->buffer ); - tfx->buffer = NULL; - } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "text_filter"; - return rc; -} - - -/**************** - * Copy data from INP to OUT and do some escaping if requested. - * md is updated as required by rfc2440 - */ -int -copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md, - int escape_dash, int escape_from, int pgp2mode ) -{ - unsigned maxlen; - byte *buffer = NULL; /* malloced buffer */ - unsigned bufsize; /* and size of this buffer */ - unsigned n; - int truncated = 0; - int pending_lf = 0; - - if( !opt.pgp2_workarounds ) - pgp2mode = 0; - - if( !escape_dash ) - escape_from = 0; - - for(;;) { - maxlen = MAX_LINELEN; - n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen ); - if( !maxlen ) - truncated++; - - if( !n ) - break; /* read_line has returned eof */ - - /* update the message digest */ - if( escape_dash ) { - if( pending_lf ) { - gcry_md_putc( md, '\r' ); - gcry_md_putc( md, '\n' ); - } - gcry_md_write( md, buffer, - len_without_trailing_chars( buffer, n, - pgp2mode? " \r\n":" \t\r\n")); - } - else - gcry_md_write( md, buffer, n ); - pending_lf = buffer[n-1] == '\n'; - - /* write the output */ - if( ( escape_dash && *buffer == '-') - || ( escape_from && n > 4 && !memcmp(buffer, "From ", 5 ) ) ) { - iobuf_put( out, '-' ); - iobuf_put( out, ' ' ); - } - -#if 0 /*defined(HAVE_DOSISH_SYSTEM)*/ - /* We don't use this anymore because my interpretation of rfc2440 7.1 - * is that there is no conversion needed. If one decides to - * clearsign a unix file on a DOS box he will get a mixed line endings. - * If at some point it turns out, that a conversion is a nice feature - * we can make an option out of it. - */ - /* make sure the lines do end in CR,LF */ - if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' ) - || (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) { - iobuf_write( out, buffer, n-2 ); - iobuf_put( out, '\r'); - iobuf_put( out, '\n'); - } - else if( n && buffer[n-1] == '\n' ) { - iobuf_write( out, buffer, n-1 ); - iobuf_put( out, '\r'); - iobuf_put( out, '\n'); - } - else - iobuf_write( out, buffer, n ); - -#else - iobuf_write( out, buffer, n ); -#endif - } - - /* at eof */ - if( !pending_lf ) { /* make sure that the file ends with a LF */ - iobuf_writestr( out, LF ); - if( !escape_dash ) - gcry_md_putc( md, '\n' ); - } - - if( truncated ) - log_info(_("input line longer than %d characters\n"), MAX_LINELEN ); - - return 0; /* okay */ -} diff --git a/g10/trustdb.c b/g10/trustdb.c deleted file mode 100644 index b3a2b369e..000000000 --- a/g10/trustdb.c +++ /dev/null @@ -1,2158 +0,0 @@ -/* trustdb.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#ifndef DISABLE_REGEX -#include <sys/types.h> -#ifdef USE_GNU_REGEX -#include "_regex.h" -#else -#include <regex.h> -#endif -#endif /* !DISABLE_REGEX */ - -#include "gpg.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "options.h" -#include "packet.h" -#include "main.h" -#include "i18n.h" -#include "tdbio.h" -#include "trustdb.h" - - -/* - * A structure to store key identification as well as some stuff needed - * for validation - */ -struct key_item { - struct key_item *next; - unsigned int ownertrust,min_ownertrust; - byte trust_depth; - byte trust_value; - char *trust_regexp; - u32 kid[2]; -}; - - -typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ - -/* - * Structure to keep track of keys, this is used as an array wherre - * the item right after the last one has a keyblock set to NULL. - * Maybe we can drop this thing and replace it by key_item - */ -struct key_array { - KBNODE keyblock; -}; - - -/* control information for the trust DB */ -static struct { - int init; - int level; - char *dbname; -} trustdb_args; - -/* some globals */ -static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */ -static struct key_item *utk_list; /* all ultimately trusted keys */ - -static int pending_check_trustdb; - -static int validate_keys (int interactive); - - -/********************************************** - ************* some helpers ******************* - **********************************************/ - -static struct key_item * -new_key_item (void) -{ - struct key_item *k; - - k = xcalloc (1,sizeof *k); - return k; -} - -static void -release_key_items (struct key_item *k) -{ - struct key_item *k2; - - for (; k; k = k2) - { - k2 = k->next; - xfree (k->trust_regexp); - xfree (k); - } -} - -/* - * For fast keylook up we need a hash table. Each byte of a KeyIDs - * should be distributed equally over the 256 possible values (except - * for v3 keyIDs but we consider them as not important here). So we - * can just use 10 bits to index a table of 1024 key items. - * Possible optimization: Don not use key_items but other hash_table when the - * duplicates lists gets too large. - */ -static KeyHashTable -new_key_hash_table (void) -{ - struct key_item **tbl; - - tbl = xcalloc (1,1024 * sizeof *tbl); - return tbl; -} - -static void -release_key_hash_table (KeyHashTable tbl) -{ - int i; - - if (!tbl) - return; - for (i=0; i < 1024; i++) - release_key_items (tbl[i]); - xfree (tbl); -} - -/* - * Returns: True if the keyID is in the given hash table - */ -static int -test_key_hash_table (KeyHashTable tbl, u32 *kid) -{ - struct key_item *k; - - for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return 1; - return 0; -} - -/* - * Add a new key to the hash table. The key is identified by its key ID. - */ -static void -add_key_hash_table (KeyHashTable tbl, u32 *kid) -{ - struct key_item *k, *kk; - - for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next) - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - return; /* already in table */ - - kk = new_key_item (); - kk->kid[0] = kid[0]; - kk->kid[1] = kid[1]; - kk->next = tbl[(kid[1] & 0x03ff)]; - tbl[(kid[1] & 0x03ff)] = kk; -} - -/* - * Release a key_array - */ -static void -release_key_array ( struct key_array *keys ) -{ - struct key_array *k; - - if (keys) { - for (k=keys; k->keyblock; k++) - release_kbnode (k->keyblock); - xfree (keys); - } -} - - -/********************************************* - ********** Initialization ***************** - *********************************************/ - - - -/* - * Used to register extra ultimately trusted keys - this has to be done - * before initializing the validation module. - * FIXME: Should be replaced by a function to add those keys to the trustdb. - */ -void -register_trusted_key( const char *string ) -{ - KEYDB_SEARCH_DESC desc; - struct key_item *k; - - if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID ) { - log_error(_("`%s' is not a valid long keyID\n"), string ); - return; - } - - k = new_key_item (); - k->kid[0] = desc.u.kid[0]; - k->kid[1] = desc.u.kid[1]; - k->next = user_utk_list; - user_utk_list = k; -} - -/* - * Helper to add a key to the global list of ultimately trusted keys. - * Retruns: true = inserted, false = already in in list. - */ -static int -add_utk (u32 *kid) -{ - struct key_item *k; - - for (k = utk_list; k; k = k->next) - { - if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) - { - return 0; - } - } - - k = new_key_item (); - k->kid[0] = kid[0]; - k->kid[1] = kid[1]; - k->ownertrust = TRUST_ULTIMATE; - k->next = utk_list; - utk_list = k; - if( opt.verbose > 1 ) - log_info(_("key %08lX: accepted as trusted key\n"), (ulong)kid[1]); - return 1; -} - - -/**************** - * Verify that all our secret keys are usable and put them into the utk_list. - */ -static void -verify_own_keys(void) -{ - TRUSTREC rec; - ulong recnum; - int rc; - struct key_item *k; - - if (utk_list) - return; - - /* scan the trustdb to find all ultimately trusted keys */ - for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ ) - { - if ( rec.rectype == RECTYPE_TRUST - && (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) - { - byte *fpr = rec.r.trust.fingerprint; - int fprlen; - u32 kid[2]; - - /* Problem: We do only use fingerprints in the trustdb but - * we need the keyID here to indetify the key; we can only - * use that ugly hack to distinguish between 16 and 20 - * butes fpr - it does not work always so we better change - * the whole validation code to only work with - * fingerprints */ - fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20; - keyid_from_fingerprint (fpr, fprlen, kid); - if (!add_utk (kid)) - log_info(_("key %08lX occurs more than once in the trustdb\n"), - (ulong)kid[1]); - } - } - - /* Put any --trusted-key keys into the trustdb */ - for (k = user_utk_list; k; k = k->next) - { - if ( add_utk (k->kid) ) - { /* not yet in trustDB as ultimately trusted */ - PKT_public_key pk; - - memset (&pk, 0, sizeof pk); - rc = get_pubkey (&pk, k->kid); - if (rc) { - log_info(_("key %08lX: no public key for trusted key - skipped\n"), - (ulong)k->kid[1] ); - } - else { - update_ownertrust (&pk, - ((get_ownertrust (&pk) & ~TRUST_MASK) - | TRUST_ULTIMATE )); - release_public_key_parts (&pk); - } - log_info (_("key %08lX marked as ultimately trusted\n"), - (ulong)k->kid[1]); - } - } - - - /* release the helper table table */ - release_key_items (user_utk_list); - user_utk_list = NULL; - return; -} - - -/********************************************* - *********** TrustDB stuff ******************* - *********************************************/ - -/* - * Read a record but die if it does not exist - */ -static void -read_record (ulong recno, TRUSTREC *rec, int rectype ) -{ - int rc = tdbio_read_record (recno, rec, rectype); - if (rc) - { - log_error(_("trust record %lu, req type %d: read failed: %s\n"), - recno, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); - } - if (rectype != rec->rectype) - { - log_error(_("trust record %lu is not of requested type %d\n"), - rec->recnum, rectype); - tdbio_invalid(); - } -} - -/* - * Write a record and die on error - */ -static void -write_record (TRUSTREC *rec) -{ - int rc = tdbio_write_record (rec); - if (rc) - { - log_error(_("trust record %lu, type %d: write failed: %s\n"), - rec->recnum, rec->rectype, gpg_strerror (rc) ); - tdbio_invalid(); - } -} - -/* - * sync the TrustDb and die on error - */ -static void -do_sync(void) -{ - int rc = tdbio_sync (); - if(rc) - { - log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) ); - g10_exit(2); - } -} - -static const char * -trust_model_string(void) -{ - switch(opt.trust_model) - { - case TM_PGP: return "PGP"; - case TM_CLASSIC: return "classic"; - case TM_ALWAYS: return "always"; - default: return "unknown"; - } -} - -/**************** - * Perform some checks over the trustdb - * level 0: only open the db - * 1: used for initial program startup - */ -int -setup_trustdb( int level, const char *dbname ) -{ - /* just store the args */ - if( trustdb_args.init ) - return 0; - trustdb_args.level = level; - trustdb_args.dbname = dbname? xstrdup (dbname): NULL; - return 0; -} - -void -init_trustdb() -{ - int rc=0; - int level = trustdb_args.level; - const char* dbname = trustdb_args.dbname; - - if( trustdb_args.init ) - return; - - trustdb_args.init = 1; - - if ( !level || level==1) - { - rc = tdbio_set_dbname( dbname, !!level ); - if( !rc ) - { - if( !level ) - return; - - /* verify that our own keys are in the trustDB - * or move them to the trustdb. */ - verify_own_keys(); - - /* should we check whether there is no other ultimately trusted - * key in the database? */ - } - } - else - BUG(); - if( rc ) - log_fatal("can't init trustdb: %s\n", gpg_strerror (rc) ); - - if(opt.trust_model==TM_AUTO) - { - /* Try and set the trust model off of whatever the trustdb says - it is. */ - opt.trust_model=tdbio_read_model(); - - /* Sanity check this ;) */ - if(opt.trust_model!=TM_PGP && opt.trust_model!=TM_CLASSIC) - { - log_info(_("unable to use unknown trust model (%d) - " - "assuming %s trust model\n"),opt.trust_model,"PGP"); - opt.trust_model=TM_PGP; - } - - if(opt.verbose) - log_info(_("using %s trust model\n"),trust_model_string()); - } - - if((opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - && !tdbio_db_matches_options()) - pending_check_trustdb=1; -} - - - - -/*********************************************** - ************* Print helpers **************** - ***********************************************/ - -/**************** - * This function returns a letter for a trustvalue Trust flags - * are ignore. - */ -static int -trust_letter (unsigned int value) -{ - switch( (value & TRUST_MASK) ) - { - case TRUST_UNKNOWN: return '-'; - case TRUST_EXPIRED: return 'e'; - case TRUST_UNDEFINED: return 'q'; - case TRUST_NEVER: return 'n'; - case TRUST_MARGINAL: return 'm'; - case TRUST_FULLY: return 'f'; - case TRUST_ULTIMATE: return 'u'; - default: return '?'; - } -} - -/* The strings here are similar to those in - pkclist.c:do_edit_ownertrust() */ -const char * -trust_value_to_string (unsigned int value) -{ - switch( (value & TRUST_MASK) ) - { - case TRUST_UNKNOWN: return _("unknown"); - case TRUST_EXPIRED: return _("expired"); - case TRUST_UNDEFINED: return _("undefined"); - case TRUST_NEVER: return _("never"); - case TRUST_MARGINAL: return _("marginal"); - case TRUST_FULLY: return _("full"); - case TRUST_ULTIMATE: return _("ultimate"); - default: return "err"; - } -} - -int -string_to_trust_value (const char *str) -{ - if(ascii_strcasecmp(str,"undefined")==0) - return TRUST_UNDEFINED; - else if(ascii_strcasecmp(str,"never")==0) - return TRUST_NEVER; - else if(ascii_strcasecmp(str,"marginal")==0) - return TRUST_MARGINAL; - else if(ascii_strcasecmp(str,"full")==0) - return TRUST_FULLY; - else if(ascii_strcasecmp(str,"ultimate")==0) - return TRUST_ULTIMATE; - else - return -1; -} - -/**************** - * Recreate the WoT but do not ask for new ownertrusts. Special - * feature: In batch mode and without a forced yes, this is only done - * when a check is due. This can be used to run the check from a crontab - */ -void -check_trustdb () -{ - init_trustdb(); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - { - if (opt.batch && !opt.answer_yes) - { - ulong scheduled; - - scheduled = tdbio_read_nextcheck (); - if (!scheduled) - { - log_info (_("no need for a trustdb check\n")); - return; - } - - if (scheduled > make_timestamp ()) - { - log_info (_("next trustdb check due at %s\n"), - strtimestamp (scheduled)); - return; - } - } - - validate_keys (0); - } - else - log_info (_("no need for a trustdb check with \"%s\" trust model\n"), - trust_model_string()); -} - - -/* - * Recreate the WoT. - */ -void -update_trustdb() -{ - init_trustdb(); - if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC) - validate_keys (1); - else - log_info (_("no need for a trustdb update with \"%s\" trust model\n"), - trust_model_string()); -} - -void -revalidation_mark (void) -{ - init_trustdb(); - /* we simply set the time for the next check to 1 (far back in 1970) - * so that a --update-trustdb will be scheduled */ - if (tdbio_write_nextcheck (1)) - do_sync (); - pending_check_trustdb = 1; -} - -int -trustdb_pending_check(void) -{ - return pending_check_trustdb; -} - -void -read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth) -{ - TRUSTREC opts; - - init_trustdb(); - - read_record(0,&opts,RECTYPE_VER); - - if(trust_model) - *trust_model=opts.r.ver.trust_model; - if(created) - *created=opts.r.ver.created; - if(nextcheck) - *nextcheck=opts.r.ver.nextcheck; - if(marginals) - *marginals=opts.r.ver.marginals; - if(completes) - *completes=opts.r.ver.completes; - if(cert_depth) - *cert_depth=opts.r.ver.cert_depth; -} - - - -/*********************************************** - *********** Ownertrust et al. **************** - ***********************************************/ - -static int -read_trust_record (PKT_public_key *pk, TRUSTREC *rec) -{ - int rc; - - init_trustdb(); - rc = tdbio_search_trust_bypk (pk, rec); - if (rc == -1) - return -1; /* no record yet */ - if (rc) - { - log_error ("trustdb: searching trust record failed: %s\n", - gpg_strerror (rc)); - return rc; - } - - if (rec->rectype != RECTYPE_TRUST) - { - log_error ("trustdb: record %lu is not a trust record\n", - rec->recnum); - return GPG_ERR_TRUSTDB; - } - - return 0; -} - -/**************** - * Return the assigned ownertrust value for the given public key. - * The key should be the primary key. - */ -unsigned int -get_ownertrust ( PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (rc == -1) - return TRUST_UNKNOWN; /* no record yet */ - if (rc) - { - tdbio_invalid (); - return rc; /* actually never reached */ - } - - return rec.r.trust.ownertrust; -} - -unsigned int -get_min_ownertrust (PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (rc == -1) - return TRUST_UNKNOWN; /* no record yet */ - if (rc) - { - tdbio_invalid (); - return rc; /* actually never reached */ - } - - return rec.r.trust.min_ownertrust; -} - -/* - * Same as get_ownertrust but this takes the minimum ownertrust value - * into into account, and will bump up the value as needed. - */ -static int -get_ownertrust_with_min (PKT_public_key *pk) -{ - unsigned int otrust,otrust_min; - - otrust = (get_ownertrust (pk) & TRUST_MASK); - otrust_min = get_min_ownertrust (pk); - if(otrust<otrust_min) - { - /* If the trust that the user has set is less than the trust - that was calculated from a trust signature chain, use the - higher of the two. We do this here and not in - get_ownertrust since the underlying ownertrust should not - really be set - just the appearance of the ownertrust. */ - - otrust=otrust_min; - } - - return otrust; -} - -/* - * Same as get_ownertrust but return a trust letter instead of an - * value. This takes the minimum ownertrust value into account. - */ -int -get_ownertrust_info (PKT_public_key *pk) -{ - return trust_letter(get_ownertrust_with_min(pk)); -} - -/* - * Same as get_ownertrust but return a trust string instead of an - * value. This takes the minimum ownertrust value into account. - */ -const char * -get_ownertrust_string (PKT_public_key *pk) -{ - return trust_value_to_string(get_ownertrust_with_min(pk)); -} - -/* - * Set the trust value of the given public key to the new value. - * The key should be a primary one. - */ -void -update_ownertrust (PKT_public_key *pk, unsigned int new_trust ) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - log_debug ("update ownertrust from %u to %u\n", - (unsigned int)rec.r.trust.ownertrust, new_trust ); - if (rec.r.trust.ownertrust != new_trust) - { - rec.r.trust.ownertrust = new_trust; - write_record( &rec ); - revalidation_mark (); - do_sync (); - } - } - else if (rc == -1) - { /* no record yet - create a new one */ - size_t dummy; - - if (DBG_TRUST) - log_debug ("insert ownertrust %u\n", new_trust ); - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy); - rec.r.trust.ownertrust = new_trust; - write_record (&rec); - revalidation_mark (); - do_sync (); - rc = 0; - } - else - { - tdbio_invalid (); - } -} - -static void -update_min_ownertrust (u32 *kid, unsigned int new_trust ) -{ - PKT_public_key *pk; - TRUSTREC rec; - int rc; - - pk = xcalloc (1,sizeof *pk); - rc = get_pubkey (pk, kid); - if (rc) - { - log_error (_("public key %08lX not found: %s\n"), - (ulong)kid[1], gpg_strerror (rc) ); - return; - } - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - log_debug ("key %08lX: update min_ownertrust from %u to %u\n", - (ulong)kid[1],(unsigned int)rec.r.trust.min_ownertrust, - new_trust ); - if (rec.r.trust.min_ownertrust != new_trust) - { - rec.r.trust.min_ownertrust = new_trust; - write_record( &rec ); - revalidation_mark (); - do_sync (); - } - } - else if (rc == -1) - { /* no record yet - create a new one */ - size_t dummy; - - if (DBG_TRUST) - log_debug ("insert min_ownertrust %u\n", new_trust ); - - memset (&rec, 0, sizeof rec); - rec.recnum = tdbio_new_recnum (); - rec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy); - rec.r.trust.min_ownertrust = new_trust; - write_record (&rec); - revalidation_mark (); - do_sync (); - rc = 0; - } - else - { - tdbio_invalid (); - } -} - -/* Clear the ownertrust and min_ownertrust values. Return true if a - change actually happened. */ -int -clear_ownertrusts (PKT_public_key *pk) -{ - TRUSTREC rec; - int rc; - - rc = read_trust_record (pk, &rec); - if (!rc) - { - if (DBG_TRUST) - { - log_debug ("clearing ownertrust (old value %u)\n", - (unsigned int)rec.r.trust.ownertrust); - log_debug ("clearing min_ownertrust (old value %u)\n", - (unsigned int)rec.r.trust.min_ownertrust); - } - if (rec.r.trust.ownertrust || rec.r.trust.min_ownertrust) - { - rec.r.trust.ownertrust = 0; - rec.r.trust.min_ownertrust = 0; - write_record( &rec ); - revalidation_mark (); - do_sync (); - return 1; - } - } - else if (rc != -1) - { - tdbio_invalid (); - } - return 0; -} - -/* - * Note: Caller has to do a sync - */ -static void -update_validity (PKT_public_key *pk, PKT_user_id *uid, - int depth, int validity) -{ - TRUSTREC trec, vrec; - int rc; - ulong recno; - - namehash_from_uid(uid); - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return; - } - if (rc == -1) /* no record yet - create a new one */ - { - size_t dummy; - - rc = 0; - memset (&trec, 0, sizeof trec); - trec.recnum = tdbio_new_recnum (); - trec.rectype = RECTYPE_TRUST; - fingerprint_from_pk (pk, trec.r.trust.fingerprint, &dummy); - trec.r.trust.ownertrust = 0; - } - - /* locate an existing one */ - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - if ( !memcmp (vrec.r.valid.namehash, uid->namehash, 20) ) - break; - recno = vrec.r.valid.next; - } - - if (!recno) /* insert a new validity record */ - { - memset (&vrec, 0, sizeof vrec); - vrec.recnum = tdbio_new_recnum (); - vrec.rectype = RECTYPE_VALID; - memcpy (vrec.r.valid.namehash, uid->namehash, 20); - vrec.r.valid.next = trec.r.trust.validlist; - trec.r.trust.validlist = vrec.recnum; - } - vrec.r.valid.validity = validity; - vrec.r.valid.full_count = uid->help_full_count; - vrec.r.valid.marginal_count = uid->help_marginal_count; - write_record (&vrec); - trec.r.trust.depth = depth; - write_record (&trec); -} - - -/* reset validity for all user IDs. Caller must sync. */ -static int -clear_validity (PKT_public_key *pk) -{ - TRUSTREC trec, vrec; - int rc; - ulong recno; - int any = 0; - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return 0; - } - if (rc == -1) /* no record yet - no need to clear it then ;-) */ - return 0; - - /* Clear minimum ownertrust, if any */ - if(trec.r.trust.min_ownertrust) - { - trec.r.trust.min_ownertrust=0; - write_record(&trec); - } - - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - if ((vrec.r.valid.validity & TRUST_MASK) - || vrec.r.valid.marginal_count || vrec.r.valid.full_count) - { - vrec.r.valid.validity &= ~TRUST_MASK; - vrec.r.valid.marginal_count = vrec.r.valid.full_count = 0; - write_record (&vrec); - any = 1; - } - recno = vrec.r.valid.next; - } - - return any; -} - -/*********************************************** - ********* Query trustdb values ************** - ***********************************************/ - -/* Return true if key is disabled */ -int -cache_disabled_value(PKT_public_key *pk) -{ - int rc; - TRUSTREC trec; - int disabled=0; - - if(pk->is_disabled) - return (pk->is_disabled==2); - - init_trustdb(); - - rc = read_trust_record (pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - goto leave; - } - if (rc == -1) /* no record found, so assume not disabled */ - goto leave; - - if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) - disabled=1; - - /* Cache it for later so we don't need to look at the trustdb every - time */ - if(disabled) - pk->is_disabled=2; - else - pk->is_disabled=1; - - leave: - return disabled; -} - -/* - * Return the validity information for PK. If the namehash is not - * NULL, the validity of the corresponsing user ID is returned, - * otherwise, a reasonable value for the entire key is returned. - */ -unsigned int -get_validity (PKT_public_key *pk, PKT_user_id *uid) -{ - static int did_nextcheck; - TRUSTREC trec, vrec; - int rc; - ulong recno; - unsigned int validity; - u32 kid[2]; - PKT_public_key *main_pk; - - if(uid) - namehash_from_uid(uid); - - init_trustdb (); - if (!did_nextcheck - && (opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)) - { - ulong scheduled; - - did_nextcheck = 1; - scheduled = tdbio_read_nextcheck (); - if (scheduled && scheduled <= make_timestamp ()) - { - if (opt.no_auto_check_trustdb) - { - pending_check_trustdb = 1; - log_info (_("please do a --check-trustdb\n")); - } - else - { - log_info (_("checking the trustdb\n")); - validate_keys (0); - } - } - } - - keyid_from_pk (pk, kid); - if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1]) - { /* this is a subkey - get the mainkey */ - main_pk = xcalloc (1,sizeof *main_pk); - rc = get_pubkey (main_pk, pk->main_keyid); - if (rc) - { - log_error ("error getting main key %08lX of subkey %08lX: %s\n", - (ulong)pk->main_keyid[1], (ulong)kid[1], gpg_strerror (rc)); - validity = TRUST_UNKNOWN; - goto leave; - } - } - else - main_pk = pk; - - rc = read_trust_record (main_pk, &trec); - if (rc && rc != -1) - { - tdbio_invalid (); - return 0; - } - if (rc == -1) /* no record found */ - { - validity = TRUST_UNKNOWN; - goto leave; - } - - /* loop over all user IDs */ - recno = trec.r.trust.validlist; - validity = 0; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - - if(uid) - { - /* If a user ID is given we return the validity for that - user ID ONLY. If the namehash is not found, then there - is no validity at all (i.e. the user ID wasn't - signed). */ - if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) - { - validity=(vrec.r.valid.validity & TRUST_MASK); - break; - } - } - else - { - /* If no namehash is given, we take the maximum validity - over all user IDs */ - if ( validity < (vrec.r.valid.validity & TRUST_MASK) ) - validity = (vrec.r.valid.validity & TRUST_MASK); - } - - recno = vrec.r.valid.next; - } - - if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) ) - { - validity |= TRUST_FLAG_DISABLED; - pk->is_disabled=2; - } - else - pk->is_disabled=1; - - leave: - /* set some flags direct from the key */ - if (main_pk->is_revoked) - validity |= TRUST_FLAG_REVOKED; - if (main_pk != pk && pk->is_revoked) - validity |= TRUST_FLAG_SUB_REVOKED; - /* Note: expiration is a trust value and not a flag - don't know why - * I initially designed it that way */ - if (main_pk->has_expired || pk->has_expired) - validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED; - - if (pending_check_trustdb) - validity |= TRUST_FLAG_PENDING_CHECK; - - if (main_pk != pk) - free_public_key (main_pk); - return validity; -} - -int -get_validity_info (PKT_public_key *pk, PKT_user_id *uid) -{ - int trustlevel; - - trustlevel = get_validity (pk, uid); - if( trustlevel & TRUST_FLAG_REVOKED ) - return 'r'; - return trust_letter ( trustlevel ); -} - -const char * -get_validity_string (PKT_public_key *pk, PKT_user_id *uid) -{ - int trustlevel; - - trustlevel = get_validity (pk, uid); - if( trustlevel & TRUST_FLAG_REVOKED ) - return _("revoked"); - return trust_value_to_string(trustlevel); -} - -static void -get_validity_counts (PKT_public_key *pk, PKT_user_id *uid) -{ - TRUSTREC trec, vrec; - ulong recno; - - if(pk==NULL || uid==NULL) - BUG(); - - namehash_from_uid(uid); - - uid->help_marginal_count=uid->help_full_count=0; - - init_trustdb (); - - if(read_trust_record (pk, &trec)!=0) - return; - - /* loop over all user IDs */ - recno = trec.r.trust.validlist; - while (recno) - { - read_record (recno, &vrec, RECTYPE_VALID); - - if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) - { - uid->help_marginal_count=vrec.r.valid.marginal_count; - uid->help_full_count=vrec.r.valid.full_count; - /* printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */ - break; - } - - recno = vrec.r.valid.next; - } -} - -void -list_trust_path( const char *username ) -{ -} - -/**************** - * Enumerate all keys, which are needed to build all trust paths for - * the given key. This function does not return the key itself or - * the ultimate key (the last point in cerificate chain). Only - * certificate chains which ends up at an ultimately trusted key - * are listed. If ownertrust or validity is not NULL, the corresponding - * value for the returned LID is also returned in these variable(s). - * - * 1) create a void pointer and initialize it to NULL - * 2) pass this void pointer by reference to this function. - * Set lid to the key you want to enumerate and pass it by reference. - * 3) call this function as long as it does not return -1 - * to indicate EOF. LID does contain the next key used to build the web - * 4) Always call this function a last time with LID set to NULL, - * so that it can free its context. - * - * Returns: -1 on EOF or the level of the returned LID - */ -int -enum_cert_paths( void **context, ulong *lid, - unsigned *ownertrust, unsigned *validity ) -{ - return -1; -} - - -/**************** - * Print the current path - */ -void -enum_cert_paths_print( void **context, FILE *fp, - int refresh, ulong selected_lid ) -{ - return; -} - - - -/**************************************** - *********** NEW NEW NEW **************** - ****************************************/ - -static int -ask_ownertrust (u32 *kid,int minimum) -{ - PKT_public_key *pk; - int rc; - int ot; - - pk = xcalloc (1,sizeof *pk); - rc = get_pubkey (pk, kid); - if (rc) - { - log_error (_("public key %08lX not found: %s\n"), - (ulong)kid[1], gpg_strerror (rc) ); - return TRUST_UNKNOWN; - } - - if(opt.force_ownertrust) - { - log_info("force trust for key %08lX%08lX to %s\n", - (ulong)kid[0],(ulong)kid[1], - trust_value_to_string(opt.force_ownertrust)); - update_ownertrust(pk,opt.force_ownertrust); - ot=opt.force_ownertrust; - } - else - { - ot=edit_ownertrust(pk,0); - if(ot>0) - ot = get_ownertrust (pk); - else if(ot==0) - ot = minimum?minimum:TRUST_UNDEFINED; - else - ot = -1; /* quit */ - } - - free_public_key( pk ); - - return ot; -} - - -static void -mark_keyblock_seen (KeyHashTable tbl, KBNODE node) -{ - for ( ;node; node = node->next ) - if (node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - { - u32 aki[2]; - - keyid_from_pk (node->pkt->pkt.public_key, aki); - add_key_hash_table (tbl, aki); - } -} - - -static void -dump_key_array (int depth, struct key_array *keys) -{ - struct key_array *kar; - - for (kar=keys; kar->keyblock; kar++) - { - KBNODE node = kar->keyblock; - u32 kid[2]; - - keyid_from_pk(node->pkt->pkt.public_key, kid); - printf ("%d:%08lX%08lX:K::%c::::\n", - depth, (ulong)kid[0], (ulong)kid[1], '?'); - - for (; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - int len = node->pkt->pkt.user_id->len; - - if (len > 30) - len = 30; - printf ("%d:%08lX%08lX:U:::%c:::", - depth, (ulong)kid[0], (ulong)kid[1], - (node->flag & 4)? 'f': - (node->flag & 2)? 'm': - (node->flag & 1)? 'q':'-'); - print_string (stdout, node->pkt->pkt.user_id->name, len, ':'); - putchar (':'); - putchar ('\n'); - } - } - } -} - - -static void -store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored) -{ - KBNODE node; - int status; - int any = 0; - - for (node=keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *uid = node->pkt->pkt.user_id; - if (node->flag & 4) - status = TRUST_FULLY; - else if (node->flag & 2) - status = TRUST_MARGINAL; - else if (node->flag & 1) - status = TRUST_UNDEFINED; - else - status = 0; - - if (status) - { - update_validity (keyblock->pkt->pkt.public_key, - uid, depth, status); - - mark_keyblock_seen(stored,keyblock); - - any = 1; - } - } - } - - if (any) - do_sync (); -} - -/* - * check whether the signature sig is in the klist k - */ -static struct key_item * -is_in_klist (struct key_item *k, PKT_signature *sig) -{ - for (; k; k = k->next) - { - if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1]) - return k; - } - return NULL; -} - -/* - * Mark the signature of the given UID which are used to certify it. - * To do this, we first revmove all signatures which are not valid and - * from the remain ones we look for the latest one. If this is not a - * certification revocation signature we mark the signature by setting - * node flag bit 8. Note that flag bits 9 and 10 are used for internal - * purposes. - */ -static void -mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode, - u32 *main_kid, struct key_item *klist, - u32 curtime, u32 *next_expire) -{ - KBNODE node; - PKT_signature *sig; - - /* first check all signatures */ - for (node=uidnode->next; node; node = node->next) - { - node->flag &= ~(1<<8 | 1<<9 | 1<<10); - if (node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ - if (node->pkt->pkttype != PKT_SIGNATURE) - continue; - - sig = node->pkt->pkt.signature; - if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1]) - continue; /* ignore self-signatures */ - if (!IS_UID_SIG(sig) && !IS_UID_REV(sig)) - continue; /* we only look at these signature classes */ - if (!is_in_klist (klist, sig)) - continue; /* no need to check it then */ - if (check_key_signature (keyblock, node, NULL)) - continue; /* ignore invalid signatures */ - node->flag |= 1<<9; - } - /* reset the remaining flags */ - for (; node; node = node->next) - node->flag &= ~(1<<8 | 1<<9 | 1 << 10); - - /* kbnode flag usage: bit 9 is here set for signatures to consider, - * bit 10 will be set by the loop to keep track of keyIDs already - * processed, bit 8 will be set for the usable signatures */ - - /* for each cert figure out the latest valid one */ - for (node=uidnode->next; node; node = node->next) - { - KBNODE n, signode; - u32 kid[2]; - u32 sigdate; - - if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; - if ( !(node->flag & (1<<9)) ) - continue; /* not a node to look at */ - if ( (node->flag & (1<<10)) ) - continue; /* signature with a keyID already processed */ - node->flag |= (1<<10); /* mark this node as processed */ - sig = node->pkt->pkt.signature; - signode = node; - sigdate = sig->timestamp; - kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1]; - for (n=uidnode->next; n; n = n->next) - { - if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; - if ( !(n->flag & (1<<9)) ) - continue; - if ( (n->flag & (1<<10)) ) - continue; /* shortcut already processed signatures */ - sig = n->pkt->pkt.signature; - if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1]) - continue; - n->flag |= (1<<10); /* mark this node as processed */ - - /* If signode is nonrevocable and unexpired and n isn't, - then take signode (skip). It doesn't matter which is - older: if signode was older then we don't want to take n - as signode is nonrevocable. If n was older then we're - automatically fine. */ - - if(((IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - (!(IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - continue; - - /* If n is nonrevocable and unexpired and signode isn't, - then take n. Again, it doesn't matter which is older: if - n was older then we don't want to take signode as n is - nonrevocable. If signode was older then we're - automatically fine. */ - - if((!(IS_UID_SIG(signode->pkt->pkt.signature) && - !signode->pkt->pkt.signature->flags.revocable && - (signode->pkt->pkt.signature->expiredate==0 || - signode->pkt->pkt.signature->expiredate>curtime))) && - ((IS_UID_SIG(n->pkt->pkt.signature) && - !n->pkt->pkt.signature->flags.revocable && - (n->pkt->pkt.signature->expiredate==0 || - n->pkt->pkt.signature->expiredate>curtime)))) - { - signode = n; - sigdate = sig->timestamp; - continue; - } - - /* At this point, if it's newer, it goes in as the only - remaining possibilities are signode and n are both either - revocable or expired or both nonrevocable and unexpired. - If the timestamps are equal take the later ordered - packet, presuming that the key packets are hopefully in - their original order. */ - - if (sig->timestamp >= sigdate) - { - signode = n; - sigdate = sig->timestamp; - } - } - sig = signode->pkt->pkt.signature; - if (IS_UID_SIG (sig)) - { /* this seems to be a usable one which is not revoked. - * Just need to check whether there is an expiration time, - * We do the expired certification after finding a suitable - * certification, the assumption is that a signator does not - * want that after the expiration of his certificate the - * system falls back to an older certification which has a - * different expiration time */ - const byte *p; - u32 expire; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL ); - expire = p? sig->timestamp + buffer_to_u32(p) : 0; - - if (expire==0 || expire > curtime ) - { - signode->flag |= (1<<8); /* yeah, found a good cert */ - if (expire && expire < *next_expire) - *next_expire = expire; - } - } - } -} - -/* Used by validate_one_keyblock to confirm a regexp within a trust - signature. Returns 1 for match, and 0 for no match or regex - error. */ -static int -check_regexp(const char *expr,const char *string) -{ -#ifdef DISABLE_REGEX - /* When DISABLE_REGEX is defined, assume all regexps do not - match. */ - return 0; -#elif defined(__riscos__) - return riscos_check_regexp(expr, string, DBG_TRUST); -#else - int ret; - regex_t pat; - - if(regcomp(&pat,expr,REG_ICASE|REG_NOSUB|REG_EXTENDED)!=0) - return 0; - - ret=regexec(&pat,string,0,NULL,0); - - regfree(&pat); - - if(DBG_TRUST) - log_debug("regexp \"%s\" on \"%s\": %s\n",expr,string,ret==0?"YES":"NO"); - - return (ret==0); -#endif -} - -/* - * Return true if the key is signed by one of the keys in the given - * key ID list. User IDs with a valid signature are marked by node - * flags as follows: - * flag bit 0: There is at least one signature - * 1: There is marginal confidence that this is a legitimate uid - * 2: There is full confidence that this is a legitimate uid. - * 8: Used for internal purposes. - * 9: Ditto (in mark_usable_uid_certs()) - * 10: Ditto (ditto) - * This function assumes that all kbnode flags are cleared on entry. - */ -static int -validate_one_keyblock (KBNODE kb, struct key_item *klist, - u32 curtime, u32 *next_expire) -{ - struct key_item *kr; - KBNODE node, uidnode=NULL; - PKT_user_id *uid=NULL; - PKT_public_key *pk = kb->pkt->pkt.public_key; - u32 main_kid[2]; - int issigned=0, any_signed = 0; - - keyid_from_pk(pk, main_kid); - for (node=kb; node; node = node->next) - { - /* A bit of discussion here: is it better for the web of trust - to be built among only self-signed uids? On the one hand, a - self-signed uid is a statement that the key owner definitely - intended that uid to be there, but on the other hand, a - signed (but not self-signed) uid does carry trust, of a sort, - even if it is a statement being made by people other than the - key owner "through" the uids on the key owner's key. I'm - going with the latter. However, if the user ID was - explicitly revoked, or passively allowed to expire, that - should stop validity through the user ID until it is - resigned. -dshaw */ - - if (node->pkt->pkttype == PKT_USER_ID - && !node->pkt->pkt.user_id->is_revoked - && !node->pkt->pkt.user_id->is_expired) - { - if (uidnode && issigned) - { - if (uid->help_full_count >= opt.completes_needed - || uid->help_marginal_count >= opt.marginals_needed ) - uidnode->flag |= 4; - else if (uid->help_full_count || uid->help_marginal_count) - uidnode->flag |= 2; - uidnode->flag |= 1; - any_signed = 1; - } - uidnode = node; - uid=uidnode->pkt->pkt.user_id; - - /* If the selfsig is going to expire... */ - if(uid->expiredate && uid->expiredate<*next_expire) - *next_expire = uid->expiredate; - - issigned = 0; - get_validity_counts(pk,uid); - mark_usable_uid_certs (kb, uidnode, main_kid, klist, - curtime, next_expire); - } - else if (node->pkt->pkttype == PKT_SIGNATURE - && (node->flag & (1<<8)) && uid) - { - /* Note that we are only seeing unrevoked sigs here */ - PKT_signature *sig = node->pkt->pkt.signature; - - kr = is_in_klist (klist, sig); - /* If the trust_regexp does not match, it's as if the sig - did not exist. This is safe for non-trust sigs as well - since we don't accept a regexp on the sig unless it's a - trust sig. */ - if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP || - (uidnode && check_regexp(kr->trust_regexp, - uidnode->pkt->pkt.user_id->name)))) - { - if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth) - log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n", - uidnode->pkt->pkt.user_id->name,sig->trust_depth, - kr->trust_depth); - - /* Are we part of a trust sig chain? We always favor - the latest trust sig, rather than the greater or - lesser trust sig or value. I could make a decent - argument for any of these cases, but this seems to be - what PGP does, and I'd like to be compatible. -dms */ - if(opt.trust_model==TM_PGP && sig->trust_depth - && pk->trust_timestamp<=sig->timestamp - && (sig->trust_depth<=kr->trust_depth - || kr->ownertrust==TRUST_ULTIMATE)) - { - /* If we got here, we know that: - - this is a trust sig. - - it's a newer trust sig than any previous trust - sig on this key (not uid). - - it is legal in that it was either generated by an - ultimate key, or a key that was part of a trust - chain, and the depth does not violate the - original trust sig. - - if there is a regexp attached, it matched - successfully. - */ - - if(DBG_TRUST) - log_debug("replacing trust value %d with %d and " - "depth %d with %d\n", - pk->trust_value,sig->trust_value, - pk->trust_depth,sig->trust_depth); - - pk->trust_value=sig->trust_value; - pk->trust_depth=sig->trust_depth-1; - - /* If the trust sig contains a regexp, record it - on the pk for the next round. */ - if(sig->trust_regexp) - pk->trust_regexp=sig->trust_regexp; - } - - if (kr->ownertrust == TRUST_ULTIMATE) - uid->help_full_count = opt.completes_needed; - else if (kr->ownertrust == TRUST_FULLY) - uid->help_full_count++; - else if (kr->ownertrust == TRUST_MARGINAL) - uid->help_marginal_count++; - issigned = 1; - } - } - } - - if (uidnode && issigned) - { - if (uid->help_full_count >= opt.completes_needed - || uid->help_marginal_count >= opt.marginals_needed ) - uidnode->flag |= 4; - else if (uid->help_full_count || uid->help_marginal_count) - uidnode->flag |= 2; - uidnode->flag |= 1; - any_signed = 1; - } - - return any_signed; -} - - -static int -search_skipfnc (void *opaque, u32 *kid) -{ - return test_key_hash_table ((KeyHashTable)opaque, kid); -} - - -/* - * Scan all keys and return a key_array of all suitable keys from - * kllist. The caller has to pass keydb handle so that we don't use - * to create our own. Returns either a key_array or NULL in case of - * an error. No results found are indicated by an empty array. - * Caller hast to release the returned array. - */ -static struct key_array * -validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust, - struct key_item *klist, u32 curtime, u32 *next_expire) -{ - KBNODE keyblock = NULL; - struct key_array *keys = NULL; - size_t nkeys, maxkeys; - int rc; - KEYDB_SEARCH_DESC desc; - - maxkeys = 1000; - keys = xmalloc ((maxkeys+1) * sizeof *keys); - nkeys = 0; - - rc = keydb_search_reset (hd); - if (rc) - { - log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - desc.skipfnc = search_skipfnc; - desc.skipfncvalue = full_trust; - rc = keydb_search (hd, &desc, 1); - if (rc == -1) - { - keys[nkeys].keyblock = NULL; - return keys; - } - if (rc) - { - log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ - do - { - PKT_public_key *pk; - - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY) - { - log_debug ("ooops: invalid pkttype %d encountered\n", - keyblock->pkt->pkttype); - dump_kbnode (keyblock); - release_kbnode(keyblock); - continue; - } - - /* prepare the keyblock for further processing */ - merge_keys_and_selfsig (keyblock); - clear_kbnode_flags (keyblock); - pk = keyblock->pkt->pkt.public_key; - if (pk->has_expired || pk->is_revoked) - { - /* it does not make sense to look further at those keys */ - mark_keyblock_seen (full_trust, keyblock); - } - else if (validate_one_keyblock (keyblock, klist, curtime, next_expire)) - { - KBNODE node; - - if (pk->expiredate && pk->expiredate >= curtime - && pk->expiredate < *next_expire) - *next_expire = pk->expiredate; - - if (nkeys == maxkeys) { - maxkeys += 1000; - keys = xrealloc (keys, (maxkeys+1) * sizeof *keys); - } - keys[nkeys++].keyblock = keyblock; - - /* Optimization - if all uids are fully trusted, then we - never need to consider this key as a candidate again. */ - - for (node=keyblock; node; node = node->next) - if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4)) - break; - - if(node==NULL) - mark_keyblock_seen (full_trust, keyblock); - - keyblock = NULL; - } - - release_kbnode (keyblock); - keyblock = NULL; - } - while ( !(rc = keydb_search (hd, &desc, 1)) ); - if (rc && rc != -1) - { - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - xfree (keys); - return NULL; - } - - keys[nkeys].keyblock = NULL; - return keys; -} - -/* Caller must sync */ -static void -reset_trust_records (KEYDB_HANDLE hd, KeyHashTable exclude) -{ - int rc; - KBNODE keyblock = NULL; - KEYDB_SEARCH_DESC desc; - int count = 0, nreset = 0; - - rc = keydb_search_reset (hd); - if (rc) - { - log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc)); - return; - } - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - if(exclude) - { - desc.skipfnc = search_skipfnc; - desc.skipfncvalue = exclude; - } - rc = keydb_search (hd, &desc, 1); - if (rc && rc != -1 ) - log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc)); - else if (!rc) - { - desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ - do - { - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) - { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - break; - } - count++; - - if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) /* paranoid assertion*/ - { - nreset += clear_validity (keyblock->pkt->pkt.public_key); - release_kbnode (keyblock); - } - } - while ( !(rc = keydb_search (hd, &desc, 1)) ); - if (rc && rc != -1) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - } - if (opt.verbose) - log_info (_("%d keys processed (%d validity counts cleared)\n"), - count, nreset); -} - -/* - * Run the key validation procedure. - * - * This works this way: - * Step 1: Find all ultimately trusted keys (UTK). - * mark them all as seen and put them into klist. - * Step 2: loop max_cert_times - * Step 3: if OWNERTRUST of any key in klist is undefined - * ask user to assign ownertrust - * Step 4: Loop over all keys in the keyDB which are not marked seen - * Step 5: if key is revoked or expired - * mark key as seen - * continue loop at Step 4 - * Step 6: For each user ID of that key signed by a key in klist - * Calculate validity by counting trusted signatures. - * Set validity of user ID - * Step 7: If any signed user ID was found - * mark key as seen - * End Loop - * Step 8: Build a new klist from all fully trusted keys from step 6 - * End Loop - * Ready - * - */ -static int -validate_keys (int interactive) -{ - int rc = 0; - int quit=0; - struct key_item *klist = NULL; - struct key_item *k; - struct key_array *keys = NULL; - struct key_array *kar; - KEYDB_HANDLE kdb = NULL; - KBNODE node; - int depth; - int key_count; - int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate; - KeyHashTable stored,used,full_trust; - u32 start_time, next_expire; - - start_time = make_timestamp (); - next_expire = 0xffffffff; /* set next expire to the year 2106 */ - stored = new_key_hash_table (); - used = new_key_hash_table (); - full_trust = new_key_hash_table (); - /* Fixme: Instead of always building a UTK list, we could just build it - * here when needed */ - if (!utk_list) - { - log_info (_("no ultimately trusted keys found\n")); - goto leave; - } - - kdb = keydb_new (0); - - reset_trust_records (kdb,NULL); - - /* mark all UTKs as used and fully_trusted and set validity to - ultimate */ - for (k=utk_list; k; k = k->next) - { - KBNODE keyblock; - PKT_public_key *pk; - - keyblock = get_pubkeyblock (k->kid); - if (!keyblock) - { - log_error (_("public key of ultimately" - " trusted key %08lX not found\n"), (ulong)k->kid[1]); - continue; - } - mark_keyblock_seen (used, keyblock); - mark_keyblock_seen (stored, keyblock); - mark_keyblock_seen (full_trust, keyblock); - pk = keyblock->pkt->pkt.public_key; - for (node=keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - update_validity (pk, node->pkt->pkt.user_id, 0, TRUST_ULTIMATE); - } - if ( pk->expiredate && pk->expiredate >= start_time - && pk->expiredate < next_expire) - next_expire = pk->expiredate; - - release_kbnode (keyblock); - do_sync (); - } - - klist = utk_list; - - log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"), - opt.marginals_needed,opt.completes_needed,trust_model_string()); - - for (depth=0; depth < opt.max_cert_depth; depth++) - { - /* See whether we should assign ownertrust values to the keys in - utk_list. */ - ot_unknown = ot_undefined = ot_never = 0; - ot_marginal = ot_full = ot_ultimate = 0; - for (k=klist; k; k = k->next) - { - int min=0; - - /* 120 and 60 are as per RFC2440 */ - if(k->trust_value>=120) - min=TRUST_FULLY; - else if(k->trust_value>=60) - min=TRUST_MARGINAL; - - if(min!=k->min_ownertrust) - update_min_ownertrust(k->kid,min); - - if (interactive && k->ownertrust == TRUST_UNKNOWN) - { - k->ownertrust = ask_ownertrust (k->kid,min); - - if (k->ownertrust == -1) - { - quit=1; - goto leave; - } - } - - /* This can happen during transition from an old trustdb - before trust sigs. It can also happen if a user uses two - different versions of GnuPG or changes the --trust-model - setting. */ - if(k->ownertrust<min) - { - if(DBG_TRUST) - log_debug("key %08lX: " - "overriding ownertrust \"%s\" with \"%s\"\n", - (ulong)k->kid[1], - trust_value_to_string(k->ownertrust), - trust_value_to_string(min)); - - k->ownertrust=min; - } - - if (k->ownertrust == TRUST_UNKNOWN) - ot_unknown++; - else if (k->ownertrust == TRUST_UNDEFINED) - ot_undefined++; - else if (k->ownertrust == TRUST_NEVER) - ot_never++; - else if (k->ownertrust == TRUST_MARGINAL) - ot_marginal++; - else if (k->ownertrust == TRUST_FULLY) - ot_full++; - else if (k->ownertrust == TRUST_ULTIMATE) - ot_ultimate++; - } - - /* Find all keys which are signed by a key in kdlist */ - keys = validate_key_list (kdb, full_trust, klist, - start_time, &next_expire); - if (!keys) - { - log_error ("validate_key_list failed\n"); - rc = GPG_ERR_GENERAL; - goto leave; - } - - for (key_count=0, kar=keys; kar->keyblock; kar++, key_count++) - ; - - /* Store the calculated valididation status somewhere */ - if (opt.verbose > 1) - dump_key_array (depth, keys); - - for (kar=keys; kar->keyblock; kar++) - store_validation_status (depth, kar->keyblock, stored); - - log_info (_("checking at depth %d valid=%d" - " ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"), - depth, key_count, ot_unknown, ot_undefined, - ot_never, ot_marginal, ot_full, ot_ultimate ); - - /* Build a new kdlist from all fully valid keys in KEYS */ - if (klist != utk_list) - release_key_items (klist); - klist = NULL; - for (kar=keys; kar->keyblock; kar++) - { - for (node=kar->keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4)) - { - u32 kid[2]; - - /* have we used this key already? */ - keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid); - if(test_key_hash_table(used,kid)==0) - { - /* Normally we add both the primary and subkey - ids to the hash via mark_keyblock_seen, but - since we aren't using this hash as a skipfnc, - that doesn't matter here. */ - add_key_hash_table (used,kid); - k = new_key_item (); - k->kid[0]=kid[0]; - k->kid[1]=kid[1]; - k->ownertrust = - (get_ownertrust (kar->keyblock->pkt->pkt.public_key) - & TRUST_MASK); - k->min_ownertrust = - get_min_ownertrust(kar->keyblock->pkt->pkt.public_key); - k->trust_depth= - kar->keyblock->pkt->pkt.public_key->trust_depth; - k->trust_value= - kar->keyblock->pkt->pkt.public_key->trust_value; - if(kar->keyblock->pkt->pkt.public_key->trust_regexp) - k->trust_regexp= - xstrdup (kar->keyblock->pkt-> - pkt.public_key->trust_regexp); - k->next = klist; - klist = k; - break; - } - } - } - } - release_key_array (keys); - keys = NULL; - if (!klist) - break; /* no need to dive in deeper */ - } - - leave: - keydb_release (kdb); - release_key_array (keys); - release_key_items (klist); - release_key_hash_table (full_trust); - release_key_hash_table (used); - release_key_hash_table (stored); - if (!rc && !quit) /* mark trustDB as checked */ - { - if (next_expire == 0xffffffff || next_expire < start_time ) - tdbio_write_nextcheck (0); - else - { - tdbio_write_nextcheck (next_expire); - log_info (_("next trustdb check due at %s\n"), - strtimestamp (next_expire)); - } - - if(tdbio_update_version_record()!=0) - { - log_error(_("unable to update trustdb version record: " - "write failed: %s\n"), gpg_strerror (rc)); - tdbio_invalid(); - } - - do_sync (); - pending_check_trustdb = 0; - } - - return rc; -} diff --git a/g10/trustdb.h b/g10/trustdb.h deleted file mode 100644 index 414c37702..000000000 --- a/g10/trustdb.h +++ /dev/null @@ -1,86 +0,0 @@ -/* trustdb.h - Trust database - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TRUSTDB_H -#define G10_TRUSTDB_H - - -/* Trust values must be sorted in ascending order */ -#define TRUST_MASK 15 -#define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */ -#define TRUST_EXPIRED 1 /* e: calculation may be invalid */ -#define TRUST_UNDEFINED 2 /* q: not enough information for calculation */ -#define TRUST_NEVER 3 /* n: never trust this pubkey */ -#define TRUST_MARGINAL 4 /* m: marginally trusted */ -#define TRUST_FULLY 5 /* f: fully trusted */ -#define TRUST_ULTIMATE 6 /* u: ultimately trusted */ -/* trust values not covered by the mask */ -#define TRUST_FLAG_REVOKED 32 /* r: revoked */ -#define TRUST_FLAG_SUB_REVOKED 64 /* r: revoked but for subkeys */ -#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */ -#define TRUST_FLAG_PENDING_CHECK 256 /* a check-trustdb is pending */ - -/*-- trustdb.c --*/ -void register_trusted_key( const char *string ); -void check_trustdb (void); -void update_trustdb (void); -int setup_trustdb( int level, const char *dbname ); -void init_trustdb( void ); -void sync_trustdb( void ); - -const char *trust_value_to_string (unsigned int value); -int string_to_trust_value (const char *str); - -void revalidation_mark (void); -int trustdb_pending_check(void); - -int cache_disabled_value(PKT_public_key *pk); - -unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid); -int get_validity_info (PKT_public_key *pk, PKT_user_id *uid); -const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid); - -void list_trust_path( const char *username ); -int enum_cert_paths( void **context, ulong *lid, - unsigned *ownertrust, unsigned *validity ); -void enum_cert_paths_print( void **context, FILE *fp, - int refresh, ulong selected_lid ); - -void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck, - byte *marginals,byte *completes,byte *cert_depth); - -unsigned int get_ownertrust (PKT_public_key *pk); -unsigned int get_min_ownertrust (PKT_public_key *pk); -int get_ownertrust_info (PKT_public_key *pk); -const char *get_ownertrust_string (PKT_public_key *pk); - -void update_ownertrust (PKT_public_key *pk, unsigned int new_trust ); -int clear_ownertrusts (PKT_public_key *pk); - -/*-- tdbdump.c --*/ -void list_trustdb(const char *username); -void export_ownertrust(void); -void import_ownertrust(const char *fname); - -/*-- pkclist.c --*/ -int edit_ownertrust (PKT_public_key *pk, int mode ); - -#endif /*G10_TRUSTDB_H*/ diff --git a/g10/verify.c b/g10/verify.c deleted file mode 100644 index cfa373637..000000000 --- a/g10/verify.c +++ /dev/null @@ -1,197 +0,0 @@ -/* verify.c - verify signed data - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> /* for isatty() */ - -#include "options.h" -#include "packet.h" -#include "errors.h" -#include "iobuf.h" -#include "keydb.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "status.h" -#include "filter.h" -#include "ttyio.h" -#include "i18n.h" - - - -/**************** - * Assume that the input is a signature and verify it without - * generating any output. With no arguments, the signature packet - * is read from stdin (it may be a detached signature when not - * used in batch mode). If only a sigfile is given, it may be a complete - * signature or a detached signature in which case the signed stuff - * is expected from stdin. With more than 1 argument, the first should - * be a detached signature and the remaining files are the signed stuff. - */ - -int -verify_signatures( int nfiles, char **files ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - const char *sigfile; - int i, rc; - STRLIST sl; - - memset( &afx, 0, sizeof afx); - /* decide whether we should handle a detached or a normal signature, - * which is needed so that the code later can hash the correct data and - * not have a normal signature act as detached signature and ignoring the - * indended signed material from the 2nd file or stdin. - * 1. gpg <file - normal - * 2. gpg file - normal (or detached) - * 3. gpg file <file2 - detached - * 4. gpg file file2 - detached - * The question is how decide between case 2 and 3? The only way - * we can do it is by reading one byte from stdin and the unget - * it; the problem here is that we may be reading from the - * terminal (which could be detected using isatty() but won't work - * when under contol of a pty using program (e.g. expect)) and - * might get us in trouble when stdin is used for another purpose - * (--passphrase-fd 0). So we have to break with the behaviour - * prior to gpg 1.0.4 by assuming that case 3 is a normal - * signature (where file2 is ignored and require for a detached - * signature to indicate signed material comes from stdin by using - * case 4 with a file2 of "-". - * - * Actually we don't have to change anything here but can handle - * that all quite easily in mainproc.c - */ - - - sigfile = nfiles? *files : NULL; - - /* open the signature file */ - fp = iobuf_open(sigfile); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s': %s\n"), - print_fname_stdin(sigfile), strerror (errno)); - return rc; - } - handle_progress (&pfx, fp, sigfile); - - if( !opt.no_armor && use_armor_filter( fp ) ) - iobuf_push_filter( fp, armor_filter, &afx ); - - sl = NULL; - for(i=1 ; i < nfiles; i++ ) - add_to_strlist( &sl, files[i] ); - rc = proc_signature_packets( NULL, fp, sl, sigfile ); - free_strlist(sl); - iobuf_close(fp); - if( afx.no_openpgp_data && rc == -1 ) { - log_error(_("the signature could not be verified.\n" - "Please remember that the signature file (.sig or .asc)\n" - "should be the first file given on the command line.\n") ); - rc = 0; - } - - return rc; -} - - -void -print_file_status( int status, const char *name, int what ) -{ - char *p = xmalloc (strlen(name)+10); - sprintf(p, "%d %s", what, name ); - write_status_text( status, p ); - xfree (p); -} - - -static int -verify_one_file( const char *name ) -{ - iobuf_t fp; - armor_filter_context_t afx; - progress_filter_context_t pfx; - int rc; - - print_file_status( STATUS_FILE_START, name, 1 ); - fp = iobuf_open(name); - if( !fp ) { - rc = gpg_error_from_errno (errno); - log_error(_("can't open `%s': %s\n"), - print_fname_stdin(name), strerror (errno)); - print_file_status( STATUS_FILE_ERROR, name, 1 ); - return rc; - } - handle_progress (&pfx, fp, name); - - if( !opt.no_armor ) { - if( use_armor_filter( fp ) ) { - memset( &afx, 0, sizeof afx); - iobuf_push_filter( fp, armor_filter, &afx ); - } - } - - rc = proc_signature_packets( NULL, fp, NULL, name ); - iobuf_close(fp); - write_status( STATUS_FILE_DONE ); - return rc; -} - -/**************** - * Verify each file given in the files array or read the names of the - * files from stdin. - * Note: This function can not handle detached signatures. - */ -int -verify_files( int nfiles, char **files ) -{ - int i; - - if( !nfiles ) { /* read the filenames from stdin */ - char line[2048]; - unsigned int lno = 0; - - while( fgets(line, DIM(line), stdin) ) { - lno++; - if( !*line || line[strlen(line)-1] != '\n' ) { - log_error(_("input line %u too long or missing LF\n"), lno ); - return GPG_ERR_GENERAL; - } - /* This code does not work on MSDOS but how cares there are - * also no script languages available. We don't strip any - * spaces, so that we can process nearly all filenames */ - line[strlen(line)-1] = 0; - verify_one_file( line ); - } - - } - else { /* take filenames from the array */ - for(i=0; i < nfiles; i++ ) - verify_one_file( files[i] ); - } - return 0; -} diff --git a/include/ChangeLog b/include/ChangeLog deleted file mode 100644 index 5b343f5a0..000000000 --- a/include/ChangeLog +++ /dev/null @@ -1,403 +0,0 @@ -2003-09-04 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Drop TIGER/192 support. - - * types.h: Prefer using uint64_t when creating a 64-bit unsigned - type. This avoids a warning on compilers that support but complain - about unsigned long long. - - * util.h: Make sure that only ascii is passed to isfoo - functions. (From Werner on stable branch). - -2003-09-04 Werner Koch <wk@gnupg.org> - - * cipher.h (PUBKEY_USAGE_AUTH): Added. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * cipher.h (DBG_CIPHER,g10c_debug_mode): Removed. - -2003-06-11 Werner Koch <wk@gnupg.org> - - * cipher.h: Include gcrypt.h and mapped cipher algo names to - gcrypt ones. Removed twofish_old and skipjack. Removed all - handle definitions and other raerely used stuff. This file will - eventually be entirely removed. - -2003-06-10 Werner Koch <wk@gnupg.org> - - * types.h (struct strlist): Removed. - -2003-05-24 David Shaw <dshaw@jabberwocky.com> - - * cipher.h, i18n.h, iobuf.h, memory.h, mpi.h, types.h, util.h: - Edit all preprocessor instructions to remove whitespace before the - '#'. This is not required by C89, but there are some compilers - out there that don't like it. - -2003-05-14 David Shaw <dshaw@jabberwocky.com> - - * types.h: Add initializer macros for 64-bit unsigned type. - -2003-05-02 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add constants for compression algorithms. - -2003-03-11 David Shaw <dshaw@jabberwocky.com> - - * http.h: Add HTTP_FLAG_TRY_SRV. - -2003-02-11 David Shaw <dshaw@jabberwocky.com> - - * types.h: Try and use uint64_t for a 64-bit type. - -2003-02-04 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add constants for new SHAs. - -2002-11-13 David Shaw <dshaw@jabberwocky.com> - - * util.h [__CYGWIN32__]: Don't need the registry prototypes. From - Werner on stable branch. - -2002-11-06 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add wipememory2() macro (same as wipememory, but can - specify the byte to wipe with). - -2002-10-31 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Prefixed all RISC OS prototypes with - riscos_* - - * zlib-riscos.h: New. This is macro magic in order to make the - zlib library calls indeed call the RISC OS ZLib module. - -2002-10-31 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add wipememory() macro. - -2002-10-29 Stefan Bellon <sbellon@sbellon.de> - - * util.h: Added parameter argument to make_basename() needed for - filetype support. - [__riscos__]: Added prototype. - -2002-10-28 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added prototypes for new filetype support. - -2002-10-19 David Shaw <dshaw@jabberwocky.com> - - * distfiles, _regex.h: Add _regex.h from glibc 2.3.1. - -2002-10-14 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Go to KEYSERVER_PROTO_VERSION 1. - -2002-10-08 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add new error code KEYSERVER_UNREACHABLE. - -2002-10-03 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add new log_warning logger command which can be switched - between log_info and log_error via log_set_strict. - -2002-09-24 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add some new error codes for better GPA support. - -2002-09-10 Werner Koch <wk@gnupg.org> - - * mpi.h (mpi_is_protected, mpi_set_protect_flag) - (mpi_clear_protect_flag): Removed. - (mpi_get_nbit_info, mpi_set_nbit_info): Removed. - -2002-08-13 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add AES aliases for RIJNDAEL algo numbers. - -2002-08-07 David Shaw <dshaw@jabberwocky.com> - - * cipher.h: Add md_algo_present(). - -2002-08-06 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added riscos_getchar(). - -2002-06-21 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Further moving away of RISC OS specific - stuff from general code. - -2002-06-20 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Added riscos_set_filetype(). - -2002-06-14 David Shaw <dshaw@jabberwocky.com> - - * util.h: Add pop_strlist() from strgutil.c. - -2002-06-07 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: RISC OS needs strings.h for strcasecmp() - and strncasecmp(). - -2002-05-22 Werner Koch <wk@gnupg.org> - - * util.h: Add strncasecmp. Removed stricmp and memicmp. - -2002-05-10 Stefan Bellon <sbellon@sbellon.de> - - * mpi.h: New function mpi_debug_alloc_like for M_DEBUG. - - * util.h [__riscos__]: Make use of __func__ that later - Norcroft compiler provides. - - * memory.h: Fixed wrong definition of m_alloc_secure_clear. - -2002-04-23 David Shaw <dshaw@jabberwocky.com> - - * util.h: New function answer_is_yes_no_default() to give a - default answer. - -2002-04-22 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Removed riscos_open, riscos_fopen and - riscos_fstat as those special versions aren't needed anymore. - -2002-02-19 David Shaw <dshaw@jabberwocky.com> - - * keyserver.h: Add KEYSERVER_NOT_SUPPORTED for unsupported actions - (say, a keyserver that has no way to search, or a readonly - keyserver that has no way to add). - -2002-01-02 Stefan Bellon <sbellon@sbellon.de> - - * util.h [__riscos__]: Updated prototype list. - - * types.h [__riscos__]: Changed comment wording. - -2001-12-27 David Shaw <dshaw@jabberwocky.com> - - * KEYSERVER_SCHEME_NOT_FOUND should be 127 to match the POSIX - system() (via /bin/sh) way of signaling this. - - * Added G10ERR_KEYSERVER - -2001-12-27 Werner Koch <wk@gnupg.org> - - * util.h [MINGW32]: Fixed name of include file. - -2001-12-22 Timo Schulz <ts@winpt.org> - - * util.h (is_file_compressed): New. - -2001-12-19 Werner Koch <wk@gnupg.org> - - * util.h [CYGWIN32]: Allow this as an alias for MINGW32. Include - stdarg.h becuase we use the va_list type. By Disastry. - -2001-09-28 Werner Koch <wk@gnupg.org> - - * cipher.h (PUBKEY_USAGE_CERT): New. - -2001-09-07 Werner Koch <wk@gnupg.org> - - * util.h: Add strsep(). - -2001-08-30 Werner Koch <wk@gnupg.org> - - * cipher.h (DEK): Added use_mdc. - -2001-08-24 Werner Koch <wk@gnupg.org> - - * cipher.h (md_write): Made buf arg const. - -2001-08-20 Werner Koch <wk@gnupg.org> - - * cipher.h (DEK): Added algo_info_printed; - - * util.h [__riscos__]: Added prototypes and made sure that we - never use __attribute__. - * cipher.h, iobuf.h, memory.h, mpi.h [__riscos__]: extern hack. - * i18n.h [__riscos__]: Use another include file - -2001-05-30 Werner Koch <wk@gnupg.org> - - * ttyio.h (tty_printf): Add missing parenthesis for non gcc. - * http.h: Removed trailing comma to make old ccs happy. Both are - by Albert Chin. - -2001-05-25 Werner Koch <wk@gnupg.org> - - * ttyio.h (tty_printf): Add printf attribute. - -2001-04-23 Werner Koch <wk@gnupg.org> - - * http.h: New flag HTTP_FLAG_NO_SHUTDOWN. - -2001-04-13 Werner Koch <wk@gnupg.org> - - * iobuf.h: Removed iobuf_fopen. - -2001-03-01 Werner Koch <wk@gnupg.org> - - * errors.h (G10ERR_UNU_SECKEY,G10ERR_UNU_PUBKEY): New - -2000-11-30 Werner Koch <wk@gnupg.org> - - * iobuf.h (iobuf_translate_file_handle): Add prototype. - -2000-11-11 Paul Eggert <eggert@twinsun.com> - - * iobuf.h (iobuf_get_filelength): Now returns off_t, not u32. - (struct iobuf_struct, iobuf_set_limit, - iobuf_tell, iobuf_seek): Use off_t, not ulong, for file offsets. - -2000-10-12 Werner Koch <wk@gnupg.org> - - * mpi.h: Changed the way mpi_limb_t is defined. - -Wed Sep 6 17:55:47 CEST 2000 Werner Koch <wk@openit.de> - - * iobuf.c (IOBUF_FILELENGTH_LIMIT): New. - -2000-03-14 14:03:43 Werner Koch (wk@habibti.openit.de) - - * types.h (HAVE_U64_TYPEDEF): Defined depending on configure test. - -Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de> - - * types.h (HAVE_U64_TYPEDEF): Add a test for _LONGLONG which fixes - this long living SGI bug. Reported by Alec Habig. - -Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de> - - * iobuf.h (IOBUFCTRL_CANCEL): Nww. - -Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de> - - * errors.h (G10ERR_NOT_PROCESSED): New. - -Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * i18n.h: Add support for simple-gettext. - -Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * util.h (stricmp): Use strcasecmp as replacement. - -Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - - * cipher.h (MD_HANDLE): Assigned a structure name. - -Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (BLOWFISH160): Removed. - -Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (DEK): increased max. key length to 32 bytes - - -Sat Feb 20 21:40:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * g10lib.h: Removed file and changed all files that includes this. - -Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * types.h (STRLIST): Add field flags. - -Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (CIPHER_ALGO_TWOFISH): Chnaged ID to 10 and renamed - the old experimenatl algorithm to xx_OLD. - -Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de> - - * cipher.h (MD_BUFFER_SIZE): Removed. - -Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * types.h: fix for SUNPRO_C - -Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de> - - * mpi.h (MPI): Changed the structure name to gcry_mpi and - changed all users. - -Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_get_temp_buffer): New. - -Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_get): Now uses .nofast - (iobuf_get2): Removed. - -Mon Sep 14 09:17:22 1998 Werner Koch (wk@(none)) - - * util.h (HAVE_ATEXIT): New. - (HAVE_RAISE): New. - -Mon Jul 6 10:41:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (PUBKEY_USAGE_): New. - -Mon Jul 6 09:49:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * iobuf.h (iobuf_set_error): New. - (iobuf_error): New. - -Sat Jun 13 17:31:32 1998 Werner Koch (wk@isil.d.shuttle.de) - - * g10lib.h: New as interface for the g10lib. - -Mon Jun 8 22:14:48 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (CIPHER_ALGO_CAST5): Changed name from .. CAST - -Thu May 21 13:25:51 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h: removed ROT 5 and changed one id and add dummy - -Tue May 19 18:09:05 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (DIGEST_ALGO_TIGER): Chnaged id from 101 to 6. - -Mon May 4 16:37:17 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (PUBKEY_ALGO_ELGAMAL_E): New, with value of the - old one. - * (is_ELGAMAL, is_RSA): New macros - -Sun Apr 26 14:35:24 1998 Werner Koch (wk@isil.d.shuttle.de) - - * types.h: New type u64 - -Mon Mar 9 12:59:55 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h: Included dsa.h. - -Tue Mar 3 15:11:21 1998 Werner Koch (wk@isil.d.shuttle.de) - - * cipher.h (random.h): Add new header and move all relevalt - functions to this header. - - - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - diff --git a/include/_regex.h b/include/_regex.h deleted file mode 100644 index fac441dc6..000000000 --- a/include/_regex.h +++ /dev/null @@ -1,574 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library. - Copyright (C) 1985,1989-93,1995-98,2000,2001,2002 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* POSIX says that <sys/types.h> must be included (by the caller) before - <regex.h>. */ - -#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS -/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it - should be there. */ -# include <stddef.h> -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned long int reg_syntax_t; - -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \<digit> matches <digit>. - If not set, then \<digit> is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, turn on internal regex debugging. - If not set, and debugging was on, turn it off. - This only works if regex.c is compiled -DDEBUG. - We define this bit always, so that all that's needed to turn on - debugging is to recompile regex.c; the calling code can always have - this bit set, and it won't affect anything in the normal case. */ -#define RE_DEBUG (RE_NO_GNU_OPS << 1) - -/* If this bit is set, a syntactically invalid interval is treated as - a string of ordinary characters. For example, the ERE 'a{1' is - treated as 'a\{1'. */ -#define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ - & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \ - | RE_CONTEXT_INVALID_OPS )) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ - | RE_INVALID_INTERVAL_ORD) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is - removed and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -# undef RE_DUP_MAX -#endif -/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ -#define RE_DUP_MAX (0x7fff) - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ -#ifdef _XOPEN_SOURCE - REG_ENOSYS = -1, /* This will never happen for this implementation. */ -#endif - - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - -#ifndef RE_TRANSLATE_TYPE -# define RE_TRANSLATE_TYPE char * -#endif - -struct re_pattern_buffer -{ -/* [[[begin pattern_buffer]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long int allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long int used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation - is applied to a pattern when it is compiled and to a string - when it is matched. */ - RE_TRANSLATE_TYPE translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ - unsigned can_be_null : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - unsigned regs_allocated : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned fastmap_accurate : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned no_sub : 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ - unsigned not_bol : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned not_eol : 1; - - /* If true, an anchor at a newline matches. */ - unsigned newline_anchor : 1; - -/* [[[end pattern_buffer]]] */ -}; - -typedef struct re_pattern_buffer regex_t; - -/* Type for byte offsets within the string. POSIX mandates this. */ -typedef int regoff_t; - - -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -# define RE_NREGS 30 -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -/* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -# define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -# define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, size_t length, - struct re_pattern_buffer *buffer)); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -extern void re_set_registers - _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, - unsigned num_regs, regoff_t *starts, regoff_t *ends)); - -#if defined _REGEX_RE_COMP || defined _LIBC -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp _RE_ARGS ((const char *)); -extern int re_exec _RE_ARGS ((const char *)); -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if defined restrict || 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif -/* gcc 3.1 and up support the [restrict] syntax. */ -#ifndef __restrict_arr -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define __restrict_arr __restrict -# else -# define __restrict_arr -# endif -#endif - -/* POSIX compatibility. */ -extern int regcomp _RE_ARGS ((regex_t *__restrict __preg, - const char *__restrict __pattern, - int __cflags)); - -extern int regexec _RE_ARGS ((const regex_t *__restrict __preg, - const char *__restrict __string, size_t __nmatch, - regmatch_t __pmatch[__restrict_arr], - int __eflags)); - -extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, - char *__errbuf, size_t __errbuf_size)); - -extern void regfree _RE_ARGS ((regex_t *__preg)); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/include/cipher.h b/include/cipher.h deleted file mode 100644 index e7e36c6d5..000000000 --- a/include/cipher.h +++ /dev/null @@ -1,97 +0,0 @@ -/* cipher.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_CIPHER_H -#define G10_CIPHER_H - -#include <gcrypt.h> - -#define CIPHER_ALGO_NONE GCRY_CIPHER_NONE -#define CIPHER_ALGO_IDEA GCRY_CIPHER_IDEA -#define CIPHER_ALGO_3DES GCRY_CIPHER_3DES -#define CIPHER_ALGO_CAST5 GCRY_CIPHER_CAST5 -#define CIPHER_ALGO_BLOWFISH GCRY_CIPHER_BLOWFISH /* 128 bit */ -#define CIPHER_ALGO_SAFER_SK128 GCRY_CIPHER_SK128 -#define CIPHER_ALGO_DES_SK GCRY_CIPHER_DES_SK -#define CIPHER_ALGO_AES GCRY_CIPHER_AES -#define CIPHER_ALGO_AES192 GCRY_CIPHER_AES192 -#define CIPHER_ALGO_AES256 GCRY_CIPHER_AES256 -#define CIPHER_ALGO_RIJNDAEL CIPHER_ALGO_AES -#define CIPHER_ALGO_RIJNDAEL192 CIPHER_ALGO_AES192 -#define CIPHER_ALGO_RIJNDAEL256 CIPHER_ALGO_AES256 -#define CIPHER_ALGO_TWOFISH GCRY_CIPHER_TWOFISH /* 256 bit */ -#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */ - -#define PUBKEY_ALGO_RSA GCRY_PK_RSA -#define PUBKEY_ALGO_RSA_E GCRY_PK_RSA_E -#define PUBKEY_ALGO_RSA_S GCRY_PK_RSA_S -#define PUBKEY_ALGO_ELGAMAL_E GCRY_PK_ELG_E -#define PUBKEY_ALGO_DSA GCRY_PK_DSA -#define PUBKEY_ALGO_ELGAMAL GCRY_PK_ELG - -#define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN -#define PUBKEY_USAGE_ENC GCRY_PK_USAGE_ENCR -#define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/ -#define PUBKEY_USAGE_AUTH 8 - -#define DIGEST_ALGO_MD5 GCRY_MD_MD5 -#define DIGEST_ALGO_SHA1 GCRY_MD_SHA1 -#define DIGEST_ALGO_RMD160 GCRY_MD_RMD160 -#define DIGEST_ALGO_SHA256 GCRY_MD_SHA256 -#define DIGEST_ALGO_SHA384 GCRY_MD_SHA384 -#define DIGEST_ALGO_SHA512 GCRY_MD_SHA512 - -#define COMPRESS_ALGO_NONE 0 -#define COMPRESS_ALGO_ZIP 1 -#define COMPRESS_ALGO_ZLIB 2 - -#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \ - || (a)==PUBKEY_ALGO_RSA_S ) -#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E) - -typedef struct { - int algo; - int keylen; - int algo_info_printed; - int use_mdc; - byte key[32]; /* this is the largest used keylen (256 bit) */ -} DEK; - - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int g10_opt_verbose; -EXTERN_UNLESS_MAIN_MODULE const char *g10_opt_homedir; - - - -#define PUBKEY_MAX_NPKEY 4 -#define PUBKEY_MAX_NSKEY 6 -#define PUBKEY_MAX_NSIG 2 -#define PUBKEY_MAX_NENC 2 - -#define MD_HANDLE gcry_md_hd_t -#define CIPHER_HANDLE gcry_cipher_hd_t - -#endif /*G10_CIPHER_H*/ diff --git a/include/distfiles b/include/distfiles deleted file mode 100644 index b11749d78..000000000 --- a/include/distfiles +++ /dev/null @@ -1,13 +0,0 @@ -cipher.h -errors.h -memory.h -mpi.h -types.h -util.h -i18n.h -host2net.h -http.h -keyserver.h -_regex.h - -ChangeLog diff --git a/include/errors.h b/include/errors.h deleted file mode 100644 index ed437fa99..000000000 --- a/include/errors.h +++ /dev/null @@ -1,101 +0,0 @@ -/* errors.h - error code - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef GNUPG_INCLUDE_ERRORS_H -#define GNUPG_INCLUDE_ERRORS_H - -#if 0 -#error Remove this file after replacing all error codes with those -#error from libgpg-error. The numerical values are identical, though. -#endif - - -#if 0 /* Not used anymore. */ -#define G10ERR_GENERAL 1 -#define G10ERR_UNKNOWN_PACKET 2 -#define G10ERR_UNKNOWN_VERSION 3 /* Unknown version (in packet) */ -#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */ -#define G10ERR_DIGEST_ALGO 5 /* Unknown digest algorithm */ -#define G10ERR_BAD_PUBKEY 6 /* Bad public key */ -#define G10ERR_BAD_SECKEY 7 /* Bad secret key */ -#define G10ERR_BAD_SIGN 8 /* Bad signature */ -#define G10ERR_NO_PUBKEY 9 /* public key not found */ -#define G10ERR_CHECKSUM 10 /* checksum error */ -#define G10ERR_BAD_PASS 11 /* Bad passphrase */ -#define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */ -#define G10ERR_KEYRING_OPEN 13 -#define G10ERR_INVALID_PACKET 14 -#define G10ERR_INVALID_ARMOR 15 -#define G10ERR_NO_USER_ID 16 -#define G10ERR_NO_SECKEY 17 /* secret key not available */ -#define G10ERR_WRONG_SECKEY 18 /* wrong seckey used */ -#define G10ERR_UNSUPPORTED 19 -#define G10ERR_BAD_KEY 20 /* bad (session) key */ -#define G10ERR_READ_FILE 21 -#define G10ERR_WRITE_FILE 22 -#define G10ERR_COMPR_ALGO 23 /* Unknown compress algorithm */ -#define G10ERR_OPEN_FILE 24 -#define G10ERR_CREATE_FILE 25 -#define G10ERR_PASSPHRASE 26 /* invalid passphrase */ -#define G10ERR_NI_PUBKEY 27 -#define G10ERR_NI_CIPHER 28 -#define G10ERR_SIG_CLASS 29 -#define G10ERR_BAD_MPI 30 -#define G10ERR_RESOURCE_LIMIT 31 -#define G10ERR_INV_KEYRING 32 -#define G10ERR_TRUSTDB 33 /* a problem with the trustdb */ -#define G10ERR_BAD_CERT 34 /* bad certicate */ -#define G10ERR_INV_USER_ID 35 -#define G10ERR_CLOSE_FILE 36 -#define G10ERR_RENAME_FILE 37 -#define G10ERR_DELETE_FILE 38 -#define G10ERR_UNEXPECTED 39 -#define G10ERR_TIME_CONFLICT 40 -#define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */ -#define G10ERR_FILE_EXISTS 42 -#define G10ERR_WEAK_KEY 43 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_WRONG_KEYLEN 44 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_INV_ARG 45 -#define G10ERR_BAD_URI 46 /* syntax error in URI */ -#define G10ERR_INVALID_URI 47 /* e.g. unsupported scheme */ -#define G10ERR_NETWORK 48 /* general network error */ -#define G10ERR_UNKNOWN_HOST 49 -#define G10ERR_SELFTEST_FAILED 50 -#define G10ERR_NOT_ENCRYPTED 51 -#define G10ERR_NOT_PROCESSED 52 -#define G10ERR_UNU_PUBKEY 53 -#define G10ERR_UNU_SECKEY 54 -#define G10ERR_KEYSERVER 55 -#endif - -#ifndef HAVE_STRERROR -char *strerror( int n ); -#endif - -#endif /*GNUPG_INCLUDE_ERRORS_H*/ - - - - - - - - - - diff --git a/include/host2net.h b/include/host2net.h deleted file mode 100644 index 0f12a8e1d..000000000 --- a/include/host2net.h +++ /dev/null @@ -1,43 +0,0 @@ -/* host2net.h - Some macros - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_HOST2NET_H -#define G10_HOST2NET_H - -#include "types.h" - -#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \ - (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3))) -#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1))) -#define ulongtobuf( p, a ) do { \ - ((byte*)p)[0] = a >> 24; \ - ((byte*)p)[1] = a >> 16; \ - ((byte*)p)[2] = a >> 8; \ - ((byte*)p)[3] = a ; \ - } while(0) -#define ushorttobuf( p, a ) do { \ - ((byte*)p)[0] = a >> 8; \ - ((byte*)p)[1] = a ; \ - } while(0) -#define buftou32( p) buftoulong( (p) ) -#define u32tobuf( p, a) ulongtobuf( (p), (a) ) - - -#endif /*G10_HOST2NET_H*/ diff --git a/include/http.h b/include/http.h deleted file mode 100644 index b53ac9f9f..000000000 --- a/include/http.h +++ /dev/null @@ -1,82 +0,0 @@ -/* http.h - HTTP protocol handler - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_HTTP_H -#define G10_HTTP_H 1 - -#include "iobuf.h" - -struct uri_tuple { - struct uri_tuple *next; - const char *name; /* a pointer into name */ - char *value; /* a pointer to value (a Nul is always appended) */ - size_t valuelen; /* and the real length of the value */ - /* because the value may contain embedded Nuls */ -}; -typedef struct uri_tuple *URI_TUPLE; - -struct parsed_uri { - /* all these pointers point into buffer; most stuff is not escaped */ - char *scheme; /* pointer to the scheme string (lowercase) */ - char *host; /* host (converted to lowercase) */ - ushort port; /* port (always set if the host is set) */ - char *path; /* the path */ - URI_TUPLE params; /* ";xxxxx" */ - URI_TUPLE query; /* "?xxx=yyy" */ - char buffer[1]; /* buffer which holds a (modified) copy of the URI */ -}; -typedef struct parsed_uri *PARSED_URI; - -typedef enum { - HTTP_REQ_GET = 1, - HTTP_REQ_HEAD = 2, - HTTP_REQ_POST = 3 -} HTTP_REQ_TYPE; - -enum { /* put flag values into an enum, so that gdb can display them */ - HTTP_FLAG_TRY_PROXY = 1, - HTTP_FLAG_NO_SHUTDOWN = 2, - HTTP_FLAG_TRY_SRV = 3 -}; - -struct http_context { - int initialized; - unsigned int status_code; - int sock; - int in_data; - IOBUF fp_read; - IOBUF fp_write; - int is_http_0_9; - PARSED_URI uri; - HTTP_REQ_TYPE req_type; - byte *buffer; /* line buffer */ - unsigned buffer_size; - unsigned int flags; -}; -typedef struct http_context *HTTP_HD; - -int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, - unsigned int flags ); -void http_start_data( HTTP_HD hd ); -int http_wait_response( HTTP_HD hd, unsigned int *ret_status ); -void http_close( HTTP_HD hd ); - -int http_open_document( HTTP_HD hd, const char *document, unsigned int flags ); - -#endif /*G10_HTTP_H*/ diff --git a/include/i18n.h b/include/i18n.h deleted file mode 100644 index 20c2570ab..000000000 --- a/include/i18n.h +++ /dev/null @@ -1,54 +0,0 @@ -/* i18n.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_I18N_H -#define G10_I18N_H - -#ifdef USE_SIMPLE_GETTEXT -int set_gettext_file( const char *filename ); -const char *gettext( const char *msgid ); - -#define _(a) gettext (a) -#define N_(a) (a) - -#else -#ifdef HAVE_LOCALE_H -#include <locale.h> /* suggested by Ernst Molitor */ -#endif - -#ifdef ENABLE_NLS -#ifndef __riscos__ -#include <libintl.h> -#else -#include "libgettext.h" -#endif /* __riscos__ */ -#define _(a) gettext (a) -#ifdef gettext_noop -#define N_(a) gettext_noop (a) -#else -#define N_(a) (a) -#endif -#else -#define _(a) (a) -#define N_(a) (a) -#endif -#endif /* !USE_SIMPLE_GETTEXT */ - -#endif /*G10_I18N_H*/ diff --git a/include/keyserver.h b/include/keyserver.h deleted file mode 100644 index 33c1b318b..000000000 --- a/include/keyserver.h +++ /dev/null @@ -1,42 +0,0 @@ -/* keyserver.h - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef _KEYSERVER_H_ -#define _KEYSERVER_H_ - -#define KEYSERVER_PROTO_VERSION 1 - -/* These are usable for return codes for the gpgkeys_ process, and - also KEY FAILED codes. */ -#define KEYSERVER_OK 0 /* not an error */ -#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */ -#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */ -#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */ -#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */ -#define KEYSERVER_NO_MEMORY 5 /* out of memory */ -#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */ -#define KEYSERVER_KEY_EXISTS 7 /* key already exists */ -#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */ -#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */ - -/* Must be 127 due to shell internal magic. */ -#define KEYSERVER_SCHEME_NOT_FOUND 127 - -#endif /* !_KEYSERVER_H_ */ diff --git a/include/memory.h b/include/memory.h deleted file mode 100644 index 959f2999e..000000000 --- a/include/memory.h +++ /dev/null @@ -1,93 +0,0 @@ -/* memory.h - memory allocation - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_MEMORY_H -#define G10_MEMORY_H - -#ifdef M_DEBUG -#ifndef STR -#define STR(v) #v -#endif -#ifndef __riscos__ -#define M_DBGINFO(a) __FUNCTION__ "["__FILE__ ":" STR(a) "]" -#else /* __riscos__ */ -#define M_DBGINFO(a) "["__FILE__ ":" STR(a) "]" -#endif /* __riscos__ */ -#define m_alloc(n) m_debug_alloc((n), M_DBGINFO( __LINE__ ) ) -#define m_alloc_clear(n) m_debug_alloc_clear((n), M_DBGINFO(__LINE__) ) -#define m_alloc_secure(n) m_debug_alloc((n), M_DBGINFO(__LINE__) ) -#define m_alloc_secure_clear(n) m_debug_alloc_secure_clear((n), M_DBGINFO(__LINE__) ) -#define m_realloc(n,m) m_debug_realloc((n),(m), M_DBGINFO(__LINE__) ) -#define m_free(n) m_debug_free((n), M_DBGINFO(__LINE__) ) -#define m_check(n) m_debug_check((n), M_DBGINFO(__LINE__) ) -/*#define m_copy(a) m_debug_copy((a), M_DBGINFO(__LINE__) )*/ -#define m_strdup(a) m_debug_strdup((a), M_DBGINFO(__LINE__) ) - -void *m_debug_alloc( size_t n, const char *info ); -void *m_debug_alloc_clear( size_t n, const char *info ); -void *m_debug_alloc_secure( size_t n, const char *info ); -void *m_debug_alloc_secure_clear( size_t n, const char *info ); -void *m_debug_realloc( void *a, size_t n, const char *info ); -void m_debug_free( void *p, const char *info ); -void m_debug_check( const void *a, const char *info ); -/*void *m_debug_copy( const void *a, const char *info );*/ -char *m_debug_strdup( const char *a, const char *info ); - -#else -void *m_alloc( size_t n ); -void *m_alloc_clear( size_t n ); -void *m_alloc_secure( size_t n ); -void *m_alloc_secure_clear( size_t n ); -void *m_realloc( void *a, size_t n ); -void m_free( void *p ); -void m_check( const void *a ); -/*void *m_copy( const void *a );*/ -char *m_strdup( const char * a); -#endif - -size_t m_size( const void *a ); -void m_print_stats(const char *prefix); - -/*-- secmem.c --*/ -void secmem_init( size_t npool ); -void secmem_term( void ); -void *secmem_malloc( size_t size ); -void *secmem_realloc( void *a, size_t newsize ); -void secmem_free( void *a ); -int m_is_secure( const void *p ); -void secmem_dump_stats(void); -void secmem_set_flags( unsigned flags ); -unsigned secmem_get_flags(void); - - -#define DBG_MEMORY memory_debug_mode -#define DBG_MEMSTAT memory_stat_debug_mode - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif -EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode; -EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; - -#endif /*G10_MEMORY_H*/ diff --git a/include/mpi.h b/include/mpi.h deleted file mode 100644 index 424e591a0..000000000 --- a/include/mpi.h +++ /dev/null @@ -1,201 +0,0 @@ -/* mpi.h - Multi Precision Integers - * Copyright (C) 1994, 1996, 1998, 1999, - * 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - * The GNU MP Library itself is published under the LGPL; - * however I decided to publish this code under the plain GPL. - */ - -#ifndef G10_MPI_H -#define G10_MPI_H - -#include <gcrypt.h> - -#if 0 - - -#include <config.h> -#include <stdio.h> -#include "iobuf.h" -#include "types.h" -#include "memory.h" - -#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT - typedef unsigned int mpi_limb_t; - typedef signed int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG - typedef unsigned long int mpi_limb_t; - typedef signed long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG - typedef unsigned long long int mpi_limb_t; - typedef signed long long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT - typedef unsigned short int mpi_limb_t; - typedef signed short int mpi_limb_signed_t; -#else -#error BYTES_PER_MPI_LIMB does not match any C type -#endif -#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) - -#ifndef EXTERN_UNLESS_MAIN_MODULE -#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE) -#define EXTERN_UNLESS_MAIN_MODULE extern -#else -#define EXTERN_UNLESS_MAIN_MODULE -#endif -#endif - -#define DBG_MPI mpi_debug_mode -EXTERN_UNLESS_MAIN_MODULE int mpi_debug_mode; - - -struct gcry_mpi { - int alloced; /* array size (# of allocated limbs) */ - int nlimbs; /* number of valid limbs */ - int nbits; /* the real number of valid bits (info only) */ - int sign; /* indicates a negative number */ - unsigned flags; /* bit 0: array must be allocated in secure memory space */ - /* bit 1: not used */ - /* bit 2: the limb is a pointer to some m_alloced data */ - mpi_limb_t *d; /* array with the limbs */ -}; - -typedef struct gcry_mpi *MPI; - -#define MPI_NULL NULL - -#define mpi_get_nlimbs(a) ((a)->nlimbs) -#define mpi_is_neg(a) ((a)->sign) - -/*-- mpiutil.c --*/ - -#ifdef M_DEBUG -#define mpi_alloc(n) mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) ) -#define mpi_alloc_secure(n) mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) ) -#define mpi_alloc_like(n) mpi_debug_alloc_like((n), M_DBGINFO( __LINE__ ) ) -#define mpi_free(a) mpi_debug_free((a), M_DBGINFO(__LINE__) ) -#define mpi_resize(a,b) mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) ) -#define mpi_copy(a) mpi_debug_copy((a), M_DBGINFO(__LINE__) ) -MPI mpi_debug_alloc( unsigned nlimbs, const char *info ); -MPI mpi_debug_alloc_secure( unsigned nlimbs, const char *info ); -MPI mpi_debug_alloc_like( MPI a, const char *info ); -void mpi_debug_free( MPI a, const char *info ); -void mpi_debug_resize( MPI a, unsigned nlimbs, const char *info ); -MPI mpi_debug_copy( MPI a, const char *info ); -#else -MPI mpi_alloc( unsigned nlimbs ); -MPI mpi_alloc_secure( unsigned nlimbs ); -MPI mpi_alloc_like( MPI a ); -void mpi_free( MPI a ); -void mpi_resize( MPI a, unsigned nlimbs ); -MPI mpi_copy( MPI a ); -#endif -#define mpi_is_opaque(a) ((a) && ((a)->flags&4)) -MPI mpi_set_opaque( MPI a, void *p, int len ); -void *mpi_get_opaque( MPI a, int *len ); -#define mpi_is_secure(a) ((a) && ((a)->flags&1)) -void mpi_set_secure( MPI a ); -void mpi_clear( MPI a ); -void mpi_set( MPI w, MPI u); -void mpi_set_ui( MPI w, ulong u); -MPI mpi_alloc_set_ui( unsigned long u); -void mpi_m_check( MPI a ); -void mpi_swap( MPI a, MPI b); - -/*-- mpicoder.c --*/ -int mpi_write( IOBUF out, MPI a ); -#ifdef M_DEBUG -#define mpi_read(a,b,c) mpi_debug_read((a),(b),(c), M_DBGINFO( __LINE__ ) ) -MPI mpi_debug_read(IOBUF inp, unsigned *nread, int secure, const char *info); -#else -MPI mpi_read(IOBUF inp, unsigned *nread, int secure); -#endif -MPI mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure); -int mpi_fromstr(MPI val, const char *str); -int mpi_print( FILE *fp, MPI a, int mode ); -void g10_log_mpidump( const char *text, MPI a ); -u32 mpi_get_keyid( MPI a, u32 *keyid ); -byte *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign ); -byte *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign ); -void mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign ); - -#define log_mpidump g10_log_mpidump - -/*-- mpi-add.c --*/ -void mpi_add_ui(MPI w, MPI u, ulong v ); -void mpi_add(MPI w, MPI u, MPI v); -void mpi_addm(MPI w, MPI u, MPI v, MPI m); -void mpi_sub_ui(MPI w, MPI u, ulong v ); -void mpi_sub( MPI w, MPI u, MPI v); -void mpi_subm( MPI w, MPI u, MPI v, MPI m); - -/*-- mpi-mul.c --*/ -void mpi_mul_ui(MPI w, MPI u, ulong v ); -void mpi_mul_2exp( MPI w, MPI u, ulong cnt); -void mpi_mul( MPI w, MPI u, MPI v); -void mpi_mulm( MPI w, MPI u, MPI v, MPI m); - -/*-- mpi-div.c --*/ -ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor ); -void mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor ); -void mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor ); -void mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor ); -void mpi_tdiv_r( MPI rem, MPI num, MPI den); -void mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den); -void mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count ); -int mpi_divisible_ui(MPI dividend, ulong divisor ); - -/*-- mpi-gcd.c --*/ -int mpi_gcd( MPI g, MPI a, MPI b ); - -/*-- mpi-pow.c --*/ -void mpi_pow( MPI w, MPI u, MPI v); -void mpi_powm( MPI res, MPI base, MPI exp, MPI mod); - -/*-- mpi-mpow.c --*/ -void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod); - -/*-- mpi-cmp.c --*/ -int mpi_cmp_ui( MPI u, ulong v ); -int mpi_cmp( MPI u, MPI v ); - -/*-- mpi-scan.c --*/ -int mpi_getbyte( MPI a, unsigned idx ); -void mpi_putbyte( MPI a, unsigned idx, int value ); -unsigned mpi_trailing_zeros( MPI a ); - -/*-- mpi-bit.c --*/ -void mpi_normalize( MPI a ); -unsigned mpi_get_nbits( MPI a ); -int mpi_test_bit( MPI a, unsigned n ); -void mpi_set_bit( MPI a, unsigned n ); -void mpi_set_highbit( MPI a, unsigned n ); -void mpi_clear_highbit( MPI a, unsigned n ); -void mpi_clear_bit( MPI a, unsigned n ); -void mpi_rshift( MPI x, MPI a, unsigned n ); - -/*-- mpi-inv.c --*/ -void mpi_invm( MPI x, MPI u, MPI v ); -#endif -#endif /*G10_MPI_H*/ diff --git a/include/types.h b/include/types.h deleted file mode 100644 index dff512061..000000000 --- a/include/types.h +++ /dev/null @@ -1,135 +0,0 @@ -/* types.h - some common typedefs - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10_TYPES_H -#define G10_TYPES_H - -#ifdef HAVE_INTTYPES_H -/* For uint64_t */ -#include <inttypes.h> -#endif - -/* The AC_CHECK_SIZEOF() in configure fails for some machines. - * we provide some fallback values here */ -#if !SIZEOF_UNSIGNED_SHORT -#undef SIZEOF_UNSIGNED_SHORT -#define SIZEOF_UNSIGNED_SHORT 2 -#endif -#if !SIZEOF_UNSIGNED_INT -#undef SIZEOF_UNSIGNED_INT -#define SIZEOF_UNSIGNED_INT 4 -#endif -#if !SIZEOF_UNSIGNED_LONG -#undef SIZEOF_UNSIGNED_LONG -#define SIZEOF_UNSIGNED_LONG 4 -#endif - - -#include <sys/types.h> - - -#ifndef HAVE_BYTE_TYPEDEF -#undef byte /* maybe there is a macro with this name */ -#ifndef __riscos__ -typedef unsigned char byte; -#else -/* Norcroft treats char = unsigned char as legal assignment - but char* = unsigned char* as illegal assignment - and the same applies to the signed variants as well */ -typedef char byte; -#endif -#define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_USHORT_TYPEDEF -#undef ushort /* maybe there is a macro with this name */ -typedef unsigned short ushort; -#define HAVE_USHORT_TYPEDEF -#endif - -#ifndef HAVE_ULONG_TYPEDEF -#undef ulong /* maybe there is a macro with this name */ -typedef unsigned long ulong; -#define HAVE_ULONG_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF -#undef u16 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 2 -typedef unsigned int u16; -#elif SIZEOF_UNSIGNED_SHORT == 2 -typedef unsigned short u16; -#else -#error no typedef for u16 -#endif -#define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF -#undef u32 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 4 -typedef unsigned int u32; -#elif SIZEOF_UNSIGNED_LONG == 4 -typedef unsigned long u32; -#else -#error no typedef for u32 -#endif -#define HAVE_U32_TYPEDEF -#endif - -/**************** - * Warning: Some systems segfault when this u64 typedef and - * the dummy code in cipher/md.c is not available. Examples are - * Solaris and IRIX. - */ -#ifndef HAVE_U64_TYPEDEF -#undef u64 /* maybe there is a macro with this name */ -#if SIZEOF_UINT64_T == 8 -typedef uint64_t u64; -#define U64_C(c) (UINT64_C(c)) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_INT == 8 -typedef unsigned int u64; -#define U64_C(c) (c ## U) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG == 8 -typedef unsigned long u64; -#define U64_C(c) (c ## UL) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG_LONG == 8 -typedef unsigned long long u64; -#define U64_C(c) (c ## ULL) -#define HAVE_U64_TYPEDEF -#endif -#endif - -typedef union { - int a; - short b; - char c[1]; - long d; -#ifdef HAVE_U64_TYPEDEF - u64 e; -#endif - float f; - double g; -} PROPERLY_ALIGNED_TYPE; - -#endif /*G10_TYPES_H*/ diff --git a/include/util.h b/include/util.h deleted file mode 100644 index ca5e5e431..000000000 --- a/include/util.h +++ /dev/null @@ -1,300 +0,0 @@ -/* util.h - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_UTIL_H -#define G10_UTIL_H - -#warning oops, using old util.h -#if 0 /* Dont use it anymore */ - -#if defined (__MINGW32__) || defined (__CYGWIN32__) -#include <stdarg.h> -#endif - -#include "types.h" -#include "errors.h" -#include "types.h" -#include "mpi.h" - - -typedef struct { - int *argc; /* pointer to argc (value subject to change) */ - char ***argv; /* pointer to argv (value subject to change) */ - unsigned flags; /* Global flags (DO NOT CHANGE) */ - int err; /* print error about last option */ - /* 1 = warning, 2 = abort */ - int r_opt; /* return option */ - int r_type; /* type of return value (0 = no argument found)*/ - union { - int ret_int; - long ret_long; - ulong ret_ulong; - char *ret_str; - } r; /* Return values */ - struct { - int idx; - int inarg; - int stopped; - const char *last; - void *aliases; - const void *cur_alias; - } internal; /* DO NOT CHANGE */ -} ARGPARSE_ARGS; - -typedef struct { - int short_opt; - const char *long_opt; - unsigned flags; - const char *description; /* optional option description */ -} ARGPARSE_OPTS; - -/*-- logger.c --*/ -void log_set_logfile( const char *name, int fd ); -FILE *log_stream(void); -void g10_log_print_prefix(const char *text); -void log_set_name( const char *name ); -const char *log_get_name(void); -void log_set_pid( int pid ); -int log_get_errorcount( int clear ); -void log_inc_errorcount(void); -int log_set_strict(int val); -void g10_log_hexdump( const char *text, const char *buf, size_t len ); - -#if defined (__riscos__) \ - || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) - void g10_log_bug( const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,1,2))); - void g10_log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); - void g10_log_fatal( const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,1,2))); - void g10_log_error( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void g10_log_info( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void g10_log_warning( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void g10_log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void g10_log_fatal_f( const char *fname, const char *fmt, ... ) - __attribute__ ((noreturn, format (printf,2,3))); - void g10_log_error_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); - void g10_log_info_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); - void g10_log_debug_f( const char *fname, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); -#ifndef __riscos__ -#define BUG() g10_log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) -#else -#define BUG() g10_log_bug0( __FILE__ , __LINE__, __func__ ) -#endif -#else - void g10_log_bug( const char *fmt, ... ); - void g10_log_bug0( const char *, int ); - void g10_log_fatal( const char *fmt, ... ); - void g10_log_error( const char *fmt, ... ); - void g10_log_info( const char *fmt, ... ); - void g10_log_warning( const char *fmt, ... ); - void g10_log_debug( const char *fmt, ... ); - void g10_log_fatal_f( const char *fname, const char *fmt, ... ); - void g10_log_error_f( const char *fname, const char *fmt, ... ); - void g10_log_info_f( const char *fname, const char *fmt, ... ); - void g10_log_debug_f( const char *fname, const char *fmt, ... ); -#define BUG() g10_log_bug0( __FILE__ , __LINE__ ) -#endif - -#define log_hexdump g10_log_hexdump -#define log_bug g10_log_bug -#define log_bug0 g10_log_bug0 -#define log_fatal g10_log_fatal -#define log_error g10_log_error -#define log_info g10_log_info -#define log_warning g10_log_warning -#define log_debug g10_log_debug -#define log_fatal_f g10_log_fatal_f -#define log_error_f g10_log_error_f -#define log_info_f g10_log_info_f -#define log_debug_f g10_log_debug_f - - -/*-- argparse.c --*/ -int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -void usage( int level ); -const char *default_strusage( int level ); - - -/*-- (main program) --*/ -const char *strusage( int level ); - - -/*-- dotlock.c --*/ -struct dotlock_handle; -typedef struct dotlock_handle *DOTLOCK; - -void disable_dotlock(void); -DOTLOCK create_dotlock( const char *file_to_lock ); -int make_dotlock( DOTLOCK h, long timeout ); -int release_dotlock( DOTLOCK h ); -void remove_lockfiles (void); - -/*-- fileutil.c --*/ -char * make_basename(const char *filepath, const char *inputpath); -char * make_dirname(const char *filepath); -char *make_filename( const char *first_part, ... ); -int compare_filenames( const char *a, const char *b ); -const char *print_fname_stdin( const char *s ); -const char *print_fname_stdout( const char *s ); -int is_file_compressed(const char *s, int *r_status); - - -/*-- miscutil.c --*/ -u32 make_timestamp(void); -u32 scan_isodatestr( const char *string ); -u32 add_days_to_timestamp( u32 stamp, u16 days ); -const char *strtimevalue( u32 stamp ); -const char *strtimestamp( u32 stamp ); /* GMT */ -const char *asctimestamp( u32 stamp ); /* localized */ -void print_string( FILE *fp, const byte *p, size_t n, int delim ); -void print_utf8_string( FILE *fp, const byte *p, size_t n ); -void print_utf8_string2( FILE *fp, const byte *p, size_t n, int delim); -char *make_printable_string( const byte *p, size_t n, int delim ); -int answer_is_yes_no_default( const char *s, int def_answer ); -int answer_is_yes( const char *s ); -int answer_is_yes_no_quit( const char *s ); - -/*-- strgutil.c --*/ - -#include "../jnlib/strlist.h" - -const char *memistr( const char *buf, size_t buflen, const char *sub ); -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); -char *mem2str( char *, const void *, size_t); -char *trim_spaces( char *string ); -unsigned int trim_trailing_chars( byte *line, unsigned int len, - const char *trimchars); -unsigned int trim_trailing_ws( byte *line, unsigned len ); -unsigned int check_trailing_chars( const byte *line, unsigned int len, - const char *trimchars ); -unsigned int check_trailing_ws( const byte *line, unsigned int len ); -int string_count_chr( const char *string, int c ); -int set_native_charset( const char *newset ); -const char* get_native_charset(void); -char *native_to_utf8( const char *string ); -char *utf8_to_native( const char *string, size_t length, int delim); -int check_utf8_string( const char *string ); - -int ascii_isupper (int c); -int ascii_islower (int c); -int ascii_toupper (int c); -int ascii_tolower (int c); -int ascii_strcasecmp( const char *a, const char *b ); -int ascii_strncasecmp( const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n); - -#ifndef HAVE_STPCPY -char *stpcpy(char *a,const char *b); -#endif -#ifndef HAVE_STRLWR -char *strlwr(char *a); -#endif -#ifndef HAVE_STRSEP -char *strsep (char **stringp, const char *delim); -#endif -#ifndef HAVE_STRCASECMP -int strcasecmp( const char *, const char *b); -#endif -#ifndef HAVE_STRNCASECMP -int strncasecmp (const char *, const char *b, size_t n); -#endif -#ifndef HAVE_STRTOUL -#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) -#endif -#ifndef HAVE_MEMMOVE -#define memmove(d, s, n) bcopy((s), (d), (n)) -#endif - -#if defined (__MINGW32__) -/*-- w32reg.c --*/ -char *read_w32_registry_string( const char *root, - const char *dir, const char *name ); -int write_w32_registry_string(const char *root, const char *dir, - const char *name, const char *value); - -/*-- strgutil.c --*/ -int vasprintf ( char **result, const char *format, va_list args); -#endif - -/**** other missing stuff ****/ -#ifndef HAVE_ATEXIT /* For SunOS */ -#define atexit(a) (on_exit((a),0)) -#endif - -#ifndef HAVE_RAISE -#define raise(a) kill(getpid(), (a)) -#endif - -/******** some macros ************/ -#ifndef STR -#define STR(v) #v -#endif -#define STR2(v) STR(v) -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - -#define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - -/******* RISC OS stuff ***********/ -#ifdef __riscos__ -/* needed for strcasecmp() */ -#include <strings.h> -/* needed for filename munging */ -#include <unixlib/local.h> -/* needed for image file system feature */ -#include <unixlib/features.h> -void riscos_global_defaults(void); -#define RISCOS_GLOBAL_STATICS(a) const char *__dynamic_da_name = (a); -int riscos_load_module(const char *name, const char * const path[], int fatal); -int riscos_get_filetype_from_string(const char *string, int len); -int riscos_get_filetype(const char *filename); -void riscos_set_filetype_by_number(const char *filename, int type); -void riscos_set_filetype_by_mimetype(const char *filename, const char *mimetype); -pid_t riscos_getpid(void); -int riscos_kill(pid_t pid, int sig); -int riscos_access(const char *path, int amode); -int riscos_getchar(void); -char *riscos_make_basename(const char *filepath, const char *inputpath); -int riscos_check_regexp(const char *exp, const char *string, int debug); -int riscos_fdopenfile(const char *filename, const int allow_write); -void riscos_close_fds(void); -int riscos_renamefile(const char *old, const char *new); -char *riscos_gstrans(const char *old); -void riscos_not_implemented(const char *feature); -#ifdef DEBUG -void riscos_dump_fdlist(void); -void riscos_list_openfiles(void); -#endif -#ifndef __RISCOS__C__ -#define getpid riscos_getpid -#define kill(a,b) riscos_kill((a),(b)) -#define access(a,b) riscos_access((a),(b)) -#endif /* !__RISCOS__C__ */ -#endif /* __riscos__ */ - -#endif - -#endif /*G10_UTIL_H*/ diff --git a/include/zlib-riscos.h b/include/zlib-riscos.h deleted file mode 100644 index fad556bcb..000000000 --- a/include/zlib-riscos.h +++ /dev/null @@ -1,134 +0,0 @@ -/* zlib-riscos.h - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#ifndef G10_ZLIB_RISCOS_H -#define G10_ZLIB_RISCOS_H - -#include <kernel.h> -#include <swis.h> - -static const char * const zlib_path[] = { - "System:310.Modules.ZLib", - NULL -}; - -#define ZLib_Compress 0x53AC0 -#define ZLib_Decompress 0x53AC1 -#define ZLib_CRC32 0x53AC2 -#define ZLib_Adler32 0x53AC3 -#define ZLib_Version 0x53AC4 -#define ZLib_ZCompress 0x53AC5 -#define ZLib_ZCompress2 0x53AC6 -#define ZLib_ZUncompress 0x53AC7 -#define ZLib_DeflateInit 0x53AC8 -#define ZLib_InflateInit 0x53AC9 -#define ZLib_DeflateInit2 0x53ACA -#define ZLib_InflateInit2 0x53ACB -#define ZLib_Deflate 0x53ACC -#define ZLib_DeflateEnd 0x53ACD -#define ZLib_Inflate 0x53ACE -#define ZLib_InflateEnd 0x53ACF -#define ZLib_DeflateSetDictionary 0x53AD0 -#define ZLib_DeflateCopy 0x53AD1 -#define ZLib_DeflateReset 0x53AD2 -#define ZLib_DeflateParams 0x53AD3 -#define ZLib_InflateSetDictionary 0x53AD4 -#define ZLib_InflateSync 0x53AD5 -#define ZLib_InflateReset 0x53AD6 -#define ZLib_GZOpen 0x53AD7 -#define ZLib_GZRead 0x53AD8 -#define ZLib_GRWrite 0x53AD9 -#define ZLib_GZFlush 0x53ADA -#define ZLib_GZClose 0x53ADB -#define ZLib_GZError 0x53ADC -#define ZLib_GZSeek 0x53ADD -#define ZLib_GZTell 0x53ADE -#define ZLib_GZEOF 0x53ADF -#define ZLib_TaskAssociate 0x53AE0 - -#define crc32(r0,r1,r2) \ - _swi(ZLib_CRC32, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define adler32(r0,r1,r2) \ - _swi(ZLib_Adler32, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define zlibVersion() \ - _swi(ZLib_Version, _RETURN(0)) -#define compress(r0,r1,r2,r3) \ - _swi(ZLib_ZCompress, _INR(0,3) | _RETURN(0)|_OUT(1), r0,r1,r2,r3, &r1) -#define compress2(r0,r1,r2,r3,r4) \ - _swi(ZLib_ZCompress2, _INR(0,4) | _RETURN(0)|_OUT(1), r0,r1,r2,r3,r4, &r1) -#define uncompress(r0,r1,r2,r3) \ - _swi(ZLib_ZUncompress, _INR(0,3) | _RETURN(0)|_OUT(1), r0,r1,r2,r3, &r1) -#define deflateInit_(r0,r1,r2,r3) \ - _swi(ZLib_DeflateInit, _INR(0,3) | _RETURN(0), r0,r1,r2,r3) -#define inflateInit_(r0,r1,r2) \ - _swi(ZLib_InflateInit, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define deflateInit2_(r0,r1,r2,r3,r4,r5,r6,r7) \ - _swi(ZLib_DeflateInit2, _INR(0,7) | _RETURN(0), r0,r1,r2,r3,r4,r5,r6,r7) -#define inflateInit2_(r0,r1,r2,r3) \ - _swi(ZLib_InflateInit2, _INR(0,3) | _RETURN(0), r0,r1,r2,r3) -#define deflate(r0,r1) \ - _swi(ZLib_Deflate, _INR(0,1) | _RETURN(0), r0,r1) -#define deflateEnd(r0) \ - _swi(ZLib_DeflateEnd, _IN(0) | _RETURN(0), r0) -#define inflate(r0,r1) \ - _swi(ZLib_Inflate, _INR(0,1) | _RETURN(0), r0,r1) -#define inflateEnd(r0) \ - _swi(ZLib_InflateEnd, _IN(0) | _RETURN(0), r0) -#define deflateSetDictionary(r0,r1,r2) \ - _swi(ZLib_DeflateSetDictionary, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define deflateCopy(r0,r1) \ - _swi(ZLib_DeflateCopy, _INR(0,1) | _RETURN(0), r0,r1) -#define deflateReset(r0) \ - _swi(ZLib_DeflateReset, _IN(0) | _RETURN(0), r0) -#define deflateParams(r0,r1,r2) \ - _swi(ZLib_DeflateParams, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define inflateSetDictionary(r0,r1,r2) \ - _swi(ZLib_InflateSetDictionary, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define inflateSync(r0) \ - _swi(ZLib_InflateSync, _IN(0) | _RETURN(0), r0) -#define inflateReset(r0) \ - _swi(ZLib_InflateReset, _IN(0) | _RETURN(0), r0) -#define gzopen(r0,r1) \ - _swi(ZLib_GZOpen, _INR(0,1) | _RETURN(0), r0) -#define gzdopen(r0,r1) BUG() -#define gzsetparams(r0,r1,r2) BUG() -#define gzread(r0,r1,r2) \ - _swi(ZLib_GZRead, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzwrite(r0,r1,r2) \ - _swi(ZLib_GZWrite, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzprintf(r0,r1,...) BUG() -#define gzputs(r0,r1) BUG() -#define gzgets(r0,r1,r2) BUG() -#define gzputc(r0,r1) BUG() -#define gzgetc(r0) BUG() -#define gzflush(r0,r1) \ - _swi(ZLib_GZFlush, _INR(0,1) | _RETURN(0), r0,r1) -#define gzclose(r0) \ - _swi(ZLib_GZClose, _IN(0) | _RETURN(0), r0) -#define gzerror(r0,r1) \ - _swi(ZLib_GZError, _IN(0) | _RETURN(0)|_OUT(1), r0, &r1) -#define gzseek(r0,r1,r2) \ - _swi(ZLib_GZSeek, _INR(0,2) | _RETURN(0), r0,r1,r2) -#define gzrewind(r0) BUG() -#define gztell(r0) \ - _swi(ZLib_GZTell, _IN(0) | _RETURN(0), r0) -#define gzeof(r0) \ - _swi(ZLib_GZEOF, _IN(0) | _RETURN(0), r0) - -#endif /* G10_ZLIB_RISCOS_H */ diff --git a/intl/ChangeLog b/intl/ChangeLog deleted file mode 100644 index eed2d21a4..000000000 --- a/intl/ChangeLog +++ /dev/null @@ -1,4 +0,0 @@ -2003-05-22 GNU <bug-gnu-gettext@gnu.org> - - * Version 0.12.1 released. - diff --git a/intl/Makefile.in b/intl/Makefile.in deleted file mode 100644 index 882396481..000000000 --- a/intl/Makefile.in +++ /dev/null @@ -1,479 +0,0 @@ -# Makefile for directory with message catalog handling library of GNU gettext -# Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = /bin/sh - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = .. -VPATH = $(srcdir) - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -transform = @program_transform_name@ -libdir = @libdir@ -includedir = @includedir@ -datadir = @datadir@ -localedir = $(datadir)/locale -gettextsrcdir = $(datadir)/gettext/intl -aliaspath = $(localedir) -subdir = intl - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) - -l = @INTL_LIBTOOL_SUFFIX_PREFIX@ - -AR = ar -CC = @CC@ -LIBTOOL = @LIBTOOL@ -RANLIB = @RANLIB@ -YACC = @INTLBISON@ -y -d -YFLAGS = --name-prefix=__gettext - -DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \ --DLIBDIR=\"$(libdir)\" -DIN_LIBINTL \ --DENABLE_RELOCATABLE=1 -DIN_LIBRARY -DINSTALLDIR=\"$(libdir)\" -DNO_XMALLOC \ --Dset_relocation_prefix=libintl_set_relocation_prefix \ --Drelocate=libintl_relocate \ --DDEPENDS_ON_LIBICONV=1 @DEFS@ -CPPFLAGS = @CPPFLAGS@ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) - -HEADERS = \ - gmo.h \ - gettextP.h \ - hash-string.h \ - loadinfo.h \ - plural-exp.h \ - eval-plural.h \ - localcharset.h \ - relocatable.h \ - os2compat.h \ - libgnuintl.h.in -SOURCES = \ - bindtextdom.c \ - dcgettext.c \ - dgettext.c \ - gettext.c \ - finddomain.c \ - loadmsgcat.c \ - localealias.c \ - textdomain.c \ - l10nflist.c \ - explodename.c \ - dcigettext.c \ - dcngettext.c \ - dngettext.c \ - ngettext.c \ - plural.y \ - plural-exp.c \ - localcharset.c \ - relocatable.c \ - localename.c \ - log.c \ - osdep.c \ - os2compat.c \ - intl-compat.c -OBJECTS = \ - bindtextdom.$lo \ - dcgettext.$lo \ - dgettext.$lo \ - gettext.$lo \ - finddomain.$lo \ - loadmsgcat.$lo \ - localealias.$lo \ - textdomain.$lo \ - l10nflist.$lo \ - explodename.$lo \ - dcigettext.$lo \ - dcngettext.$lo \ - dngettext.$lo \ - ngettext.$lo \ - plural.$lo \ - plural-exp.$lo \ - localcharset.$lo \ - relocatable.$lo \ - localename.$lo \ - log.$lo \ - osdep.$lo \ - intl-compat.$lo -DISTFILES.common = Makefile.in \ -config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES) -DISTFILES.generated = plural.c -DISTFILES.normal = VERSION -DISTFILES.gettext = COPYING.LIB-2.0 COPYING.LIB-2.1 libintl.glibc \ -Makefile.vms libgnuintl.h.msvc-shared README.woe32 Makefile.msvc -DISTFILES.obsolete = xopen-msg.sed linux-msg.sed po2tbl.sed.in cat-compat.c \ -COPYING.LIB-2 gettext.h libgettext.h plural-eval.c libgnuintl.h - -all: all-@USE_INCLUDED_LIBINTL@ -all-yes: libintl.$la libintl.h charset.alias ref-add.sed ref-del.sed -all-no: all-no-@BUILD_INCLUDED_LIBINTL@ -all-no-yes: libgnuintl.$la -all-no-no: - -libintl.a libgnuintl.a: $(OBJECTS) - rm -f $@ - $(AR) cru $@ $(OBJECTS) - $(RANLIB) $@ - -libintl.la libgnuintl.la: $(OBJECTS) - $(LIBTOOL) --mode=link \ - $(CC) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) $(LDFLAGS) -o $@ \ - $(OBJECTS) @LTLIBICONV@ $(LIBS) -lc \ - -version-info $(LTV_CURRENT):$(LTV_REVISION):$(LTV_AGE) \ - -rpath $(libdir) \ - -no-undefined - -# Libtool's library version information for libintl. -# Before making a gettext release, the gettext maintainer must change this -# according to the libtool documentation, section "Library interface versions". -# Maintainers of other packages that include the intl directory must *not* -# change these values. -LTV_CURRENT=5 -LTV_REVISION=0 -LTV_AGE=3 - -.SUFFIXES: -.SUFFIXES: .c .y .o .lo .sin .sed - -.c.o: - $(COMPILE) $< - -.y.c: - $(YACC) $(YFLAGS) --output $@ $< - rm -f $*.h - -bindtextdom.lo: $(srcdir)/bindtextdom.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/bindtextdom.c -dcgettext.lo: $(srcdir)/dcgettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcgettext.c -dgettext.lo: $(srcdir)/dgettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dgettext.c -gettext.lo: $(srcdir)/gettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/gettext.c -finddomain.lo: $(srcdir)/finddomain.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/finddomain.c -loadmsgcat.lo: $(srcdir)/loadmsgcat.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/loadmsgcat.c -localealias.lo: $(srcdir)/localealias.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localealias.c -textdomain.lo: $(srcdir)/textdomain.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/textdomain.c -l10nflist.lo: $(srcdir)/l10nflist.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/l10nflist.c -explodename.lo: $(srcdir)/explodename.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/explodename.c -dcigettext.lo: $(srcdir)/dcigettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcigettext.c -dcngettext.lo: $(srcdir)/dcngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dcngettext.c -dngettext.lo: $(srcdir)/dngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/dngettext.c -ngettext.lo: $(srcdir)/ngettext.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/ngettext.c -plural.lo: $(srcdir)/plural.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural.c -plural-exp.lo: $(srcdir)/plural-exp.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/plural-exp.c -localcharset.lo: $(srcdir)/localcharset.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localcharset.c -relocatable.lo: $(srcdir)/relocatable.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/relocatable.c -localename.lo: $(srcdir)/localename.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/localename.c -log.lo: $(srcdir)/log.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/log.c -osdep.lo: $(srcdir)/osdep.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/osdep.c -intl-compat.lo: $(srcdir)/intl-compat.c - $(LIBTOOL) --mode=compile $(COMPILE) $(srcdir)/intl-compat.c - -ref-add.sed: $(srcdir)/ref-add.sin - sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-ref-add.sed - mv t-ref-add.sed ref-add.sed -ref-del.sed: $(srcdir)/ref-del.sin - sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-ref-del.sed - mv t-ref-del.sed ref-del.sed - -INCLUDES = -I. -I$(srcdir) -I.. - -libgnuintl.h: $(srcdir)/libgnuintl.h.in - cp $(srcdir)/libgnuintl.h.in libgnuintl.h - -libintl.h: libgnuintl.h - cp libgnuintl.h libintl.h - -charset.alias: $(srcdir)/config.charset - $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ - mv t-$@ $@ - -check: all - -# We must not install the libintl.h/libintl.a files if we are on a -# system which has the GNU gettext() function in its C library or in a -# separate library. -# If you want to use the one which comes with this version of the -# package, you have to use `configure --with-included-gettext'. -install: install-exec install-data -install-exec: all - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ - $(INSTALL_DATA) libintl.h $(DESTDIR)$(includedir)/libintl.h; \ - $(LIBTOOL) --mode=install \ - $(INSTALL_DATA) libintl.$la $(DESTDIR)$(libdir)/libintl.$la; \ - if test "@RELOCATABLE@" = yes; then \ - dependencies=`sed -n -e 's,^dependency_libs=\(.*\),\1,p' < $(DESTDIR)$(libdir)/libintl.la | sed -e "s,^',," -e "s,'\$$,,"`; \ - if test -n "$dependencies"; then \ - rm -f $(DESTDIR)$(libdir)/libintl.la; \ - fi; \ - fi; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir); \ - $(LIBTOOL) --mode=install \ - $(INSTALL_DATA) libgnuintl.$la $(DESTDIR)$(libdir)/libgnuintl.$la; \ - rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - $(INSTALL_DATA) $(DESTDIR)$(libdir)/libgnuintl.so $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - $(LIBTOOL) --mode=uninstall \ - rm -f $(DESTDIR)$(libdir)/libgnuintl.$la; \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ - temp=$(DESTDIR)$(libdir)/t-charset.alias; \ - dest=$(DESTDIR)$(libdir)/charset.alias; \ - if test -f $(DESTDIR)$(libdir)/charset.alias; then \ - orig=$(DESTDIR)$(libdir)/charset.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - else \ - if test @GLIBC21@ = no; then \ - orig=charset.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - fi; \ - fi; \ - $(mkinstalldirs) $(DESTDIR)$(localedir); \ - test -f $(DESTDIR)$(localedir)/locale.alias \ - && orig=$(DESTDIR)$(localedir)/locale.alias \ - || orig=$(srcdir)/locale.alias; \ - temp=$(DESTDIR)$(localedir)/t-locale.alias; \ - dest=$(DESTDIR)$(localedir)/locale.alias; \ - sed -f ref-add.sed $$orig > $$temp; \ - $(INSTALL_DATA) $$temp $$dest; \ - rm -f $$temp; \ - else \ - : ; \ - fi -install-data: all - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - $(INSTALL_DATA) VERSION $(DESTDIR)$(gettextsrcdir)/VERSION; \ - $(INSTALL_DATA) ChangeLog.inst $(DESTDIR)$(gettextsrcdir)/ChangeLog; \ - dists="COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common)"; \ - for file in $$dists; do \ - $(INSTALL_DATA) $(srcdir)/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - chmod a+x $(DESTDIR)$(gettextsrcdir)/config.charset; \ - dists="$(DISTFILES.generated)"; \ - for file in $$dists; do \ - if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ - $(INSTALL_DATA) $$dir/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - dists="$(DISTFILES.obsolete)"; \ - for file in $$dists; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -install-strip: install - -installdirs: - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir); \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir); \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir); \ - $(mkinstalldirs) $(DESTDIR)$(localedir); \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - else \ - : ; \ - fi - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: - if { test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; } \ - && test '@USE_INCLUDED_LIBINTL@' = yes; then \ - rm -f $(DESTDIR)$(includedir)/libintl.h; \ - $(LIBTOOL) --mode=uninstall \ - rm -f $(DESTDIR)$(libdir)/libintl.$la; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools" \ - && test '@USE_INCLUDED_LIBINTL@' = no; then \ - rm -f $(DESTDIR)$(libdir)/preloadable_libintl.so; \ - else \ - : ; \ - fi - if test '@USE_INCLUDED_LIBINTL@' = yes; then \ - if test -f $(DESTDIR)$(libdir)/charset.alias; then \ - temp=$(DESTDIR)$(libdir)/t-charset.alias; \ - dest=$(DESTDIR)$(libdir)/charset.alias; \ - sed -f ref-del.sed $$dest > $$temp; \ - if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ - rm -f $$dest; \ - else \ - $(INSTALL_DATA) $$temp $$dest; \ - fi; \ - rm -f $$temp; \ - fi; \ - if test -f $(DESTDIR)$(localedir)/locale.alias; then \ - temp=$(DESTDIR)$(localedir)/t-locale.alias; \ - dest=$(DESTDIR)$(localedir)/locale.alias; \ - sed -f ref-del.sed $$dest > $$temp; \ - if grep '^# Packages using this file: $$' $$temp > /dev/null; then \ - rm -f $$dest; \ - else \ - $(INSTALL_DATA) $$temp $$dest; \ - fi; \ - rm -f $$temp; \ - fi; \ - else \ - : ; \ - fi - if test "$(PACKAGE)" = "gettext-tools"; then \ - for file in VERSION ChangeLog COPYING.LIB-2.0 COPYING.LIB-2.1 $(DISTFILES.common) $(DISTFILES.generated); do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi - -info dvi ps pdf html: - -$(OBJECTS): ../config.h libgnuintl.h -bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h -dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h -explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h -dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h -dcigettext.$lo: $(srcdir)/eval-plural.h -localcharset.$lo: $(srcdir)/localcharset.h -localealias.$lo localcharset.$lo relocatable.$lo: $(srcdir)/relocatable.h - -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) - -ctags: CTAGS - -CTAGS: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && ctags -o $$here/CTAGS $(HEADERS) $(SOURCES) - -id: ID - -ID: $(HEADERS) $(SOURCES) - here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) - - -mostlyclean: - rm -f *.a *.la *.o *.obj *.lo core core.* - rm -f libgnuintl.h libintl.h charset.alias ref-add.sed ref-del.sed - rm -f -r .libs _libs - -clean: mostlyclean - -distclean: clean - rm -f Makefile ID TAGS - if test "$(PACKAGE)" = "gettext-runtime" || test "$(PACKAGE)" = "gettext-tools"; then \ - rm -f ChangeLog.inst $(DISTFILES.normal); \ - else \ - : ; \ - fi - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - - -# GNU gettext needs not contain the file `VERSION' but contains some -# other files which should not be distributed in other packages. -distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: Makefile - if test "$(PACKAGE)" = "gettext-tools"; then \ - : ; \ - else \ - if test "$(PACKAGE)" = "gettext-runtime"; then \ - additional="$(DISTFILES.gettext)"; \ - else \ - additional="$(DISTFILES.normal)"; \ - fi; \ - $(MAKE) $(DISTFILES.common) $(DISTFILES.generated) $$additional; \ - for file in ChangeLog $(DISTFILES.common) $(DISTFILES.generated) $$additional; do \ - if test -f $$file; then dir=.; else dir=$(srcdir); fi; \ - cp -p $$dir/$$file $(distdir); \ - done; \ - fi - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status -# This would be more efficient, but doesn't work any more with autoconf-2.57, -# when AC_CONFIG_FILES([intl/Makefile:somedir/Makefile.in]) is used. -# cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/intl/VERSION b/intl/VERSION deleted file mode 100644 index 130318357..000000000 --- a/intl/VERSION +++ /dev/null @@ -1 +0,0 @@ -GNU gettext library from gettext-0.12.1 diff --git a/intl/bindtextdom.c b/intl/bindtextdom.c deleted file mode 100644 index 250f5e863..000000000 --- a/intl/bindtextdom.c +++ /dev/null @@ -1,374 +0,0 @@ -/* Implementation of the bindtextdomain(3) function - Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "gettextP.h" - -#ifdef _LIBC -/* We have to handle multi-threaded applications. */ -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_dirname libintl_nl_default_dirname -# define _nl_domain_bindings libintl_nl_domain_bindings -#endif - -/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ -#ifndef offsetof -# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) -#endif - -/* @@ end of prolog @@ */ - -/* Contains the default location of the message catalogs. */ -extern const char _nl_default_dirname[]; -#ifdef _LIBC -extern const char _nl_default_dirname_internal[] attribute_hidden; -#else -# define INTUSE(name) name -#endif - -/* List with bindings of specific domains. */ -extern struct binding *_nl_domain_bindings; - -/* Lock variable to protect the global data in the gettext implementation. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define BINDTEXTDOMAIN __bindtextdomain -# define BIND_TEXTDOMAIN_CODESET __bind_textdomain_codeset -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define BINDTEXTDOMAIN libintl_bindtextdomain -# define BIND_TEXTDOMAIN_CODESET libintl_bind_textdomain_codeset -#endif - -/* Prototypes for local functions. */ -static void set_binding_values PARAMS ((const char *domainname, - const char **dirnamep, - const char **codesetp)); - -/* Specifies the directory name *DIRNAMEP and the output codeset *CODESETP - to be used for the DOMAINNAME message catalog. - If *DIRNAMEP or *CODESETP is NULL, the corresponding attribute is not - modified, only the current value is returned. - If DIRNAMEP or CODESETP is NULL, the corresponding attribute is neither - modified nor returned. */ -static void -set_binding_values (domainname, dirnamep, codesetp) - const char *domainname; - const char **dirnamep; - const char **codesetp; -{ - struct binding *binding; - int modified; - - /* Some sanity checks. */ - if (domainname == NULL || domainname[0] == '\0') - { - if (dirnamep) - *dirnamep = NULL; - if (codesetp) - *codesetp = NULL; - return; - } - - __libc_rwlock_wrlock (_nl_state_lock); - - modified = 0; - - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding != NULL) - { - if (dirnamep) - { - const char *dirname = *dirnamep; - - if (dirname == NULL) - /* The current binding has be to returned. */ - *dirnamep = binding->dirname; - else - { - /* The domain is already bound. If the new value and the old - one are equal we simply do nothing. Otherwise replace the - old binding. */ - char *result = binding->dirname; - if (strcmp (dirname, result) != 0) - { - if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) - result = (char *) INTUSE(_nl_default_dirname); - else - { -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (dirname); -#else - size_t len = strlen (dirname) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result != NULL, 1)) - memcpy (result, dirname, len); -#endif - } - - if (__builtin_expect (result != NULL, 1)) - { - if (binding->dirname != INTUSE(_nl_default_dirname)) - free (binding->dirname); - - binding->dirname = result; - modified = 1; - } - } - *dirnamep = result; - } - } - - if (codesetp) - { - const char *codeset = *codesetp; - - if (codeset == NULL) - /* The current binding has be to returned. */ - *codesetp = binding->codeset; - else - { - /* The domain is already bound. If the new value and the old - one are equal we simply do nothing. Otherwise replace the - old binding. */ - char *result = binding->codeset; - if (result == NULL || strcmp (codeset, result) != 0) - { -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (codeset); -#else - size_t len = strlen (codeset) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result != NULL, 1)) - memcpy (result, codeset, len); -#endif - - if (__builtin_expect (result != NULL, 1)) - { - if (binding->codeset != NULL) - free (binding->codeset); - - binding->codeset = result; - binding->codeset_cntr++; - modified = 1; - } - } - *codesetp = result; - } - } - } - else if ((dirnamep == NULL || *dirnamep == NULL) - && (codesetp == NULL || *codesetp == NULL)) - { - /* Simply return the default values. */ - if (dirnamep) - *dirnamep = INTUSE(_nl_default_dirname); - if (codesetp) - *codesetp = NULL; - } - else - { - /* We have to create a new binding. */ - size_t len = strlen (domainname) + 1; - struct binding *new_binding = - (struct binding *) malloc (offsetof (struct binding, domainname) + len); - - if (__builtin_expect (new_binding == NULL, 0)) - goto failed; - - memcpy (new_binding->domainname, domainname, len); - - if (dirnamep) - { - const char *dirname = *dirnamep; - - if (dirname == NULL) - /* The default value. */ - dirname = INTUSE(_nl_default_dirname); - else - { - if (strcmp (dirname, INTUSE(_nl_default_dirname)) == 0) - dirname = INTUSE(_nl_default_dirname); - else - { - char *result; -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (dirname); - if (__builtin_expect (result == NULL, 0)) - goto failed_dirname; -#else - size_t len = strlen (dirname) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result == NULL, 0)) - goto failed_dirname; - memcpy (result, dirname, len); -#endif - dirname = result; - } - } - *dirnamep = dirname; - new_binding->dirname = (char *) dirname; - } - else - /* The default value. */ - new_binding->dirname = (char *) INTUSE(_nl_default_dirname); - - new_binding->codeset_cntr = 0; - - if (codesetp) - { - const char *codeset = *codesetp; - - if (codeset != NULL) - { - char *result; - -#if defined _LIBC || defined HAVE_STRDUP - result = strdup (codeset); - if (__builtin_expect (result == NULL, 0)) - goto failed_codeset; -#else - size_t len = strlen (codeset) + 1; - result = (char *) malloc (len); - if (__builtin_expect (result == NULL, 0)) - goto failed_codeset; - memcpy (result, codeset, len); -#endif - codeset = result; - new_binding->codeset_cntr++; - } - *codesetp = codeset; - new_binding->codeset = (char *) codeset; - } - else - new_binding->codeset = NULL; - - /* Now enqueue it. */ - if (_nl_domain_bindings == NULL - || strcmp (domainname, _nl_domain_bindings->domainname) < 0) - { - new_binding->next = _nl_domain_bindings; - _nl_domain_bindings = new_binding; - } - else - { - binding = _nl_domain_bindings; - while (binding->next != NULL - && strcmp (domainname, binding->next->domainname) > 0) - binding = binding->next; - - new_binding->next = binding->next; - binding->next = new_binding; - } - - modified = 1; - - /* Here we deal with memory allocation failures. */ - if (0) - { - failed_codeset: - if (new_binding->dirname != INTUSE(_nl_default_dirname)) - free (new_binding->dirname); - failed_dirname: - free (new_binding); - failed: - if (dirnamep) - *dirnamep = NULL; - if (codesetp) - *codesetp = NULL; - } - } - - /* If we modified any binding, we flush the caches. */ - if (modified) - ++_nl_msg_cat_cntr; - - __libc_rwlock_unlock (_nl_state_lock); -} - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -char * -BINDTEXTDOMAIN (domainname, dirname) - const char *domainname; - const char *dirname; -{ - set_binding_values (domainname, &dirname, NULL); - return (char *) dirname; -} - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -char * -BIND_TEXTDOMAIN_CODESET (domainname, codeset) - const char *domainname; - const char *codeset; -{ - set_binding_values (domainname, NULL, &codeset); - return (char *) codeset; -} - -#ifdef _LIBC -/* Aliases for function names in GNU C Library. */ -weak_alias (__bindtextdomain, bindtextdomain); -weak_alias (__bind_textdomain_codeset, bind_textdomain_codeset); -#endif diff --git a/intl/config.charset b/intl/config.charset deleted file mode 100755 index 32becece9..000000000 --- a/intl/config.charset +++ /dev/null @@ -1,467 +0,0 @@ -#! /bin/sh -# Output a system dependent table of character encoding aliases. -# -# Copyright (C) 2000-2003 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# The table consists of lines of the form -# ALIAS CANONICAL -# -# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". -# ALIAS is compared in a case sensitive way. -# -# CANONICAL is the GNU canonical name for this character encoding. -# It must be an encoding supported by libiconv. Support by GNU libc is -# also desirable. CANONICAL is case insensitive. Usually an upper case -# MIME charset name is preferred. -# The current list of GNU canonical charset names is as follows. -# -# name used by which systems a MIME name? -# ASCII, ANSI_X3.4-1968 glibc solaris freebsd -# ISO-8859-1 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-2 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-3 glibc solaris yes -# ISO-8859-4 osf solaris freebsd yes -# ISO-8859-5 glibc aix hpux irix osf solaris freebsd yes -# ISO-8859-6 glibc aix hpux solaris yes -# ISO-8859-7 glibc aix hpux irix osf solaris yes -# ISO-8859-8 glibc aix hpux osf solaris yes -# ISO-8859-9 glibc aix hpux irix osf solaris yes -# ISO-8859-13 glibc -# ISO-8859-14 glibc -# ISO-8859-15 glibc aix osf solaris freebsd -# KOI8-R glibc solaris freebsd yes -# KOI8-U glibc freebsd yes -# KOI8-T glibc -# CP437 dos -# CP775 dos -# CP850 aix osf dos -# CP852 dos -# CP855 dos -# CP856 aix -# CP857 dos -# CP861 dos -# CP862 dos -# CP864 dos -# CP865 dos -# CP866 freebsd dos -# CP869 dos -# CP874 woe32 dos -# CP922 aix -# CP932 aix woe32 dos -# CP943 aix -# CP949 osf woe32 dos -# CP950 woe32 dos -# CP1046 aix -# CP1124 aix -# CP1125 dos -# CP1129 aix -# CP1250 woe32 -# CP1251 glibc solaris woe32 -# CP1252 aix woe32 -# CP1253 woe32 -# CP1254 woe32 -# CP1255 glibc woe32 -# CP1256 woe32 -# CP1257 woe32 -# GB2312 glibc aix hpux irix solaris freebsd yes -# EUC-JP glibc aix hpux irix osf solaris freebsd yes -# EUC-KR glibc aix hpux irix osf solaris freebsd yes -# EUC-TW glibc aix hpux irix osf solaris -# BIG5 glibc aix hpux osf solaris freebsd yes -# BIG5-HKSCS glibc solaris -# GBK glibc aix osf solaris woe32 dos -# GB18030 glibc solaris -# SHIFT_JIS hpux osf solaris freebsd yes -# JOHAB glibc solaris woe32 -# TIS-620 glibc aix hpux osf solaris -# VISCII glibc yes -# TCVN5712-1 glibc -# GEORGIAN-PS glibc -# HP-ROMAN8 hpux -# HP-ARABIC8 hpux -# HP-GREEK8 hpux -# HP-HEBREW8 hpux -# HP-TURKISH8 hpux -# HP-KANA8 hpux -# DEC-KANJI osf -# DEC-HANYU osf -# UTF-8 glibc aix hpux osf solaris yes -# -# Note: Names which are not marked as being a MIME name should not be used in -# Internet protocols for information interchange (mail, news, etc.). -# -# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications -# must understand both names and treat them as equivalent. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM - -host="$1" -os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` -echo "# This file contains a table of character encoding aliases," -echo "# suitable for operating system '${os}'." -echo "# It was automatically generated from config.charset." -# List of references, updated during installation: -echo "# Packages using this file: " -case "$os" in - linux* | *-gnu*) - # With glibc-2.1 or newer, we don't need any canonicalization, - # because glibc has iconv and both glibc and libiconv support all - # GNU canonical names directly. Therefore, the Makefile does not - # need to install the alias file at all. - # The following applies only to glibc-2.0.x and older libcs. - echo "ISO_646.IRV:1983 ASCII" - ;; - aix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "IBM-850 CP850" - echo "IBM-856 CP856" - echo "IBM-921 ISO-8859-13" - echo "IBM-922 CP922" - echo "IBM-932 CP932" - echo "IBM-943 CP943" - echo "IBM-1046 CP1046" - echo "IBM-1124 CP1124" - echo "IBM-1129 CP1129" - echo "IBM-1252 CP1252" - echo "IBM-eucCN GB2312" - echo "IBM-eucJP EUC-JP" - echo "IBM-eucKR EUC-KR" - echo "IBM-eucTW EUC-TW" - echo "big5 BIG5" - echo "GBK GBK" - echo "TIS-620 TIS-620" - echo "UTF-8 UTF-8" - ;; - hpux*) - echo "iso88591 ISO-8859-1" - echo "iso88592 ISO-8859-2" - echo "iso88595 ISO-8859-5" - echo "iso88596 ISO-8859-6" - echo "iso88597 ISO-8859-7" - echo "iso88598 ISO-8859-8" - echo "iso88599 ISO-8859-9" - echo "iso885915 ISO-8859-15" - echo "roman8 HP-ROMAN8" - echo "arabic8 HP-ARABIC8" - echo "greek8 HP-GREEK8" - echo "hebrew8 HP-HEBREW8" - echo "turkish8 HP-TURKISH8" - echo "kana8 HP-KANA8" - echo "tis620 TIS-620" - echo "big5 BIG5" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "hp15CN GB2312" - #echo "ccdc ?" # what is this? - echo "SJIS SHIFT_JIS" - echo "utf8 UTF-8" - ;; - irix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - ;; - osf*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "cp850 CP850" - echo "big5 BIG5" - echo "dechanyu DEC-HANYU" - echo "dechanzi GB2312" - echo "deckanji DEC-KANJI" - echo "deckorean EUC-KR" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "GBK GBK" - echo "KSC5601 CP949" - echo "sdeckanji EUC-JP" - echo "SJIS SHIFT_JIS" - echo "TACTIS TIS-620" - echo "UTF-8 UTF-8" - ;; - solaris*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-3 ISO-8859-3" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "koi8-r KOI8-R" - echo "ansi-1251 CP1251" - echo "BIG5 BIG5" - echo "Big5-HKSCS BIG5-HKSCS" - echo "gb2312 GB2312" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "cns11643 EUC-TW" - echo "5601 EUC-KR" - echo "ko_KR.johap92 JOHAB" - echo "eucJP EUC-JP" - echo "PCK SHIFT_JIS" - echo "TIS620.2533 TIS-620" - #echo "sun_eu_greek ?" # what is this? - echo "UTF-8 UTF-8" - ;; - freebsd* | os2*) - # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just - # reuse FreeBSD's locale data for OS/2. - echo "C ASCII" - echo "US-ASCII ASCII" - for l in la_LN lt_LN; do - echo "$l.ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ - lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do - echo "$l.ISO_8859-1 ISO-8859-1" - echo "$l.DIS_8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do - echo "$l.ISO_8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO_8859-4 ISO-8859-4" - done - for l in ru_RU ru_SU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO_8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ja_JP.Shift_JIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - netbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-15 ISO-8859-15" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "BIG5 BIG5" - echo "SJIS SHIFT_JIS" - ;; - beos*) - # BeOS has a single locale, and it has UTF-8 encoding. - echo "* UTF-8" - ;; - msdosdjgpp*) - # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "#" - echo "# The encodings given here may not all be correct." - echo "# If you find that the encoding given for your language and" - echo "# country is not the one your DOS machine actually uses, just" - echo "# correct it in this file, and send a mail to" - echo "# Juan Manuel Guerrero <st001906@hrz1.hrz.tu-darmstadt.de>" - echo "# and Bruno Haible <bruno@clisp.org>." - echo "#" - echo "C ASCII" - # ISO-8859-1 languages - echo "ca CP850" - echo "ca_ES CP850" - echo "da CP865" # not CP850 ?? - echo "da_DK CP865" # not CP850 ?? - echo "de CP850" - echo "de_AT CP850" - echo "de_CH CP850" - echo "de_DE CP850" - echo "en CP850" - echo "en_AU CP850" # not CP437 ?? - echo "en_CA CP850" - echo "en_GB CP850" - echo "en_NZ CP437" - echo "en_US CP437" - echo "en_ZA CP850" # not CP437 ?? - echo "es CP850" - echo "es_AR CP850" - echo "es_BO CP850" - echo "es_CL CP850" - echo "es_CO CP850" - echo "es_CR CP850" - echo "es_CU CP850" - echo "es_DO CP850" - echo "es_EC CP850" - echo "es_ES CP850" - echo "es_GT CP850" - echo "es_HN CP850" - echo "es_MX CP850" - echo "es_NI CP850" - echo "es_PA CP850" - echo "es_PY CP850" - echo "es_PE CP850" - echo "es_SV CP850" - echo "es_UY CP850" - echo "es_VE CP850" - echo "et CP850" - echo "et_EE CP850" - echo "eu CP850" - echo "eu_ES CP850" - echo "fi CP850" - echo "fi_FI CP850" - echo "fr CP850" - echo "fr_BE CP850" - echo "fr_CA CP850" - echo "fr_CH CP850" - echo "fr_FR CP850" - echo "ga CP850" - echo "ga_IE CP850" - echo "gd CP850" - echo "gd_GB CP850" - echo "gl CP850" - echo "gl_ES CP850" - echo "id CP850" # not CP437 ?? - echo "id_ID CP850" # not CP437 ?? - echo "is CP861" # not CP850 ?? - echo "is_IS CP861" # not CP850 ?? - echo "it CP850" - echo "it_CH CP850" - echo "it_IT CP850" - echo "lt CP775" - echo "lt_LT CP775" - echo "lv CP775" - echo "lv_LV CP775" - echo "nb CP865" # not CP850 ?? - echo "nb_NO CP865" # not CP850 ?? - echo "nl CP850" - echo "nl_BE CP850" - echo "nl_NL CP850" - echo "nn CP865" # not CP850 ?? - echo "nn_NO CP865" # not CP850 ?? - echo "no CP865" # not CP850 ?? - echo "no_NO CP865" # not CP850 ?? - echo "pt CP850" - echo "pt_BR CP850" - echo "pt_PT CP850" - echo "sv CP850" - echo "sv_SE CP850" - # ISO-8859-2 languages - echo "cs CP852" - echo "cs_CZ CP852" - echo "hr CP852" - echo "hr_HR CP852" - echo "hu CP852" - echo "hu_HU CP852" - echo "pl CP852" - echo "pl_PL CP852" - echo "ro CP852" - echo "ro_RO CP852" - echo "sk CP852" - echo "sk_SK CP852" - echo "sl CP852" - echo "sl_SI CP852" - echo "sq CP852" - echo "sq_AL CP852" - echo "sr CP852" # CP852 or CP866 or CP855 ?? - echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? - # ISO-8859-3 languages - echo "mt CP850" - echo "mt_MT CP850" - # ISO-8859-5 languages - echo "be CP866" - echo "be_BE CP866" - echo "bg CP866" # not CP855 ?? - echo "bg_BG CP866" # not CP855 ?? - echo "mk CP866" # not CP855 ?? - echo "mk_MK CP866" # not CP855 ?? - echo "ru CP866" - echo "ru_RU CP866" - echo "uk CP1125" - echo "uk_UA CP1125" - # ISO-8859-6 languages - echo "ar CP864" - echo "ar_AE CP864" - echo "ar_DZ CP864" - echo "ar_EG CP864" - echo "ar_IQ CP864" - echo "ar_IR CP864" - echo "ar_JO CP864" - echo "ar_KW CP864" - echo "ar_MA CP864" - echo "ar_OM CP864" - echo "ar_QA CP864" - echo "ar_SA CP864" - echo "ar_SY CP864" - # ISO-8859-7 languages - echo "el CP869" - echo "el_GR CP869" - # ISO-8859-8 languages - echo "he CP862" - echo "he_IL CP862" - # ISO-8859-9 languages - echo "tr CP857" - echo "tr_TR CP857" - # Japanese - echo "ja CP932" - echo "ja_JP CP932" - # Chinese - echo "zh_CN GBK" - echo "zh_TW CP950" # not CP938 ?? - # Korean - echo "kr CP949" # not CP934 ?? - echo "kr_KR CP949" # not CP934 ?? - # Thai - echo "th CP874" - echo "th_TH CP874" - # Other - echo "eo CP850" - echo "eo_EO CP850" - ;; -esac diff --git a/intl/dcgettext.c b/intl/dcgettext.c deleted file mode 100644 index ca6a1c82d..000000000 --- a/intl/dcgettext.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Implementation of the dcgettext(3) function. - Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCGETTEXT __dcgettext -# define DCIGETTEXT __dcigettext -#else -# define DCGETTEXT libintl_dcgettext -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -char * -DCGETTEXT (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ - return DCIGETTEXT (domainname, msgid, NULL, 0, 0, category); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -INTDEF(__dcgettext) -weak_alias (__dcgettext, dcgettext); -#endif diff --git a/intl/dcigettext.c b/intl/dcigettext.c deleted file mode 100644 index f6edb95c0..000000000 --- a/intl/dcigettext.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* Implementation of the internal dcigettext function. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <sys/types.h> - -#ifdef __GNUC__ -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <errno.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(val) errno = (val) -#endif - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#include <locale.h> - -#ifdef _LIBC - /* Guess whether integer division by zero raises signal SIGFPE. - Set to 1 only if you know for sure. In case of doubt, set to 0. */ -# if defined __alpha__ || defined __arm__ || defined __i386__ \ - || defined __m68k__ || defined __s390__ -# define INTDIV0_RAISES_SIGFPE 1 -# else -# define INTDIV0_RAISES_SIGFPE 0 -# endif -#endif -#if !INTDIV0_RAISES_SIGFPE -# include <signal.h> -#endif - -#if defined HAVE_SYS_PARAM_H || defined _LIBC -# include <sys/param.h> -#endif - -#include "gettextP.h" -#include "plural-exp.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "hash-string.h" - -/* Thread safetyness. */ -#ifdef _LIBC -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_lock_define_initialized(CLASS, NAME) -# define __libc_lock_lock(NAME) -# define __libc_lock_unlock(NAME) -# define __libc_rwlock_define_initialized(CLASS, NAME) -# define __libc_rwlock_rdlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* Alignment of types. */ -#if defined __GNUC__ && __GNUC__ >= 2 -# define alignof(TYPE) __alignof__ (TYPE) -#else -# define alignof(TYPE) \ - ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_default_domain libintl_nl_default_default_domain -# define _nl_current_default_domain libintl_nl_current_default_domain -# define _nl_default_dirname libintl_nl_default_dirname -# define _nl_domain_bindings libintl_nl_domain_bindings -#endif - -/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */ -#ifndef offsetof -# define offsetof(type,ident) ((size_t)&(((type*)0)->ident)) -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define getcwd __getcwd -# ifndef stpcpy -# define stpcpy __stpcpy -# endif -# define tfind __tfind -#else -# if !defined HAVE_GETCWD -char *getwd (); -# define getcwd(buf, max) getwd (buf) -# else -char *getcwd (); -# endif -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -# ifndef HAVE_MEMPCPY -static void *mempcpy PARAMS ((void *dest, const void *src, size_t n)); -# endif -#endif - -/* Amount to increase buffer size by in each try. */ -#define PATH_INCR 32 - -/* The following is from pathmax.h. */ -/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define - PATH_MAX but might cause redefinition warnings when sys/param.h is - later included (as on MORE/BSD 4.3). */ -#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__) -# include <limits.h> -#endif - -#ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 255 -#endif - -#if !defined PATH_MAX && defined _PC_PATH_MAX -# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) -#endif - -/* Don't include sys/param.h if it already has been. */ -#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN -# include <sys/param.h> -#endif - -#if !defined PATH_MAX && defined MAXPATHLEN -# define PATH_MAX MAXPATHLEN -#endif - -#ifndef PATH_MAX -# define PATH_MAX _POSIX_PATH_MAX -#endif - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, - it may be concatenated to a directory pathname. - IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) -# define IS_PATH_WITH_DIR(P) \ - (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) -# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) -#endif - -/* This is the type used for the search tree where known translations - are stored. */ -struct known_translation_t -{ - /* Domain in which to search. */ - char *domainname; - - /* The category. */ - int category; - - /* State of the catalog counter at the point the string was found. */ - int counter; - - /* Catalog where the string was found. */ - struct loaded_l10nfile *domain; - - /* And finally the translation. */ - const char *translation; - size_t translation_length; - - /* Pointer to the string in question. */ - char msgid[ZERO]; -}; - -/* Root of the search tree with known translations. We can use this - only if the system provides the `tsearch' function family. */ -#if defined HAVE_TSEARCH || defined _LIBC -# include <search.h> - -static void *root; - -# ifdef _LIBC -# define tsearch __tsearch -# endif - -/* Function to compare two entries in the table of known translations. */ -static int transcmp PARAMS ((const void *p1, const void *p2)); -static int -transcmp (p1, p2) - const void *p1; - const void *p2; -{ - const struct known_translation_t *s1; - const struct known_translation_t *s2; - int result; - - s1 = (const struct known_translation_t *) p1; - s2 = (const struct known_translation_t *) p2; - - result = strcmp (s1->msgid, s2->msgid); - if (result == 0) - { - result = strcmp (s1->domainname, s2->domainname); - if (result == 0) - /* We compare the category last (though this is the cheapest - operation) since it is hopefully always the same (namely - LC_MESSAGES). */ - result = s1->category - s2->category; - } - - return result; -} -#endif - -#ifndef INTVARDEF -# define INTVARDEF(name) -#endif -#ifndef INTUSE -# define INTUSE(name) name -#endif - -/* Name of the default domain used for gettext(3) prior any call to - textdomain(3). The default value for this is "messages". */ -const char _nl_default_default_domain[] attribute_hidden = "messages"; - -/* Value used as the default domain for gettext(3). */ -const char *_nl_current_default_domain attribute_hidden - = _nl_default_default_domain; - -/* Contains the default location of the message catalogs. */ -#if defined __EMX__ -extern const char _nl_default_dirname[]; -#else -const char _nl_default_dirname[] = LOCALEDIR; -INTVARDEF (_nl_default_dirname) -#endif - -/* List with bindings of specific domains created by bindtextdomain() - calls. */ -struct binding *_nl_domain_bindings; - -/* Prototypes for local functions. */ -static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain, - unsigned long int n, - const char *translation, - size_t translation_len)) - internal_function; -static const char *guess_category_value PARAMS ((int category, - const char *categoryname)) - internal_function; -#ifdef _LIBC -# include "../locale/localeinfo.h" -# define category_to_name(category) _nl_category_names[category] -#else -static const char *category_to_name PARAMS ((int category)) internal_function; -#endif - - -/* For those loosing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -/* Nothing has to be done. */ -# define freea(p) /* nothing */ -# define ADD_BLOCK(list, address) /* nothing */ -# define FREE_BLOCKS(list) /* nothing */ -#else -struct block_list -{ - void *address; - struct block_list *next; -}; -# define ADD_BLOCK(list, addr) \ - do { \ - struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ - /* If we cannot get a free block we cannot add the new element to \ - the list. */ \ - if (newp != NULL) { \ - newp->address = (addr); \ - newp->next = (list); \ - (list) = newp; \ - } \ - } while (0) -# define FREE_BLOCKS(list) \ - do { \ - while (list != NULL) { \ - struct block_list *old = list; \ - list = list->next; \ - free (old->address); \ - free (old); \ - } \ - } while (0) -# undef alloca -# define alloca(size) (malloc (size)) -# define freea(p) free (p) -#endif /* have alloca */ - - -#ifdef _LIBC -/* List of blocks allocated for translations. */ -typedef struct transmem_list -{ - struct transmem_list *next; - char data[ZERO]; -} transmem_block_t; -static struct transmem_list *transmem_list; -#else -typedef unsigned char transmem_block_t; -#endif - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCIGETTEXT __dcigettext -#else -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Lock variable to protect the global data in the gettext implementation. */ -#ifdef _LIBC -__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden) -#endif - -/* Checking whether the binaries runs SUID must be done and glibc provides - easier methods therefore we make a difference here. */ -#ifdef _LIBC -# define ENABLE_SECURE __libc_enable_secure -# define DETERMINE_SECURE -#else -# ifndef HAVE_GETUID -# define getuid() 0 -# endif -# ifndef HAVE_GETGID -# define getgid() 0 -# endif -# ifndef HAVE_GETEUID -# define geteuid() getuid() -# endif -# ifndef HAVE_GETEGID -# define getegid() getgid() -# endif -static int enable_secure; -# define ENABLE_SECURE (enable_secure == 1) -# define DETERMINE_SECURE \ - if (enable_secure == 0) \ - { \ - if (getuid () != geteuid () || getgid () != getegid ()) \ - enable_secure = 1; \ - else \ - enable_secure = -1; \ - } -#endif - -/* Get the function to evaluate the plural expression. */ -#include "eval-plural.h" - -/* Look up MSGID in the DOMAINNAME message catalog for the current - CATEGORY locale and, if PLURAL is nonzero, search over string - depending on the plural form determined by N. */ -char * -DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - int plural; - unsigned long int n; - int category; -{ -#ifndef HAVE_ALLOCA - struct block_list *block_list = NULL; -#endif - struct loaded_l10nfile *domain; - struct binding *binding; - const char *categoryname; - const char *categoryvalue; - char *dirname, *xdomainname; - char *single_locale; - char *retval; - size_t retlen; - int saved_errno; -#if defined HAVE_TSEARCH || defined _LIBC - struct known_translation_t *search; - struct known_translation_t **foundp = NULL; - size_t msgid_len; -#endif - size_t domainname_len; - - /* If no real MSGID is given return NULL. */ - if (msgid1 == NULL) - return NULL; - -#ifdef _LIBC - if (category < 0 || category >= __LC_LAST || category == LC_ALL) - /* Bogus. */ - return (plural == 0 - ? (char *) msgid1 - /* Use the Germanic plural rule. */ - : n == 1 ? (char *) msgid1 : (char *) msgid2); -#endif - - __libc_rwlock_rdlock (_nl_state_lock); - - /* If DOMAINNAME is NULL, we are interested in the default domain. If - CATEGORY is not LC_MESSAGES this might not make much sense but the - definition left this undefined. */ - if (domainname == NULL) - domainname = _nl_current_default_domain; - - /* OS/2 specific: backward compatibility with older libintl versions */ -#ifdef LC_MESSAGES_COMPAT - if (category == LC_MESSAGES_COMPAT) - category = LC_MESSAGES; -#endif - -#if defined HAVE_TSEARCH || defined _LIBC - msgid_len = strlen (msgid1) + 1; - - /* Try to find the translation among those which we found at - some time. */ - search = (struct known_translation_t *) - alloca (offsetof (struct known_translation_t, msgid) + msgid_len); - memcpy (search->msgid, msgid1, msgid_len); - search->domainname = (char *) domainname; - search->category = category; - - foundp = (struct known_translation_t **) tfind (search, &root, transcmp); - freea (search); - if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr) - { - /* Now deal with plural. */ - if (plural) - retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation, - (*foundp)->translation_length); - else - retval = (char *) (*foundp)->translation; - - __libc_rwlock_unlock (_nl_state_lock); - return retval; - } -#endif - - /* Preserve the `errno' value. */ - saved_errno = errno; - - /* See whether this is a SUID binary or not. */ - DETERMINE_SECURE; - - /* First find matching binding. */ - for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) - { - int compare = strcmp (domainname, binding->domainname); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It is not in the list. */ - binding = NULL; - break; - } - } - - if (binding == NULL) - dirname = (char *) INTUSE(_nl_default_dirname); - else if (IS_ABSOLUTE_PATH (binding->dirname)) - dirname = binding->dirname; - else - { - /* We have a relative path. Make it absolute now. */ - size_t dirname_len = strlen (binding->dirname) + 1; - size_t path_max; - char *ret; - - path_max = (unsigned int) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ - - for (;;) - { - dirname = (char *) alloca (path_max + dirname_len); - ADD_BLOCK (block_list, dirname); - - __set_errno (0); - ret = getcwd (dirname, path_max); - if (ret != NULL || errno != ERANGE) - break; - - path_max += path_max / 2; - path_max += PATH_INCR; - } - - if (ret == NULL) - /* We cannot get the current working directory. Don't signal an - error but simply return the default string. */ - goto return_untranslated; - - stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); - } - - /* Now determine the symbolic name of CATEGORY and its value. */ - categoryname = category_to_name (category); - categoryvalue = guess_category_value (category, categoryname); - - domainname_len = strlen (domainname); - xdomainname = (char *) alloca (strlen (categoryname) - + domainname_len + 5); - ADD_BLOCK (block_list, xdomainname); - - stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), - domainname, domainname_len), - ".mo"); - - /* Creating working area. */ - single_locale = (char *) alloca (strlen (categoryvalue) + 1); - ADD_BLOCK (block_list, single_locale); - - - /* Search for the given string. This is a loop because we perhaps - got an ordered list of languages to consider for the translation. */ - while (1) - { - /* Make CATEGORYVALUE point to the next element of the list. */ - while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') - ++categoryvalue; - if (categoryvalue[0] == '\0') - { - /* The whole contents of CATEGORYVALUE has been searched but - no valid entry has been found. We solve this situation - by implicitly appending a "C" entry, i.e. no translation - will take place. */ - single_locale[0] = 'C'; - single_locale[1] = '\0'; - } - else - { - char *cp = single_locale; - while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') - *cp++ = *categoryvalue++; - *cp = '\0'; - - /* When this is a SUID binary we must not allow accessing files - outside the dedicated directories. */ - if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale)) - /* Ingore this entry. */ - continue; - } - - /* If the current locale value is C (or POSIX) we don't load a - domain. Return the MSGID. */ - if (strcmp (single_locale, "C") == 0 - || strcmp (single_locale, "POSIX") == 0) - break; - - /* Find structure describing the message catalog matching the - DOMAINNAME and CATEGORY. */ - domain = _nl_find_domain (dirname, single_locale, xdomainname, binding); - - if (domain != NULL) - { - retval = _nl_find_msg (domain, binding, msgid1, &retlen); - - if (retval == NULL) - { - int cnt; - - for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) - { - retval = _nl_find_msg (domain->successor[cnt], binding, - msgid1, &retlen); - - if (retval != NULL) - { - domain = domain->successor[cnt]; - break; - } - } - } - - if (retval != NULL) - { - /* Found the translation of MSGID1 in domain DOMAIN: - starting at RETVAL, RETLEN bytes. */ - FREE_BLOCKS (block_list); -#if defined HAVE_TSEARCH || defined _LIBC - if (foundp == NULL) - { - /* Create a new entry and add it to the search tree. */ - struct known_translation_t *newp; - - newp = (struct known_translation_t *) - malloc (offsetof (struct known_translation_t, msgid) - + msgid_len + domainname_len + 1); - if (newp != NULL) - { - newp->domainname = - mempcpy (newp->msgid, msgid1, msgid_len); - memcpy (newp->domainname, domainname, domainname_len + 1); - newp->category = category; - newp->counter = _nl_msg_cat_cntr; - newp->domain = domain; - newp->translation = retval; - newp->translation_length = retlen; - - /* Insert the entry in the search tree. */ - foundp = (struct known_translation_t **) - tsearch (newp, &root, transcmp); - if (foundp == NULL - || __builtin_expect (*foundp != newp, 0)) - /* The insert failed. */ - free (newp); - } - } - else - { - /* We can update the existing entry. */ - (*foundp)->counter = _nl_msg_cat_cntr; - (*foundp)->domain = domain; - (*foundp)->translation = retval; - (*foundp)->translation_length = retlen; - } -#endif - __set_errno (saved_errno); - - /* Now deal with plural. */ - if (plural) - retval = plural_lookup (domain, n, retval, retlen); - - __libc_rwlock_unlock (_nl_state_lock); - return retval; - } - } - } - - return_untranslated: - /* Return the untranslated MSGID. */ - FREE_BLOCKS (block_list); - __libc_rwlock_unlock (_nl_state_lock); -#ifndef _LIBC - if (!ENABLE_SECURE) - { - extern void _nl_log_untranslated PARAMS ((const char *logfilename, - const char *domainname, - const char *msgid1, - const char *msgid2, - int plural)); - const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED"); - - if (logfilename != NULL && logfilename[0] != '\0') - _nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural); - } -#endif - __set_errno (saved_errno); - return (plural == 0 - ? (char *) msgid1 - /* Use the Germanic plural rule. */ - : n == 1 ? (char *) msgid1 : (char *) msgid2); -} - - -char * -internal_function -_nl_find_msg (domain_file, domainbinding, msgid, lengthp) - struct loaded_l10nfile *domain_file; - struct binding *domainbinding; - const char *msgid; - size_t *lengthp; -{ - struct loaded_domain *domain; - nls_uint32 nstrings; - size_t act; - char *result; - size_t resultlen; - - if (domain_file->decided == 0) - _nl_load_domain (domain_file, domainbinding); - - if (domain_file->data == NULL) - return NULL; - - domain = (struct loaded_domain *) domain_file->data; - - nstrings = domain->nstrings; - - /* Locate the MSGID and its translation. */ - if (domain->hash_tab != NULL) - { - /* Use the hashing table. */ - nls_uint32 len = strlen (msgid); - nls_uint32 hash_val = hash_string (msgid); - nls_uint32 idx = hash_val % domain->hash_size; - nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - - while (1) - { - nls_uint32 nstr = - W (domain->must_swap_hash_tab, domain->hash_tab[idx]); - - if (nstr == 0) - /* Hash table entry is empty. */ - return NULL; - - nstr--; - - /* Compare msgid with the original string at index nstr. - We compare the lengths with >=, not ==, because plural entries - are represented by strings with an embedded NUL. */ - if (nstr < nstrings - ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len - && (strcmp (msgid, - domain->data + W (domain->must_swap, - domain->orig_tab[nstr].offset)) - == 0) - : domain->orig_sysdep_tab[nstr - nstrings].length > len - && (strcmp (msgid, - domain->orig_sysdep_tab[nstr - nstrings].pointer) - == 0)) - { - act = nstr; - goto found; - } - - if (idx >= domain->hash_size - incr) - idx -= domain->hash_size - incr; - else - idx += incr; - } - /* NOTREACHED */ - } - else - { - /* Try the default method: binary search in the sorted array of - messages. */ - size_t top, bottom; - - bottom = 0; - top = nstrings; - while (bottom < top) - { - int cmp_val; - - act = (bottom + top) / 2; - cmp_val = strcmp (msgid, (domain->data - + W (domain->must_swap, - domain->orig_tab[act].offset))); - if (cmp_val < 0) - top = act; - else if (cmp_val > 0) - bottom = act + 1; - else - goto found; - } - /* No translation was found. */ - return NULL; - } - - found: - /* The translation was found at index ACT. If we have to convert the - string to use a different character set, this is the time. */ - if (act < nstrings) - { - result = (char *) - (domain->data + W (domain->must_swap, domain->trans_tab[act].offset)); - resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1; - } - else - { - result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer; - resultlen = domain->trans_sysdep_tab[act - nstrings].length; - } - -#if defined _LIBC || HAVE_ICONV - if (domain->codeset_cntr - != (domainbinding != NULL ? domainbinding->codeset_cntr : 0)) - { - /* The domain's codeset has changed through bind_textdomain_codeset() - since the message catalog was initialized or last accessed. We - have to reinitialize the converter. */ - _nl_free_domain_conv (domain); - _nl_init_domain_conv (domain_file, domain, domainbinding); - } - - if ( -# ifdef _LIBC - domain->conv != (__gconv_t) -1 -# else -# if HAVE_ICONV - domain->conv != (iconv_t) -1 -# endif -# endif - ) - { - /* We are supposed to do a conversion. First allocate an - appropriate table with the same structure as the table - of translations in the file, where we can put the pointers - to the converted strings in. - There is a slight complication with plural entries. They - are represented by consecutive NUL terminated strings. We - handle this case by converting RESULTLEN bytes, including - NULs. */ - - if (domain->conv_tab == NULL - && ((domain->conv_tab = - (char **) calloc (nstrings + domain->n_sysdep_strings, - sizeof (char *))) - == NULL)) - /* Mark that we didn't succeed allocating a table. */ - domain->conv_tab = (char **) -1; - - if (__builtin_expect (domain->conv_tab == (char **) -1, 0)) - /* Nothing we can do, no more memory. */ - goto converted; - - if (domain->conv_tab[act] == NULL) - { - /* We haven't used this string so far, so it is not - translated yet. Do this now. */ - /* We use a bit more efficient memory handling. - We allocate always larger blocks which get used over - time. This is faster than many small allocations. */ - __libc_lock_define_initialized (static, lock) -# define INITIAL_BLOCK_SIZE 4080 - static unsigned char *freemem; - static size_t freemem_size; - - const unsigned char *inbuf; - unsigned char *outbuf; - int malloc_count; -# ifndef _LIBC - transmem_block_t *transmem_list = NULL; -# endif - - __libc_lock_lock (lock); - - inbuf = (const unsigned char *) result; - outbuf = freemem + sizeof (size_t); - - malloc_count = 0; - while (1) - { - transmem_block_t *newmem; -# ifdef _LIBC - size_t non_reversible; - int res; - - if (freemem_size < sizeof (size_t)) - goto resize_freemem; - - res = __gconv (domain->conv, - &inbuf, inbuf + resultlen, - &outbuf, - outbuf + freemem_size - sizeof (size_t), - &non_reversible); - - if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT) - break; - - if (res != __GCONV_FULL_OUTPUT) - { - __libc_lock_unlock (lock); - goto converted; - } - - inbuf = result; -# else -# if HAVE_ICONV - const char *inptr = (const char *) inbuf; - size_t inleft = resultlen; - char *outptr = (char *) outbuf; - size_t outleft; - - if (freemem_size < sizeof (size_t)) - goto resize_freemem; - - outleft = freemem_size - sizeof (size_t); - if (iconv (domain->conv, - (ICONV_CONST char **) &inptr, &inleft, - &outptr, &outleft) - != (size_t) (-1)) - { - outbuf = (unsigned char *) outptr; - break; - } - if (errno != E2BIG) - { - __libc_lock_unlock (lock); - goto converted; - } -# endif -# endif - - resize_freemem: - /* We must allocate a new buffer or resize the old one. */ - if (malloc_count > 0) - { - ++malloc_count; - freemem_size = malloc_count * INITIAL_BLOCK_SIZE; - newmem = (transmem_block_t *) realloc (transmem_list, - freemem_size); -# ifdef _LIBC - if (newmem != NULL) - transmem_list = transmem_list->next; - else - { - struct transmem_list *old = transmem_list; - - transmem_list = transmem_list->next; - free (old); - } -# endif - } - else - { - malloc_count = 1; - freemem_size = INITIAL_BLOCK_SIZE; - newmem = (transmem_block_t *) malloc (freemem_size); - } - if (__builtin_expect (newmem == NULL, 0)) - { - freemem = NULL; - freemem_size = 0; - __libc_lock_unlock (lock); - goto converted; - } - -# ifdef _LIBC - /* Add the block to the list of blocks we have to free - at some point. */ - newmem->next = transmem_list; - transmem_list = newmem; - - freemem = newmem->data; - freemem_size -= offsetof (struct transmem_list, data); -# else - transmem_list = newmem; - freemem = newmem; -# endif - - outbuf = freemem + sizeof (size_t); - } - - /* We have now in our buffer a converted string. Put this - into the table of conversions. */ - *(size_t *) freemem = outbuf - freemem - sizeof (size_t); - domain->conv_tab[act] = (char *) freemem; - /* Shrink freemem, but keep it aligned. */ - freemem_size -= outbuf - freemem; - freemem = outbuf; - freemem += freemem_size & (alignof (size_t) - 1); - freemem_size = freemem_size & ~ (alignof (size_t) - 1); - - __libc_lock_unlock (lock); - } - - /* Now domain->conv_tab[act] contains the translation of all - the plural variants. */ - result = domain->conv_tab[act] + sizeof (size_t); - resultlen = *(size_t *) domain->conv_tab[act]; - } - - converted: - /* The result string is converted. */ - -#endif /* _LIBC || HAVE_ICONV */ - - *lengthp = resultlen; - return result; -} - - -/* Look up a plural variant. */ -static char * -internal_function -plural_lookup (domain, n, translation, translation_len) - struct loaded_l10nfile *domain; - unsigned long int n; - const char *translation; - size_t translation_len; -{ - struct loaded_domain *domaindata = (struct loaded_domain *) domain->data; - unsigned long int index; - const char *p; - - index = plural_eval (domaindata->plural, n); - if (index >= domaindata->nplurals) - /* This should never happen. It means the plural expression and the - given maximum value do not match. */ - index = 0; - - /* Skip INDEX strings at TRANSLATION. */ - p = translation; - while (index-- > 0) - { -#ifdef _LIBC - p = __rawmemchr (p, '\0'); -#else - p = strchr (p, '\0'); -#endif - /* And skip over the NUL byte. */ - p++; - - if (p >= translation + translation_len) - /* This should never happen. It means the plural expression - evaluated to a value larger than the number of variants - available for MSGID1. */ - return (char *) translation; - } - return (char *) p; -} - -#ifndef _LIBC -/* Return string representation of locale CATEGORY. */ -static const char * -internal_function -category_to_name (category) - int category; -{ - const char *retval; - - switch (category) - { -#ifdef LC_COLLATE - case LC_COLLATE: - retval = "LC_COLLATE"; - break; -#endif -#ifdef LC_CTYPE - case LC_CTYPE: - retval = "LC_CTYPE"; - break; -#endif -#ifdef LC_MONETARY - case LC_MONETARY: - retval = "LC_MONETARY"; - break; -#endif -#ifdef LC_NUMERIC - case LC_NUMERIC: - retval = "LC_NUMERIC"; - break; -#endif -#ifdef LC_TIME - case LC_TIME: - retval = "LC_TIME"; - break; -#endif -#ifdef LC_MESSAGES - case LC_MESSAGES: - retval = "LC_MESSAGES"; - break; -#endif -#ifdef LC_RESPONSE - case LC_RESPONSE: - retval = "LC_RESPONSE"; - break; -#endif -#ifdef LC_ALL - case LC_ALL: - /* This might not make sense but is perhaps better than any other - value. */ - retval = "LC_ALL"; - break; -#endif - default: - /* If you have a better idea for a default value let me know. */ - retval = "LC_XXX"; - } - - return retval; -} -#endif - -/* Guess value of current locale from value of the environment variables. */ -static const char * -internal_function -guess_category_value (category, categoryname) - int category; - const char *categoryname; -{ - const char *language; - const char *retval; - - /* The highest priority value is the `LANGUAGE' environment - variable. But we don't use the value if the currently selected - locale is the C locale. This is a GNU extension. */ - language = getenv ("LANGUAGE"); - if (language != NULL && language[0] == '\0') - language = NULL; - - /* We have to proceed with the POSIX methods of looking to `LC_ALL', - `LC_xxx', and `LANG'. On some systems this can be done by the - `setlocale' function itself. */ -#ifdef _LIBC - retval = __current_locale_name (category); -#else - retval = _nl_locale_name (category, categoryname); -#endif - - /* Ignore LANGUAGE if the locale is set to "C" because - 1. "C" locale usually uses the ASCII encoding, and most international - messages use non-ASCII characters. These characters get displayed - as question marks (if using glibc's iconv()) or as invalid 8-bit - characters (because other iconv()s refuse to convert most non-ASCII - characters to ASCII). In any case, the output is ugly. - 2. The precise output of some programs in the "C" locale is specified - by POSIX and should not depend on environment variables like - "LANGUAGE". We allow such programs to use gettext(). */ - return language != NULL && strcmp (retval, "C") != 0 ? language : retval; -} - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif - -#if !_LIBC && !HAVE_MEMPCPY -static void * -mempcpy (dest, src, n) - void *dest; - const void *src; - size_t n; -{ - return (void *) ((char *) memcpy (dest, src, n) + n); -} -#endif - - -#ifdef _LIBC -/* If we want to free all resources we have to do some work at - program's end. */ -libc_freeres_fn (free_mem) -{ - void *old; - - while (_nl_domain_bindings != NULL) - { - struct binding *oldp = _nl_domain_bindings; - _nl_domain_bindings = _nl_domain_bindings->next; - if (oldp->dirname != INTUSE(_nl_default_dirname)) - /* Yes, this is a pointer comparison. */ - free (oldp->dirname); - free (oldp->codeset); - free (oldp); - } - - if (_nl_current_default_domain != _nl_default_default_domain) - /* Yes, again a pointer comparison. */ - free ((char *) _nl_current_default_domain); - - /* Remove the search tree with the known translations. */ - __tdestroy (root, free); - root = NULL; - - while (transmem_list != NULL) - { - old = transmem_list; - transmem_list = transmem_list->next; - free (old); - } -} -#endif diff --git a/intl/dcngettext.c b/intl/dcngettext.c deleted file mode 100644 index 3a3404e2c..000000000 --- a/intl/dcngettext.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Implementation of the dcngettext(3) function. - Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DCNGETTEXT __dcngettext -# define DCIGETTEXT __dcigettext -#else -# define DCNGETTEXT libintl_dcngettext -# define DCIGETTEXT libintl_dcigettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -char * -DCNGETTEXT (domainname, msgid1, msgid2, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; - int category; -{ - return DCIGETTEXT (domainname, msgid1, msgid2, 1, n, category); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dcngettext, dcngettext); -#endif diff --git a/intl/dgettext.c b/intl/dgettext.c deleted file mode 100644 index cf5b4037f..000000000 --- a/intl/dgettext.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Implementation of the dgettext(3) function. - Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <locale.h> - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DGETTEXT __dgettext -# define DCGETTEXT INTUSE(__dcgettext) -#else -# define DGETTEXT libintl_dgettext -# define DCGETTEXT libintl_dcgettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog of the current - LC_MESSAGES locale. */ -char * -DGETTEXT (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return DCGETTEXT (domainname, msgid, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dgettext, dgettext); -#endif diff --git a/intl/dngettext.c b/intl/dngettext.c deleted file mode 100644 index 67fd030f2..000000000 --- a/intl/dngettext.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Implementation of the dngettext(3) function. - Copyright (C) 1995-1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <locale.h> - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define DNGETTEXT __dngettext -# define DCNGETTEXT __dcngettext -#else -# define DNGETTEXT libintl_dngettext -# define DCNGETTEXT libintl_dcngettext -#endif - -/* Look up MSGID in the DOMAINNAME message catalog of the current - LC_MESSAGES locale and skip message according to the plural form. */ -char * -DNGETTEXT (domainname, msgid1, msgid2, n) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return DCNGETTEXT (domainname, msgid1, msgid2, n, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__dngettext, dngettext); -#endif diff --git a/intl/eval-plural.h b/intl/eval-plural.h deleted file mode 100644 index 19c7ca6ae..000000000 --- a/intl/eval-plural.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Plural expression evaluation. - Copyright (C) 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef STATIC -#define STATIC static -#endif - -/* Evaluate the plural expression and return an index value. */ -STATIC unsigned long int plural_eval PARAMS ((struct expression *pexp, - unsigned long int n)) - internal_function; - -STATIC -unsigned long int -internal_function -plural_eval (pexp, n) - struct expression *pexp; - unsigned long int n; -{ - switch (pexp->nargs) - { - case 0: - switch (pexp->operation) - { - case var: - return n; - case num: - return pexp->val.num; - default: - break; - } - /* NOTREACHED */ - break; - case 1: - { - /* pexp->operation must be lnot. */ - unsigned long int arg = plural_eval (pexp->val.args[0], n); - return ! arg; - } - case 2: - { - unsigned long int leftarg = plural_eval (pexp->val.args[0], n); - if (pexp->operation == lor) - return leftarg || plural_eval (pexp->val.args[1], n); - else if (pexp->operation == land) - return leftarg && plural_eval (pexp->val.args[1], n); - else - { - unsigned long int rightarg = plural_eval (pexp->val.args[1], n); - - switch (pexp->operation) - { - case mult: - return leftarg * rightarg; - case divide: -#if !INTDIV0_RAISES_SIGFPE - if (rightarg == 0) - raise (SIGFPE); -#endif - return leftarg / rightarg; - case module: -#if !INTDIV0_RAISES_SIGFPE - if (rightarg == 0) - raise (SIGFPE); -#endif - return leftarg % rightarg; - case plus: - return leftarg + rightarg; - case minus: - return leftarg - rightarg; - case less_than: - return leftarg < rightarg; - case greater_than: - return leftarg > rightarg; - case less_or_equal: - return leftarg <= rightarg; - case greater_or_equal: - return leftarg >= rightarg; - case equal: - return leftarg == rightarg; - case not_equal: - return leftarg != rightarg; - default: - break; - } - } - /* NOTREACHED */ - break; - } - case 3: - { - /* pexp->operation must be qmop. */ - unsigned long int boolarg = plural_eval (pexp->val.args[0], n); - return plural_eval (pexp->val.args[boolarg ? 1 : 2], n); - } - } - /* NOTREACHED */ - return 0; -} diff --git a/intl/explodename.c b/intl/explodename.c deleted file mode 100644 index 2985064c9..000000000 --- a/intl/explodename.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -char * -_nl_find_language (name) - const char *name; -{ - while (name[0] != '\0' && name[0] != '_' && name[0] != '@' - && name[0] != '+' && name[0] != ',') - ++name; - - return (char *) name; -} - - -int -_nl_explode_name (name, language, modifier, territory, codeset, - normalized_codeset, special, sponsor, revision) - char *name; - const char **language; - const char **modifier; - const char **territory; - const char **codeset; - const char **normalized_codeset; - const char **special; - const char **sponsor; - const char **revision; -{ - enum { undecided, xpg, cen } syntax; - char *cp; - int mask; - - *modifier = NULL; - *territory = NULL; - *codeset = NULL; - *normalized_codeset = NULL; - *special = NULL; - *sponsor = NULL; - *revision = NULL; - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = 0; - syntax = undecided; - *language = cp = name; - cp = _nl_find_language (*language); - - if (*language == cp) - /* This does not make sense: language has to be specified. Use - this entry as it is without exploding. Perhaps it is an alias. */ - cp = strchr (*language, '\0'); - else if (cp[0] == '_') - { - /* Next is the territory. */ - cp[0] = '\0'; - *territory = ++cp; - - while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' - && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= TERRITORY; - - if (cp[0] == '.') - { - /* Next is the codeset. */ - syntax = xpg; - cp[0] = '\0'; - *codeset = ++cp; - - while (cp[0] != '\0' && cp[0] != '@') - ++cp; - - mask |= XPG_CODESET; - - if (*codeset != cp && (*codeset)[0] != '\0') - { - *normalized_codeset = _nl_normalize_codeset (*codeset, - cp - *codeset); - if (strcmp (*codeset, *normalized_codeset) == 0) - free ((char *) *normalized_codeset); - else - mask |= XPG_NORM_CODESET; - } - } - } - - if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) - { - /* Next is the modifier. */ - syntax = cp[0] == '@' ? xpg : cen; - cp[0] = '\0'; - *modifier = ++cp; - - while (syntax == cen && cp[0] != '\0' && cp[0] != '+' - && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= XPG_MODIFIER | CEN_AUDIENCE; - } - - if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) - { - syntax = cen; - - if (cp[0] == '+') - { - /* Next is special application (CEN syntax). */ - cp[0] = '\0'; - *special = ++cp; - - while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') - ++cp; - - mask |= CEN_SPECIAL; - } - - if (cp[0] == ',') - { - /* Next is sponsor (CEN syntax). */ - cp[0] = '\0'; - *sponsor = ++cp; - - while (cp[0] != '\0' && cp[0] != '_') - ++cp; - - mask |= CEN_SPONSOR; - } - - if (cp[0] == '_') - { - /* Next is revision (CEN syntax). */ - cp[0] = '\0'; - *revision = ++cp; - - mask |= CEN_REVISION; - } - } - - /* For CEN syntax values it might be important to have the - separator character in the file name, not for XPG syntax. */ - if (syntax == xpg) - { - if (*territory != NULL && (*territory)[0] == '\0') - mask &= ~TERRITORY; - - if (*codeset != NULL && (*codeset)[0] == '\0') - mask &= ~XPG_CODESET; - - if (*modifier != NULL && (*modifier)[0] == '\0') - mask &= ~XPG_MODIFIER; - } - - return mask; -} diff --git a/intl/finddomain.c b/intl/finddomain.c deleted file mode 100644 index d24276442..000000000 --- a/intl/finddomain.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Handle list of needed message catalogs - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@gnu.org>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ -/* List of already loaded domains. */ -static struct loaded_l10nfile *_nl_loaded_domains; - - -/* Return a data structure describing the message catalog described by - the DOMAINNAME and CATEGORY parameters with respect to the currently - established bindings. */ -struct loaded_l10nfile * -internal_function -_nl_find_domain (dirname, locale, domainname, domainbinding) - const char *dirname; - char *locale; - const char *domainname; - struct binding *domainbinding; -{ - struct loaded_l10nfile *retval; - const char *language; - const char *modifier; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *special; - const char *sponsor; - const char *revision; - const char *alias_value; - int mask; - - /* LOCALE can consist of up to four recognized parts for the XPG syntax: - - language[_territory[.codeset]][@modifier] - - and six parts for the CEN syntax: - - language[_territory][+audience][+special][,[sponsor][_revision]] - - Beside the first part all of them are allowed to be missing. If - the full specified locale is not found, the less specific one are - looked for. The various parts will be stripped off according to - the following order: - (1) revision - (2) sponsor - (3) special - (4) codeset - (5) normalized codeset - (6) territory - (7) audience/modifier - */ - - /* If we have already tested for this locale entry there has to - be one data set in the list of loaded domains. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, 0, locale, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, domainname, 0); - if (retval != NULL) - { - /* We know something about this locale. */ - int cnt; - - if (retval->decided == 0) - _nl_load_domain (retval, domainbinding); - - if (retval->data != NULL) - return retval; - - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt], domainbinding); - - if (retval->successor[cnt]->data != NULL) - break; - } - return cnt >= 0 ? retval : NULL; - /* NOTREACHED */ - } - - /* See whether the locale value is an alias. If yes its value - *overwrites* the alias name. No test for the original value is - done. */ - alias_value = _nl_expand_alias (locale); - if (alias_value != NULL) - { -#if defined _LIBC || defined HAVE_STRDUP - locale = strdup (alias_value); - if (locale == NULL) - return NULL; -#else - size_t len = strlen (alias_value) + 1; - locale = (char *) malloc (len); - if (locale == NULL) - return NULL; - - memcpy (locale, alias_value, len); -#endif - } - - /* Now we determine the single parts of the locale name. First - look for the language. Termination symbols are `_' and `@' if - we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ - mask = _nl_explode_name (locale, &language, &modifier, &territory, - &codeset, &normalized_codeset, &special, - &sponsor, &revision); - - /* Create all possible locale entries which might be interested in - generalization. */ - retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, - strlen (dirname) + 1, mask, language, territory, - codeset, normalized_codeset, modifier, special, - sponsor, revision, domainname, 1); - if (retval == NULL) - /* This means we are out of core. */ - return NULL; - - if (retval->decided == 0) - _nl_load_domain (retval, domainbinding); - if (retval->data == NULL) - { - int cnt; - for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) - { - if (retval->successor[cnt]->decided == 0) - _nl_load_domain (retval->successor[cnt], domainbinding); - if (retval->successor[cnt]->data != NULL) - break; - } - } - - /* The room for an alias was dynamically allocated. Free it now. */ - if (alias_value != NULL) - free (locale); - - /* The space for normalized_codeset is dynamically allocated. Free it. */ - if (mask & XPG_NORM_CODESET) - free ((void *) normalized_codeset); - - return retval; -} - - -#ifdef _LIBC -libc_freeres_fn (free_mem) -{ - struct loaded_l10nfile *runp = _nl_loaded_domains; - - while (runp != NULL) - { - struct loaded_l10nfile *here = runp; - if (runp->data != NULL) - _nl_unload_domain ((struct loaded_domain *) runp->data); - runp = runp->next; - free ((char *) here->filename); - free (here); - } -} -#endif diff --git a/intl/gettext.c b/intl/gettext.c deleted file mode 100644 index 43d689f55..000000000 --- a/intl/gettext.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Implementation of gettext(3) function. - Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef _LIBC -# define __need_NULL -# include <stddef.h> -#else -# include <stdlib.h> /* Just for NULL. */ -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define GETTEXT __gettext -# define DCGETTEXT INTUSE(__dcgettext) -#else -# define GETTEXT libintl_gettext -# define DCGETTEXT libintl_dcgettext -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -char * -GETTEXT (msgid) - const char *msgid; -{ - return DCGETTEXT (NULL, msgid, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__gettext, gettext); -#endif diff --git a/intl/gettextP.h b/intl/gettextP.h deleted file mode 100644 index f1748a356..000000000 --- a/intl/gettextP.h +++ /dev/null @@ -1,224 +0,0 @@ -/* Header describing internals of libintl library. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _GETTEXTP_H -#define _GETTEXTP_H - -#include <stddef.h> /* Get size_t. */ - -#ifdef _LIBC -# include "../iconv/gconv_int.h" -#else -# if HAVE_ICONV -# include <iconv.h> -# endif -#endif - -#include "loadinfo.h" - -#include "gmo.h" /* Get nls_uint32. */ - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* Tell the compiler when a conditional or integer expression is - almost always true or almost always false. */ -#ifndef HAVE_BUILTIN_EXPECT -# define __builtin_expect(expr, val) (expr) -#endif - -#ifndef W -# define W(flag, data) ((flag) ? SWAP (data) : (data)) -#endif - - -#ifdef _LIBC -# include <byteswap.h> -# define SWAP(i) bswap_32 (i) -#else -static inline nls_uint32 -SWAP (i) - nls_uint32 i; -{ - return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); -} -#endif - - -/* In-memory representation of system dependent string. */ -struct sysdep_string_desc -{ - /* Length of addressed string, including the trailing NUL. */ - size_t length; - /* Pointer to addressed string. */ - const char *pointer; -}; - -/* The representation of an opened message catalog. */ -struct loaded_domain -{ - /* Pointer to memory containing the .mo file. */ - const char *data; - /* 1 if the memory is mmap()ed, 0 if the memory is malloc()ed. */ - int use_mmap; - /* Size of mmap()ed memory. */ - size_t mmap_size; - /* 1 if the .mo file uses a different endianness than this machine. */ - int must_swap; - /* Pointer to additional malloc()ed memory. */ - void *malloced; - - /* Number of static strings pairs. */ - nls_uint32 nstrings; - /* Pointer to descriptors of original strings in the file. */ - const struct string_desc *orig_tab; - /* Pointer to descriptors of translated strings in the file. */ - const struct string_desc *trans_tab; - - /* Number of system dependent strings pairs. */ - nls_uint32 n_sysdep_strings; - /* Pointer to descriptors of original sysdep strings. */ - const struct sysdep_string_desc *orig_sysdep_tab; - /* Pointer to descriptors of translated sysdep strings. */ - const struct sysdep_string_desc *trans_sysdep_tab; - - /* Size of hash table. */ - nls_uint32 hash_size; - /* Pointer to hash table. */ - const nls_uint32 *hash_tab; - /* 1 if the hash table uses a different endianness than this machine. */ - int must_swap_hash_tab; - - int codeset_cntr; -#ifdef _LIBC - __gconv_t conv; -#else -# if HAVE_ICONV - iconv_t conv; -# endif -#endif - char **conv_tab; - - struct expression *plural; - unsigned long int nplurals; -}; - -/* We want to allocate a string at the end of the struct. But ISO C - doesn't allow zero sized arrays. */ -#ifdef __GNUC__ -# define ZERO 0 -#else -# define ZERO 1 -#endif - -/* A set of settings bound to a message domain. Used to store settings - from bindtextdomain() and bind_textdomain_codeset(). */ -struct binding -{ - struct binding *next; - char *dirname; - int codeset_cntr; /* Incremented each time codeset changes. */ - char *codeset; - char domainname[ZERO]; -}; - -/* A counter which is incremented each time some previous translations - become invalid. - This variable is part of the external ABI of the GNU libintl. */ -extern int _nl_msg_cat_cntr; - -#ifndef _LIBC -const char *_nl_locale_name PARAMS ((int category, const char *categoryname)); -#endif - -struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, - char *__locale, - const char *__domainname, - struct binding *__domainbinding)) - internal_function; -void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain, - struct binding *__domainbinding)) - internal_function; -void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) - internal_function; -const char *_nl_init_domain_conv PARAMS ((struct loaded_l10nfile *__domain_file, - struct loaded_domain *__domain, - struct binding *__domainbinding)) - internal_function; -void _nl_free_domain_conv PARAMS ((struct loaded_domain *__domain)) - internal_function; - -char *_nl_find_msg PARAMS ((struct loaded_l10nfile *domain_file, - struct binding *domainbinding, - const char *msgid, size_t *lengthp)) - internal_function; - -#ifdef _LIBC -extern char *__gettext PARAMS ((const char *__msgid)); -extern char *__dgettext PARAMS ((const char *__domainname, - const char *__msgid)); -extern char *__dcgettext PARAMS ((const char *__domainname, - const char *__msgid, int __category)); -extern char *__ngettext PARAMS ((const char *__msgid1, const char *__msgid2, - unsigned long int __n)); -extern char *__dngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int n)); -extern char *__dcngettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category)); -extern char *__dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -extern char *__textdomain PARAMS ((const char *__domainname)); -extern char *__bindtextdomain PARAMS ((const char *__domainname, - const char *__dirname)); -extern char *__bind_textdomain_codeset PARAMS ((const char *__domainname, - const char *__codeset)); -#else -/* Declare the exported libintl_* functions, in a way that allows us to - call them under their real name. */ -# define _INTL_REDIRECT_MACROS -# include "libgnuintl.h" -extern char *libintl_dcigettext PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - int __plural, unsigned long int __n, - int __category)); -#endif - -/* @@ begin of epilog @@ */ - -#endif /* gettextP.h */ diff --git a/intl/gmo.h b/intl/gmo.h deleted file mode 100644 index d1fe4d6b8..000000000 --- a/intl/gmo.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Description of GNU message catalog format: general file layout. - Copyright (C) 1995, 1997, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _GETTEXT_H -#define _GETTEXT_H 1 - -#include <limits.h> - -/* @@ end of prolog @@ */ - -/* The magic number of the GNU message catalog format. */ -#define _MAGIC 0x950412de -#define _MAGIC_SWAPPED 0xde120495 - -/* Revision number of the currently used .mo (binary) file format. */ -#define MO_REVISION_NUMBER 0 - -/* The following contortions are an attempt to use the C preprocessor - to determine an unsigned integral type that is 32 bits wide. An - alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but - as of version autoconf-2.13, the AC_CHECK_SIZEOF macro doesn't work - when cross-compiling. */ - -#if __STDC__ -# define UINT_MAX_32_BITS 4294967295U -#else -# define UINT_MAX_32_BITS 0xFFFFFFFF -#endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - This should be valid for all systems GNU cares about because - that doesn't include 16-bit systems, and only modern systems - (that certainly have <limits.h>) have 64+-bit integral types. */ - -#ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -#endif - -#if UINT_MAX == UINT_MAX_32_BITS -typedef unsigned nls_uint32; -#else -# if USHRT_MAX == UINT_MAX_32_BITS -typedef unsigned short nls_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS -typedef unsigned long nls_uint32; -# else - /* The following line is intended to throw an error. Using #error is - not portable enough. */ - "Cannot determine unsigned 32-bit data type." -# endif -# endif -#endif - - -/* Header for binary .mo file format. */ -struct mo_file_header -{ - /* The magic number. */ - nls_uint32 magic; - /* The revision number of the file format. */ - nls_uint32 revision; - - /* The following are only used in .mo files with major revision 0. */ - - /* The number of strings pairs. */ - nls_uint32 nstrings; - /* Offset of table with start offsets of original strings. */ - nls_uint32 orig_tab_offset; - /* Offset of table with start offsets of translated strings. */ - nls_uint32 trans_tab_offset; - /* Size of hash table. */ - nls_uint32 hash_tab_size; - /* Offset of first hash table entry. */ - nls_uint32 hash_tab_offset; - - /* The following are only used in .mo files with minor revision >= 1. */ - - /* The number of system dependent segments. */ - nls_uint32 n_sysdep_segments; - /* Offset of table describing system dependent segments. */ - nls_uint32 sysdep_segments_offset; - /* The number of system dependent strings pairs. */ - nls_uint32 n_sysdep_strings; - /* Offset of table with start offsets of original sysdep strings. */ - nls_uint32 orig_sysdep_tab_offset; - /* Offset of table with start offsets of translated sysdep strings. */ - nls_uint32 trans_sysdep_tab_offset; -}; - -/* Descriptor for static string contained in the binary .mo file. */ -struct string_desc -{ - /* Length of addressed string, not including the trailing NUL. */ - nls_uint32 length; - /* Offset of string in file. */ - nls_uint32 offset; -}; - -/* The following are only used in .mo files with minor revision >= 1. */ - -/* Descriptor for system dependent string segment. */ -struct sysdep_segment -{ - /* Length of addressed string, including the trailing NUL. */ - nls_uint32 length; - /* Offset of string in file. */ - nls_uint32 offset; -}; - -/* Descriptor for system dependent string. */ -struct sysdep_string -{ - /* Offset of static string segments in file. */ - nls_uint32 offset; - /* Alternating sequence of static and system dependent segments. - The last segment is a static segment, including the trailing NUL. */ - struct segment_pair - { - /* Size of static segment. */ - nls_uint32 segsize; - /* Reference to system dependent string segment, or ~0 at the end. */ - nls_uint32 sysdepref; - } segments[1]; -}; - -/* Marker for the end of the segments[] array. This has the value 0xFFFFFFFF, - regardless whether 'int' is 16 bit, 32 bit, or 64 bit. */ -#define SEGMENTS_END ((nls_uint32) ~0) - -/* @@ begin of epilog @@ */ - -#endif /* gettext.h */ diff --git a/intl/hash-string.h b/intl/hash-string.h deleted file mode 100644 index b267a8778..000000000 --- a/intl/hash-string.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Description of GNU message catalog format: string hashing function. - Copyright (C) 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* @@ end of prolog @@ */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -/* We assume to have `unsigned long int' value with at least 32 bits. */ -#define HASHWORDBITS 32 - - -/* Defines the so called `hashpjw' function by P.J. Weinberger - [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, - 1986, 1987 Bell Telephone Laboratories, Inc.] */ -static unsigned long int hash_string PARAMS ((const char *__str_param)); - -static inline unsigned long int -hash_string (str_param) - const char *str_param; -{ - unsigned long int hval, g; - const char *str = str_param; - - /* Compute the hash value for the given string. */ - hval = 0; - while (*str != '\0') - { - hval <<= 4; - hval += (unsigned long int) *str++; - g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); - if (g != 0) - { - hval ^= g >> (HASHWORDBITS - 8); - hval ^= g; - } - } - return hval; -} diff --git a/intl/intl-compat.c b/intl/intl-compat.c deleted file mode 100644 index 36b7af0f8..000000000 --- a/intl/intl-compat.c +++ /dev/null @@ -1,151 +0,0 @@ -/* intl-compat.c - Stub functions to call gettext functions from GNU gettext - Library. - Copyright (C) 1995, 2000-2003 Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include "gettextP.h" - -/* @@ end of prolog @@ */ - -/* This file redirects the gettext functions (without prefix) to those - defined in the included GNU libintl library (with "libintl_" prefix). - It is compiled into libintl in order to make the AM_GNU_GETTEXT test - of gettext <= 0.11.2 work with the libintl library >= 0.11.3 which - has the redirections primarily in the <libintl.h> include file. - It is also compiled into libgnuintl so that libgnuintl.so can be used - as LD_PRELOADable library on glibc systems, to provide the extra - features that the functions in the libc don't have (namely, logging). */ - - -#undef gettext -#undef dgettext -#undef dcgettext -#undef ngettext -#undef dngettext -#undef dcngettext -#undef textdomain -#undef bindtextdomain -#undef bind_textdomain_codeset - - -/* When building a DLL, we must export some functions. Note that because - the functions are only defined for binary backward compatibility, we - don't need to use __declspec(dllimport) in any case. */ -#if defined _MSC_VER && BUILDING_DLL -# define DLL_EXPORTED __declspec(dllexport) -#else -# define DLL_EXPORTED -#endif - - -DLL_EXPORTED -char * -gettext (msgid) - const char *msgid; -{ - return libintl_gettext (msgid); -} - - -DLL_EXPORTED -char * -dgettext (domainname, msgid) - const char *domainname; - const char *msgid; -{ - return libintl_dgettext (domainname, msgid); -} - - -DLL_EXPORTED -char * -dcgettext (domainname, msgid, category) - const char *domainname; - const char *msgid; - int category; -{ - return libintl_dcgettext (domainname, msgid, category); -} - - -DLL_EXPORTED -char * -ngettext (msgid1, msgid2, n) - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return libintl_ngettext (msgid1, msgid2, n); -} - - -DLL_EXPORTED -char * -dngettext (domainname, msgid1, msgid2, n) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return libintl_dngettext (domainname, msgid1, msgid2, n); -} - - -DLL_EXPORTED -char * -dcngettext (domainname, msgid1, msgid2, n, category) - const char *domainname; - const char *msgid1; - const char *msgid2; - unsigned long int n; - int category; -{ - return libintl_dcngettext (domainname, msgid1, msgid2, n, category); -} - - -DLL_EXPORTED -char * -textdomain (domainname) - const char *domainname; -{ - return libintl_textdomain (domainname); -} - - -DLL_EXPORTED -char * -bindtextdomain (domainname, dirname) - const char *domainname; - const char *dirname; -{ - return libintl_bindtextdomain (domainname, dirname); -} - - -DLL_EXPORTED -char * -bind_textdomain_codeset (domainname, codeset) - const char *domainname; - const char *codeset; -{ - return libintl_bind_textdomain_codeset (domainname, codeset); -} diff --git a/intl/l10nflist.c b/intl/l10nflist.c deleted file mode 100644 index ec8713f8e..000000000 --- a/intl/l10nflist.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for stpcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <string.h> - -#if defined _LIBC || defined HAVE_ARGZ_H -# include <argz.h> -#endif -#include <ctype.h> -#include <sys/types.h> -#include <stdlib.h> - -#include "loadinfo.h" - -/* On some strange systems still no definition of NULL is found. Sigh! */ -#ifndef NULL -# if defined __STDC__ && __STDC__ -# define NULL ((void *) 0) -# else -# define NULL 0 -# endif -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# ifndef stpcpy -# define stpcpy(dest, src) __stpcpy(dest, src) -# endif -#else -# ifndef HAVE_STPCPY -static char *stpcpy PARAMS ((char *dest, const char *src)); -# endif -#endif - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not, - it may be concatenated to a directory pathname. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P)) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0]) -#endif - -/* Define function which are usually not available. */ - -#if !defined _LIBC && !defined HAVE___ARGZ_COUNT -/* Returns the number of strings in ARGZ. */ -static size_t argz_count__ PARAMS ((const char *argz, size_t len)); - -static size_t -argz_count__ (argz, len) - const char *argz; - size_t len; -{ - size_t count = 0; - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len + 1; - len -= part_len + 1; - count++; - } - return count; -} -# undef __argz_count -# define __argz_count(argz, len) argz_count__ (argz, len) -#else -# ifdef _LIBC -# define __argz_count(argz, len) INTUSE(__argz_count) (argz, len) -# endif -#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ - -#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY -/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's - except the last into the character SEP. */ -static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); - -static void -argz_stringify__ (argz, len, sep) - char *argz; - size_t len; - int sep; -{ - while (len > 0) - { - size_t part_len = strlen (argz); - argz += part_len; - len -= part_len + 1; - if (len > 0) - *argz++ = sep; - } -} -# undef __argz_stringify -# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) -#else -# ifdef _LIBC -# define __argz_stringify(argz, len, sep) \ - INTUSE(__argz_stringify) (argz, len, sep) -# endif -#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ - -#if !defined _LIBC && !defined HAVE___ARGZ_NEXT -static char *argz_next__ PARAMS ((char *argz, size_t argz_len, - const char *entry)); - -static char * -argz_next__ (argz, argz_len, entry) - char *argz; - size_t argz_len; - const char *entry; -{ - if (entry) - { - if (entry < argz + argz_len) - entry = strchr (entry, '\0') + 1; - - return entry >= argz + argz_len ? NULL : (char *) entry; - } - else - if (argz_len > 0) - return argz; - else - return 0; -} -# undef __argz_next -# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) -#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ - - -/* Return number of bits set in X. */ -static int pop PARAMS ((int x)); - -static inline int -pop (x) - int x; -{ - /* We assume that no more than 16 bits are used. */ - x = ((x & ~0x5555) >> 1) + (x & 0x5555); - x = ((x & ~0x3333) >> 2) + (x & 0x3333); - x = ((x >> 4) + x) & 0x0f0f; - x = ((x >> 8) + x) & 0xff; - - return x; -} - - -struct loaded_l10nfile * -_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, - territory, codeset, normalized_codeset, modifier, special, - sponsor, revision, filename, do_allocate) - struct loaded_l10nfile **l10nfile_list; - const char *dirlist; - size_t dirlist_len; - int mask; - const char *language; - const char *territory; - const char *codeset; - const char *normalized_codeset; - const char *modifier; - const char *special; - const char *sponsor; - const char *revision; - const char *filename; - int do_allocate; -{ - char *abs_filename; - struct loaded_l10nfile **lastp; - struct loaded_l10nfile *retval; - char *cp; - size_t dirlist_count; - size_t entries; - int cnt; - - /* If LANGUAGE contains an absolute directory specification, we ignore - DIRLIST. */ - if (IS_ABSOLUTE_PATH (language)) - dirlist_len = 0; - - /* Allocate room for the full file name. */ - abs_filename = (char *) malloc (dirlist_len - + strlen (language) - + ((mask & TERRITORY) != 0 - ? strlen (territory) + 1 : 0) - + ((mask & XPG_CODESET) != 0 - ? strlen (codeset) + 1 : 0) - + ((mask & XPG_NORM_CODESET) != 0 - ? strlen (normalized_codeset) + 1 : 0) - + (((mask & XPG_MODIFIER) != 0 - || (mask & CEN_AUDIENCE) != 0) - ? strlen (modifier) + 1 : 0) - + ((mask & CEN_SPECIAL) != 0 - ? strlen (special) + 1 : 0) - + (((mask & CEN_SPONSOR) != 0 - || (mask & CEN_REVISION) != 0) - ? (1 + ((mask & CEN_SPONSOR) != 0 - ? strlen (sponsor) : 0) - + ((mask & CEN_REVISION) != 0 - ? strlen (revision) + 1 : 0)) : 0) - + 1 + strlen (filename) + 1); - - if (abs_filename == NULL) - return NULL; - - /* Construct file name. */ - cp = abs_filename; - if (dirlist_len > 0) - { - memcpy (cp, dirlist, dirlist_len); - __argz_stringify (cp, dirlist_len, PATH_SEPARATOR); - cp += dirlist_len; - cp[-1] = '/'; - } - - cp = stpcpy (cp, language); - - if ((mask & TERRITORY) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, territory); - } - if ((mask & XPG_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, codeset); - } - if ((mask & XPG_NORM_CODESET) != 0) - { - *cp++ = '.'; - cp = stpcpy (cp, normalized_codeset); - } - if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) - { - /* This component can be part of both syntaces but has different - leading characters. For CEN we use `+', else `@'. */ - *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; - cp = stpcpy (cp, modifier); - } - if ((mask & CEN_SPECIAL) != 0) - { - *cp++ = '+'; - cp = stpcpy (cp, special); - } - if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) - { - *cp++ = ','; - if ((mask & CEN_SPONSOR) != 0) - cp = stpcpy (cp, sponsor); - if ((mask & CEN_REVISION) != 0) - { - *cp++ = '_'; - cp = stpcpy (cp, revision); - } - } - - *cp++ = '/'; - stpcpy (cp, filename); - - /* Look in list of already loaded domains whether it is already - available. */ - lastp = l10nfile_list; - for (retval = *l10nfile_list; retval != NULL; retval = retval->next) - if (retval->filename != NULL) - { - int compare = strcmp (retval->filename, abs_filename); - if (compare == 0) - /* We found it! */ - break; - if (compare < 0) - { - /* It's not in the list. */ - retval = NULL; - break; - } - - lastp = &retval->next; - } - - if (retval != NULL || do_allocate == 0) - { - free (abs_filename); - return retval; - } - - dirlist_count = (dirlist_len > 0 ? __argz_count (dirlist, dirlist_len) : 1); - - /* Allocate a new loaded_l10nfile. */ - retval = - (struct loaded_l10nfile *) - malloc (sizeof (*retval) - + (((dirlist_count << pop (mask)) + (dirlist_count > 1 ? 1 : 0)) - * sizeof (struct loaded_l10nfile *))); - if (retval == NULL) - return NULL; - - retval->filename = abs_filename; - - /* We set retval->data to NULL here; it is filled in later. - Setting retval->decided to 1 here means that retval does not - correspond to a real file (dirlist_count > 1) or is not worth - looking up (if an unnormalized codeset was specified). */ - retval->decided = (dirlist_count > 1 - || ((mask & XPG_CODESET) != 0 - && (mask & XPG_NORM_CODESET) != 0)); - retval->data = NULL; - - retval->next = *lastp; - *lastp = retval; - - entries = 0; - /* Recurse to fill the inheritance list of RETVAL. - If the DIRLIST is a real list (i.e. DIRLIST_COUNT > 1), the RETVAL - entry does not correspond to a real file; retval->filename contains - colons. In this case we loop across all elements of DIRLIST and - across all bit patterns dominated by MASK. - If the DIRLIST is a single directory or entirely redundant (i.e. - DIRLIST_COUNT == 1), we loop across all bit patterns dominated by - MASK, excluding MASK itself. - In either case, we loop down from MASK to 0. This has the effect - that the extra bits in the locale name are dropped in this order: - first the modifier, then the territory, then the codeset, then the - normalized_codeset. */ - for (cnt = dirlist_count > 1 ? mask : mask - 1; cnt >= 0; --cnt) - if ((cnt & ~mask) == 0 - && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) - && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) - { - if (dirlist_count > 1) - { - /* Iterate over all elements of the DIRLIST. */ - char *dir = NULL; - - while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) - != NULL) - retval->successor[entries++] - = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, - cnt, language, territory, codeset, - normalized_codeset, modifier, special, - sponsor, revision, filename, 1); - } - else - retval->successor[entries++] - = _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, - cnt, language, territory, codeset, - normalized_codeset, modifier, special, - sponsor, revision, filename, 1); - } - retval->successor[entries] = NULL; - - return retval; -} - -/* Normalize codeset name. There is no standard for the codeset - names. Normalization allows the user to use any of the common - names. The return value is dynamically allocated and has to be - freed by the caller. */ -const char * -_nl_normalize_codeset (codeset, name_len) - const char *codeset; - size_t name_len; -{ - int len = 0; - int only_digit = 1; - char *retval; - char *wp; - size_t cnt; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalnum ((unsigned char) codeset[cnt])) - { - ++len; - - if (isalpha ((unsigned char) codeset[cnt])) - only_digit = 0; - } - - retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); - - if (retval != NULL) - { - if (only_digit) - wp = stpcpy (retval, "iso"); - else - wp = retval; - - for (cnt = 0; cnt < name_len; ++cnt) - if (isalpha ((unsigned char) codeset[cnt])) - *wp++ = tolower ((unsigned char) codeset[cnt]); - else if (isdigit ((unsigned char) codeset[cnt])) - *wp++ = codeset[cnt]; - - *wp = '\0'; - } - - return (const char *) retval; -} - - -/* @@ begin of epilog @@ */ - -/* We don't want libintl.a to depend on any other library. So we - avoid the non-standard function stpcpy. In GNU C Library this - function is available, though. Also allow the symbol HAVE_STPCPY - to be defined. */ -#if !_LIBC && !HAVE_STPCPY -static char * -stpcpy (dest, src) - char *dest; - const char *src; -{ - while ((*dest++ = *src++) != '\0') - /* Do nothing. */ ; - return dest - 1; -} -#endif diff --git a/intl/libgnuintl.h b/intl/libgnuintl.h deleted file mode 100644 index ed25fe9f5..000000000 --- a/intl/libgnuintl.h +++ /dev/null @@ -1,296 +0,0 @@ -/* Message catalogs for internationalization. - Copyright (C) 1995-1997, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LIBINTL_H -#define _LIBINTL_H 1 - -#include <locale.h> - -/* The LC_MESSAGES locale category is the category used by the functions - gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. - On systems that don't define it, use an arbitrary value instead. - On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5) - then includes <libintl.h> (i.e. this file!) and then only defines - LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES - in this case. */ -#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) -# define LC_MESSAGES 1729 -#endif - -/* We define an additional symbol to signal that we use the GNU - implementation of gettext. */ -#define __USE_GNU_GETTEXT 1 - -/* Provide information about the supported file formats. Returns the - maximum minor revision number supported for a given major revision. */ -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \ - ((major) == 0 ? 1 : -1) - -/* Resolve a platform specific conflict on DJGPP. GNU gettext takes - precedence over _conio_gettext. */ -#ifdef __DJGPP__ -# undef gettext -#endif - -/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers - used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */ -#ifndef _INTL_PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define _INTL_PARAMS(args) args -# else -# define _INTL_PARAMS(args) () -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* We redirect the functions to those prefixed with "libintl_". This is - necessary, because some systems define gettext/textdomain/... in the C - library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). - If we used the unprefixed names, there would be cases where the - definition in the C library would override the one in the libintl.so - shared library. Recall that on ELF systems, the symbols are looked - up in the following order: - 1. in the executable, - 2. in the shared libraries specified on the link command line, in order, - 3. in the dependencies of the shared libraries specified on the link - command line, - 4. in the dlopen()ed shared libraries, in the order in which they were - dlopen()ed. - The definition in the C library would override the one in libintl.so if - either - * -lc is given on the link command line and -lintl isn't, or - * -lc is given on the link command line before -lintl, or - * libintl.so is a dependency of a dlopen()ed shared library but not - linked to the executable at link time. - Since Solaris gettext() behaves differently than GNU gettext(), this - would be unacceptable. - - The redirection happens by default through macros in C, so that &gettext - is independent of the compilation unit, but through inline functions in - C++, in order not to interfere with the name mangling of class fields or - class methods called 'gettext'. */ - -/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS. - If he doesn't, we choose the method. A third possible method is - _INTL_REDIRECT_ASM, supported only by GCC. */ -#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS) -# if __GNUC__ >= 2 && (defined __STDC__ || defined __cplusplus) -# define _INTL_REDIRECT_ASM -# else -# ifdef __cplusplus -# define _INTL_REDIRECT_INLINE -# else -# define _INTL_REDIRECT_MACROS -# endif -# endif -#endif -/* Auxiliary macros. */ -#ifdef _INTL_REDIRECT_ASM -# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname)) -# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring -# define _INTL_STRINGIFY(prefix) #prefix -#else -# define _INTL_ASM(cname) -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_gettext (const char *__msgid); -static inline char *gettext (const char *__msgid) -{ - return libintl_gettext (__msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define gettext libintl_gettext -#endif -extern char *gettext _INTL_PARAMS ((const char *__msgid)) - _INTL_ASM (libintl_gettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current - LC_MESSAGES locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dgettext (const char *__domainname, const char *__msgid); -static inline char *dgettext (const char *__domainname, const char *__msgid) -{ - return libintl_dgettext (__domainname, __msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dgettext libintl_dgettext -#endif -extern char *dgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid)) - _INTL_ASM (libintl_dgettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcgettext (const char *__domainname, const char *__msgid, - int __category); -static inline char *dcgettext (const char *__domainname, const char *__msgid, - int __category) -{ - return libintl_dcgettext (__domainname, __msgid, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcgettext libintl_dcgettext -#endif -extern char *dcgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid, - int __category)) - _INTL_ASM (libintl_dcgettext); -#endif - - -/* Similar to `gettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n); -static inline char *ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n) -{ - return libintl_ngettext (__msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define ngettext libintl_ngettext -#endif -extern char *ngettext _INTL_PARAMS ((const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_ngettext); -#endif - -/* Similar to `dgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n); -static inline char *dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n) -{ - return libintl_dngettext (__domainname, __msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dngettext libintl_dngettext -#endif -extern char *dngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_dngettext); -#endif - -/* Similar to `dcgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category); -static inline char *dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category) -{ - return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcngettext libintl_dcngettext -#endif -extern char *dcngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n, - int __category)) - _INTL_ASM (libintl_dcngettext); -#endif - - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_textdomain (const char *__domainname); -static inline char *textdomain (const char *__domainname) -{ - return libintl_textdomain (__domainname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define textdomain libintl_textdomain -#endif -extern char *textdomain _INTL_PARAMS ((const char *__domainname)) - _INTL_ASM (libintl_textdomain); -#endif - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bindtextdomain (const char *__domainname, - const char *__dirname); -static inline char *bindtextdomain (const char *__domainname, - const char *__dirname) -{ - return libintl_bindtextdomain (__domainname, __dirname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bindtextdomain libintl_bindtextdomain -#endif -extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname, - const char *__dirname)) - _INTL_ASM (libintl_bindtextdomain); -#endif - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bind_textdomain_codeset (const char *__domainname, - const char *__codeset); -static inline char *bind_textdomain_codeset (const char *__domainname, - const char *__codeset) -{ - return libintl_bind_textdomain_codeset (__domainname, __codeset); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bind_textdomain_codeset libintl_bind_textdomain_codeset -#endif -extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname, - const char *__codeset)) - _INTL_ASM (libintl_bind_textdomain_codeset); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* libintl.h */ diff --git a/intl/libgnuintl.h.in b/intl/libgnuintl.h.in deleted file mode 100644 index f596cfcb2..000000000 --- a/intl/libgnuintl.h.in +++ /dev/null @@ -1,309 +0,0 @@ -/* Message catalogs for internationalization. - Copyright (C) 1995-1997, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LIBINTL_H -#define _LIBINTL_H 1 - -#include <locale.h> - -/* The LC_MESSAGES locale category is the category used by the functions - gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. - On systems that don't define it, use an arbitrary value instead. - On Solaris, <locale.h> defines __LOCALE_H (or _LOCALE_H in Solaris 2.5) - then includes <libintl.h> (i.e. this file!) and then only defines - LC_MESSAGES. To avoid a redefinition warning, don't define LC_MESSAGES - in this case. */ -#if !defined LC_MESSAGES && !(defined __LOCALE_H || (defined _LOCALE_H && defined __sun)) -# define LC_MESSAGES 1729 -#endif - -/* We define an additional symbol to signal that we use the GNU - implementation of gettext. */ -#define __USE_GNU_GETTEXT 1 - -/* Provide information about the supported file formats. Returns the - maximum minor revision number supported for a given major revision. */ -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) \ - ((major) == 0 ? 1 : -1) - -/* Resolve a platform specific conflict on DJGPP. GNU gettext takes - precedence over _conio_gettext. */ -#ifdef __DJGPP__ -# undef gettext -#endif - -/* Use _INTL_PARAMS, not PARAMS, in order to avoid clashes with identifiers - used by programs. Similarly, test __PROTOTYPES, not PROTOTYPES. */ -#ifndef _INTL_PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define _INTL_PARAMS(args) args -# else -# define _INTL_PARAMS(args) () -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* We redirect the functions to those prefixed with "libintl_". This is - necessary, because some systems define gettext/textdomain/... in the C - library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). - If we used the unprefixed names, there would be cases where the - definition in the C library would override the one in the libintl.so - shared library. Recall that on ELF systems, the symbols are looked - up in the following order: - 1. in the executable, - 2. in the shared libraries specified on the link command line, in order, - 3. in the dependencies of the shared libraries specified on the link - command line, - 4. in the dlopen()ed shared libraries, in the order in which they were - dlopen()ed. - The definition in the C library would override the one in libintl.so if - either - * -lc is given on the link command line and -lintl isn't, or - * -lc is given on the link command line before -lintl, or - * libintl.so is a dependency of a dlopen()ed shared library but not - linked to the executable at link time. - Since Solaris gettext() behaves differently than GNU gettext(), this - would be unacceptable. - - The redirection happens by default through macros in C, so that &gettext - is independent of the compilation unit, but through inline functions in - C++, in order not to interfere with the name mangling of class fields or - class methods called 'gettext'. */ - -/* The user can define _INTL_REDIRECT_INLINE or _INTL_REDIRECT_MACROS. - If he doesn't, we choose the method. A third possible method is - _INTL_REDIRECT_ASM, supported only by GCC. */ -#if !(defined _INTL_REDIRECT_INLINE || defined _INTL_REDIRECT_MACROS) -# if __GNUC__ >= 2 && !defined __APPLE_CC__ && (defined __STDC__ || defined __cplusplus) -# define _INTL_REDIRECT_ASM -# else -# ifdef __cplusplus -# define _INTL_REDIRECT_INLINE -# else -# define _INTL_REDIRECT_MACROS -# endif -# endif -#endif -/* Auxiliary macros. */ -#ifdef _INTL_REDIRECT_ASM -# define _INTL_ASM(cname) __asm__ (_INTL_ASMNAME (__USER_LABEL_PREFIX__, #cname)) -# define _INTL_ASMNAME(prefix,cnamestring) _INTL_STRINGIFY (prefix) cnamestring -# define _INTL_STRINGIFY(prefix) #prefix -#else -# define _INTL_ASM(cname) -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_gettext (const char *__msgid); -static inline char *gettext (const char *__msgid) -{ - return libintl_gettext (__msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define gettext libintl_gettext -#endif -extern char *gettext _INTL_PARAMS ((const char *__msgid)) - _INTL_ASM (libintl_gettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current - LC_MESSAGES locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dgettext (const char *__domainname, const char *__msgid); -static inline char *dgettext (const char *__domainname, const char *__msgid) -{ - return libintl_dgettext (__domainname, __msgid); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dgettext libintl_dgettext -#endif -extern char *dgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid)) - _INTL_ASM (libintl_dgettext); -#endif - -/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY - locale. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcgettext (const char *__domainname, const char *__msgid, - int __category); -static inline char *dcgettext (const char *__domainname, const char *__msgid, - int __category) -{ - return libintl_dcgettext (__domainname, __msgid, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcgettext libintl_dcgettext -#endif -extern char *dcgettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid, - int __category)) - _INTL_ASM (libintl_dcgettext); -#endif - - -/* Similar to `gettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n); -static inline char *ngettext (const char *__msgid1, const char *__msgid2, - unsigned long int __n) -{ - return libintl_ngettext (__msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define ngettext libintl_ngettext -#endif -extern char *ngettext _INTL_PARAMS ((const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_ngettext); -#endif - -/* Similar to `dgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n); -static inline char *dngettext (const char *__domainname, const char *__msgid1, - const char *__msgid2, unsigned long int __n) -{ - return libintl_dngettext (__domainname, __msgid1, __msgid2, __n); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dngettext libintl_dngettext -#endif -extern char *dngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n)) - _INTL_ASM (libintl_dngettext); -#endif - -/* Similar to `dcgettext' but select the plural form corresponding to the - number N. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category); -static inline char *dcngettext (const char *__domainname, - const char *__msgid1, const char *__msgid2, - unsigned long int __n, int __category) -{ - return libintl_dcngettext (__domainname, __msgid1, __msgid2, __n, __category); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define dcngettext libintl_dcngettext -#endif -extern char *dcngettext _INTL_PARAMS ((const char *__domainname, - const char *__msgid1, - const char *__msgid2, - unsigned long int __n, - int __category)) - _INTL_ASM (libintl_dcngettext); -#endif - - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_textdomain (const char *__domainname); -static inline char *textdomain (const char *__domainname) -{ - return libintl_textdomain (__domainname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define textdomain libintl_textdomain -#endif -extern char *textdomain _INTL_PARAMS ((const char *__domainname)) - _INTL_ASM (libintl_textdomain); -#endif - -/* Specify that the DOMAINNAME message catalog will be found - in DIRNAME rather than in the system locale data base. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bindtextdomain (const char *__domainname, - const char *__dirname); -static inline char *bindtextdomain (const char *__domainname, - const char *__dirname) -{ - return libintl_bindtextdomain (__domainname, __dirname); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bindtextdomain libintl_bindtextdomain -#endif -extern char *bindtextdomain _INTL_PARAMS ((const char *__domainname, - const char *__dirname)) - _INTL_ASM (libintl_bindtextdomain); -#endif - -/* Specify the character encoding in which the messages from the - DOMAINNAME message catalog will be returned. */ -#ifdef _INTL_REDIRECT_INLINE -extern char *libintl_bind_textdomain_codeset (const char *__domainname, - const char *__codeset); -static inline char *bind_textdomain_codeset (const char *__domainname, - const char *__codeset) -{ - return libintl_bind_textdomain_codeset (__domainname, __codeset); -} -#else -#ifdef _INTL_REDIRECT_MACROS -# define bind_textdomain_codeset libintl_bind_textdomain_codeset -#endif -extern char *bind_textdomain_codeset _INTL_PARAMS ((const char *__domainname, - const char *__codeset)) - _INTL_ASM (libintl_bind_textdomain_codeset); -#endif - - -/* Support for relocatable packages. */ - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -#define libintl_set_relocation_prefix libintl_set_relocation_prefix -extern void - libintl_set_relocation_prefix _INTL_PARAMS ((const char *orig_prefix, - const char *curr_prefix)); - - -#ifdef __cplusplus -} -#endif - -#endif /* libintl.h */ diff --git a/intl/loadinfo.h b/intl/loadinfo.h deleted file mode 100644 index 1d3ba6162..000000000 --- a/intl/loadinfo.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (C) 1996-1999, 2000-2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LOADINFO_H -#define _LOADINFO_H 1 - -/* Declarations of locale dependent catalog lookup functions. - Implemented in - - localealias.c Possibly replace a locale name by another. - explodename.c Split a locale name into its various fields. - l10nflist.c Generate a list of filenames of possible message catalogs. - finddomain.c Find and open the relevant message catalogs. - - The main function _nl_find_domain() in finddomain.c is declared - in gettextP.h. - */ - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -/* Tell the compiler when a conditional or integer expression is - almost always true or almost always false. */ -#ifndef HAVE_BUILTIN_EXPECT -# define __builtin_expect(expr, val) (expr) -#endif - -/* Separator in PATH like lists of pathnames. */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define PATH_SEPARATOR ';' -#else - /* Unix */ -# define PATH_SEPARATOR ':' -#endif - -/* Encoding of locale name parts. */ -#define CEN_REVISION 1 -#define CEN_SPONSOR 2 -#define CEN_SPECIAL 4 -#define XPG_NORM_CODESET 8 -#define XPG_CODESET 16 -#define TERRITORY 32 -#define CEN_AUDIENCE 64 -#define XPG_MODIFIER 128 - -#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) -#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) - - -struct loaded_l10nfile -{ - const char *filename; - int decided; - - const void *data; - - struct loaded_l10nfile *next; - struct loaded_l10nfile *successor[1]; -}; - - -/* Normalize codeset name. There is no standard for the codeset - names. Normalization allows the user to use any of the common - names. The return value is dynamically allocated and has to be - freed by the caller. */ -extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, - size_t name_len)); - -/* Lookup a locale dependent file. - *L10NFILE_LIST denotes a pool of lookup results of locale dependent - files of the same kind, sorted in decreasing order of ->filename. - DIRLIST and DIRLIST_LEN are an argz list of directories in which to - look, containing at least one directory (i.e. DIRLIST_LEN > 0). - MASK, LANGUAGE, TERRITORY, CODESET, NORMALIZED_CODESET, MODIFIER, - SPECIAL, SPONSOR, REVISION are the pieces of the locale name, as - produced by _nl_explode_name(). FILENAME is the filename suffix. - The return value is the lookup result, either found in *L10NFILE_LIST, - or - if DO_ALLOCATE is nonzero - freshly allocated, or possibly NULL. - If the return value is non-NULL, it is added to *L10NFILE_LIST, and - its ->next field denotes the chaining inside *L10NFILE_LIST, and - furthermore its ->successor[] field contains a list of other lookup - results from which this lookup result inherits. */ -extern struct loaded_l10nfile * -_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, - const char *dirlist, size_t dirlist_len, int mask, - const char *language, const char *territory, - const char *codeset, - const char *normalized_codeset, - const char *modifier, const char *special, - const char *sponsor, const char *revision, - const char *filename, int do_allocate)); - -/* Lookup the real locale name for a locale alias NAME, or NULL if - NAME is not a locale alias (but possibly a real locale name). - The return value is statically allocated and must not be freed. */ -extern const char *_nl_expand_alias PARAMS ((const char *name)); - -/* Split a locale name NAME into its pieces: language, modifier, - territory, codeset, special, sponsor, revision. - NAME gets destructively modified: NUL bytes are inserted here and - there. *LANGUAGE gets assigned NAME. Each of *MODIFIER, *TERRITORY, - *CODESET, *SPECIAL, *SPONSOR, *REVISION gets assigned either a - pointer into the old NAME string, or NULL. *NORMALIZED_CODESET - gets assigned the expanded *CODESET, if it is different from *CODESET; - this one is dynamically allocated and has to be freed by the caller. - The return value is a bitmask, where each bit corresponds to one - filled-in value: - XPG_MODIFIER, CEN_AUDIENCE for *MODIFIER, - TERRITORY for *TERRITORY, - XPG_CODESET for *CODESET, - XPG_NORM_CODESET for *NORMALIZED_CODESET, - CEN_SPECIAL for *SPECIAL, - CEN_SPONSOR for *SPONSOR, - CEN_REVISION for *REVISION. - */ -extern int _nl_explode_name PARAMS ((char *name, const char **language, - const char **modifier, - const char **territory, - const char **codeset, - const char **normalized_codeset, - const char **special, - const char **sponsor, - const char **revision)); - -/* Split a locale name NAME into a leading language part and all the - rest. Return a pointer to the first character after the language, - i.e. to the first byte of the rest. */ -extern char *_nl_find_language PARAMS ((const char *name)); - -#endif /* loadinfo.h */ diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c deleted file mode 100644 index 8509bd345..000000000 --- a/intl/loadmsgcat.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* Load needed message catalogs. - Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <stdlib.h> -#include <string.h> - -#if defined HAVE_UNISTD_H || defined _LIBC -# include <unistd.h> -#endif - -#ifdef _LIBC -# include <langinfo.h> -# include <locale.h> -#endif - -#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ - || (defined _LIBC && defined _POSIX_MAPPED_FILES) -# include <sys/mman.h> -# undef HAVE_MMAP -# define HAVE_MMAP 1 -#else -# undef HAVE_MMAP -#endif - -#if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC -# include <stdint.h> -#endif -#if defined HAVE_INTTYPES_H || defined _LIBC -# include <inttypes.h> -#endif - -#include "gmo.h" -#include "gettextP.h" -#include "hash-string.h" -#include "plural-exp.h" - -#ifdef _LIBC -# include "../locale/localeinfo.h" -#endif - -/* Provide fallback values for macros that ought to be defined in <inttypes.h>. - Note that our fallback values need not be literal strings, because we don't - use them with preprocessor string concatenation. */ -#if !defined PRId8 || PRI_MACROS_BROKEN -# undef PRId8 -# define PRId8 "d" -#endif -#if !defined PRIi8 || PRI_MACROS_BROKEN -# undef PRIi8 -# define PRIi8 "i" -#endif -#if !defined PRIo8 || PRI_MACROS_BROKEN -# undef PRIo8 -# define PRIo8 "o" -#endif -#if !defined PRIu8 || PRI_MACROS_BROKEN -# undef PRIu8 -# define PRIu8 "u" -#endif -#if !defined PRIx8 || PRI_MACROS_BROKEN -# undef PRIx8 -# define PRIx8 "x" -#endif -#if !defined PRIX8 || PRI_MACROS_BROKEN -# undef PRIX8 -# define PRIX8 "X" -#endif -#if !defined PRId16 || PRI_MACROS_BROKEN -# undef PRId16 -# define PRId16 "d" -#endif -#if !defined PRIi16 || PRI_MACROS_BROKEN -# undef PRIi16 -# define PRIi16 "i" -#endif -#if !defined PRIo16 || PRI_MACROS_BROKEN -# undef PRIo16 -# define PRIo16 "o" -#endif -#if !defined PRIu16 || PRI_MACROS_BROKEN -# undef PRIu16 -# define PRIu16 "u" -#endif -#if !defined PRIx16 || PRI_MACROS_BROKEN -# undef PRIx16 -# define PRIx16 "x" -#endif -#if !defined PRIX16 || PRI_MACROS_BROKEN -# undef PRIX16 -# define PRIX16 "X" -#endif -#if !defined PRId32 || PRI_MACROS_BROKEN -# undef PRId32 -# define PRId32 "d" -#endif -#if !defined PRIi32 || PRI_MACROS_BROKEN -# undef PRIi32 -# define PRIi32 "i" -#endif -#if !defined PRIo32 || PRI_MACROS_BROKEN -# undef PRIo32 -# define PRIo32 "o" -#endif -#if !defined PRIu32 || PRI_MACROS_BROKEN -# undef PRIu32 -# define PRIu32 "u" -#endif -#if !defined PRIx32 || PRI_MACROS_BROKEN -# undef PRIx32 -# define PRIx32 "x" -#endif -#if !defined PRIX32 || PRI_MACROS_BROKEN -# undef PRIX32 -# define PRIX32 "X" -#endif -#if !defined PRId64 || PRI_MACROS_BROKEN -# undef PRId64 -# define PRId64 (sizeof (long) == 8 ? "ld" : "lld") -#endif -#if !defined PRIi64 || PRI_MACROS_BROKEN -# undef PRIi64 -# define PRIi64 (sizeof (long) == 8 ? "li" : "lli") -#endif -#if !defined PRIo64 || PRI_MACROS_BROKEN -# undef PRIo64 -# define PRIo64 (sizeof (long) == 8 ? "lo" : "llo") -#endif -#if !defined PRIu64 || PRI_MACROS_BROKEN -# undef PRIu64 -# define PRIu64 (sizeof (long) == 8 ? "lu" : "llu") -#endif -#if !defined PRIx64 || PRI_MACROS_BROKEN -# undef PRIx64 -# define PRIx64 (sizeof (long) == 8 ? "lx" : "llx") -#endif -#if !defined PRIX64 || PRI_MACROS_BROKEN -# undef PRIX64 -# define PRIX64 (sizeof (long) == 8 ? "lX" : "llX") -#endif -#if !defined PRIdLEAST8 || PRI_MACROS_BROKEN -# undef PRIdLEAST8 -# define PRIdLEAST8 "d" -#endif -#if !defined PRIiLEAST8 || PRI_MACROS_BROKEN -# undef PRIiLEAST8 -# define PRIiLEAST8 "i" -#endif -#if !defined PRIoLEAST8 || PRI_MACROS_BROKEN -# undef PRIoLEAST8 -# define PRIoLEAST8 "o" -#endif -#if !defined PRIuLEAST8 || PRI_MACROS_BROKEN -# undef PRIuLEAST8 -# define PRIuLEAST8 "u" -#endif -#if !defined PRIxLEAST8 || PRI_MACROS_BROKEN -# undef PRIxLEAST8 -# define PRIxLEAST8 "x" -#endif -#if !defined PRIXLEAST8 || PRI_MACROS_BROKEN -# undef PRIXLEAST8 -# define PRIXLEAST8 "X" -#endif -#if !defined PRIdLEAST16 || PRI_MACROS_BROKEN -# undef PRIdLEAST16 -# define PRIdLEAST16 "d" -#endif -#if !defined PRIiLEAST16 || PRI_MACROS_BROKEN -# undef PRIiLEAST16 -# define PRIiLEAST16 "i" -#endif -#if !defined PRIoLEAST16 || PRI_MACROS_BROKEN -# undef PRIoLEAST16 -# define PRIoLEAST16 "o" -#endif -#if !defined PRIuLEAST16 || PRI_MACROS_BROKEN -# undef PRIuLEAST16 -# define PRIuLEAST16 "u" -#endif -#if !defined PRIxLEAST16 || PRI_MACROS_BROKEN -# undef PRIxLEAST16 -# define PRIxLEAST16 "x" -#endif -#if !defined PRIXLEAST16 || PRI_MACROS_BROKEN -# undef PRIXLEAST16 -# define PRIXLEAST16 "X" -#endif -#if !defined PRIdLEAST32 || PRI_MACROS_BROKEN -# undef PRIdLEAST32 -# define PRIdLEAST32 "d" -#endif -#if !defined PRIiLEAST32 || PRI_MACROS_BROKEN -# undef PRIiLEAST32 -# define PRIiLEAST32 "i" -#endif -#if !defined PRIoLEAST32 || PRI_MACROS_BROKEN -# undef PRIoLEAST32 -# define PRIoLEAST32 "o" -#endif -#if !defined PRIuLEAST32 || PRI_MACROS_BROKEN -# undef PRIuLEAST32 -# define PRIuLEAST32 "u" -#endif -#if !defined PRIxLEAST32 || PRI_MACROS_BROKEN -# undef PRIxLEAST32 -# define PRIxLEAST32 "x" -#endif -#if !defined PRIXLEAST32 || PRI_MACROS_BROKEN -# undef PRIXLEAST32 -# define PRIXLEAST32 "X" -#endif -#if !defined PRIdLEAST64 || PRI_MACROS_BROKEN -# undef PRIdLEAST64 -# define PRIdLEAST64 PRId64 -#endif -#if !defined PRIiLEAST64 || PRI_MACROS_BROKEN -# undef PRIiLEAST64 -# define PRIiLEAST64 PRIi64 -#endif -#if !defined PRIoLEAST64 || PRI_MACROS_BROKEN -# undef PRIoLEAST64 -# define PRIoLEAST64 PRIo64 -#endif -#if !defined PRIuLEAST64 || PRI_MACROS_BROKEN -# undef PRIuLEAST64 -# define PRIuLEAST64 PRIu64 -#endif -#if !defined PRIxLEAST64 || PRI_MACROS_BROKEN -# undef PRIxLEAST64 -# define PRIxLEAST64 PRIx64 -#endif -#if !defined PRIXLEAST64 || PRI_MACROS_BROKEN -# undef PRIXLEAST64 -# define PRIXLEAST64 PRIX64 -#endif -#if !defined PRIdFAST8 || PRI_MACROS_BROKEN -# undef PRIdFAST8 -# define PRIdFAST8 "d" -#endif -#if !defined PRIiFAST8 || PRI_MACROS_BROKEN -# undef PRIiFAST8 -# define PRIiFAST8 "i" -#endif -#if !defined PRIoFAST8 || PRI_MACROS_BROKEN -# undef PRIoFAST8 -# define PRIoFAST8 "o" -#endif -#if !defined PRIuFAST8 || PRI_MACROS_BROKEN -# undef PRIuFAST8 -# define PRIuFAST8 "u" -#endif -#if !defined PRIxFAST8 || PRI_MACROS_BROKEN -# undef PRIxFAST8 -# define PRIxFAST8 "x" -#endif -#if !defined PRIXFAST8 || PRI_MACROS_BROKEN -# undef PRIXFAST8 -# define PRIXFAST8 "X" -#endif -#if !defined PRIdFAST16 || PRI_MACROS_BROKEN -# undef PRIdFAST16 -# define PRIdFAST16 "d" -#endif -#if !defined PRIiFAST16 || PRI_MACROS_BROKEN -# undef PRIiFAST16 -# define PRIiFAST16 "i" -#endif -#if !defined PRIoFAST16 || PRI_MACROS_BROKEN -# undef PRIoFAST16 -# define PRIoFAST16 "o" -#endif -#if !defined PRIuFAST16 || PRI_MACROS_BROKEN -# undef PRIuFAST16 -# define PRIuFAST16 "u" -#endif -#if !defined PRIxFAST16 || PRI_MACROS_BROKEN -# undef PRIxFAST16 -# define PRIxFAST16 "x" -#endif -#if !defined PRIXFAST16 || PRI_MACROS_BROKEN -# undef PRIXFAST16 -# define PRIXFAST16 "X" -#endif -#if !defined PRIdFAST32 || PRI_MACROS_BROKEN -# undef PRIdFAST32 -# define PRIdFAST32 "d" -#endif -#if !defined PRIiFAST32 || PRI_MACROS_BROKEN -# undef PRIiFAST32 -# define PRIiFAST32 "i" -#endif -#if !defined PRIoFAST32 || PRI_MACROS_BROKEN -# undef PRIoFAST32 -# define PRIoFAST32 "o" -#endif -#if !defined PRIuFAST32 || PRI_MACROS_BROKEN -# undef PRIuFAST32 -# define PRIuFAST32 "u" -#endif -#if !defined PRIxFAST32 || PRI_MACROS_BROKEN -# undef PRIxFAST32 -# define PRIxFAST32 "x" -#endif -#if !defined PRIXFAST32 || PRI_MACROS_BROKEN -# undef PRIXFAST32 -# define PRIXFAST32 "X" -#endif -#if !defined PRIdFAST64 || PRI_MACROS_BROKEN -# undef PRIdFAST64 -# define PRIdFAST64 PRId64 -#endif -#if !defined PRIiFAST64 || PRI_MACROS_BROKEN -# undef PRIiFAST64 -# define PRIiFAST64 PRIi64 -#endif -#if !defined PRIoFAST64 || PRI_MACROS_BROKEN -# undef PRIoFAST64 -# define PRIoFAST64 PRIo64 -#endif -#if !defined PRIuFAST64 || PRI_MACROS_BROKEN -# undef PRIuFAST64 -# define PRIuFAST64 PRIu64 -#endif -#if !defined PRIxFAST64 || PRI_MACROS_BROKEN -# undef PRIxFAST64 -# define PRIxFAST64 PRIx64 -#endif -#if !defined PRIXFAST64 || PRI_MACROS_BROKEN -# undef PRIXFAST64 -# define PRIXFAST64 PRIX64 -#endif -#if !defined PRIdMAX || PRI_MACROS_BROKEN -# undef PRIdMAX -# define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld") -#endif -#if !defined PRIiMAX || PRI_MACROS_BROKEN -# undef PRIiMAX -# define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli") -#endif -#if !defined PRIoMAX || PRI_MACROS_BROKEN -# undef PRIoMAX -# define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo") -#endif -#if !defined PRIuMAX || PRI_MACROS_BROKEN -# undef PRIuMAX -# define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu") -#endif -#if !defined PRIxMAX || PRI_MACROS_BROKEN -# undef PRIxMAX -# define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx") -#endif -#if !defined PRIXMAX || PRI_MACROS_BROKEN -# undef PRIXMAX -# define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX") -#endif -#if !defined PRIdPTR || PRI_MACROS_BROKEN -# undef PRIdPTR -# define PRIdPTR \ - (sizeof (void *) == sizeof (long) ? "ld" : \ - sizeof (void *) == sizeof (int) ? "d" : \ - "lld") -#endif -#if !defined PRIiPTR || PRI_MACROS_BROKEN -# undef PRIiPTR -# define PRIiPTR \ - (sizeof (void *) == sizeof (long) ? "li" : \ - sizeof (void *) == sizeof (int) ? "i" : \ - "lli") -#endif -#if !defined PRIoPTR || PRI_MACROS_BROKEN -# undef PRIoPTR -# define PRIoPTR \ - (sizeof (void *) == sizeof (long) ? "lo" : \ - sizeof (void *) == sizeof (int) ? "o" : \ - "llo") -#endif -#if !defined PRIuPTR || PRI_MACROS_BROKEN -# undef PRIuPTR -# define PRIuPTR \ - (sizeof (void *) == sizeof (long) ? "lu" : \ - sizeof (void *) == sizeof (int) ? "u" : \ - "llu") -#endif -#if !defined PRIxPTR || PRI_MACROS_BROKEN -# undef PRIxPTR -# define PRIxPTR \ - (sizeof (void *) == sizeof (long) ? "lx" : \ - sizeof (void *) == sizeof (int) ? "x" : \ - "llx") -#endif -#if !defined PRIXPTR || PRI_MACROS_BROKEN -# undef PRIXPTR -# define PRIXPTR \ - (sizeof (void *) == sizeof (long) ? "lX" : \ - sizeof (void *) == sizeof (int) ? "X" : \ - "llX") -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ISO C functions. This is required by the standard - because some ISO C functions will require linking with this object - file and the name space must not be polluted. */ -# define open __open -# define close __close -# define read __read -# define mmap __mmap -# define munmap __munmap -#endif - -/* For those losing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -# define freea(p) /* nothing */ -#else -# define alloca(n) malloc (n) -# define freea(p) free (p) -#endif - -/* For systems that distinguish between text and binary I/O. - O_BINARY is usually declared in <fcntl.h>. */ -#if !defined O_BINARY && defined _O_BINARY - /* For MSC-compatible compilers. */ -# define O_BINARY _O_BINARY -# define O_TEXT _O_TEXT -#endif -#ifdef __BEOS__ - /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ -# undef O_BINARY -# undef O_TEXT -#endif -/* On reasonable systems, binary I/O is the default. */ -#ifndef O_BINARY -# define O_BINARY 0 -#endif - - -/* Prototypes for local functions. Needed to ensure compiler checking of - function argument counts despite of K&R C function definition syntax. */ -static const char *get_sysdep_segment_value PARAMS ((const char *name)); - - -/* We need a sign, whether a new catalog was loaded, which can be associated - with all translations. This is important if the translations are - cached by one of GCC's features. */ -int _nl_msg_cat_cntr; - - -/* Expand a system dependent string segment. Return NULL if unsupported. */ -static const char * -get_sysdep_segment_value (name) - const char *name; -{ - /* Test for an ISO C 99 section 7.8.1 format string directive. - Syntax: - P R I { d | i | o | u | x | X } - { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */ - /* We don't use a table of 14 times 6 'const char *' strings here, because - data relocations cost startup time. */ - if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I') - { - if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u' - || name[3] == 'x' || name[3] == 'X') - { - if (name[4] == '8' && name[5] == '\0') - { - if (name[3] == 'd') - return PRId8; - if (name[3] == 'i') - return PRIi8; - if (name[3] == 'o') - return PRIo8; - if (name[3] == 'u') - return PRIu8; - if (name[3] == 'x') - return PRIx8; - if (name[3] == 'X') - return PRIX8; - abort (); - } - if (name[4] == '1' && name[5] == '6' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId16; - if (name[3] == 'i') - return PRIi16; - if (name[3] == 'o') - return PRIo16; - if (name[3] == 'u') - return PRIu16; - if (name[3] == 'x') - return PRIx16; - if (name[3] == 'X') - return PRIX16; - abort (); - } - if (name[4] == '3' && name[5] == '2' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId32; - if (name[3] == 'i') - return PRIi32; - if (name[3] == 'o') - return PRIo32; - if (name[3] == 'u') - return PRIu32; - if (name[3] == 'x') - return PRIx32; - if (name[3] == 'X') - return PRIX32; - abort (); - } - if (name[4] == '6' && name[5] == '4' && name[6] == '\0') - { - if (name[3] == 'd') - return PRId64; - if (name[3] == 'i') - return PRIi64; - if (name[3] == 'o') - return PRIo64; - if (name[3] == 'u') - return PRIu64; - if (name[3] == 'x') - return PRIx64; - if (name[3] == 'X') - return PRIX64; - abort (); - } - if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A' - && name[7] == 'S' && name[8] == 'T') - { - if (name[9] == '8' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST8; - if (name[3] == 'i') - return PRIiLEAST8; - if (name[3] == 'o') - return PRIoLEAST8; - if (name[3] == 'u') - return PRIuLEAST8; - if (name[3] == 'x') - return PRIxLEAST8; - if (name[3] == 'X') - return PRIXLEAST8; - abort (); - } - if (name[9] == '1' && name[10] == '6' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST16; - if (name[3] == 'i') - return PRIiLEAST16; - if (name[3] == 'o') - return PRIoLEAST16; - if (name[3] == 'u') - return PRIuLEAST16; - if (name[3] == 'x') - return PRIxLEAST16; - if (name[3] == 'X') - return PRIXLEAST16; - abort (); - } - if (name[9] == '3' && name[10] == '2' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST32; - if (name[3] == 'i') - return PRIiLEAST32; - if (name[3] == 'o') - return PRIoLEAST32; - if (name[3] == 'u') - return PRIuLEAST32; - if (name[3] == 'x') - return PRIxLEAST32; - if (name[3] == 'X') - return PRIXLEAST32; - abort (); - } - if (name[9] == '6' && name[10] == '4' && name[11] == '\0') - { - if (name[3] == 'd') - return PRIdLEAST64; - if (name[3] == 'i') - return PRIiLEAST64; - if (name[3] == 'o') - return PRIoLEAST64; - if (name[3] == 'u') - return PRIuLEAST64; - if (name[3] == 'x') - return PRIxLEAST64; - if (name[3] == 'X') - return PRIXLEAST64; - abort (); - } - } - if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S' - && name[7] == 'T') - { - if (name[8] == '8' && name[9] == '\0') - { - if (name[3] == 'd') - return PRIdFAST8; - if (name[3] == 'i') - return PRIiFAST8; - if (name[3] == 'o') - return PRIoFAST8; - if (name[3] == 'u') - return PRIuFAST8; - if (name[3] == 'x') - return PRIxFAST8; - if (name[3] == 'X') - return PRIXFAST8; - abort (); - } - if (name[8] == '1' && name[9] == '6' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST16; - if (name[3] == 'i') - return PRIiFAST16; - if (name[3] == 'o') - return PRIoFAST16; - if (name[3] == 'u') - return PRIuFAST16; - if (name[3] == 'x') - return PRIxFAST16; - if (name[3] == 'X') - return PRIXFAST16; - abort (); - } - if (name[8] == '3' && name[9] == '2' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST32; - if (name[3] == 'i') - return PRIiFAST32; - if (name[3] == 'o') - return PRIoFAST32; - if (name[3] == 'u') - return PRIuFAST32; - if (name[3] == 'x') - return PRIxFAST32; - if (name[3] == 'X') - return PRIXFAST32; - abort (); - } - if (name[8] == '6' && name[9] == '4' && name[10] == '\0') - { - if (name[3] == 'd') - return PRIdFAST64; - if (name[3] == 'i') - return PRIiFAST64; - if (name[3] == 'o') - return PRIoFAST64; - if (name[3] == 'u') - return PRIuFAST64; - if (name[3] == 'x') - return PRIxFAST64; - if (name[3] == 'X') - return PRIXFAST64; - abort (); - } - } - if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X' - && name[7] == '\0') - { - if (name[3] == 'd') - return PRIdMAX; - if (name[3] == 'i') - return PRIiMAX; - if (name[3] == 'o') - return PRIoMAX; - if (name[3] == 'u') - return PRIuMAX; - if (name[3] == 'x') - return PRIxMAX; - if (name[3] == 'X') - return PRIXMAX; - abort (); - } - if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R' - && name[7] == '\0') - { - if (name[3] == 'd') - return PRIdPTR; - if (name[3] == 'i') - return PRIiPTR; - if (name[3] == 'o') - return PRIoPTR; - if (name[3] == 'u') - return PRIuPTR; - if (name[3] == 'x') - return PRIxPTR; - if (name[3] == 'X') - return PRIXPTR; - abort (); - } - } - } - /* Other system dependent strings are not valid. */ - return NULL; -} - -/* Initialize the codeset dependent parts of an opened message catalog. - Return the header entry. */ -const char * -internal_function -_nl_init_domain_conv (domain_file, domain, domainbinding) - struct loaded_l10nfile *domain_file; - struct loaded_domain *domain; - struct binding *domainbinding; -{ - /* Find out about the character set the file is encoded with. - This can be found (in textual form) in the entry "". If this - entry does not exist or if this does not contain the `charset=' - information, we will assume the charset matches the one the - current locale and we don't have to perform any conversion. */ - char *nullentry; - size_t nullentrylen; - - /* Preinitialize fields, to avoid recursion during _nl_find_msg. */ - domain->codeset_cntr = - (domainbinding != NULL ? domainbinding->codeset_cntr : 0); -#ifdef _LIBC - domain->conv = (__gconv_t) -1; -#else -# if HAVE_ICONV - domain->conv = (iconv_t) -1; -# endif -#endif - domain->conv_tab = NULL; - - /* Get the header entry. */ - nullentry = _nl_find_msg (domain_file, domainbinding, "", &nullentrylen); - - if (nullentry != NULL) - { -#if defined _LIBC || HAVE_ICONV - const char *charsetstr; - - charsetstr = strstr (nullentry, "charset="); - if (charsetstr != NULL) - { - size_t len; - char *charset; - const char *outcharset; - - charsetstr += strlen ("charset="); - len = strcspn (charsetstr, " \t\n"); - - charset = (char *) alloca (len + 1); -# if defined _LIBC || HAVE_MEMPCPY - *((char *) mempcpy (charset, charsetstr, len)) = '\0'; -# else - memcpy (charset, charsetstr, len); - charset[len] = '\0'; -# endif - - /* The output charset should normally be determined by the - locale. But sometimes the locale is not used or not correctly - set up, so we provide a possibility for the user to override - this. Moreover, the value specified through - bind_textdomain_codeset overrides both. */ - if (domainbinding != NULL && domainbinding->codeset != NULL) - outcharset = domainbinding->codeset; - else - { - outcharset = getenv ("OUTPUT_CHARSET"); - if (outcharset == NULL || outcharset[0] == '\0') - { -# ifdef _LIBC - outcharset = _NL_CURRENT (LC_CTYPE, CODESET); -# else -# if HAVE_ICONV - extern const char *locale_charset PARAMS ((void)); - outcharset = locale_charset (); -# endif -# endif - } - } - -# ifdef _LIBC - /* We always want to use transliteration. */ - outcharset = norm_add_slashes (outcharset, "TRANSLIT"); - charset = norm_add_slashes (charset, NULL); - if (__gconv_open (outcharset, charset, &domain->conv, - GCONV_AVOID_NOCONV) - != __GCONV_OK) - domain->conv = (__gconv_t) -1; -# else -# if HAVE_ICONV - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ - || _LIBICONV_VERSION >= 0x0105 - if (strchr (outcharset, '/') == NULL) - { - char *tmp; - - len = strlen (outcharset); - tmp = (char *) alloca (len + 10 + 1); - memcpy (tmp, outcharset, len); - memcpy (tmp + len, "//TRANSLIT", 10 + 1); - outcharset = tmp; - - domain->conv = iconv_open (outcharset, charset); - - freea (outcharset); - } - else -# endif - domain->conv = iconv_open (outcharset, charset); -# endif -# endif - - freea (charset); - } -#endif /* _LIBC || HAVE_ICONV */ - } - - return nullentry; -} - -/* Frees the codeset dependent parts of an opened message catalog. */ -void -internal_function -_nl_free_domain_conv (domain) - struct loaded_domain *domain; -{ - if (domain->conv_tab != NULL && domain->conv_tab != (char **) -1) - free (domain->conv_tab); - -#ifdef _LIBC - if (domain->conv != (__gconv_t) -1) - __gconv_close (domain->conv); -#else -# if HAVE_ICONV - if (domain->conv != (iconv_t) -1) - iconv_close (domain->conv); -# endif -#endif -} - -/* Load the message catalogs specified by FILENAME. If it is no valid - message catalog do nothing. */ -void -internal_function -_nl_load_domain (domain_file, domainbinding) - struct loaded_l10nfile *domain_file; - struct binding *domainbinding; -{ - int fd; - size_t size; -#ifdef _LIBC - struct stat64 st; -#else - struct stat st; -#endif - struct mo_file_header *data = (struct mo_file_header *) -1; - int use_mmap = 0; - struct loaded_domain *domain; - int revision; - const char *nullentry; - - domain_file->decided = 1; - domain_file->data = NULL; - - /* Note that it would be useless to store domainbinding in domain_file - because domainbinding might be == NULL now but != NULL later (after - a call to bind_textdomain_codeset). */ - - /* If the record does not represent a valid locale the FILENAME - might be NULL. This can happen when according to the given - specification the locale file name is different for XPG and CEN - syntax. */ - if (domain_file->filename == NULL) - return; - - /* Try to open the addressed file. */ - fd = open (domain_file->filename, O_RDONLY | O_BINARY); - if (fd == -1) - return; - - /* We must know about the size of the file. */ - if ( -#ifdef _LIBC - __builtin_expect (fstat64 (fd, &st) != 0, 0) -#else - __builtin_expect (fstat (fd, &st) != 0, 0) -#endif - || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0) - || __builtin_expect (size < sizeof (struct mo_file_header), 0)) - { - /* Something went wrong. */ - close (fd); - return; - } - -#ifdef HAVE_MMAP - /* Now we are ready to load the file. If mmap() is available we try - this first. If not available or it failed we try to load it. */ - data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, - MAP_PRIVATE, fd, 0); - - if (__builtin_expect (data != (struct mo_file_header *) -1, 1)) - { - /* mmap() call was successful. */ - close (fd); - use_mmap = 1; - } -#endif - - /* If the data is not yet available (i.e. mmap'ed) we try to load - it manually. */ - if (data == (struct mo_file_header *) -1) - { - size_t to_read; - char *read_ptr; - - data = (struct mo_file_header *) malloc (size); - if (data == NULL) - return; - - to_read = size; - read_ptr = (char *) data; - do - { - long int nb = (long int) read (fd, read_ptr, to_read); - if (nb <= 0) - { -#ifdef EINTR - if (nb == -1 && errno == EINTR) - continue; -#endif - close (fd); - return; - } - read_ptr += nb; - to_read -= nb; - } - while (to_read > 0); - - close (fd); - } - - /* Using the magic number we can test whether it really is a message - catalog file. */ - if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED, - 0)) - { - /* The magic number is wrong: not a message catalog file. */ -#ifdef HAVE_MMAP - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - return; - } - - domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); - if (domain == NULL) - return; - domain_file->data = domain; - - domain->data = (char *) data; - domain->use_mmap = use_mmap; - domain->mmap_size = size; - domain->must_swap = data->magic != _MAGIC; - domain->malloced = NULL; - - /* Fill in the information about the available tables. */ - revision = W (domain->must_swap, data->revision); - /* We support only the major revision 0. */ - switch (revision >> 16) - { - case 0: - domain->nstrings = W (domain->must_swap, data->nstrings); - domain->orig_tab = (const struct string_desc *) - ((char *) data + W (domain->must_swap, data->orig_tab_offset)); - domain->trans_tab = (const struct string_desc *) - ((char *) data + W (domain->must_swap, data->trans_tab_offset)); - domain->hash_size = W (domain->must_swap, data->hash_tab_size); - domain->hash_tab = - (domain->hash_size > 2 - ? (const nls_uint32 *) - ((char *) data + W (domain->must_swap, data->hash_tab_offset)) - : NULL); - domain->must_swap_hash_tab = domain->must_swap; - - /* Now dispatch on the minor revision. */ - switch (revision & 0xffff) - { - case 0: - domain->n_sysdep_strings = 0; - domain->orig_sysdep_tab = NULL; - domain->trans_sysdep_tab = NULL; - break; - case 1: - default: - { - nls_uint32 n_sysdep_strings; - - if (domain->hash_tab == NULL) - /* This is invalid. These minor revisions need a hash table. */ - goto invalid; - - n_sysdep_strings = - W (domain->must_swap, data->n_sysdep_strings); - if (n_sysdep_strings > 0) - { - nls_uint32 n_sysdep_segments; - const struct sysdep_segment *sysdep_segments; - const char **sysdep_segment_values; - const nls_uint32 *orig_sysdep_tab; - const nls_uint32 *trans_sysdep_tab; - size_t memneed; - char *mem; - struct sysdep_string_desc *inmem_orig_sysdep_tab; - struct sysdep_string_desc *inmem_trans_sysdep_tab; - nls_uint32 *inmem_hash_tab; - unsigned int i; - - /* Get the values of the system dependent segments. */ - n_sysdep_segments = - W (domain->must_swap, data->n_sysdep_segments); - sysdep_segments = (const struct sysdep_segment *) - ((char *) data - + W (domain->must_swap, data->sysdep_segments_offset)); - sysdep_segment_values = - alloca (n_sysdep_segments * sizeof (const char *)); - for (i = 0; i < n_sysdep_segments; i++) - { - const char *name = - (char *) data - + W (domain->must_swap, sysdep_segments[i].offset); - nls_uint32 namelen = - W (domain->must_swap, sysdep_segments[i].length); - - if (!(namelen > 0 && name[namelen - 1] == '\0')) - { - freea (sysdep_segment_values); - goto invalid; - } - - sysdep_segment_values[i] = get_sysdep_segment_value (name); - } - - orig_sysdep_tab = (const nls_uint32 *) - ((char *) data - + W (domain->must_swap, data->orig_sysdep_tab_offset)); - trans_sysdep_tab = (const nls_uint32 *) - ((char *) data - + W (domain->must_swap, data->trans_sysdep_tab_offset)); - - /* Compute the amount of additional memory needed for the - system dependent strings and the augmented hash table. */ - memneed = 2 * n_sysdep_strings - * sizeof (struct sysdep_string_desc) - + domain->hash_size * sizeof (nls_uint32); - for (i = 0; i < 2 * n_sysdep_strings; i++) - { - const struct sysdep_string *sysdep_string = - (const struct sysdep_string *) - ((char *) data - + W (domain->must_swap, - i < n_sysdep_strings - ? orig_sysdep_tab[i] - : trans_sysdep_tab[i - n_sysdep_strings])); - size_t need = 0; - const struct segment_pair *p = sysdep_string->segments; - - if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END) - for (p = sysdep_string->segments;; p++) - { - nls_uint32 sysdepref; - - need += W (domain->must_swap, p->segsize); - - sysdepref = W (domain->must_swap, p->sysdepref); - if (sysdepref == SEGMENTS_END) - break; - - if (sysdepref >= n_sysdep_segments) - { - /* Invalid. */ - freea (sysdep_segment_values); - goto invalid; - } - - need += strlen (sysdep_segment_values[sysdepref]); - } - - memneed += need; - } - - /* Allocate additional memory. */ - mem = (char *) malloc (memneed); - if (mem == NULL) - goto invalid; - - domain->malloced = mem; - inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem; - mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); - inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem; - mem += n_sysdep_strings * sizeof (struct sysdep_string_desc); - inmem_hash_tab = (nls_uint32 *) mem; - mem += domain->hash_size * sizeof (nls_uint32); - - /* Compute the system dependent strings. */ - for (i = 0; i < 2 * n_sysdep_strings; i++) - { - const struct sysdep_string *sysdep_string = - (const struct sysdep_string *) - ((char *) data - + W (domain->must_swap, - i < n_sysdep_strings - ? orig_sysdep_tab[i] - : trans_sysdep_tab[i - n_sysdep_strings])); - const char *static_segments = - (char *) data - + W (domain->must_swap, sysdep_string->offset); - const struct segment_pair *p = sysdep_string->segments; - - /* Concatenate the segments, and fill - inmem_orig_sysdep_tab[i] (for i < n_sysdep_strings) and - inmem_trans_sysdep_tab[i-n_sysdep_strings] (for - i >= n_sysdep_strings). */ - - if (W (domain->must_swap, p->sysdepref) == SEGMENTS_END) - { - /* Only one static segment. */ - inmem_orig_sysdep_tab[i].length = - W (domain->must_swap, p->segsize); - inmem_orig_sysdep_tab[i].pointer = static_segments; - } - else - { - inmem_orig_sysdep_tab[i].pointer = mem; - - for (p = sysdep_string->segments;; p++) - { - nls_uint32 segsize = - W (domain->must_swap, p->segsize); - nls_uint32 sysdepref = - W (domain->must_swap, p->sysdepref); - size_t n; - - if (segsize > 0) - { - memcpy (mem, static_segments, segsize); - mem += segsize; - static_segments += segsize; - } - - if (sysdepref == SEGMENTS_END) - break; - - n = strlen (sysdep_segment_values[sysdepref]); - memcpy (mem, sysdep_segment_values[sysdepref], n); - mem += n; - } - - inmem_orig_sysdep_tab[i].length = - mem - inmem_orig_sysdep_tab[i].pointer; - } - } - - /* Compute the augmented hash table. */ - for (i = 0; i < domain->hash_size; i++) - inmem_hash_tab[i] = - W (domain->must_swap_hash_tab, domain->hash_tab[i]); - for (i = 0; i < n_sysdep_strings; i++) - { - const char *msgid = inmem_orig_sysdep_tab[i].pointer; - nls_uint32 hash_val = hash_string (msgid); - nls_uint32 idx = hash_val % domain->hash_size; - nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); - - for (;;) - { - if (inmem_hash_tab[idx] == 0) - { - /* Hash table entry is empty. Use it. */ - inmem_hash_tab[idx] = 1 + domain->nstrings + i; - break; - } - - if (idx >= domain->hash_size - incr) - idx -= domain->hash_size - incr; - else - idx += incr; - } - } - - freea (sysdep_segment_values); - - domain->n_sysdep_strings = n_sysdep_strings; - domain->orig_sysdep_tab = inmem_orig_sysdep_tab; - domain->trans_sysdep_tab = inmem_trans_sysdep_tab; - - domain->hash_tab = inmem_hash_tab; - domain->must_swap_hash_tab = 0; - } - else - { - domain->n_sysdep_strings = 0; - domain->orig_sysdep_tab = NULL; - domain->trans_sysdep_tab = NULL; - } - } - break; - } - break; - default: - /* This is an invalid revision. */ - invalid: - /* This is an invalid .mo file. */ - if (domain->malloced) - free (domain->malloced); -#ifdef HAVE_MMAP - if (use_mmap) - munmap ((caddr_t) data, size); - else -#endif - free (data); - free (domain); - domain_file->data = NULL; - return; - } - - /* Now initialize the character set converter from the character set - the file is encoded with (found in the header entry) to the domain's - specified character set or the locale's character set. */ - nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding); - - /* Also look for a plural specification. */ - EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); -} - - -#ifdef _LIBC -void -internal_function -_nl_unload_domain (domain) - struct loaded_domain *domain; -{ - if (domain->plural != &__gettext_germanic_plural) - __gettext_free_exp (domain->plural); - - _nl_free_domain_conv (domain); - - if (domain->malloced) - free (domain->malloced); - -# ifdef _POSIX_MAPPED_FILES - if (domain->use_mmap) - munmap ((caddr_t) domain->data, domain->mmap_size); - else -# endif /* _POSIX_MAPPED_FILES */ - free ((void *) domain->data); - - free (domain); -} -#endif diff --git a/intl/localcharset.c b/intl/localcharset.c deleted file mode 100644 index d04d05368..000000000 --- a/intl/localcharset.c +++ /dev/null @@ -1,398 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - - Copyright (C) 2000-2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -/* Specification. */ -#include "localcharset.h" - -#if HAVE_STDDEF_H -# include <stddef.h> -#endif - -#include <stdio.h> -#if HAVE_STRING_H -# include <string.h> -#else -# include <strings.h> -#endif -#if HAVE_STDLIB_H -# include <stdlib.h> -#endif - -#if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 -#endif - -#if defined __EMX__ -/* Assume EMX program runs on OS/2, even if compiled under DOS. */ -# define OS2 -#endif - -#if !defined WIN32 -# if HAVE_LANGINFO_CODESET -# include <langinfo.h> -# else -# if HAVE_SETLOCALE -# include <locale.h> -# endif -# endif -#elif defined WIN32 -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -#endif -#if defined OS2 -# define INCL_DOS -# include <os2.h> -#endif - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -#endif - -#ifdef HAVE_GETC_UNLOCKED -# undef getc -# define getc getc_unlocked -#endif - -/* The following static variable is declared 'volatile' to avoid a - possible multithread problem in the function get_charset_aliases. If we - are running in a threaded environment, and if two threads initialize - 'charset_aliases' simultaneously, both will produce the same value, - and everything will be ok if the two assignments to 'charset_aliases' - are atomic. But I don't know what will happen if the two assignments mix. */ -#if __STDC__ != 1 -# define volatile /* empty */ -#endif -/* Pointer to the contents of the charset.alias file, if it has already been - read, else NULL. Its format is: - ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ -static const char * volatile charset_aliases; - -/* Return a pointer to the contents of the charset.alias file. */ -static const char * -get_charset_aliases () -{ - const char *cp; - - cp = charset_aliases; - if (cp == NULL) - { -#if !(defined VMS || defined WIN32) - FILE *fp; - const char *dir = relocate (LIBDIR); - const char *base = "charset.alias"; - char *file_name; - - /* Concatenate dir and base into freshly allocated file_name. */ - { - size_t dir_len = strlen (dir); - size_t base_len = strlen (base); - int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); - file_name = (char *) malloc (dir_len + add_slash + base_len + 1); - if (file_name != NULL) - { - memcpy (file_name, dir, dir_len); - if (add_slash) - file_name[dir_len] = DIRECTORY_SEPARATOR; - memcpy (file_name + dir_len + add_slash, base, base_len + 1); - } - } - - if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) - /* Out of memory or file not found, treat it as empty. */ - cp = ""; - else - { - /* Parse the file's contents. */ - int c; - char buf1[50+1]; - char buf2[50+1]; - char *res_ptr = NULL; - size_t res_size = 0; - size_t l1, l2; - - for (;;) - { - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - if (res_size == 0) - { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); - } - else - { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); - } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; - } - } - - if (file_name != NULL) - free (file_name); - -#else - -# if defined VMS - /* To avoid the troubles of an extra file charset.alias_vms in the - sources of many GNU packages, simply inline the aliases here. */ - /* The list of encodings is taken from the OpenVMS 7.3-1 documentation - "Compaq C Run-Time Library Reference Manual for OpenVMS systems" - section 10.7 "Handling Different Character Sets". */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-8" "\0" "ISO-8859-8" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - /* Japanese */ - "eucJP" "\0" "EUC-JP" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "DECKANJI" "\0" "DEC-KANJI" "\0" - "SDECKANJI" "\0" "EUC-JP" "\0" - /* Chinese */ - "eucTW" "\0" "EUC-TW" "\0" - "DECHANYU" "\0" "DEC-HANYU" "\0" - "DECHANZI" "\0" "GB2312" "\0" - /* Korean */ - "DECKOREAN" "\0" "EUC-KR" "\0"; -# endif - -# if defined WIN32 - /* To avoid the troubles of installing a separate file in the same - directory as the DLL and of retrieving the DLL's directory at - runtime, simply inline the aliases here. */ - - cp = "CP936" "\0" "GBK" "\0" - "CP1361" "\0" "JOHAB" "\0" - "CP20127" "\0" "ASCII" "\0" - "CP20866" "\0" "KOI8-R" "\0" - "CP21866" "\0" "KOI8-RU" "\0" - "CP28591" "\0" "ISO-8859-1" "\0" - "CP28592" "\0" "ISO-8859-2" "\0" - "CP28593" "\0" "ISO-8859-3" "\0" - "CP28594" "\0" "ISO-8859-4" "\0" - "CP28595" "\0" "ISO-8859-5" "\0" - "CP28596" "\0" "ISO-8859-6" "\0" - "CP28597" "\0" "ISO-8859-7" "\0" - "CP28598" "\0" "ISO-8859-8" "\0" - "CP28599" "\0" "ISO-8859-9" "\0" - "CP28605" "\0" "ISO-8859-15" "\0"; -# endif -#endif - - charset_aliases = cp; - } - - return cp; -} - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ - -#ifdef STATIC -STATIC -#endif -const char * -locale_charset () -{ - const char *codeset; - const char *aliases; - -#if !(defined WIN32 || defined OS2) - -# if HAVE_LANGINFO_CODESET - - /* Most systems support nl_langinfo (CODESET) nowadays. */ - codeset = nl_langinfo (CODESET); - -# else - - /* On old systems which lack it, use setlocale or getenv. */ - const char *locale = NULL; - - /* But most old systems don't have a complete set of locales. Some - (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't - use setlocale here; it would return "C" when it doesn't support the - locale name the user has set. */ -# if HAVE_SETLOCALE && 0 - locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - } - - /* On some old systems, one used to set locale = "iso8859_1". On others, - you set it to "language_COUNTRY.charset". In any case, we resolve it - through the charset.alias file. */ - codeset = locale; - -# endif - -#elif defined WIN32 - - static char buf[2 + 10 + 1]; - - /* Woe32 has a function returning the locale's codepage as a number. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - -#elif defined OS2 - - const char *locale; - static char buf[2 + 10 + 1]; - ULONG cp[3]; - ULONG cplen; - - /* Allow user to override the codeset, as set in the operating system, - with standard language environment variables. */ - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - - /* Resolve through the charset.alias file. */ - codeset = locale; - } - else - { - /* OS/2 has a function returning the locale's codepage as a number. */ - if (DosQueryCp (sizeof (cp), cp, &cplen)) - codeset = ""; - else - { - sprintf (buf, "CP%u", cp[0]); - codeset = buf; - } - } - -#endif - - if (codeset == NULL) - /* The canonical name cannot be determined. */ - codeset = ""; - - /* Resolve alias. */ - for (aliases = get_charset_aliases (); - *aliases != '\0'; - aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) - if (strcmp (codeset, aliases) == 0 - || (aliases[0] == '*' && aliases[1] == '\0')) - { - codeset = aliases + strlen (aliases) + 1; - break; - } - - /* Don't return an empty string. GNU libc and GNU libiconv interpret - the empty string as denoting "the locale's character encoding", - thus GNU libiconv would call this function a second time. */ - if (codeset[0] == '\0') - codeset = "ASCII"; - - return codeset; -} diff --git a/intl/localcharset.h b/intl/localcharset.h deleted file mode 100644 index 3b137e73c..000000000 --- a/intl/localcharset.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003 Free Software Foundation, Inc. - This file is part of the GNU CHARSET Library. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LOCALCHARSET_H -#define _LOCALCHARSET_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ -extern const char * locale_charset (void); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _LOCALCHARSET_H */ diff --git a/intl/locale.alias b/intl/locale.alias deleted file mode 100644 index bd7b9b31e..000000000 --- a/intl/locale.alias +++ /dev/null @@ -1,78 +0,0 @@ -# Locale name alias data base. -# Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. - -# The format of this file is the same as for the corresponding file of -# the X Window System, which normally can be found in -# /usr/lib/X11/locale/locale.alias -# A single line contains two fields: an alias and a substitution value. -# All entries are case independent. - -# Note: This file is far from being complete. If you have a value for -# your own site which you think might be useful for others too, share -# it with the rest of us. Send it using the `glibcbug' script to -# bugs@gnu.org. - -# Packages using this file: - -bokmal no_NO.ISO-8859-1 -bokmål no_NO.ISO-8859-1 -catalan ca_ES.ISO-8859-1 -croatian hr_HR.ISO-8859-2 -czech cs_CZ.ISO-8859-2 -danish da_DK.ISO-8859-1 -dansk da_DK.ISO-8859-1 -deutsch de_DE.ISO-8859-1 -dutch nl_NL.ISO-8859-1 -eesti et_EE.ISO-8859-1 -estonian et_EE.ISO-8859-1 -finnish fi_FI.ISO-8859-1 -français fr_FR.ISO-8859-1 -french fr_FR.ISO-8859-1 -galego gl_ES.ISO-8859-1 -galician gl_ES.ISO-8859-1 -german de_DE.ISO-8859-1 -greek el_GR.ISO-8859-7 -hebrew he_IL.ISO-8859-8 -hrvatski hr_HR.ISO-8859-2 -hungarian hu_HU.ISO-8859-2 -icelandic is_IS.ISO-8859-1 -italian it_IT.ISO-8859-1 -japanese ja_JP.eucJP -japanese.euc ja_JP.eucJP -ja_JP ja_JP.eucJP -ja_JP.ujis ja_JP.eucJP -japanese.sjis ja_JP.SJIS -korean ko_KR.eucKR -korean.euc ko_KR.eucKR -ko_KR ko_KR.eucKR -lithuanian lt_LT.ISO-8859-13 -nb_NO no_NO.ISO-8859-1 -nb_NO.ISO-8859-1 no_NO.ISO-8859-1 -norwegian no_NO.ISO-8859-1 -nynorsk nn_NO.ISO-8859-1 -polish pl_PL.ISO-8859-2 -portuguese pt_PT.ISO-8859-1 -romanian ro_RO.ISO-8859-2 -russian ru_RU.ISO-8859-5 -slovak sk_SK.ISO-8859-2 -slovene sl_SI.ISO-8859-2 -slovenian sl_SI.ISO-8859-2 -spanish es_ES.ISO-8859-1 -swedish sv_SE.ISO-8859-1 -thai th_TH.TIS-620 -turkish tr_TR.ISO-8859-9 diff --git a/intl/localealias.c b/intl/localealias.c deleted file mode 100644 index 7c4ce58f2..000000000 --- a/intl/localealias.c +++ /dev/null @@ -1,419 +0,0 @@ -/* Handle aliases for locale names. - Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Tell glibc's <string.h> to provide a prototype for mempcpy(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <stdio.h> -#if defined _LIBC || defined HAVE___FSETLOCKING -# include <stdio_ext.h> -#endif -#include <sys/types.h> - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -# define HAVE_ALLOCA 1 -#else -# ifdef _MSC_VER -# include <malloc.h> -# define alloca _alloca -# else -# if defined HAVE_ALLOCA_H || defined _LIBC -# include <alloca.h> -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca -char *alloca (); -# endif -# endif -# endif -# endif -#endif - -#include <stdlib.h> -#include <string.h> - -#include "gettextP.h" - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -/* @@ end of prolog @@ */ - -#ifdef _LIBC -/* Rename the non ANSI C functions. This is required by the standard - because some ANSI C functions will require linking with this object - file and the name space must not be polluted. */ -# define strcasecmp __strcasecmp - -# ifndef mempcpy -# define mempcpy __mempcpy -# endif -# define HAVE_MEMPCPY 1 -# define HAVE___FSETLOCKING 1 - -/* We need locking here since we can be called from different places. */ -# include <bits/libc-lock.h> - -__libc_lock_define_initialized (static, lock); -#endif - -#ifndef internal_function -# define internal_function -#endif - -/* Some optimizations for glibc. */ -#ifdef _LIBC -# define FEOF(fp) feof_unlocked (fp) -# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp) -#else -# define FEOF(fp) feof (fp) -# define FGETS(buf, n, fp) fgets (buf, n, fp) -#endif - -/* For those losing systems which don't have `alloca' we have to add - some additional code emulating it. */ -#ifdef HAVE_ALLOCA -# define freea(p) /* nothing */ -#else -# define alloca(n) malloc (n) -# define freea(p) free (p) -#endif - -#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED -# undef fgets -# define fgets(buf, len, s) fgets_unlocked (buf, len, s) -#endif -#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED -# undef feof -# define feof(s) feof_unlocked (s) -#endif - - -struct alias_map -{ - const char *alias; - const char *value; -}; - - -#ifndef _LIBC -# define libc_freeres_ptr(decl) decl -#endif - -libc_freeres_ptr (static char *string_space); -static size_t string_space_act; -static size_t string_space_max; -libc_freeres_ptr (static struct alias_map *map); -static size_t nmap; -static size_t maxmap; - - -/* Prototypes for local functions. */ -static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) - internal_function; -static int extend_alias_table PARAMS ((void)); -static int alias_compare PARAMS ((const struct alias_map *map1, - const struct alias_map *map2)); - - -const char * -_nl_expand_alias (name) - const char *name; -{ - static const char *locale_alias_path; - struct alias_map *retval; - const char *result = NULL; - size_t added; - -#ifdef _LIBC - __libc_lock_lock (lock); -#endif - - if (locale_alias_path == NULL) - locale_alias_path = LOCALE_ALIAS_PATH; - - do - { - struct alias_map item; - - item.alias = name; - - if (nmap > 0) - retval = (struct alias_map *) bsearch (&item, map, nmap, - sizeof (struct alias_map), - (int (*) PARAMS ((const void *, - const void *)) - ) alias_compare); - else - retval = NULL; - - /* We really found an alias. Return the value. */ - if (retval != NULL) - { - result = retval->value; - break; - } - - /* Perhaps we can find another alias file. */ - added = 0; - while (added == 0 && locale_alias_path[0] != '\0') - { - const char *start; - - while (locale_alias_path[0] == PATH_SEPARATOR) - ++locale_alias_path; - start = locale_alias_path; - - while (locale_alias_path[0] != '\0' - && locale_alias_path[0] != PATH_SEPARATOR) - ++locale_alias_path; - - if (start < locale_alias_path) - added = read_alias_file (start, locale_alias_path - start); - } - } - while (added != 0); - -#ifdef _LIBC - __libc_lock_unlock (lock); -#endif - - return result; -} - - -static size_t -internal_function -read_alias_file (fname, fname_len) - const char *fname; - int fname_len; -{ - FILE *fp; - char *full_fname; - size_t added; - static const char aliasfile[] = "/locale.alias"; - - full_fname = (char *) alloca (fname_len + sizeof aliasfile); -#ifdef HAVE_MEMPCPY - mempcpy (mempcpy (full_fname, fname, fname_len), - aliasfile, sizeof aliasfile); -#else - memcpy (full_fname, fname, fname_len); - memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); -#endif - - fp = fopen (relocate (full_fname), "r"); - freea (full_fname); - if (fp == NULL) - return 0; - -#ifdef HAVE___FSETLOCKING - /* No threads present. */ - __fsetlocking (fp, FSETLOCKING_BYCALLER); -#endif - - added = 0; - while (!FEOF (fp)) - { - /* It is a reasonable approach to use a fix buffer here because - a) we are only interested in the first two fields - b) these fields must be usable as file names and so must not - be that long - We avoid a multi-kilobyte buffer here since this would use up - stack space which we might not have if the program ran out of - memory. */ - char buf[400]; - char *alias; - char *value; - char *cp; - - if (FGETS (buf, sizeof buf, fp) == NULL) - /* EOF reached. */ - break; - - cp = buf; - /* Ignore leading white space. */ - while (isspace ((unsigned char) cp[0])) - ++cp; - - /* A leading '#' signals a comment line. */ - if (cp[0] != '\0' && cp[0] != '#') - { - alias = cp++; - while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) - ++cp; - /* Terminate alias name. */ - if (cp[0] != '\0') - *cp++ = '\0'; - - /* Now look for the beginning of the value. */ - while (isspace ((unsigned char) cp[0])) - ++cp; - - if (cp[0] != '\0') - { - size_t alias_len; - size_t value_len; - - value = cp++; - while (cp[0] != '\0' && !isspace ((unsigned char) cp[0])) - ++cp; - /* Terminate value. */ - if (cp[0] == '\n') - { - /* This has to be done to make the following test - for the end of line possible. We are looking for - the terminating '\n' which do not overwrite here. */ - *cp++ = '\0'; - *cp = '\n'; - } - else if (cp[0] != '\0') - *cp++ = '\0'; - - if (nmap >= maxmap) - if (__builtin_expect (extend_alias_table (), 0)) - return added; - - alias_len = strlen (alias) + 1; - value_len = strlen (value) + 1; - - if (string_space_act + alias_len + value_len > string_space_max) - { - /* Increase size of memory pool. */ - size_t new_size = (string_space_max - + (alias_len + value_len > 1024 - ? alias_len + value_len : 1024)); - char *new_pool = (char *) realloc (string_space, new_size); - if (new_pool == NULL) - return added; - - if (__builtin_expect (string_space != new_pool, 0)) - { - size_t i; - - for (i = 0; i < nmap; i++) - { - map[i].alias += new_pool - string_space; - map[i].value += new_pool - string_space; - } - } - - string_space = new_pool; - string_space_max = new_size; - } - - map[nmap].alias = memcpy (&string_space[string_space_act], - alias, alias_len); - string_space_act += alias_len; - - map[nmap].value = memcpy (&string_space[string_space_act], - value, value_len); - string_space_act += value_len; - - ++nmap; - ++added; - } - } - - /* Possibly not the whole line fits into the buffer. Ignore - the rest of the line. */ - while (strchr (buf, '\n') == NULL) - if (FGETS (buf, sizeof buf, fp) == NULL) - /* Make sure the inner loop will be left. The outer loop - will exit at the `feof' test. */ - break; - } - - /* Should we test for ferror()? I think we have to silently ignore - errors. --drepper */ - fclose (fp); - - if (added > 0) - qsort (map, nmap, sizeof (struct alias_map), - (int (*) PARAMS ((const void *, const void *))) alias_compare); - - return added; -} - - -static int -extend_alias_table () -{ - size_t new_size; - struct alias_map *new_map; - - new_size = maxmap == 0 ? 100 : 2 * maxmap; - new_map = (struct alias_map *) realloc (map, (new_size - * sizeof (struct alias_map))); - if (new_map == NULL) - /* Simply don't extend: we don't have any more core. */ - return -1; - - map = new_map; - maxmap = new_size; - return 0; -} - - -static int -alias_compare (map1, map2) - const struct alias_map *map1; - const struct alias_map *map2; -{ -#if defined _LIBC || defined HAVE_STRCASECMP - return strcasecmp (map1->alias, map2->alias); -#else - const unsigned char *p1 = (const unsigned char *) map1->alias; - const unsigned char *p2 = (const unsigned char *) map2->alias; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - /* I know this seems to be odd but the tolower() function in - some systems libc cannot handle nonalpha characters. */ - c1 = isupper (*p1) ? tolower (*p1) : *p1; - c2 = isupper (*p2) ? tolower (*p2) : *p2; - if (c1 == '\0') - break; - ++p1; - ++p2; - } - while (c1 == c2); - - return c1 - c2; -#endif -} diff --git a/intl/localename.c b/intl/localename.c deleted file mode 100644 index faacecd50..000000000 --- a/intl/localename.c +++ /dev/null @@ -1,772 +0,0 @@ -/* Determine the current selected locale. - Copyright (C) 1995-1999, 2000-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Ulrich Drepper <drepper@gnu.org>, 1995. */ -/* Win32 code written by Tor Lillqvist <tml@iki.fi>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <locale.h> - -#if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 -#endif - -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -/* Mingw headers don't have latest language and sublanguage codes. */ -# ifndef LANG_AFRIKAANS -# define LANG_AFRIKAANS 0x36 -# endif -# ifndef LANG_ALBANIAN -# define LANG_ALBANIAN 0x1c -# endif -# ifndef LANG_ARABIC -# define LANG_ARABIC 0x01 -# endif -# ifndef LANG_ARMENIAN -# define LANG_ARMENIAN 0x2b -# endif -# ifndef LANG_ASSAMESE -# define LANG_ASSAMESE 0x4d -# endif -# ifndef LANG_AZERI -# define LANG_AZERI 0x2c -# endif -# ifndef LANG_BASQUE -# define LANG_BASQUE 0x2d -# endif -# ifndef LANG_BELARUSIAN -# define LANG_BELARUSIAN 0x23 -# endif -# ifndef LANG_BENGALI -# define LANG_BENGALI 0x45 -# endif -# ifndef LANG_CATALAN -# define LANG_CATALAN 0x03 -# endif -# ifndef LANG_DIVEHI -# define LANG_DIVEHI 0x65 -# endif -# ifndef LANG_ESTONIAN -# define LANG_ESTONIAN 0x25 -# endif -# ifndef LANG_FAEROESE -# define LANG_FAEROESE 0x38 -# endif -# ifndef LANG_FARSI -# define LANG_FARSI 0x29 -# endif -# ifndef LANG_GALICIAN -# define LANG_GALICIAN 0x56 -# endif -# ifndef LANG_GEORGIAN -# define LANG_GEORGIAN 0x37 -# endif -# ifndef LANG_GUJARATI -# define LANG_GUJARATI 0x47 -# endif -# ifndef LANG_HEBREW -# define LANG_HEBREW 0x0d -# endif -# ifndef LANG_HINDI -# define LANG_HINDI 0x39 -# endif -# ifndef LANG_INDONESIAN -# define LANG_INDONESIAN 0x21 -# endif -# ifndef LANG_KANNADA -# define LANG_KANNADA 0x4b -# endif -# ifndef LANG_KASHMIRI -# define LANG_KASHMIRI 0x60 -# endif -# ifndef LANG_KAZAK -# define LANG_KAZAK 0x3f -# endif -# ifndef LANG_KONKANI -# define LANG_KONKANI 0x57 -# endif -# ifndef LANG_KYRGYZ -# define LANG_KYRGYZ 0x40 -# endif -# ifndef LANG_LATVIAN -# define LANG_LATVIAN 0x26 -# endif -# ifndef LANG_LITHUANIAN -# define LANG_LITHUANIAN 0x27 -# endif -# ifndef LANG_MACEDONIAN -# define LANG_MACEDONIAN 0x2f -# endif -# ifndef LANG_MALAY -# define LANG_MALAY 0x3e -# endif -# ifndef LANG_MALAYALAM -# define LANG_MALAYALAM 0x4c -# endif -# ifndef LANG_MANIPURI -# define LANG_MANIPURI 0x58 -# endif -# ifndef LANG_MARATHI -# define LANG_MARATHI 0x4e -# endif -# ifndef LANG_MONGOLIAN -# define LANG_MONGOLIAN 0x50 -# endif -# ifndef LANG_NEPALI -# define LANG_NEPALI 0x61 -# endif -# ifndef LANG_ORIYA -# define LANG_ORIYA 0x48 -# endif -# ifndef LANG_PUNJABI -# define LANG_PUNJABI 0x46 -# endif -# ifndef LANG_SANSKRIT -# define LANG_SANSKRIT 0x4f -# endif -# ifndef LANG_SERBIAN -# define LANG_SERBIAN 0x1a -# endif -# ifndef LANG_SINDHI -# define LANG_SINDHI 0x59 -# endif -# ifndef LANG_SLOVAK -# define LANG_SLOVAK 0x1b -# endif -# ifndef LANG_SORBIAN -# define LANG_SORBIAN 0x2e -# endif -# ifndef LANG_SWAHILI -# define LANG_SWAHILI 0x41 -# endif -# ifndef LANG_SYRIAC -# define LANG_SYRIAC 0x5a -# endif -# ifndef LANG_TAMIL -# define LANG_TAMIL 0x49 -# endif -# ifndef LANG_TATAR -# define LANG_TATAR 0x44 -# endif -# ifndef LANG_TELUGU -# define LANG_TELUGU 0x4a -# endif -# ifndef LANG_THAI -# define LANG_THAI 0x1e -# endif -# ifndef LANG_UKRAINIAN -# define LANG_UKRAINIAN 0x22 -# endif -# ifndef LANG_URDU -# define LANG_URDU 0x20 -# endif -# ifndef LANG_UZBEK -# define LANG_UZBEK 0x43 -# endif -# ifndef LANG_VIETNAMESE -# define LANG_VIETNAMESE 0x2a -# endif -# ifndef SUBLANG_ARABIC_SAUDI_ARABIA -# define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 -# endif -# ifndef SUBLANG_ARABIC_IRAQ -# define SUBLANG_ARABIC_IRAQ 0x02 -# endif -# ifndef SUBLANG_ARABIC_EGYPT -# define SUBLANG_ARABIC_EGYPT 0x03 -# endif -# ifndef SUBLANG_ARABIC_LIBYA -# define SUBLANG_ARABIC_LIBYA 0x04 -# endif -# ifndef SUBLANG_ARABIC_ALGERIA -# define SUBLANG_ARABIC_ALGERIA 0x05 -# endif -# ifndef SUBLANG_ARABIC_MOROCCO -# define SUBLANG_ARABIC_MOROCCO 0x06 -# endif -# ifndef SUBLANG_ARABIC_TUNISIA -# define SUBLANG_ARABIC_TUNISIA 0x07 -# endif -# ifndef SUBLANG_ARABIC_OMAN -# define SUBLANG_ARABIC_OMAN 0x08 -# endif -# ifndef SUBLANG_ARABIC_YEMEN -# define SUBLANG_ARABIC_YEMEN 0x09 -# endif -# ifndef SUBLANG_ARABIC_SYRIA -# define SUBLANG_ARABIC_SYRIA 0x0a -# endif -# ifndef SUBLANG_ARABIC_JORDAN -# define SUBLANG_ARABIC_JORDAN 0x0b -# endif -# ifndef SUBLANG_ARABIC_LEBANON -# define SUBLANG_ARABIC_LEBANON 0x0c -# endif -# ifndef SUBLANG_ARABIC_KUWAIT -# define SUBLANG_ARABIC_KUWAIT 0x0d -# endif -# ifndef SUBLANG_ARABIC_UAE -# define SUBLANG_ARABIC_UAE 0x0e -# endif -# ifndef SUBLANG_ARABIC_BAHRAIN -# define SUBLANG_ARABIC_BAHRAIN 0x0f -# endif -# ifndef SUBLANG_ARABIC_QATAR -# define SUBLANG_ARABIC_QATAR 0x10 -# endif -# ifndef SUBLANG_AZERI_LATIN -# define SUBLANG_AZERI_LATIN 0x01 -# endif -# ifndef SUBLANG_AZERI_CYRILLIC -# define SUBLANG_AZERI_CYRILLIC 0x02 -# endif -# ifndef SUBLANG_CHINESE_MACAU -# define SUBLANG_CHINESE_MACAU 0x05 -# endif -# ifndef SUBLANG_ENGLISH_SOUTH_AFRICA -# define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 -# endif -# ifndef SUBLANG_ENGLISH_JAMAICA -# define SUBLANG_ENGLISH_JAMAICA 0x08 -# endif -# ifndef SUBLANG_ENGLISH_CARIBBEAN -# define SUBLANG_ENGLISH_CARIBBEAN 0x09 -# endif -# ifndef SUBLANG_ENGLISH_BELIZE -# define SUBLANG_ENGLISH_BELIZE 0x0a -# endif -# ifndef SUBLANG_ENGLISH_TRINIDAD -# define SUBLANG_ENGLISH_TRINIDAD 0x0b -# endif -# ifndef SUBLANG_ENGLISH_ZIMBABWE -# define SUBLANG_ENGLISH_ZIMBABWE 0x0c -# endif -# ifndef SUBLANG_ENGLISH_PHILIPPINES -# define SUBLANG_ENGLISH_PHILIPPINES 0x0d -# endif -# ifndef SUBLANG_FRENCH_LUXEMBOURG -# define SUBLANG_FRENCH_LUXEMBOURG 0x05 -# endif -# ifndef SUBLANG_FRENCH_MONACO -# define SUBLANG_FRENCH_MONACO 0x06 -# endif -# ifndef SUBLANG_GERMAN_LUXEMBOURG -# define SUBLANG_GERMAN_LUXEMBOURG 0x04 -# endif -# ifndef SUBLANG_GERMAN_LIECHTENSTEIN -# define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 -# endif -# ifndef SUBLANG_KASHMIRI_INDIA -# define SUBLANG_KASHMIRI_INDIA 0x02 -# endif -# ifndef SUBLANG_MALAY_MALAYSIA -# define SUBLANG_MALAY_MALAYSIA 0x01 -# endif -# ifndef SUBLANG_MALAY_BRUNEI_DARUSSALAM -# define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 -# endif -# ifndef SUBLANG_NEPALI_INDIA -# define SUBLANG_NEPALI_INDIA 0x02 -# endif -# ifndef SUBLANG_SERBIAN_LATIN -# define SUBLANG_SERBIAN_LATIN 0x02 -# endif -# ifndef SUBLANG_SERBIAN_CYRILLIC -# define SUBLANG_SERBIAN_CYRILLIC 0x03 -# endif -# ifndef SUBLANG_SPANISH_GUATEMALA -# define SUBLANG_SPANISH_GUATEMALA 0x04 -# endif -# ifndef SUBLANG_SPANISH_COSTA_RICA -# define SUBLANG_SPANISH_COSTA_RICA 0x05 -# endif -# ifndef SUBLANG_SPANISH_PANAMA -# define SUBLANG_SPANISH_PANAMA 0x06 -# endif -# ifndef SUBLANG_SPANISH_DOMINICAN_REPUBLIC -# define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 -# endif -# ifndef SUBLANG_SPANISH_VENEZUELA -# define SUBLANG_SPANISH_VENEZUELA 0x08 -# endif -# ifndef SUBLANG_SPANISH_COLOMBIA -# define SUBLANG_SPANISH_COLOMBIA 0x09 -# endif -# ifndef SUBLANG_SPANISH_PERU -# define SUBLANG_SPANISH_PERU 0x0a -# endif -# ifndef SUBLANG_SPANISH_ARGENTINA -# define SUBLANG_SPANISH_ARGENTINA 0x0b -# endif -# ifndef SUBLANG_SPANISH_ECUADOR -# define SUBLANG_SPANISH_ECUADOR 0x0c -# endif -# ifndef SUBLANG_SPANISH_CHILE -# define SUBLANG_SPANISH_CHILE 0x0d -# endif -# ifndef SUBLANG_SPANISH_URUGUAY -# define SUBLANG_SPANISH_URUGUAY 0x0e -# endif -# ifndef SUBLANG_SPANISH_PARAGUAY -# define SUBLANG_SPANISH_PARAGUAY 0x0f -# endif -# ifndef SUBLANG_SPANISH_BOLIVIA -# define SUBLANG_SPANISH_BOLIVIA 0x10 -# endif -# ifndef SUBLANG_SPANISH_EL_SALVADOR -# define SUBLANG_SPANISH_EL_SALVADOR 0x11 -# endif -# ifndef SUBLANG_SPANISH_HONDURAS -# define SUBLANG_SPANISH_HONDURAS 0x12 -# endif -# ifndef SUBLANG_SPANISH_NICARAGUA -# define SUBLANG_SPANISH_NICARAGUA 0x13 -# endif -# ifndef SUBLANG_SPANISH_PUERTO_RICO -# define SUBLANG_SPANISH_PUERTO_RICO 0x14 -# endif -# ifndef SUBLANG_SWEDISH_FINLAND -# define SUBLANG_SWEDISH_FINLAND 0x02 -# endif -# ifndef SUBLANG_URDU_PAKISTAN -# define SUBLANG_URDU_PAKISTAN 0x01 -# endif -# ifndef SUBLANG_URDU_INDIA -# define SUBLANG_URDU_INDIA 0x02 -# endif -# ifndef SUBLANG_UZBEK_LATIN -# define SUBLANG_UZBEK_LATIN 0x01 -# endif -# ifndef SUBLANG_UZBEK_CYRILLIC -# define SUBLANG_UZBEK_CYRILLIC 0x02 -# endif -#endif - -/* XPG3 defines the result of 'setlocale (category, NULL)' as: - "Directs 'setlocale()' to query 'category' and return the current - setting of 'local'." - However it does not specify the exact format. Neither do SUSV2 and - ISO C 99. So we can use this feature only on selected systems (e.g. - those using GNU C Library). */ -#if defined _LIBC || (defined __GNU_LIBRARY__ && __GNU_LIBRARY__ >= 2) -# define HAVE_LOCALE_NULL -#endif - -/* Determine the current locale's name, and canonicalize it into XPG syntax - language[_territory[.codeset]][@modifier] - The codeset part in the result is not reliable; the locale_charset() - should be used for codeset information instead. - The result must not be freed; it is statically allocated. */ - -const char * -_nl_locale_name (category, categoryname) - int category; - const char *categoryname; -{ - const char *retval; - -#ifndef WIN32 - - /* Use the POSIX methods of looking to 'LC_ALL', 'LC_xxx', and 'LANG'. - On some systems this can be done by the 'setlocale' function itself. */ -# if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL - retval = setlocale (category, NULL); -# else - /* Setting of LC_ALL overwrites all other. */ - retval = getenv ("LC_ALL"); - if (retval == NULL || retval[0] == '\0') - { - /* Next comes the name of the desired category. */ - retval = getenv (categoryname); - if (retval == NULL || retval[0] == '\0') - { - /* Last possibility is the LANG environment variable. */ - retval = getenv ("LANG"); - if (retval == NULL || retval[0] == '\0') - /* We use C as the default domain. POSIX says this is - implementation defined. */ - retval = "C"; - } - } -# endif - - return retval; - -#else /* WIN32 */ - - /* Return an XPG style locale name language[_territory][@modifier]. - Don't even bother determining the codeset; it's not useful in this - context, because message catalogs are not specific to a single - codeset. */ - - LCID lcid; - LANGID langid; - int primary, sub; - - /* Let the user override the system settings through environment - variables, as on POSIX systems. */ - retval = getenv ("LC_ALL"); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv (categoryname); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv ("LANG"); - if (retval != NULL && retval[0] != '\0') - return retval; - - /* Use native Win32 API locale ID. */ - lcid = GetThreadLocale (); - - /* Strip off the sorting rules, keep only the language part. */ - langid = LANGIDFROMLCID (lcid); - - /* Split into language and territory part. */ - primary = PRIMARYLANGID (langid); - sub = SUBLANGID (langid); - - /* Dispatch on language. - See also http://www.unicode.org/unicode/onlinedat/languages.html . - For details about languages, see http://www.ethnologue.com/ . */ - switch (primary) - { - case LANG_AFRIKAANS: return "af_ZA"; - case LANG_ALBANIAN: return "sq_AL"; - case 0x5e: /* AMHARIC */ return "am_ET"; - case LANG_ARABIC: - switch (sub) - { - case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA"; - case SUBLANG_ARABIC_IRAQ: return "ar_IQ"; - case SUBLANG_ARABIC_EGYPT: return "ar_EG"; - case SUBLANG_ARABIC_LIBYA: return "ar_LY"; - case SUBLANG_ARABIC_ALGERIA: return "ar_DZ"; - case SUBLANG_ARABIC_MOROCCO: return "ar_MA"; - case SUBLANG_ARABIC_TUNISIA: return "ar_TN"; - case SUBLANG_ARABIC_OMAN: return "ar_OM"; - case SUBLANG_ARABIC_YEMEN: return "ar_YE"; - case SUBLANG_ARABIC_SYRIA: return "ar_SY"; - case SUBLANG_ARABIC_JORDAN: return "ar_JO"; - case SUBLANG_ARABIC_LEBANON: return "ar_LB"; - case SUBLANG_ARABIC_KUWAIT: return "ar_KW"; - case SUBLANG_ARABIC_UAE: return "ar_AE"; - case SUBLANG_ARABIC_BAHRAIN: return "ar_BH"; - case SUBLANG_ARABIC_QATAR: return "ar_QA"; - } - return "ar"; - case LANG_ARMENIAN: return "hy_AM"; - case LANG_ASSAMESE: return "as_IN"; - case LANG_AZERI: - switch (sub) - { - /* FIXME: Adjust this when Azerbaijani locales appear on Unix. */ - case SUBLANG_AZERI_LATIN: return "az_AZ@latin"; - case SUBLANG_AZERI_CYRILLIC: return "az_AZ@cyrillic"; - } - return "az"; - case LANG_BASQUE: - return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR". */ - case LANG_BELARUSIAN: return "be_BY"; - case LANG_BENGALI: return "bn_IN"; - case LANG_BULGARIAN: return "bg_BG"; - case 0x55: /* BURMESE */ return "my_MM"; - case 0x53: /* CAMBODIAN */ return "km_KH"; - case LANG_CATALAN: return "ca_ES"; - case 0x5c: /* CHEROKEE */ return "chr_US"; - case LANG_CHINESE: - switch (sub) - { - case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW"; - case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN"; - case SUBLANG_CHINESE_HONGKONG: return "zh_HK"; - case SUBLANG_CHINESE_SINGAPORE: return "zh_SG"; - case SUBLANG_CHINESE_MACAU: return "zh_MO"; - } - return "zh"; - case LANG_CROATIAN: /* LANG_CROATIAN == LANG_SERBIAN - * What used to be called Serbo-Croatian - * should really now be two separate - * languages because of political reasons. - * (Says tml, who knows nothing about Serbian - * or Croatian.) - * (I can feel those flames coming already.) - */ - switch (sub) - { - case SUBLANG_DEFAULT: return "hr_HR"; - case SUBLANG_SERBIAN_LATIN: return "sr_YU"; - case SUBLANG_SERBIAN_CYRILLIC: return "sr_YU@cyrillic"; - } - return "hr"; - case LANG_CZECH: return "cs_CZ"; - case LANG_DANISH: return "da_DK"; - case LANG_DIVEHI: return "div_MV"; - case LANG_DUTCH: - switch (sub) - { - case SUBLANG_DUTCH: return "nl_NL"; - case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE"; - } - return "nl"; - case 0x66: /* EDO */ return "bin_NG"; - case LANG_ENGLISH: - switch (sub) - { - /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought - * English was the language spoken in England. - * Oh well. - */ - case SUBLANG_ENGLISH_US: return "en_US"; - case SUBLANG_ENGLISH_UK: return "en_GB"; - case SUBLANG_ENGLISH_AUS: return "en_AU"; - case SUBLANG_ENGLISH_CAN: return "en_CA"; - case SUBLANG_ENGLISH_NZ: return "en_NZ"; - case SUBLANG_ENGLISH_EIRE: return "en_IE"; - case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA"; - case SUBLANG_ENGLISH_JAMAICA: return "en_JM"; - case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */ - case SUBLANG_ENGLISH_BELIZE: return "en_BZ"; - case SUBLANG_ENGLISH_TRINIDAD: return "en_TT"; - case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW"; - case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH"; - } - return "en"; - case LANG_ESTONIAN: return "et_EE"; - case LANG_FAEROESE: return "fo_FO"; - case LANG_FARSI: return "fa_IR"; - case LANG_FINNISH: return "fi_FI"; - case LANG_FRENCH: - switch (sub) - { - case SUBLANG_FRENCH: return "fr_FR"; - case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE"; - case SUBLANG_FRENCH_CANADIAN: return "fr_CA"; - case SUBLANG_FRENCH_SWISS: return "fr_CH"; - case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU"; - case SUBLANG_FRENCH_MONACO: return "fr_MC"; - } - return "fr"; - case 0x62: /* FRISIAN */ return "fy_NL"; - case 0x67: /* FULFULDE */ return "ful_NG"; - case 0x3c: /* GAELIC */ - switch (sub) - { - case 0x01: /* SCOTTISH */ return "gd_GB"; - case 0x02: /* IRISH */ return "ga_IE"; - } - return "C"; - case LANG_GALICIAN: return "gl_ES"; - case LANG_GEORGIAN: return "ka_GE"; - case LANG_GERMAN: - switch (sub) - { - case SUBLANG_GERMAN: return "de_DE"; - case SUBLANG_GERMAN_SWISS: return "de_CH"; - case SUBLANG_GERMAN_AUSTRIAN: return "de_AT"; - case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU"; - case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI"; - } - return "de"; - case LANG_GREEK: return "el_GR"; - case 0x74: /* GUARANI */ return "gn_PY"; - case LANG_GUJARATI: return "gu_IN"; - case 0x68: /* HAUSA */ return "ha_NG"; - case 0x75: /* HAWAIIAN */ - /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers) - or Hawaii Creole English ("cpe_US", 600000 speakers)? */ - return "cpe_US"; - case LANG_HEBREW: return "he_IL"; - case LANG_HINDI: return "hi_IN"; - case LANG_HUNGARIAN: return "hu_HU"; - case 0x69: /* IBIBIO */ return "nic_NG"; - case LANG_ICELANDIC: return "is_IS"; - case 0x70: /* IGBO */ return "ibo_NG"; - case LANG_INDONESIAN: return "id_ID"; - case 0x5d: /* INUKTITUT */ return "iu_CA"; - case LANG_ITALIAN: - switch (sub) - { - case SUBLANG_ITALIAN: return "it_IT"; - case SUBLANG_ITALIAN_SWISS: return "it_CH"; - } - return "it"; - case LANG_JAPANESE: return "ja_JP"; - case LANG_KANNADA: return "kn_IN"; - case 0x71: /* KANURI */ return "kau_NG"; - case LANG_KASHMIRI: - switch (sub) - { - case SUBLANG_DEFAULT: return "ks_PK"; - case SUBLANG_KASHMIRI_INDIA: return "ks_IN"; - } - return "ks"; - case LANG_KAZAK: return "kk_KZ"; - case LANG_KONKANI: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "kok_IN"; - case LANG_KOREAN: return "ko_KR"; - case LANG_KYRGYZ: return "ky_KG"; - case 0x54: /* LAO */ return "lo_LA"; - case 0x76: /* LATIN */ return "la_VA"; - case LANG_LATVIAN: return "lv_LV"; - case LANG_LITHUANIAN: return "lt_LT"; - case LANG_MACEDONIAN: return "mk_MK"; - case LANG_MALAY: - switch (sub) - { - case SUBLANG_MALAY_MALAYSIA: return "ms_MY"; - case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN"; - } - return "ms"; - case LANG_MALAYALAM: return "ml_IN"; - case 0x3a: /* MALTESE */ return "mt_MT"; - case LANG_MANIPURI: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "mni_IN"; - case LANG_MARATHI: return "mr_IN"; - case LANG_MONGOLIAN: - return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN". */ - case LANG_NEPALI: - switch (sub) - { - case SUBLANG_DEFAULT: return "ne_NP"; - case SUBLANG_NEPALI_INDIA: return "ne_IN"; - } - return "ne"; - case LANG_NORWEGIAN: - switch (sub) - { - case SUBLANG_NORWEGIAN_BOKMAL: return "no_NO"; - case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO"; - } - return "no"; - case LANG_ORIYA: return "or_IN"; - case 0x72: /* OROMO */ return "om_ET"; - case 0x79: /* PAPIAMENTU */ return "pap_AN"; - case 0x63: /* PASHTO */ - return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF". */ - case LANG_POLISH: return "pl_PL"; - case LANG_PORTUGUESE: - switch (sub) - { - case SUBLANG_PORTUGUESE: return "pt_PT"; - /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT. - Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */ - case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR"; - } - return "pt"; - case LANG_PUNJABI: return "pa_IN"; - case 0x17: /* RHAETO-ROMANCE */ return "rm_CH"; - case LANG_ROMANIAN: return "ro_RO"; - case LANG_RUSSIAN: - return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA". */ - case 0x3b: /* SAMI */ return "se_NO"; - case LANG_SANSKRIT: return "sa_IN"; - case LANG_SINDHI: return "sd"; - case 0x5b: /* SINHALESE */ return "si_LK"; - case LANG_SLOVAK: return "sk_SK"; - case LANG_SLOVENIAN: return "sl_SI"; - case 0x77: /* SOMALI */ return "so_SO"; - case LANG_SORBIAN: - /* FIXME: Adjust this when such locales appear on Unix. */ - return "wen_DE"; - case LANG_SPANISH: - switch (sub) - { - case SUBLANG_SPANISH: return "es_ES"; - case SUBLANG_SPANISH_MEXICAN: return "es_MX"; - case SUBLANG_SPANISH_MODERN: - return "es_ES@modern"; /* not seen on Unix */ - case SUBLANG_SPANISH_GUATEMALA: return "es_GT"; - case SUBLANG_SPANISH_COSTA_RICA: return "es_CR"; - case SUBLANG_SPANISH_PANAMA: return "es_PA"; - case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO"; - case SUBLANG_SPANISH_VENEZUELA: return "es_VE"; - case SUBLANG_SPANISH_COLOMBIA: return "es_CO"; - case SUBLANG_SPANISH_PERU: return "es_PE"; - case SUBLANG_SPANISH_ARGENTINA: return "es_AR"; - case SUBLANG_SPANISH_ECUADOR: return "es_EC"; - case SUBLANG_SPANISH_CHILE: return "es_CL"; - case SUBLANG_SPANISH_URUGUAY: return "es_UY"; - case SUBLANG_SPANISH_PARAGUAY: return "es_PY"; - case SUBLANG_SPANISH_BOLIVIA: return "es_BO"; - case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV"; - case SUBLANG_SPANISH_HONDURAS: return "es_HN"; - case SUBLANG_SPANISH_NICARAGUA: return "es_NI"; - case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR"; - } - return "es"; - case 0x30: /* SUTU */ return "bnt_TZ"; - case LANG_SWAHILI: return "sw_KE"; - case LANG_SWEDISH: - switch (sub) - { - case SUBLANG_DEFAULT: return "sv_SE"; - case SUBLANG_SWEDISH_FINLAND: return "sv_FI"; - } - return "sv"; - case LANG_SYRIAC: return "syr_TR"; /* An extinct language. */ - case 0x64: /* TAGALOG */ return "tl_PH"; - case 0x28: /* TAJIK */ return "tg_TJ"; - case 0x5f: /* TAMAZIGHT */ return "ber_MA"; - case LANG_TAMIL: - return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG". */ - case LANG_TATAR: return "tt_RU"; - case LANG_TELUGU: return "te_IN"; - case LANG_THAI: return "th_TH"; - case 0x51: /* TIBETAN */ return "bo_CN"; - case 0x73: /* TIGRINYA */ return "ti_ET"; - case 0x31: /* TSONGA */ return "ts_ZA"; - case LANG_TURKISH: return "tr_TR"; - case 0x42: /* TURKMEN */ return "tk_TM"; - case LANG_UKRAINIAN: return "uk_UA"; - case LANG_URDU: - switch (sub) - { - case SUBLANG_URDU_PAKISTAN: return "ur_PK"; - case SUBLANG_URDU_INDIA: return "ur_IN"; - } - return "ur"; - case LANG_UZBEK: - switch (sub) - { - /* FIXME: Adjust this when Uzbek locales appear on Unix. */ - case SUBLANG_UZBEK_LATIN: return "uz_UZ@latin"; - case SUBLANG_UZBEK_CYRILLIC: return "uz_UZ@cyrillic"; - } - return "uz"; - case 0x33: /* VENDA */ return "ven_ZA"; - case LANG_VIETNAMESE: return "vi_VN"; - case 0x52: /* WELSH */ return "cy_GB"; - case 0x34: /* XHOSA */ return "xh_ZA"; - case 0x78: /* YI */ return "sit_CN"; - case 0x3d: /* YIDDISH */ return "yi_IL"; - case 0x6a: /* YORUBA */ return "yo_NG"; - case 0x35: /* ZULU */ return "zu_ZA"; - default: return "C"; - } - -#endif -} diff --git a/intl/log.c b/intl/log.c deleted file mode 100644 index 9c84791b9..000000000 --- a/intl/log.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Log file output. - Copyright (C) 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* Written by Bruno Haible <bruno@clisp.org>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* Print an ASCII string with quotes and escape sequences where needed. */ -static void -print_escaped (stream, str) - FILE *stream; - const char *str; -{ - putc ('"', stream); - for (; *str != '\0'; str++) - if (*str == '\n') - { - fputs ("\\n\"", stream); - if (str[1] == '\0') - return; - fputs ("\n\"", stream); - } - else - { - if (*str == '"' || *str == '\\') - putc ('\\', stream); - putc (*str, stream); - } - putc ('"', stream); -} - -/* Add to the log file an entry denoting a failed translation. */ -void -_nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural) - const char *logfilename; - const char *domainname; - const char *msgid1; - const char *msgid2; - int plural; -{ - static char *last_logfilename = NULL; - static FILE *last_logfile = NULL; - FILE *logfile; - - /* Can we reuse the last opened logfile? */ - if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0) - { - /* Close the last used logfile. */ - if (last_logfilename != NULL) - { - if (last_logfile != NULL) - { - fclose (last_logfile); - last_logfile = NULL; - } - free (last_logfilename); - last_logfilename = NULL; - } - /* Open the logfile. */ - last_logfilename = (char *) malloc (strlen (logfilename) + 1); - if (last_logfilename == NULL) - return; - strcpy (last_logfilename, logfilename); - last_logfile = fopen (logfilename, "a"); - if (last_logfile == NULL) - return; - } - logfile = last_logfile; - - fprintf (logfile, "domain "); - print_escaped (logfile, domainname); - fprintf (logfile, "\nmsgid "); - print_escaped (logfile, msgid1); - if (plural) - { - fprintf (logfile, "\nmsgid_plural "); - print_escaped (logfile, msgid2); - fprintf (logfile, "\nmsgstr[0] \"\"\n"); - } - else - fprintf (logfile, "\nmsgstr \"\"\n"); - putc ('\n', logfile); -} diff --git a/intl/ngettext.c b/intl/ngettext.c deleted file mode 100644 index 17a27f4aa..000000000 --- a/intl/ngettext.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Implementation of ngettext(3) function. - Copyright (C) 1995, 1997, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef _LIBC -# define __need_NULL -# include <stddef.h> -#else -# include <stdlib.h> /* Just for NULL. */ -#endif - -#include "gettextP.h" -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif - -#include <locale.h> - -/* @@ end of prolog @@ */ - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define NGETTEXT __ngettext -# define DCNGETTEXT __dcngettext -#else -# define NGETTEXT libintl_ngettext -# define DCNGETTEXT libintl_dcngettext -#endif - -/* Look up MSGID in the current default message catalog for the current - LC_MESSAGES locale. If not found, returns MSGID itself (the default - text). */ -char * -NGETTEXT (msgid1, msgid2, n) - const char *msgid1; - const char *msgid2; - unsigned long int n; -{ - return DCNGETTEXT (NULL, msgid1, msgid2, n, LC_MESSAGES); -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__ngettext, ngettext); -#endif diff --git a/intl/os2compat.c b/intl/os2compat.c deleted file mode 100644 index c8dc33e7c..000000000 --- a/intl/os2compat.c +++ /dev/null @@ -1,98 +0,0 @@ -/* OS/2 compatibility functions. - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#define OS2_AWARE -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <sys/param.h> - -/* A version of getenv() that works from DLLs */ -extern unsigned long DosScanEnv (const unsigned char *pszName, unsigned char **ppszValue); - -char * -_nl_getenv (const char *name) -{ - unsigned char *value; - if (DosScanEnv (name, &value)) - return NULL; - else - return value; -} - -/* A fixed size buffer. */ -char libintl_nl_default_dirname[MAXPATHLEN+1]; - -char *_nlos2_libdir = NULL; -char *_nlos2_localealiaspath = NULL; -char *_nlos2_localedir = NULL; - -static __attribute__((constructor)) void -nlos2_initialize () -{ - char *root = getenv ("UNIXROOT"); - char *gnulocaledir = getenv ("GNULOCALEDIR"); - - _nlos2_libdir = gnulocaledir; - if (!_nlos2_libdir) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_libdir = (char *) malloc (sl + strlen (LIBDIR) + 1); - memcpy (_nlos2_libdir, root, sl); - memcpy (_nlos2_libdir + sl, LIBDIR, strlen (LIBDIR) + 1); - } - else - _nlos2_libdir = LIBDIR; - } - - _nlos2_localealiaspath = gnulocaledir; - if (!_nlos2_localealiaspath) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_localealiaspath = (char *) malloc (sl + strlen (LOCALE_ALIAS_PATH) + 1); - memcpy (_nlos2_localealiaspath, root, sl); - memcpy (_nlos2_localealiaspath + sl, LOCALE_ALIAS_PATH, strlen (LOCALE_ALIAS_PATH) + 1); - } - else - _nlos2_localealiaspath = LOCALE_ALIAS_PATH; - } - - _nlos2_localedir = gnulocaledir; - if (!_nlos2_localedir) - { - if (root) - { - size_t sl = strlen (root); - _nlos2_localedir = (char *) malloc (sl + strlen (LOCALEDIR) + 1); - memcpy (_nlos2_localedir, root, sl); - memcpy (_nlos2_localedir + sl, LOCALEDIR, strlen (LOCALEDIR) + 1); - } - else - _nlos2_localedir = LOCALEDIR; - } - - if (strlen (_nlos2_localedir) <= MAXPATHLEN) - strcpy (libintl_nl_default_dirname, _nlos2_localedir); -} diff --git a/intl/os2compat.h b/intl/os2compat.h deleted file mode 100644 index 4f74e8c03..000000000 --- a/intl/os2compat.h +++ /dev/null @@ -1,46 +0,0 @@ -/* OS/2 compatibility defines. - This file is intended to be included from config.h - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* When included from os2compat.h we need all the original definitions */ -#ifndef OS2_AWARE - -#undef LIBDIR -#define LIBDIR _nlos2_libdir -extern char *_nlos2_libdir; - -#undef LOCALEDIR -#define LOCALEDIR _nlos2_localedir -extern char *_nlos2_localedir; - -#undef LOCALE_ALIAS_PATH -#define LOCALE_ALIAS_PATH _nlos2_localealiaspath -extern char *_nlos2_localealiaspath; - -#endif - -#undef HAVE_STRCASECMP -#define HAVE_STRCASECMP 1 -#define strcasecmp stricmp -#define strncasecmp strnicmp - -/* We have our own getenv() which works even if library is compiled as DLL */ -#define getenv _nl_getenv - -/* Older versions of gettext used -1 as the value of LC_MESSAGES */ -#define LC_MESSAGES_COMPAT (-1) diff --git a/intl/osdep.c b/intl/osdep.c deleted file mode 100644 index b37259838..000000000 --- a/intl/osdep.c +++ /dev/null @@ -1,24 +0,0 @@ -/* OS dependent parts of libintl. - Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#if defined __EMX__ -# include "os2compat.c" -#else -/* Avoid AIX compiler warning. */ -typedef int dummy; -#endif diff --git a/intl/plural-exp.c b/intl/plural-exp.c deleted file mode 100644 index c937c011a..000000000 --- a/intl/plural-exp.c +++ /dev/null @@ -1,156 +0,0 @@ -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "plural-exp.h" - -#if (defined __GNUC__ && !defined __APPLE_CC__) \ - || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - -/* These structs are the constant expression for the germanic plural - form determination. It represents the expression "n != 1". */ -static const struct expression plvar = -{ - .nargs = 0, - .operation = var, -}; -static const struct expression plone = -{ - .nargs = 0, - .operation = num, - .val = - { - .num = 1 - } -}; -struct expression GERMANIC_PLURAL = -{ - .nargs = 2, - .operation = not_equal, - .val = - { - .args = - { - [0] = (struct expression *) &plvar, - [1] = (struct expression *) &plone - } - } -}; - -# define INIT_GERMANIC_PLURAL() - -#else - -/* For compilers without support for ISO C 99 struct/union initializers: - Initialization at run-time. */ - -static struct expression plvar; -static struct expression plone; -struct expression GERMANIC_PLURAL; - -static void -init_germanic_plural () -{ - if (plone.val.num == 0) - { - plvar.nargs = 0; - plvar.operation = var; - - plone.nargs = 0; - plone.operation = num; - plone.val.num = 1; - - GERMANIC_PLURAL.nargs = 2; - GERMANIC_PLURAL.operation = not_equal; - GERMANIC_PLURAL.val.args[0] = &plvar; - GERMANIC_PLURAL.val.args[1] = &plone; - } -} - -# define INIT_GERMANIC_PLURAL() init_germanic_plural () - -#endif - -void -internal_function -EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp) - const char *nullentry; - struct expression **pluralp; - unsigned long int *npluralsp; -{ - if (nullentry != NULL) - { - const char *plural; - const char *nplurals; - - plural = strstr (nullentry, "plural="); - nplurals = strstr (nullentry, "nplurals="); - if (plural == NULL || nplurals == NULL) - goto no_plural; - else - { - char *endp; - unsigned long int n; - struct parse_args args; - - /* First get the number. */ - nplurals += 9; - while (*nplurals != '\0' && isspace ((unsigned char) *nplurals)) - ++nplurals; - if (!(*nplurals >= '0' && *nplurals <= '9')) - goto no_plural; -#if defined HAVE_STRTOUL || defined _LIBC - n = strtoul (nplurals, &endp, 10); -#else - for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++) - n = n * 10 + (*endp - '0'); -#endif - if (nplurals == endp) - goto no_plural; - *npluralsp = n; - - /* Due to the restrictions bison imposes onto the interface of the - scanner function we have to put the input string and the result - passed up from the parser into the same structure which address - is passed down to the parser. */ - plural += 7; - args.cp = plural; - if (PLURAL_PARSE (&args) != 0) - goto no_plural; - *pluralp = args.res; - } - } - else - { - /* By default we are using the Germanic form: singular form only - for `one', the plural form otherwise. Yes, this is also what - English is using since English is a Germanic language. */ - no_plural: - INIT_GERMANIC_PLURAL (); - *pluralp = &GERMANIC_PLURAL; - *npluralsp = 2; - } -} diff --git a/intl/plural-exp.h b/intl/plural-exp.h deleted file mode 100644 index 9e5d16583..000000000 --- a/intl/plural-exp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Expression parsing and evaluation for plural form selection. - Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _PLURAL_EXP_H -#define _PLURAL_EXP_H - -#ifndef PARAMS -# if __STDC__ || defined __GNUC__ || defined __SUNPRO_C || defined __cplusplus || __PROTOTYPES -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -#ifndef internal_function -# define internal_function -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - - -/* This is the representation of the expressions to determine the - plural form. */ -struct expression -{ - int nargs; /* Number of arguments. */ - enum operator - { - /* Without arguments: */ - var, /* The variable "n". */ - num, /* Decimal number. */ - /* Unary operators: */ - lnot, /* Logical NOT. */ - /* Binary operators: */ - mult, /* Multiplication. */ - divide, /* Division. */ - module, /* Modulo operation. */ - plus, /* Addition. */ - minus, /* Subtraction. */ - less_than, /* Comparison. */ - greater_than, /* Comparison. */ - less_or_equal, /* Comparison. */ - greater_or_equal, /* Comparison. */ - equal, /* Comparison for equality. */ - not_equal, /* Comparison for inequality. */ - land, /* Logical AND. */ - lor, /* Logical OR. */ - /* Ternary operators: */ - qmop /* Question mark operator. */ - } operation; - union - { - unsigned long int num; /* Number value for `num'. */ - struct expression *args[3]; /* Up to three arguments. */ - } val; -}; - -/* This is the data structure to pass information to the parser and get - the result in a thread-safe way. */ -struct parse_args -{ - const char *cp; - struct expression *res; -}; - - -/* Names for the libintl functions are a problem. This source code is used - 1. in the GNU C Library library, - 2. in the GNU libintl library, - 3. in the GNU gettext tools. - The function names in each situation must be different, to allow for - binary incompatible changes in 'struct expression'. Furthermore, - 1. in the GNU C Library library, the names have a __ prefix, - 2.+3. in the GNU libintl library and in the GNU gettext tools, the names - must follow ANSI C and not start with __. - So we have to distinguish the three cases. */ -#ifdef _LIBC -# define FREE_EXPRESSION __gettext_free_exp -# define PLURAL_PARSE __gettextparse -# define GERMANIC_PLURAL __gettext_germanic_plural -# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural -#elif defined (IN_LIBINTL) -# define FREE_EXPRESSION libintl_gettext_free_exp -# define PLURAL_PARSE libintl_gettextparse -# define GERMANIC_PLURAL libintl_gettext_germanic_plural -# define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural -#else -# define FREE_EXPRESSION free_plural_expression -# define PLURAL_PARSE parse_plural_expression -# define GERMANIC_PLURAL germanic_plural -# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression -#endif - -extern void FREE_EXPRESSION PARAMS ((struct expression *exp)) - internal_function; -extern int PLURAL_PARSE PARAMS ((void *arg)); -extern struct expression GERMANIC_PLURAL attribute_hidden; -extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry, - struct expression **pluralp, - unsigned long int *npluralsp)) - internal_function; - -#if !defined (_LIBC) && !defined (IN_LIBINTL) -extern unsigned long int plural_eval PARAMS ((struct expression *pexp, - unsigned long int n)); -#endif - -#endif /* _PLURAL_EXP_H */ diff --git a/intl/plural.c b/intl/plural.c deleted file mode 100644 index 3a4fa20ca..000000000 --- a/intl/plural.c +++ /dev/null @@ -1,1518 +0,0 @@ -/* A Bison parser, made from plural.y - by GNU bison 1.35. */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define yyparse __gettextparse -#define yylex __gettextlex -#define yyerror __gettexterror -#define yylval __gettextlval -#define yychar __gettextchar -#define yydebug __gettextdebug -#define yynerrs __gettextnerrs -# define EQUOP2 257 -# define CMPOP2 258 -# define ADDOP2 259 -# define MULOP2 260 -# define NUMBER 261 - -#line 1 "plural.y" - -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before <config.h> - because <config.h> may include arbitrary system headers. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include "plural-exp.h" - -/* The main function generated by the parser is called __gettextparse, - but we want it to be called PLURAL_PARSE. */ -#ifndef _LIBC -# define __gettextparse PLURAL_PARSE -#endif - -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg - -#line 49 "plural.y" -#ifndef YYSTYPE -typedef union { - unsigned long int num; - enum operator op; - struct expression *exp; -} yystype; -# define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 -#endif -#line 55 "plural.y" - -/* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); - -/* Allocation of expressions. */ - -static struct expression * -new_exp (nargs, op, args) - int nargs; - enum operator op; - struct expression * const *args; -{ - int i; - struct expression *newp; - - /* If any of the argument could not be malloc'ed, just return NULL. */ - for (i = nargs - 1; i >= 0; i--) - if (args[i] == NULL) - goto fail; - - /* Allocate a new expression. */ - newp = (struct expression *) malloc (sizeof (*newp)); - if (newp != NULL) - { - newp->nargs = nargs; - newp->operation = op; - for (i = nargs - 1; i >= 0; i--) - newp->val.args[i] = args[i]; - return newp; - } - - fail: - for (i = nargs - 1; i >= 0; i--) - FREE_EXPRESSION (args[i]); - - return NULL; -} - -static inline struct expression * -new_exp_0 (op) - enum operator op; -{ - return new_exp (0, op, NULL); -} - -static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; -{ - struct expression *args[1]; - - args[0] = right; - return new_exp (1, op, args); -} - -static struct expression * -new_exp_2 (op, left, right) - enum operator op; - struct expression *left; - struct expression *right; -{ - struct expression *args[2]; - - args[0] = left; - args[1] = right; - return new_exp (2, op, args); -} - -static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; -{ - struct expression *args[3]; - - args[0] = bexp; - args[1] = tbranch; - args[2] = fbranch; - return new_exp (3, op, args); -} - -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - - - -#define YYFINAL 27 -#define YYFLAG -32768 -#define YYNTBASE 16 - -/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 261 ? yytranslate[x] : 18) - -/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ -static const char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 10, 2, 2, 2, 2, 5, 2, - 14, 15, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 12, 2, - 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 6, 7, 8, - 9, 11 -}; - -#if YYDEBUG -static const short yyprhs[] = -{ - 0, 0, 2, 8, 12, 16, 20, 24, 28, 32, - 35, 37, 39 -}; -static const short yyrhs[] = -{ - 17, 0, 17, 3, 17, 12, 17, 0, 17, 4, - 17, 0, 17, 5, 17, 0, 17, 6, 17, 0, - 17, 7, 17, 0, 17, 8, 17, 0, 17, 9, - 17, 0, 10, 17, 0, 13, 0, 11, 0, 14, - 17, 15, 0 -}; - -#endif - -#if YYDEBUG -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const short yyrline[] = -{ - 0, 174, 182, 186, 190, 194, 198, 202, 206, 210, - 214, 218, 223 -}; -#endif - - -#if (YYDEBUG) || defined YYERROR_VERBOSE - -/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ -static const char *const yytname[] = -{ - "$", "error", "$undefined.", "'?'", "'|'", "'&'", "EQUOP2", "CMPOP2", - "ADDOP2", "MULOP2", "'!'", "NUMBER", "':'", "'n'", "'('", "')'", - "start", "exp", 0 -}; -#endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const short yyr1[] = -{ - 0, 16, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const short yyr2[] = -{ - 0, 1, 5, 3, 3, 3, 3, 3, 3, 2, - 1, 1, 3 -}; - -/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ -static const short yydefact[] = -{ - 0, 0, 11, 10, 0, 1, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 3, 4, 5, - 6, 7, 8, 0, 2, 0, 0, 0 -}; - -static const short yydefgoto[] = -{ - 25, 5 -}; - -static const short yypact[] = -{ - -9, -9,-32768,-32768, -9, 34,-32768, 11, -9, -9, - -9, -9, -9, -9, -9,-32768, 24, 39, 43, 16, - 26, -3,-32768, -9, 34, 21, 53,-32768 -}; - -static const short yypgoto[] = -{ - -32768, -1 -}; - - -#define YYLAST 53 - - -static const short yytable[] = -{ - 6, 1, 2, 7, 3, 4, 14, 16, 17, 18, - 19, 20, 21, 22, 8, 9, 10, 11, 12, 13, - 14, 26, 24, 12, 13, 14, 15, 8, 9, 10, - 11, 12, 13, 14, 13, 14, 23, 8, 9, 10, - 11, 12, 13, 14, 10, 11, 12, 13, 14, 11, - 12, 13, 14, 27 -}; - -static const short yycheck[] = -{ - 1, 10, 11, 4, 13, 14, 9, 8, 9, 10, - 11, 12, 13, 14, 3, 4, 5, 6, 7, 8, - 9, 0, 23, 7, 8, 9, 15, 3, 4, 5, - 6, 7, 8, 9, 8, 9, 12, 3, 4, 5, - 6, 7, 8, 9, 5, 6, 7, 8, 9, 6, - 7, 8, 9, 0 -}; -#define YYPURE 1 - -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/local/share/bison/bison.simple" - -/* Skeleton output parser for bison, - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser when - the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; -# if YYLSP_NEEDED - YYLTYPE yyls; -# endif -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# if YYLSP_NEEDED -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAX) -# else -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up"); \ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). - - When YYLLOC_DEFAULT is run, CURRENT is set the location of the - first token. By default, to implement support for ranges, extend - its range to the last symbol. */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#if YYPURE -# if YYLSP_NEEDED -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval, &yylloc) -# endif -# else /* !YYLSP_NEEDED */ -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval) -# endif -# endif /* !YYLSP_NEEDED */ -#else /* !YYPURE */ -# define YYLEX yylex () -#endif /* !YYPURE */ - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -#endif /* !YYDEBUG */ - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - -#ifdef YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif -#endif - -#line 315 "/usr/local/share/bison/bison.simple" - - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -# define YYPARSE_PARAM_DECL -# else -# define YYPARSE_PARAM_ARG YYPARSE_PARAM -# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -# endif -#else /* !YYPARSE_PARAM */ -# define YYPARSE_PARAM_ARG -# define YYPARSE_PARAM_DECL -#endif /* !YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -# ifdef YYPARSE_PARAM -int yyparse (void *); -# else -int yyparse (void); -# endif -#endif - -/* YY_DECL_VARIABLES -- depending whether we use a pure parser, - variables are global, or local to YYPARSE. */ - -#define YY_DECL_NON_LSP_VARIABLES \ -/* The lookahead symbol. */ \ -int yychar; \ - \ -/* The semantic value of the lookahead symbol. */ \ -YYSTYPE yylval; \ - \ -/* Number of parse errors so far. */ \ -int yynerrs; - -#if YYLSP_NEEDED -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES \ - \ -/* Location data for the lookahead symbol. */ \ -YYLTYPE yylloc; -#else -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES -#endif - - -/* If nonreentrant, generate the variables here. */ - -#if !YYPURE -YY_DECL_VARIABLES -#endif /* !YYPURE */ - -int -yyparse (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - /* If reentrant, generate the variables here. */ -#if YYPURE - YY_DECL_VARIABLES -#endif /* !YYPURE */ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yychar1 = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - -#if YYLSP_NEEDED - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; -#endif - -#if YYLSP_NEEDED -# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -# define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - YYSIZE_T yystacksize = YYINITDEPTH; - - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -#if YYLSP_NEEDED - YYLTYPE yyloc; -#endif - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; -#if YYLSP_NEEDED - yylsp = yyls; -#endif - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. */ -# if YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - yyls = yyls1; -# else - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); -# endif - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - goto yyoverflowlab; - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); -# if YYLSP_NEEDED - YYSTACK_RELOCATE (yyls); -# endif -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; -#if YYLSP_NEEDED - yylsp = yyls + yysize - 1; -#endif - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yychar1 = YYTRANSLATE (yychar); - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables - which are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - YYFPRINTF (stderr, "Next token is %d (%s", - yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise - meaning of a token, for further debugging info. */ -# ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -# endif - YYFPRINTF (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %d (%s), ", - yychar, yytname[yychar1])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to the semantic value of - the lookahead token. This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -#if YYLSP_NEEDED - /* Similarly for the default location. Let the user run additional - commands if for instance locations are ranges. */ - yyloc = yylsp[1-yylen]; - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); -#endif - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables which - are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - int yyi; - - YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) - YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); - YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - switch (yyn) { - -case 1: -#line 175 "plural.y" -{ - if (yyvsp[0].exp == NULL) - YYABORT; - ((struct parse_args *) arg)->res = yyvsp[0].exp; - } - break; -case 2: -#line 183 "plural.y" -{ - yyval.exp = new_exp_3 (qmop, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 3: -#line 187 "plural.y" -{ - yyval.exp = new_exp_2 (lor, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 4: -#line 191 "plural.y" -{ - yyval.exp = new_exp_2 (land, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 5: -#line 195 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 6: -#line 199 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 7: -#line 203 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 8: -#line 207 "plural.y" -{ - yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp); - } - break; -case 9: -#line 211 "plural.y" -{ - yyval.exp = new_exp_1 (lnot, yyvsp[0].exp); - } - break; -case 10: -#line 215 "plural.y" -{ - yyval.exp = new_exp_0 (var); - } - break; -case 11: -#line 219 "plural.y" -{ - if ((yyval.exp = new_exp_0 (num)) != NULL) - yyval.exp->val.num = yyvsp[0].num; - } - break; -case 12: -#line 224 "plural.y" -{ - yyval.exp = yyvsp[-1].exp; - } - break; -} - -#line 705 "/usr/local/share/bison/bison.simple" - - - yyvsp -= yylen; - yyssp -= yylen; -#if YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; -#if YYLSP_NEEDED - *++yylsp = yyloc; -#endif - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("parse error, unexpected ") + 1; - yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "parse error, unexpected "); - yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("parse error; also virtual memory exhausted"); - } - else -#endif /* defined (YYERROR_VERBOSE) */ - yyerror ("parse error"); - } - goto yyerrlab1; - - -/*--------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action | -`--------------------------------------------------*/ -yyerrlab1: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - YYDPRINTF ((stderr, "Discarding token %d (%s).\n", - yychar, yytname[yychar1])); - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - - -/*-------------------------------------------------------------------. -| yyerrdefault -- current state does not do anything special for the | -| error token. | -`-------------------------------------------------------------------*/ -yyerrdefault: -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - - /* If its default is to accept any token, ok. Otherwise pop it. */ - yyn = yydefact[yystate]; - if (yyn) - goto yydefault; -#endif - - -/*---------------------------------------------------------------. -| yyerrpop -- pop the current state because it cannot handle the | -| error token | -`---------------------------------------------------------------*/ -yyerrpop: - if (yyssp == yyss) - YYABORT; - yyvsp--; - yystate = *--yyssp; -#if YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "Error: state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - -/*--------------. -| yyerrhandle. | -`--------------*/ -yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -/*---------------------------------------------. -| yyoverflowab -- parser overflow comes here. | -`---------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} -#line 229 "plural.y" - - -void -internal_function -FREE_EXPRESSION (exp) - struct expression *exp; -{ - if (exp == NULL) - return; - - /* Handle the recursive case. */ - switch (exp->nargs) - { - case 3: - FREE_EXPRESSION (exp->val.args[2]); - /* FALLTHROUGH */ - case 2: - FREE_EXPRESSION (exp->val.args[1]); - /* FALLTHROUGH */ - case 1: - FREE_EXPRESSION (exp->val.args[0]); - /* FALLTHROUGH */ - default: - break; - } - - free (exp); -} - - -static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; -{ - const char *exp = *pexp; - int result; - - while (1) - { - if (exp[0] == '\0') - { - *pexp = exp; - return YYEOF; - } - - if (exp[0] != ' ' && exp[0] != '\t') - break; - - ++exp; - } - - result = *exp++; - switch (result) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - unsigned long int n = result - '0'; - while (exp[0] >= '0' && exp[0] <= '9') - { - n *= 10; - n += exp[0] - '0'; - ++exp; - } - lval->num = n; - result = NUMBER; - } - break; - - case '=': - if (exp[0] == '=') - { - ++exp; - lval->op = equal; - result = EQUOP2; - } - else - result = YYERRCODE; - break; - - case '!': - if (exp[0] == '=') - { - ++exp; - lval->op = not_equal; - result = EQUOP2; - } - break; - - case '&': - case '|': - if (exp[0] == result) - ++exp; - else - result = YYERRCODE; - break; - - case '<': - if (exp[0] == '=') - { - ++exp; - lval->op = less_or_equal; - } - else - lval->op = less_than; - result = CMPOP2; - break; - - case '>': - if (exp[0] == '=') - { - ++exp; - lval->op = greater_or_equal; - } - else - lval->op = greater_than; - result = CMPOP2; - break; - - case '*': - lval->op = mult; - result = MULOP2; - break; - - case '/': - lval->op = divide; - result = MULOP2; - break; - - case '%': - lval->op = module; - result = MULOP2; - break; - - case '+': - lval->op = plus; - result = ADDOP2; - break; - - case '-': - lval->op = minus; - result = ADDOP2; - break; - - case 'n': - case '?': - case ':': - case '(': - case ')': - /* Nothing, just return the character. */ - break; - - case ';': - case '\n': - case '\0': - /* Be safe and let the user call this function again. */ - --exp; - result = YYEOF; - break; - - default: - result = YYERRCODE; -#if YYDEBUG != 0 - --exp; -#endif - break; - } - - *pexp = exp; - - return result; -} - - -static void -yyerror (str) - const char *str; -{ - /* Do nothing. We don't print error messages here. */ -} diff --git a/intl/plural.y b/intl/plural.y deleted file mode 100644 index 616b7c11a..000000000 --- a/intl/plural.y +++ /dev/null @@ -1,409 +0,0 @@ -%{ -/* Expression parsing for plural form selection. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Written by Ulrich Drepper <drepper@cygnus.com>, 2000. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* The bison generated parser uses alloca. AIX 3 forces us to put this - declaration at the beginning of the file. The declaration in bison's - skeleton file comes too late. This must come before <config.h> - because <config.h> may include arbitrary system headers. */ -#if defined _AIX && !defined __GNUC__ - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stddef.h> -#include <stdlib.h> -#include "plural-exp.h" - -/* The main function generated by the parser is called __gettextparse, - but we want it to be called PLURAL_PARSE. */ -#ifndef _LIBC -# define __gettextparse PLURAL_PARSE -#endif - -#define YYLEX_PARAM &((struct parse_args *) arg)->cp -#define YYPARSE_PARAM arg -%} -%pure_parser -%expect 7 - -%union { - unsigned long int num; - enum operator op; - struct expression *exp; -} - -%{ -/* Prototypes for local functions. */ -static struct expression *new_exp PARAMS ((int nargs, enum operator op, - struct expression * const *args)); -static inline struct expression *new_exp_0 PARAMS ((enum operator op)); -static inline struct expression *new_exp_1 PARAMS ((enum operator op, - struct expression *right)); -static struct expression *new_exp_2 PARAMS ((enum operator op, - struct expression *left, - struct expression *right)); -static inline struct expression *new_exp_3 PARAMS ((enum operator op, - struct expression *bexp, - struct expression *tbranch, - struct expression *fbranch)); -static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); -static void yyerror PARAMS ((const char *str)); - -/* Allocation of expressions. */ - -static struct expression * -new_exp (nargs, op, args) - int nargs; - enum operator op; - struct expression * const *args; -{ - int i; - struct expression *newp; - - /* If any of the argument could not be malloc'ed, just return NULL. */ - for (i = nargs - 1; i >= 0; i--) - if (args[i] == NULL) - goto fail; - - /* Allocate a new expression. */ - newp = (struct expression *) malloc (sizeof (*newp)); - if (newp != NULL) - { - newp->nargs = nargs; - newp->operation = op; - for (i = nargs - 1; i >= 0; i--) - newp->val.args[i] = args[i]; - return newp; - } - - fail: - for (i = nargs - 1; i >= 0; i--) - FREE_EXPRESSION (args[i]); - - return NULL; -} - -static inline struct expression * -new_exp_0 (op) - enum operator op; -{ - return new_exp (0, op, NULL); -} - -static inline struct expression * -new_exp_1 (op, right) - enum operator op; - struct expression *right; -{ - struct expression *args[1]; - - args[0] = right; - return new_exp (1, op, args); -} - -static struct expression * -new_exp_2 (op, left, right) - enum operator op; - struct expression *left; - struct expression *right; -{ - struct expression *args[2]; - - args[0] = left; - args[1] = right; - return new_exp (2, op, args); -} - -static inline struct expression * -new_exp_3 (op, bexp, tbranch, fbranch) - enum operator op; - struct expression *bexp; - struct expression *tbranch; - struct expression *fbranch; -{ - struct expression *args[3]; - - args[0] = bexp; - args[1] = tbranch; - args[2] = fbranch; - return new_exp (3, op, args); -} - -%} - -/* This declares that all operators have the same associativity and the - precedence order as in C. See [Harbison, Steele: C, A Reference Manual]. - There is no unary minus and no bitwise operators. - Operators with the same syntactic behaviour have been merged into a single - token, to save space in the array generated by bison. */ -%right '?' /* ? */ -%left '|' /* || */ -%left '&' /* && */ -%left EQUOP2 /* == != */ -%left CMPOP2 /* < > <= >= */ -%left ADDOP2 /* + - */ -%left MULOP2 /* * / % */ -%right '!' /* ! */ - -%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2 -%token <num> NUMBER -%type <exp> exp - -%% - -start: exp - { - if ($1 == NULL) - YYABORT; - ((struct parse_args *) arg)->res = $1; - } - ; - -exp: exp '?' exp ':' exp - { - $$ = new_exp_3 (qmop, $1, $3, $5); - } - | exp '|' exp - { - $$ = new_exp_2 (lor, $1, $3); - } - | exp '&' exp - { - $$ = new_exp_2 (land, $1, $3); - } - | exp EQUOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp CMPOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp ADDOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | exp MULOP2 exp - { - $$ = new_exp_2 ($2, $1, $3); - } - | '!' exp - { - $$ = new_exp_1 (lnot, $2); - } - | 'n' - { - $$ = new_exp_0 (var); - } - | NUMBER - { - if (($$ = new_exp_0 (num)) != NULL) - $$->val.num = $1; - } - | '(' exp ')' - { - $$ = $2; - } - ; - -%% - -void -internal_function -FREE_EXPRESSION (exp) - struct expression *exp; -{ - if (exp == NULL) - return; - - /* Handle the recursive case. */ - switch (exp->nargs) - { - case 3: - FREE_EXPRESSION (exp->val.args[2]); - /* FALLTHROUGH */ - case 2: - FREE_EXPRESSION (exp->val.args[1]); - /* FALLTHROUGH */ - case 1: - FREE_EXPRESSION (exp->val.args[0]); - /* FALLTHROUGH */ - default: - break; - } - - free (exp); -} - - -static int -yylex (lval, pexp) - YYSTYPE *lval; - const char **pexp; -{ - const char *exp = *pexp; - int result; - - while (1) - { - if (exp[0] == '\0') - { - *pexp = exp; - return YYEOF; - } - - if (exp[0] != ' ' && exp[0] != '\t') - break; - - ++exp; - } - - result = *exp++; - switch (result) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - unsigned long int n = result - '0'; - while (exp[0] >= '0' && exp[0] <= '9') - { - n *= 10; - n += exp[0] - '0'; - ++exp; - } - lval->num = n; - result = NUMBER; - } - break; - - case '=': - if (exp[0] == '=') - { - ++exp; - lval->op = equal; - result = EQUOP2; - } - else - result = YYERRCODE; - break; - - case '!': - if (exp[0] == '=') - { - ++exp; - lval->op = not_equal; - result = EQUOP2; - } - break; - - case '&': - case '|': - if (exp[0] == result) - ++exp; - else - result = YYERRCODE; - break; - - case '<': - if (exp[0] == '=') - { - ++exp; - lval->op = less_or_equal; - } - else - lval->op = less_than; - result = CMPOP2; - break; - - case '>': - if (exp[0] == '=') - { - ++exp; - lval->op = greater_or_equal; - } - else - lval->op = greater_than; - result = CMPOP2; - break; - - case '*': - lval->op = mult; - result = MULOP2; - break; - - case '/': - lval->op = divide; - result = MULOP2; - break; - - case '%': - lval->op = module; - result = MULOP2; - break; - - case '+': - lval->op = plus; - result = ADDOP2; - break; - - case '-': - lval->op = minus; - result = ADDOP2; - break; - - case 'n': - case '?': - case ':': - case '(': - case ')': - /* Nothing, just return the character. */ - break; - - case ';': - case '\n': - case '\0': - /* Be safe and let the user call this function again. */ - --exp; - result = YYEOF; - break; - - default: - result = YYERRCODE; -#if YYDEBUG != 0 - --exp; -#endif - break; - } - - *pexp = exp; - - return result; -} - - -static void -yyerror (str) - const char *str; -{ - /* Do nothing. We don't print error messages here. */ -} diff --git a/intl/ref-add.sin b/intl/ref-add.sin deleted file mode 100644 index 167374e3c..000000000 --- a/intl/ref-add.sin +++ /dev/null @@ -1,31 +0,0 @@ -# Add this package to a list of references stored in a text file. -# -# Copyright (C) 2000 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# Written by Bruno Haible <haible@clisp.cons.org>. -# -/^# Packages using this file: / { - s/# Packages using this file:// - ta - :a - s/ @PACKAGE@ / @PACKAGE@ / - tb - s/ $/ @PACKAGE@ / - :b - s/^/# Packages using this file:/ -} diff --git a/intl/ref-del.sin b/intl/ref-del.sin deleted file mode 100644 index 613cf37f3..000000000 --- a/intl/ref-del.sin +++ /dev/null @@ -1,26 +0,0 @@ -# Remove this package from a list of references stored in a text file. -# -# Copyright (C) 2000 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU Library General Public License as published -# by the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA. -# -# Written by Bruno Haible <haible@clisp.cons.org>. -# -/^# Packages using this file: / { - s/# Packages using this file:// - s/ @PACKAGE@ / / - s/^/# Packages using this file:/ -} diff --git a/intl/relocatable.c b/intl/relocatable.c deleted file mode 100644 index 16f79a528..000000000 --- a/intl/relocatable.c +++ /dev/null @@ -1,439 +0,0 @@ -/* Provide relocatable packages. - Copyright (C) 2003 Free Software Foundation, Inc. - Written by Bruno Haible <bruno@clisp.org>, 2003. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - - -/* Tell glibc's <stdio.h> to provide a prototype for getline(). - This must come before <config.h> because <config.h> may include - <features.h>, and once <features.h> has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -/* Specification. */ -#include "relocatable.h" - -#if ENABLE_RELOCATABLE - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef NO_XMALLOC -# define xmalloc malloc -#else -# include "xmalloc.h" -#endif - -#if DEPENDS_ON_LIBCHARSET -# include <libcharset.h> -#endif -#if DEPENDS_ON_LIBICONV && HAVE_ICONV -# include <iconv.h> -#endif -#if DEPENDS_ON_LIBINTL && ENABLE_NLS -# include <libintl.h> -#endif - -/* Faked cheap 'bool'. */ -#undef bool -#undef false -#undef true -#define bool int -#define false 0 -#define true 1 - -/* Pathname support. - ISSLASH(C) tests whether C is a directory separator character. - IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. - */ -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_PATH_WITH_DIR(P) \ - (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) -# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) -# define FILESYSTEM_PREFIX_LEN(P) 0 -#endif - -/* Original installation prefix. */ -static char *orig_prefix; -static size_t orig_prefix_len; -/* Current installation prefix. */ -static char *curr_prefix; -static size_t curr_prefix_len; -/* These prefixes do not end in a slash. Anything that will be concatenated - to them must start with a slash. */ - -/* Sets the original and the current installation prefix of this module. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -static void -set_this_relocation_prefix (const char *orig_prefix_arg, - const char *curr_prefix_arg) -{ - if (orig_prefix_arg != NULL && curr_prefix_arg != NULL - /* Optimization: if orig_prefix and curr_prefix are equal, the - relocation is a nop. */ - && strcmp (orig_prefix_arg, curr_prefix_arg) != 0) - { - /* Duplicate the argument strings. */ - char *memory; - - orig_prefix_len = strlen (orig_prefix_arg); - curr_prefix_len = strlen (curr_prefix_arg); - memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1); -#ifdef NO_XMALLOC - if (memory != NULL) -#endif - { - memcpy (memory, orig_prefix_arg, orig_prefix_len + 1); - orig_prefix = memory; - memory += orig_prefix_len + 1; - memcpy (memory, curr_prefix_arg, curr_prefix_len + 1); - curr_prefix = memory; - return; - } - } - orig_prefix = NULL; - curr_prefix = NULL; - /* Don't worry about wasted memory here - this function is usually only - called once. */ -} - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -void -set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg) -{ - set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg); - - /* Now notify all dependent libraries. */ -#if DEPENDS_ON_LIBCHARSET - libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109 - libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix - libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); -#endif -} - -/* Convenience function: - Computes the current installation prefix, based on the original - installation prefix, the original installation directory of a particular - file, and the current pathname of this file. Returns NULL upon failure. */ -#ifdef IN_LIBRARY -#define compute_curr_prefix local_compute_curr_prefix -static -#endif -const char * -compute_curr_prefix (const char *orig_installprefix, - const char *orig_installdir, - const char *curr_pathname) -{ - const char *curr_installdir; - const char *rel_installdir; - - if (curr_pathname == NULL) - return NULL; - - /* Determine the relative installation directory, relative to the prefix. - This is simply the difference between orig_installprefix and - orig_installdir. */ - if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix)) - != 0) - /* Shouldn't happen - nothing should be installed outside $(prefix). */ - return NULL; - rel_installdir = orig_installdir + strlen (orig_installprefix); - - /* Determine the current installation directory. */ - { - const char *p_base = curr_pathname + FILESYSTEM_PREFIX_LEN (curr_pathname); - const char *p = curr_pathname + strlen (curr_pathname); - char *q; - - while (p > p_base) - { - p--; - if (ISSLASH (*p)) - break; - } - - q = (char *) xmalloc (p - curr_pathname + 1); -#ifdef NO_XMALLOC - if (q == NULL) - return NULL; -#endif - memcpy (q, curr_pathname, p - curr_pathname); - q[p - curr_pathname] = '\0'; - curr_installdir = q; - } - - /* Compute the current installation prefix by removing the trailing - rel_installdir from it. */ - { - const char *rp = rel_installdir + strlen (rel_installdir); - const char *cp = curr_installdir + strlen (curr_installdir); - const char *cp_base = - curr_installdir + FILESYSTEM_PREFIX_LEN (curr_installdir); - - while (rp > rel_installdir && cp > cp_base) - { - bool same = false; - const char *rpi = rp; - const char *cpi = cp; - - while (rpi > rel_installdir && cpi > cp_base) - { - rpi--; - cpi--; - if (ISSLASH (*rpi) || ISSLASH (*cpi)) - { - if (ISSLASH (*rpi) && ISSLASH (*cpi)) - same = true; - break; - } -#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS - case insignificant filesystem */ - if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi) - != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi)) - break; -#else - if (*rpi != *cpi) - break; -#endif - } - if (!same) - break; - /* The last pathname component was the same. opi and cpi now point - to the slash before it. */ - rp = rpi; - cp = cpi; - } - - if (rp > rel_installdir) - /* Unexpected: The curr_installdir does not end with rel_installdir. */ - return NULL; - - { - size_t curr_prefix_len = cp - curr_installdir; - char *curr_prefix; - - curr_prefix = (char *) xmalloc (curr_prefix_len + 1); -#ifdef NO_XMALLOC - if (curr_prefix == NULL) - return NULL; -#endif - memcpy (curr_prefix, curr_installdir, curr_prefix_len); - curr_prefix[curr_prefix_len] = '\0'; - - return curr_prefix; - } - } -} - -#if defined PIC && defined INSTALLDIR - -/* Full pathname of shared library, or NULL. */ -static char *shared_library_fullname; - -#if defined _WIN32 || defined __WIN32__ - -/* Determine the full pathname of the shared library when it is loaded. */ - -BOOL WINAPI -DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved) -{ - (void) reserved; - - if (event == DLL_PROCESS_ATTACH) - { - /* The DLL is being loaded into an application's address range. */ - static char location[MAX_PATH]; - - if (!GetModuleFileName (module_handle, location, sizeof (location))) - /* Shouldn't happen. */ - return FALSE; - - if (!IS_PATH_WITH_DIR (location)) - /* Shouldn't happen. */ - return FALSE; - - shared_library_fullname = strdup (location); - } - - return TRUE; -} - -#else /* Unix */ - -static void -find_shared_library_fullname () -{ -#ifdef __linux__ - FILE *fp; - - /* Open the current process' maps file. It describes one VMA per line. */ - fp = fopen ("/proc/self/maps", "r"); - if (fp) - { - unsigned long address = (unsigned long) &find_shared_library_fullname; - for (;;) - { - unsigned long start, end; - int c; - - if (fscanf (fp, "%lx-%lx", &start, &end) != 2) - break; - if (address >= start && address <= end - 1) - { - /* Found it. Now see if this line contains a filename. */ - while (c = getc (fp), c != EOF && c != '\n' && c != '/') - continue; - if (c == '/') - { - size_t size; - int len; - - ungetc (c, fp); - shared_library_fullname = NULL; size = 0; - len = getline (&shared_library_fullname, &size, fp); - if (len >= 0) - { - /* Success: filled shared_library_fullname. */ - if (len > 0 && shared_library_fullname[len - 1] == '\n') - shared_library_fullname[len - 1] = '\0'; - } - } - break; - } - while (c = getc (fp), c != EOF && c != '\n') - continue; - } - fclose (fp); - } -#endif -} - -#endif /* WIN32 / Unix */ - -/* Return the full pathname of the current shared library. - Return NULL if unknown. - Guaranteed to work only on Linux and Woe32. */ -static char * -get_shared_library_fullname () -{ -#if !(defined _WIN32 || defined __WIN32__) - static bool tried_find_shared_library_fullname; - if (!tried_find_shared_library_fullname) - { - find_shared_library_fullname (); - tried_find_shared_library_fullname = true; - } -#endif - return shared_library_fullname; -} - -#endif /* PIC */ - -/* Returns the pathname, relocated according to the current installation - directory. */ -const char * -relocate (const char *pathname) -{ -#if defined PIC && defined INSTALLDIR - static int initialized; - - /* Initialization code for a shared library. */ - if (!initialized) - { - /* At this point, orig_prefix and curr_prefix likely have already been - set through the main program's set_program_name_and_installdir - function. This is sufficient in the case that the library has - initially been installed in the same orig_prefix. But we can do - better, to also cover the cases that 1. it has been installed - in a different prefix before being moved to orig_prefix and (later) - to curr_prefix, 2. unlike the program, it has not moved away from - orig_prefix. */ - const char *orig_installprefix = INSTALLPREFIX; - const char *orig_installdir = INSTALLDIR; - const char *curr_prefix_better; - - curr_prefix_better = - compute_curr_prefix (orig_installprefix, orig_installdir, - get_shared_library_fullname ()); - if (curr_prefix_better == NULL) - curr_prefix_better = curr_prefix; - - set_relocation_prefix (orig_installprefix, curr_prefix_better); - - initialized = 1; - } -#endif - - /* Note: It is not necessary to perform case insensitive comparison here, - even for DOS-like filesystems, because the pathname argument was - typically created from the same Makefile variable as orig_prefix came - from. */ - if (orig_prefix != NULL && curr_prefix != NULL - && strncmp (pathname, orig_prefix, orig_prefix_len) == 0) - { - if (pathname[orig_prefix_len] == '\0') - /* pathname equals orig_prefix. */ - return curr_prefix; - if (ISSLASH (pathname[orig_prefix_len])) - { - /* pathname starts with orig_prefix. */ - const char *pathname_tail = &pathname[orig_prefix_len]; - char *result = - (char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1); - -#ifdef NO_XMALLOC - if (result != NULL) -#endif - { - memcpy (result, curr_prefix, curr_prefix_len); - strcpy (result + curr_prefix_len, pathname_tail); - return result; - } - } - } - /* Nothing to relocate. */ - return pathname; -} - -#endif diff --git a/intl/relocatable.h b/intl/relocatable.h deleted file mode 100644 index d141200a6..000000000 --- a/intl/relocatable.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Provide relocatable packages. - Copyright (C) 2003 Free Software Foundation, Inc. - Written by Bruno Haible <bruno@clisp.org>, 2003. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _RELOCATABLE_H -#define _RELOCATABLE_H - -/* This can be enabled through the configure --enable-relocatable option. */ -#if ENABLE_RELOCATABLE - -/* When building a DLL, we must export some functions. Note that because - this is a private .h file, we don't need to use __declspec(dllimport) - in any case. */ -#if defined _MSC_VER && BUILDING_DLL -# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport) -#else -# define RELOCATABLE_DLL_EXPORTED -#endif - -/* Sets the original and the current installation prefix of the package. - Relocation simply replaces a pathname starting with the original prefix - by the corresponding pathname with the current prefix instead. Both - prefixes should be directory names without trailing slash (i.e. use "" - instead of "/"). */ -extern RELOCATABLE_DLL_EXPORTED void - set_relocation_prefix (const char *orig_prefix, - const char *curr_prefix); - -/* Returns the pathname, relocated according to the current installation - directory. */ -extern const char * relocate (const char *pathname); - -/* Memory management: relocate() leaks memory, because it has to construct - a fresh pathname. If this is a problem because your program calls - relocate() frequently, think about caching the result. */ - -/* Convenience function: - Computes the current installation prefix, based on the original - installation prefix, the original installation directory of a particular - file, and the current pathname of this file. Returns NULL upon failure. */ -extern const char * compute_curr_prefix (const char *orig_installprefix, - const char *orig_installdir, - const char *curr_pathname); - -#else - -/* By default, we use the hardwired pathnames. */ -#define relocate(pathname) (pathname) - -#endif - -#endif /* _RELOCATABLE_H */ diff --git a/intl/textdomain.c b/intl/textdomain.c deleted file mode 100644 index f259c696d..000000000 --- a/intl/textdomain.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Implementation of the textdomain(3) function. - Copyright (C) 1995-1998, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef _LIBC -# include <libintl.h> -#else -# include "libgnuintl.h" -#endif -#include "gettextP.h" - -#ifdef _LIBC -/* We have to handle multi-threaded applications. */ -# include <bits/libc-lock.h> -#else -/* Provide dummy implementation if this is outside glibc. */ -# define __libc_rwlock_define(CLASS, NAME) -# define __libc_rwlock_wrlock(NAME) -# define __libc_rwlock_unlock(NAME) -#endif - -/* The internal variables in the standalone libintl.a must have different - names than the internal variables in GNU libc, otherwise programs - using libintl.a cannot be linked statically. */ -#if !defined _LIBC -# define _nl_default_default_domain libintl_nl_default_default_domain -# define _nl_current_default_domain libintl_nl_current_default_domain -#endif - -/* @@ end of prolog @@ */ - -/* Name of the default text domain. */ -extern const char _nl_default_default_domain[] attribute_hidden; - -/* Default text domain in which entries for gettext(3) are to be found. */ -extern const char *_nl_current_default_domain attribute_hidden; - - -/* Names for the libintl functions are a problem. They must not clash - with existing names and they should follow ANSI C. But this source - code is also used in GNU C Library where the names have a __ - prefix. So we have to make a difference here. */ -#ifdef _LIBC -# define TEXTDOMAIN __textdomain -# ifndef strdup -# define strdup(str) __strdup (str) -# endif -#else -# define TEXTDOMAIN libintl_textdomain -#endif - -/* Lock variable to protect the global data in the gettext implementation. */ -__libc_rwlock_define (extern, _nl_state_lock attribute_hidden) - -/* Set the current default message catalog to DOMAINNAME. - If DOMAINNAME is null, return the current default. - If DOMAINNAME is "", reset to the default of "messages". */ -char * -TEXTDOMAIN (domainname) - const char *domainname; -{ - char *new_domain; - char *old_domain; - - /* A NULL pointer requests the current setting. */ - if (domainname == NULL) - return (char *) _nl_current_default_domain; - - __libc_rwlock_wrlock (_nl_state_lock); - - old_domain = (char *) _nl_current_default_domain; - - /* If domain name is the null string set to default domain "messages". */ - if (domainname[0] == '\0' - || strcmp (domainname, _nl_default_default_domain) == 0) - { - _nl_current_default_domain = _nl_default_default_domain; - new_domain = (char *) _nl_current_default_domain; - } - else if (strcmp (domainname, old_domain) == 0) - /* This can happen and people will use it to signal that some - environment variable changed. */ - new_domain = old_domain; - else - { - /* If the following malloc fails `_nl_current_default_domain' - will be NULL. This value will be returned and so signals we - are out of core. */ -#if defined _LIBC || defined HAVE_STRDUP - new_domain = strdup (domainname); -#else - size_t len = strlen (domainname) + 1; - new_domain = (char *) malloc (len); - if (new_domain != NULL) - memcpy (new_domain, domainname, len); -#endif - - if (new_domain != NULL) - _nl_current_default_domain = new_domain; - } - - /* We use this possibility to signal a change of the loaded catalogs - since this is most likely the case and there is no other easy we - to do it. Do it only when the call was successful. */ - if (new_domain != NULL) - { - ++_nl_msg_cat_cntr; - - if (old_domain != new_domain && old_domain != _nl_default_default_domain) - free (old_domain); - } - - __libc_rwlock_unlock (_nl_state_lock); - - return new_domain; -} - -#ifdef _LIBC -/* Alias for function name in GNU C Library. */ -weak_alias (__textdomain, textdomain); -#endif diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog deleted file mode 100644 index e9f643774..000000000 --- a/jnlib/ChangeLog +++ /dev/null @@ -1,209 +0,0 @@ -2004-05-05 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_file): Oops, don't close if LOGSTREAM is NULL. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_file): Make sure the log stream will be - closed even if the stderr fileno will be assigned to a new socket. - -2004-04-16 Werner Koch <wk@gnupg.org> - - * logging.h (JNLIB_LOG_WITH_PREFIX): Add constants for the flag - values. - * logging.c (log_set_prefix): New flag DETACHED. - (fun_writer): Take care of this flag. - (log_test_fd): New. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * stringhelp.c (print_sanitized_buffer): Don't care about - non-ASCII characaters. - (sanitize_buffer): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * Makefile.am: Replaced INCLUDES by AM_CPPFLAGS. - -2004-01-05 Werner Koch <wk@gnupg.org> - - * argparse.c (strusage): Changed default copyright year to 2004. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * argparse.c (initialize): Replaced use of non-literal format - args. Suggested by Florian Weimer. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * logging.c (writen, fun_writer, fun_closer): New. - (log_set_file): Add feature to log to a socket. - (log_set_file, do_logv): Force printing with prefix and pid. - -2003-11-13 Werner Koch <wk@gnupg.org> - - * strlist.c (strlist_copy): New. - - * dotlock.c: Define DIRSEP_C et al. if not defined. - -2003-11-06 Werner Koch <wk@gnupg.org> - - * strlist.h (strlist_t): New. STRLIST is now deprecated. - -2003-06-18 Werner Koch <wk@gnupg.org> - - * strlist.c (strlist_pop): New. - - * dotlock.c (dotlock_remove_lockfiles): Prefixed with dotlock_ and - made global. - -2003-06-17 Werner Koch <wk@gnupg.org> - - * stringhelp.c (length_sans_trailing_chars) - (length_sans_trailing_ws): New. - - * logging.c (log_inc_errorcount): New. - - * stringhelp.c (print_sanitized_utf8_buffer): Implement utf8 - conversion. - (sanitize_buffer): New. Based on gnupg 1.3.2 make_printable_string. - - * dotlock.c: Updated to match the version from 1.3.2 - * utf8conv.c: New. Code taken from strgutil.c of gnupg 1.3.2. - * utf8conv.h: New. - -2003-06-16 Werner Koch <wk@gnupg.org> - - * logging.c (do_logv): Hack to optionally suppress a leading space. - - * stringhelp.c (ascii_strncasecmp): New. Taken from gnupg 1.3. - (ascii_memistr): New. Taken from gnupg 1.3 - -2003-06-13 Werner Koch <wk@gnupg.org> - - * mischelp.h (wipememory2,wipememory): New. Taken from GnuPG 1.3.2. - -2002-06-04 Werner Koch <wk@gnupg.org> - - * stringhelp.c (print_sanitized_utf8_string): New. No real - implementation for now. - (print_sanitized_utf8_buffer): Ditto. - -2002-04-04 Werner Koch <wk@gnupg.org> - - * logging.c (log_get_prefix): New. - -2002-03-15 Werner Koch <wk@gnupg.org> - - * argparse.c (optfile_parse): Fixed missing argument handling. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * stringhelp.c (ascii_memcasemem): New. - -2002-02-14 Werner Koch <wk@gnupg.org> - - * Makefile.am (INCLUDES): Add cflags for libgcrypt. - -2002-02-07 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_fd): New. - - * stringhelp.c (print_sanitized_buffer): New. - (print_sanitized_string): New. - -2002-01-24 Werner Koch <wk@gnupg.org> - - * argparse.c (strusage): Set default copyright notice year to 2002. - - Fixed the copyright notice of this file, as it has always been - part of GnuPG and therefore belongs to the FSF. - -2001-11-01 Marcus Brinkmann <marcus@g10code.de> - - * logging.c (log_printf): Do not initialize ARG_PTR with 0, we - don't know the correct type. Instead, run va_start and va_end - unconditionally. - Reported by Jose Carlos Garcia Sogo <jsogo@debian.org>. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * logging.c (log_get_stream): New. - -2001-12-05 Werner Koch <wk@gnupg.org> - - * logging.c (log_set_prefix): New. - (do_logv): Include prefix and pid only if enabled. Print time only - when explicitly enabled. - (log_logv): New. - * logging.h: Include log_logv() only when requested. - -2001-11-06 Werner Koch <wk@gnupg.org> - - * strlist.c, strlist.h: New. Taken from pgnupg/util/strgutil.c - -2001-08-30 Werner Koch <wk@gnupg.org> - - * logging.c (log_printf): Don't pass NULL instead of arg_ptr. - -2001-07-19 Werner Koch <wk@gnupg.org> - - * stringhelp.c (ascii_memistr,ascii_isupper,ascii_islower, - ascii_toupper,ascii_tolower, ascii_strcasecmp, ascii_memcasecmp): New. - -2000-07-26 10:02:51 Werner Koch (wk@habibti.openit.de) - - * stringhelp.c.: Add stdarg.h - * argparse.h: s/ulong/unsigned long/ although this should be defined - by types.h. - -2000-06-28 19:40:23 Werner Koch (wk@habibti.openit.de) - - * Makefile.am: Replaced second logging.c by .h - -2000-05-24 08:58:15 Werner Koch (wk@habibti.openit.de) - - * logging.c (log_get_errorcount): New. - -2000-05-24 08:44:47 Werner Koch (wk@habibti.openit.de) - - * stringhelp.c: Added a few filename related helper functions. - -2000-05-11 18:04:43 Werner Koch (wk@habibti.openit.de) - - * xmalloc.c (xstrcat2): Replaced stpcpy to quickly address W32 - problems. - -2000-05-02 19:43:38 Werner Koch (wk@habibti.openit.de) - - * xmalloc.c (xstrcat2): New. - -Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de> - - * README: New. - * Makefile.am: new. - * argparse.c argparse.h logging.c logging.h - mischelp.h stringhelp.c stringhelp.h xmalloc.c - xmalloc.h dotlock.c: Moved from ../util to here. - * dotlock.h: New. - * libjnlib-config.h: New. - - * logging.c (log_set_file): New. - (log_printf): New. - (do_logv): Add kludge to insert LFs. - - - *********************************************************** - * Please note that Jnlib is maintained as part of GnuPG. * - * You may find it source-copied in other packages. * - *********************************************************** - - Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am deleted file mode 100644 index bad3c5a71..000000000 --- a/jnlib/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (C) 1999, 2000, 2001, 2004 Feee Software Soundation, Inc. -# -# This file is part of GnuPG -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = README - -AM_CPPFLAGS = -I$(top_srcdir)/intl - -# We need libgcrypt because libjnlib-config includes gcrypt.h -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) - -noinst_LIBRARIES = libjnlib.a - - -#libjnlib_a_LDFLAGS = -libjnlib_a_SOURCES = \ - libjnlib-config.h \ - stringhelp.c stringhelp.h \ - strlist.c strlist.h \ - utf8conv.c utf8conv.h \ - argparse.c argparse.h \ - logging.c logging.h \ - dotlock.c dotlock.h \ - types.h mischelp.h - -# xmalloc.c xmalloc.h - diff --git a/jnlib/README b/jnlib/README deleted file mode 100644 index e49ef4450..000000000 --- a/jnlib/README +++ /dev/null @@ -1,7 +0,0 @@ -jnlib - this is a collection of utility function which are -too small to put into a library. - -libjnlib-config.h should be be modified for each project -to make these functions fit into the software. Mainly these -are memory functions in case you need another allocator. - diff --git a/jnlib/argparse.c b/jnlib/argparse.c deleted file mode 100644 index de828e8ce..000000000 --- a/jnlib/argparse.c +++ /dev/null @@ -1,999 +0,0 @@ -/* [argparse.c wk 17.06.97] Argument Parser for option handling - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> - -#include "libjnlib-config.h" -#include "mischelp.h" -#include "stringhelp.h" -#include "logging.h" -#include "argparse.h" - - -/********************************* - * @Summary arg_parse - * #include <wk/lib.h> - * - * typedef struct { - * char *argc; pointer to argc (value subject to change) - * char ***argv; pointer to argv (value subject to change) - * unsigned flags; Global flags (DO NOT CHANGE) - * int err; print error about last option - * 1 = warning, 2 = abort - * int r_opt; return option - * int r_type; type of return value (0 = no argument found) - * union { - * int ret_int; - * long ret_long - * ulong ret_ulong; - * char *ret_str; - * } r; Return values - * struct { - * int idx; - * const char *last; - * void *aliases; - * } internal; DO NOT CHANGE - * } ARGPARSE_ARGS; - * - * typedef struct { - * int short_opt; - * const char *long_opt; - * unsigned flags; - * } ARGPARSE_OPTS; - * - * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts ); - * - * @Description - * This is my replacement for getopt(). See the example for a typical usage. - * Global flags are: - * Bit 0 : Do not remove options form argv - * Bit 1 : Do not stop at last option but return other args - * with r_opt set to -1. - * Bit 2 : Assume options and real args are mixed. - * Bit 3 : Do not use -- to stop option processing. - * Bit 4 : Do not skip the first arg. - * Bit 5 : allow usage of long option with only one dash - * Bit 6 : ignore --version - * all other bits must be set to zero, this value is modified by the - * function, so assume this is write only. - * Local flags (for each option): - * Bit 2-0 : 0 = does not take an argument - * 1 = takes int argument - * 2 = takes string argument - * 3 = takes long argument - * 4 = takes ulong argument - * Bit 3 : argument is optional (r_type will the be set to 0) - * Bit 4 : allow 0x etc. prefixed values. - * Bit 7 : this is a command and not an option - * You stop the option processing by setting opts to NULL, the function will - * then return 0. - * @Return Value - * Returns the args.r_opt or 0 if ready - * r_opt may be -2/-7 to indicate an unknown option/command. - * @See Also - * ArgExpand - * @Notes - * You do not need to process the options 'h', '--help' or '--version' - * because this function includes standard help processing; but if you - * specify '-h', '--help' or '--version' you have to do it yourself. - * The option '--' stops argument processing; if bit 1 is set the function - * continues to return normal arguments. - * To process float args or unsigned args you must use a string args and do - * the conversion yourself. - * @Example - * - * ARGPARSE_OPTS opts[] = { - * { 'v', "verbose", 0 }, - * { 'd', "debug", 0 }, - * { 'o', "output", 2 }, - * { 'c', "cross-ref", 2|8 }, - * { 'm', "my-option", 1|8 }, - * { 500, "have-no-short-option-for-this-long-option", 0 }, - * {0} }; - * ARGPARSE_ARGS pargs = { &argc, &argv, 0 } - * - * while( ArgParse( &pargs, &opts) ) { - * switch( pargs.r_opt ) { - * case 'v': opt.verbose++; break; - * case 'd': opt.debug++; break; - * case 'o': opt.outfile = pargs.r.ret_str; break; - * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - * case 500: opt.a_long_one++; break - * default : pargs.err = 1; break; -- force warning output -- - * } - * } - * if( argc > 1 ) - * log_fatal( "Too many args"); - * - */ - -typedef struct alias_def_s *ALIAS_DEF; -struct alias_def_s { - ALIAS_DEF next; - char *name; /* malloced buffer with name, \0, value */ - const char *value; /* ptr into name */ -}; - -static const char *(*strusage_handler)( int ) = NULL; - -static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); -static void show_help(ARGPARSE_OPTS *opts, unsigned flags); -static void show_version(void); - - -static void -initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) -{ - if( !(arg->flags & (1<<15)) ) { /* initialize this instance */ - arg->internal.idx = 0; - arg->internal.last = NULL; - arg->internal.inarg = 0; - arg->internal.stopped = 0; - arg->internal.aliases = NULL; - arg->internal.cur_alias = NULL; - arg->err = 0; - arg->flags |= 1<<15; /* mark initialized */ - if( *arg->argc < 0 ) - jnlib_log_bug("Invalid argument for ArgParse\n"); - } - - - if( arg->err ) { /* last option was erroneous */ - const char *s; - - if( filename ) { - if( arg->r_opt == -6 ) - s = "argument not expected\n"; - else if( arg->r_opt == -5 ) - s = "read error\n"; - else if( arg->r_opt == -4 ) - s = "keyword too long\n"; - else if( arg->r_opt == -3 ) - s = "missing argument\n"; - else if( arg->r_opt == -7 ) - s = "invalid command\n"; - else if( arg->r_opt == -10 ) - s = "invalid alias definition\n"; - else - s = "invalid option\n"; - jnlib_log_error("%s:%u: %s\n", filename, *lineno, s); - } - else { - s = arg->internal.last? arg->internal.last:"[??]"; - - if( arg->r_opt == -3 ) - jnlib_log_error ("Missing argument for option \"%.50s\"\n", s); - else if( arg->r_opt == -6 ) - jnlib_log_error ("Option \"%.50s\" does not expect an argument\n", - s ); - else if( arg->r_opt == -7 ) - jnlib_log_error ("Invalid command \"%.50s\"\n", s); - else if( arg->r_opt == -8 ) - jnlib_log_error ("Option \"%.50s\" is ambiguous\n", s); - else if( arg->r_opt == -9 ) - jnlib_log_error ("Command \"%.50s\" is ambiguous\n",s ); - else - jnlib_log_error ("Invalid option \"%.50s\"\n", s); - } - if( arg->err != 1 ) - exit(2); - arg->err = 0; - } - - /* clearout the return value union */ - arg->r.ret_str = NULL; - arg->r.ret_long= 0; -} - - -static void -store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) -{ - /* TODO: replace this dummy function with a rea one - * and fix the probelms IRIX has with (ALIAS_DEV)arg.. - * used as lvalue - */ -#if 0 - ALIAS_DEF a = jnlib_xmalloc( sizeof *a ); - a->name = name; - a->value = value; - a->next = (ALIAS_DEF)arg->internal.aliases; - (ALIAS_DEF)arg->internal.aliases = a; -#endif -} - -/**************** - * Get options from a file. - * Lines starting with '#' are comment lines. - * Syntax is simply a keyword and the argument. - * Valid keywords are all keywords from the long_opt list without - * the leading dashes. The special keywords "help", "warranty" and "version" - * are not valid here. - * The special keyword "alias" may be used to store alias definitions, - * which are later expanded like long options. - * Caller must free returned strings. - * If called with FP set to NULL command line args are parse instead. - * - * Q: Should we allow the syntax - * keyword = value - * and accept for boolean options a value of 1/0, yes/no or true/false? - * Note: Abbreviation of options is here not allowed. - */ -int -optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int state, i, c; - int idx=0; - char keyword[100]; - char *buffer = NULL; - size_t buflen = 0; - int inverse=0; - int in_alias=0; - - if( !fp ) /* same as arg_parse() in this case */ - return arg_parse( arg, opts ); - - initialize( arg, filename, lineno ); - - /* find the next keyword */ - state = i = 0; - for(;;) { - c=getc(fp); - if( c == '\n' || c== EOF ) { - if( c != EOF ) - ++*lineno; - if( state == -1 ) - break; - else if( state == 2 ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( inverse ) /* this does not have an effect, hmmm */ - arg->r_opt = -arg->r_opt; - if( !opts[idx].short_opt ) /* unknown command/option */ - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* argument is optional */ - arg->r_type = 0; /* okay */ - else /* required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 3 ) { /* no argument found */ - if( in_alias ) - arg->r_opt = -3; /* error */ - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* no optional argument */ - arg->r_type = 0; /* okay */ - else /* no required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 4 ) { /* have an argument */ - if( in_alias ) { - if( !buffer ) - arg->r_opt = -6; - else { - char *p; - - buffer[i] = 0; - p = strpbrk( buffer, " \t" ); - if( p ) { - *p++ = 0; - trim_spaces( p ); - } - if( !p || !*p ) { - jnlib_free( buffer ); - arg->r_opt = -10; - } - else { - store_alias( arg, buffer, p ); - } - } - } - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_opt = -6; /* error */ - else { - char *p; - if( !buffer ) { - keyword[i] = 0; - buffer = jnlib_xstrdup(keyword); - } - else - buffer[i] = 0; - - trim_spaces( buffer ); - p = buffer; - if( *p == '"' ) { /* remove quotes */ - p++; - if( *p && p[strlen(p)-1] == '"' ) - p[strlen(p)-1] = 0; - } - if( !set_opt_arg(arg, opts[idx].flags, p) ) - jnlib_free(buffer); - } - break; - } - else if( c == EOF ) { - if( ferror(fp) ) - arg->r_opt = -5; /* read error */ - else - arg->r_opt = 0; /* eof */ - break; - } - state = 0; - i = 0; - } - else if( state == -1 ) - ; /* skip */ - else if( !state && isspace(c) ) - ; /* skip leading white space */ - else if( !state && c == '#' ) - state = 1; /* start of a comment */ - else if( state == 1 ) - ; /* skip comments */ - else if( state == 2 && isspace(c) ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( !opts[idx].short_opt ) { - if( !strcmp( keyword, "alias" ) ) { - in_alias = 1; - state = 3; - } - else { - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - state = -1; /* skip rest of line and leave */ - } - } - else - state = 3; - } - else if( state == 3 ) { /* skip leading spaces of the argument */ - if( !isspace(c) ) { - i = 0; - keyword[i++] = c; - state = 4; - } - } - else if( state == 4 ) { /* collect the argument */ - if( buffer ) { - if( i < buflen-1 ) - buffer[i++] = c; - else { - buflen += 50; - buffer = jnlib_xrealloc(buffer, buflen); - buffer[i++] = c; - } - } - else if( i < DIM(keyword)-1 ) - keyword[i++] = c; - else { - buflen = DIM(keyword)+50; - buffer = jnlib_xmalloc(buflen); - memcpy(buffer, keyword, i); - buffer[i++] = c; - } - } - else if( i >= DIM(keyword)-1 ) { - arg->r_opt = -4; /* keyword to long */ - state = -1; /* skip rest of line and leave */ - } - else { - keyword[i++] = c; - state = 2; - } - } - - return arg->r_opt; -} - - - -static int -find_long_option( ARGPARSE_ARGS *arg, - ARGPARSE_OPTS *opts, const char *keyword ) -{ - int i; - size_t n; - - /* Would be better if we can do a binary search, but it is not - possible to reorder our option table because we would mess - up our help strings - What we can do is: Build a nice option - lookup table wehn this function is first invoked */ - if( !*keyword ) - return -1; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - return i; - #if 0 - { - ALIAS_DEF a; - /* see whether it is an alias */ - for( a = args->internal.aliases; a; a = a->next ) { - if( !strcmp( a->name, keyword) ) { - /* todo: must parse the alias here */ - args->internal.cur_alias = a; - return -3; /* alias available */ - } - } - } - #endif - /* not found, see whether it is an abbreviation */ - /* aliases may not be abbreviated */ - n = strlen( keyword ); - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) { - int j; - for(j=i+1; opts[j].short_opt; j++ ) { - if( opts[j].long_opt - && !strncmp( opts[j].long_opt, keyword, n ) ) - return -2; /* abbreviation is ambiguous */ - } - return i; - } - } - return -1; -} - -int -arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int idx; - int argc; - char **argv; - char *s, *s2; - int i; - - initialize( arg, NULL, NULL ); - argc = *arg->argc; - argv = *arg->argv; - idx = arg->internal.idx; - - if( !idx && argc && !(arg->flags & (1<<4)) ) { /* skip the first entry */ - argc--; argv++; idx++; - } - - next_one: - if( !argc ) { /* no more args */ - arg->r_opt = 0; - goto leave; /* ready */ - } - - s = *argv; - arg->internal.last = s; - - if( arg->internal.stopped && (arg->flags & (1<<1)) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else if( arg->internal.stopped ) { /* ready */ - arg->r_opt = 0; - goto leave; - } - else if( *s == '-' && s[1] == '-' ) { /* long option */ - char *argpos; - - arg->internal.inarg = 0; - if( !s[2] && !(arg->flags & (1<<3)) ) { /* stop option processing */ - arg->internal.stopped = 1; - argc--; argv++; idx++; - goto next_one; - } - - argpos = strchr( s+2, '=' ); - if( argpos ) - *argpos = 0; - i = find_long_option( arg, opts, s+2 ); - if( argpos ) - *argpos = '='; - - if( i < 0 && !strcmp( "help", s+2) ) - show_help(opts, arg->flags); - else if( i < 0 && !strcmp( "version", s+2) ) { - if( !(arg->flags & (1<<6)) ) { - show_version(); - exit(0); - } - } - else if( i < 0 && !strcmp( "warranty", s+2) ) { - puts( strusage(16) ); - exit(0); - } - else if( i < 0 && !strcmp( "dump-options", s+2) ) { - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - printf( "--%s\n", opts[i].long_opt ); - } - fputs("--dump-options\n--help\n--version\n--warranty\n", stdout ); - exit(0); - } - - if( i == -2 ) /* ambiguous option */ - arg->r_opt = -8; - else if( i == -1 ) { - arg->r_opt = -2; - arg->r.ret_str = s+2; - } - else - arg->r_opt = opts[i].short_opt; - if( i < 0 ) - ; - else if( (opts[i].flags & 7) ) { - if( argpos ) { - s2 = argpos+1; - if( !*s2 ) - s2 = NULL; - } - else - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - if( !argpos ) { - argc--; argv++; idx++; /* skip one */ - } - } - } - else { /* does not take an argument */ - if( argpos ) - arg->r_type = -6; /* argument not expected */ - else - arg->r_type = 0; - } - argc--; argv++; idx++; /* set to next one */ - } - else if( (*s == '-' && s[1]) || arg->internal.inarg ) { /* short option */ - int dash_kludge = 0; - i = 0; - if( !arg->internal.inarg ) { - arg->internal.inarg++; - if( arg->flags & (1<<5) ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, s+1)) { - dash_kludge=1; - break; - } - } - } - s += arg->internal.inarg; - - if( !dash_kludge ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].short_opt == *s ) - break; - } - - if( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) ) - show_help(opts, arg->flags); - - arg->r_opt = opts[i].short_opt; - if( !opts[i].short_opt ) { - arg->r_opt = (opts[i].flags & 256)? -7:-2; - arg->internal.inarg++; /* point to the next arg */ - arg->r.ret_str = s; - } - else if( (opts[i].flags & 7) ) { - if( s[1] && !dash_kludge ) { - s2 = s+1; - set_opt_arg(arg, opts[i].flags, s2); - } - else { - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( *s2 == '-' && s2[1] && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - argc--; argv++; idx++; /* skip one */ - } - } - s = "x"; /* so that !s[1] yields false */ - } - else { /* does not take an argument */ - arg->r_type = 0; - arg->internal.inarg++; /* point to the next arg */ - } - if( !s[1] || dash_kludge ) { /* no more concatenated short options */ - arg->internal.inarg = 0; - argc--; argv++; idx++; - } - } - else if( arg->flags & (1<<2) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else { - arg->internal.stopped = 1; /* stop option processing */ - goto next_one; - } - - leave: - *arg->argc = argc; - *arg->argv = argv; - arg->internal.idx = idx; - return arg->r_opt; -} - - - -static int -set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s) -{ - int base = (flags & 16)? 0 : 10; - - switch( arg->r_type = (flags & 7) ) { - case 1: /* takes int argument */ - arg->r.ret_int = (int)strtol(s,NULL,base); - return 0; - case 3: /* takes long argument */ - arg->r.ret_long= strtol(s,NULL,base); - return 0; - case 4: /* takes ulong argument */ - arg->r.ret_ulong= strtoul(s,NULL,base); - return 0; - case 2: /* takes string argument */ - default: - arg->r.ret_str = s; - return 1; - } -} - - -static size_t -long_opt_strlen( ARGPARSE_OPTS *o ) -{ - size_t n = strlen(o->long_opt); - - if( o->description && *o->description == '|' ) { - const char *s; - - s=o->description+1; - if( *s != '=' ) - n++; - for(; *s && *s != '|'; s++ ) - n++; - } - return n; -} - -/**************** - * Print formatted help. The description string has some special - * meanings: - * - A description string which is "@" suppresses help output for - * this option - * - a description,ine which starts with a '@' and is followed by - * any other characters is printed as is; this may be used for examples - * ans such. - * - A description which starts with a '|' outputs the string between this - * bar and the next one as arguments of the long option. - */ -static void -show_help( ARGPARSE_OPTS *opts, unsigned flags ) -{ - const char *s; - - show_version(); - putchar('\n'); - s = strusage(41); - puts(s); - if( opts[0].description ) { /* auto format the option description */ - int i,j, indent; - /* get max. length of long options */ - for(i=indent=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - if( !opts[i].description || *opts[i].description != '@' ) - if( (j=long_opt_strlen(opts+i)) > indent && j < 35 ) - indent = j; - } - /* example: " -v, --verbose Viele Sachen ausgeben" */ - indent += 10; - if( *opts[0].description != '@' ) - puts("Options:"); - for(i=0; opts[i].short_opt; i++ ) { - s = _( opts[i].description ); - if( s && *s== '@' && !s[1] ) /* hide this line */ - continue; - if( s && *s == '@' ) { /* unindented comment only line */ - for(s++; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) - putchar('\n'); - } - else - putchar(*s); - } - putchar('\n'); - continue; - } - - j = 3; - if( opts[i].short_opt < 256 ) { - printf(" -%c", opts[i].short_opt ); - if( !opts[i].long_opt ) { - if(s && *s == '|' ) { - putchar(' '); j++; - for(s++ ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - } - } - else - fputs(" ", stdout); - if( opts[i].long_opt ) { - j += printf("%c --%s", opts[i].short_opt < 256?',':' ', - opts[i].long_opt ); - if(s && *s == '|' ) { - if( *++s != '=' ) { - putchar(' '); - j++; - } - for( ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - fputs(" ", stdout); - j += 3; - } - for(;j < indent; j++ ) - putchar(' '); - if( s ) { - if( *s && j > indent ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - for(; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - } - else - putchar(*s); - } - } - putchar('\n'); - } - if( flags & 32 ) - puts("\n(A single dash may be used instead of the double ones)"); - } - if( (s=strusage(19)) ) { /* bug reports to ... */ - putchar('\n'); - fputs(s, stdout); - } - fflush(stdout); - exit(0); -} - -static void -show_version() -{ - const char *s; - int i; - /* version line */ - fputs(strusage(11), stdout); - if( (s=strusage(12)) ) - printf(" (%s)", s ); - printf(" %s\n", strusage(13) ); - /* additional version lines */ - for(i=20; i < 30; i++ ) - if( (s=strusage(i)) ) - printf("%s\n", s ); - /* copyright string */ - if( (s=strusage(14)) ) - printf("%s\n", s ); - /* copying conditions */ - if( (s=strusage(15)) ) - fputs(s, stdout); - /* thanks */ - if( (s=strusage(18)) ) - fputs(s, stdout); - /* additional program info */ - for(i=30; i < 40; i++ ) - if( (s=strusage(i)) ) - fputs( (const byte*)s, stdout); - fflush(stdout); -} - - -void -usage( int level ) -{ - if( !level ) { - fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), - strusage(14) ); - fflush(stderr); - } - else if( level == 1 ) { - fputs(strusage(40),stderr); - exit(2); - } - else if( level == 2 ) { - puts(strusage(41)); - exit(0); - } -} - -/* Level - * 0: Copyright String auf stderr ausgeben - * 1: Kurzusage auf stderr ausgeben und beenden - * 2: Langusage auf stdout ausgeben und beenden - * 11: name of program - * 12: optional name of package which includes this program. - * 13: version string - * 14: copyright string - * 15: Short copying conditions (with LFs) - * 16: Long copying conditions (with LFs) - * 17: Optional printable OS name - * 18: Optional thanks list (with LFs) - * 19: Bug report info - *20..29: Additional lib version strings. - *30..39: Additional program info (with LFs) - * 40: short usage note (with LF) - * 41: long usage note (with LF) - */ -const char * -strusage( int level ) -{ - const char *p = strusage_handler? strusage_handler(level) : NULL; - - if( p ) - return p; - - switch( level ) { - case 11: p = "foo"; break; - case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2004 Free Software Foundation, Inc."; break; - case 15: p = -"This program comes with ABSOLUTELY NO WARRANTY.\n" -"This is free software, and you are welcome to redistribute it\n" -"under certain conditions. See the file COPYING for details.\n"; break; - case 16: p = -"This is free software; you can redistribute it and/or modify\n" -"it under the terms of the GNU General Public License as published by\n" -"the Free Software Foundation; either version 2 of the License, or\n" -"(at your option) any later version.\n\n" -"It is distributed in the hope that it will be useful,\n" -"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" -"GNU General Public License for more details.\n\n" -"You should have received a copy of the GNU General Public License\n" -"along with this program; if not, write to the Free Software\n" -"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; - break; - case 40: /* short and long usage */ - case 41: p = ""; break; - } - - return p; -} - -void -set_strusage( const char *(*f)( int ) ) -{ - strusage_handler = f; -} - - -#ifdef TEST -static struct { - int verbose; - int debug; - char *outfile; - char *crf; - int myopt; - int echo; - int a_long_one; -}opt; - -int -main(int argc, char **argv) -{ - ARGPARSE_OPTS opts[] = { - { 'v', "verbose", 0 , "Laut sein"}, - { 'e', "echo" , 0 , "Zeile ausgeben, damit wir sehen, was wir einegegeben haben"}, - { 'd', "debug", 0 , "Debug\nfalls mal etasws\nSchief geht"}, - { 'o', "output", 2 }, - { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" }, - { 'm', "my-option", 1|8 }, - { 500, "a-long-option", 0 }, - {0} }; - ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 }; - int i; - - while( ArgParse( &pargs, opts) ) { - switch( pargs.r_opt ) { - case -1 : printf( "arg=`%s'\n", pargs.r.ret_str); break; - case 'v': opt.verbose++; break; - case 'e': opt.echo++; break; - case 'd': opt.debug++; break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - case 500: opt.a_long_one++; break; - default : pargs.err = 1; break; /* force warning output */ - } - } - for(i=0; i < argc; i++ ) - printf("%3d -> (%s)\n", i, argv[i] ); - puts("Options:"); - if( opt.verbose ) - printf(" verbose=%d\n", opt.verbose ); - if( opt.debug ) - printf(" debug=%d\n", opt.debug ); - if( opt.outfile ) - printf(" outfile=`%s'\n", opt.outfile ); - if( opt.crf ) - printf(" crffile=`%s'\n", opt.crf ); - if( opt.myopt ) - printf(" myopt=%d\n", opt.myopt ); - if( opt.a_long_one ) - printf(" a-long-one=%d\n", opt.a_long_one ); - if( opt.echo ) - printf(" echo=%d\n", opt.echo ); - return 0; -} -#endif - -/**** bottom of file ****/ diff --git a/jnlib/argparse.h b/jnlib/argparse.h deleted file mode 100644 index e8922faa4..000000000 --- a/jnlib/argparse.h +++ /dev/null @@ -1,67 +0,0 @@ -/* argparse.h - * Copyright (C) 1998,1999,2000,2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_ARGPARSE_H -#define LIBJNLIB_ARGPARSE_H - -#include <stdio.h> -#include "types.h" - -typedef struct { - int *argc; /* pointer to argc (value subject to change) */ - char ***argv; /* pointer to argv (value subject to change) */ - unsigned flags; /* Global flags (DO NOT CHANGE) */ - int err; /* print error about last option */ - /* 1 = warning, 2 = abort */ - int r_opt; /* return option */ - int r_type; /* type of return value (0 = no argument found)*/ - union { - int ret_int; - long ret_long; - unsigned long ret_ulong; - char *ret_str; - } r; /* Return values */ - struct { - int idx; - int inarg; - int stopped; - const char *last; - void *aliases; - const void *cur_alias; - } internal; /* DO NOT CHANGE */ -} ARGPARSE_ARGS; - -typedef struct { - int short_opt; - const char *long_opt; - unsigned flags; - const char *description; /* optional option description */ -} ARGPARSE_OPTS; - - - -int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); -void usage( int level ); -const char *strusage( int level ); -void set_strusage( const char *(*f)( int ) ); - -#endif /*LIBJNLIB_ARGPARSE_H*/ diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c deleted file mode 100644 index a50a0ee99..000000000 --- a/jnlib/dotlock.c +++ /dev/null @@ -1,436 +0,0 @@ -/* dotlock.c - dotfile locking - * Copyright (C) 1998,2000,2001,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <errno.h> -#include <unistd.h> -#ifndef HAVE_DOSISH_SYSTEM -#include <sys/utsname.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <signal.h> - -#include "libjnlib-config.h" -#include "dotlock.h" - -#if !defined(DIRSEP_C) && !defined(EXTSEP_C) \ - && !defined(DIRSEP_S) && !defined(EXTSEP_S) -#ifdef HAVE_DOSISH_SYSTEM -#define DIRSEP_C '\\' -#define EXTSEP_C '.' -#define DIRSEP_S "\\" -#define EXTSEP_S "." -#else -#define DIRSEP_C '/' -#define EXTSEP_C '.' -#define DIRSEP_S "/" -#define EXTSEP_S "." -#endif -#endif - - -struct dotlock_handle { - struct dotlock_handle *next; - char *tname; /* name of lockfile template */ - char *lockname; /* name of the real lockfile */ - int locked; /* lock status */ - int disable; /* locking */ -}; - - -static volatile DOTLOCK all_lockfiles; -static int never_lock; - -static int read_lockfile( const char *name ); - -void -disable_dotlock(void) -{ - never_lock = 1; -} - -/**************** - * Create a lockfile with the given name and return an object of - * type DOTLOCK which may be used later to actually do the lock. - * A cleanup routine gets installed to cleanup left over locks - * or other files used together with the lockmechanism. - * Althoug the function is called dotlock, this does not necessarily - * mean that real lockfiles are used - the function may decide to - * use fcntl locking. Calling the function with NULL only install - * the atexit handler and maybe used to assure that the cleanup - * is called after all other atexit handlers. - * - * Notes: This function creates a lock file in the same directory - * as file_to_lock with the name "file_to_lock.lock" - * A temporary file ".#lk.<hostname>.pid[.threadid] is used. - * This function does nothing for Windoze. - */ -DOTLOCK -create_dotlock( const char *file_to_lock ) -{ - static int initialized; - DOTLOCK h; - int fd = -1; - char pidstr[16]; - #ifndef HAVE_DOSISH_SYSTEM - struct utsname utsbuf; - #endif - const char *nodename; - const char *dirpart; - int dirpartlen; - - if( !initialized ) { - atexit( dotlock_remove_lockfiles ); - initialized = 1; - } - if( !file_to_lock ) - return NULL; - - h = jnlib_xcalloc( 1, sizeof *h ); - if( never_lock ) { - h->disable = 1; -#ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ -#endif - h->next = all_lockfiles; - all_lockfiles = h; - return h; - } - -#ifndef HAVE_DOSISH_SYSTEM - sprintf( pidstr, "%10d\n", (int)getpid() ); - /* fixme: add the hostname to the second line (FQDN or IP addr?) */ - - /* create a temporary file */ - if( uname( &utsbuf ) ) - nodename = "unknown"; - else - nodename = utsbuf.nodename; - -#ifdef __riscos__ - { - char *iter = (char *) nodename; - for (; iter[0]; iter++) - if (iter[0] == '.') - iter[0] = '/'; - } -#endif /* __riscos__ */ - - if( !(dirpart = strrchr( file_to_lock, DIRSEP_C )) ) { - dirpart = EXTSEP_S; - dirpartlen = 1; - } - else { - dirpartlen = dirpart - file_to_lock; - dirpart = file_to_lock; - } - - #ifdef _REENTRANT - /* fixme: aquire mutex on all_lockfiles */ - #endif - h->next = all_lockfiles; - all_lockfiles = h; - - h->tname = jnlib_xmalloc( dirpartlen + 6+30+ strlen(nodename) + 11 ); -#ifndef __riscos__ - sprintf( h->tname, "%.*s/.#lk%p.%s.%d", - dirpartlen, dirpart, h, nodename, (int)getpid() ); -#else /* __riscos__ */ - sprintf( h->tname, "%.*s.lk%p/%s/%d", - dirpartlen, dirpart, h, nodename, (int)getpid() ); -#endif /* __riscos__ */ - - do { - errno = 0; - fd = open( h->tname, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR ); - } while( fd == -1 && errno == EINTR ); - if( fd == -1 ) { - all_lockfiles = h->next; - log_error( "failed to create temporary file `%s': %s\n", - h->tname, strerror(errno)); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - if( write(fd, pidstr, 11 ) != 11 ) { - all_lockfiles = h->next; - #ifdef _REENTRANT - /* release mutex */ - #endif - log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - if( close(fd) ) { - all_lockfiles = h->next; - #ifdef _REENTRANT - /* release mutex */ - #endif - log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h); - return NULL; - } - - #ifdef _REENTRANT - /* release mutex */ - #endif -#endif /* !HAVE_DOSISH_SYSTEM */ - h->lockname = jnlib_xmalloc( strlen(file_to_lock) + 6 ); - strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); - return h; -} - -static int -maybe_deadlock( DOTLOCK h ) -{ - DOTLOCK r; - - for( r=all_lockfiles; r; r = r->next ) { - if( r != h && r->locked ) - return 1; - } - return 0; -} - -/**************** - * Do a lock on H. A TIMEOUT of 0 returns immediately, - * -1 waits forever (hopefully not), other - * values are timeouts in milliseconds. - * Returns: 0 on success - */ -int -make_dotlock( DOTLOCK h, long timeout ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int pid; - const char *maybe_dead=""; - int backoff=0; - - if( h->disable ) { - return 0; - } - - if( h->locked ) { -#ifndef __riscos__ - log_debug("oops, `%s' is already locked\n", h->lockname ); -#endif /* !__riscos__ */ - return 0; - } - - for(;;) { -#ifndef __riscos__ - if( !link(h->tname, h->lockname) ) { - /* fixme: better use stat to check the link count */ - h->locked = 1; - return 0; /* okay */ - } - if( errno != EEXIST ) { - log_error( "lock not made: link() failed: %s\n", strerror(errno) ); - return -1; - } -#else /* __riscos__ */ - if( !renamefile(h->tname, h->lockname) ) { - h->locked = 1; - return 0; /* okay */ - } - if( errno != EEXIST ) { - log_error( "lock not made: rename() failed: %s\n", strerror(errno) ); - return -1; - } -#endif /* __riscos__ */ - if( (pid = read_lockfile(h->lockname)) == -1 ) { - if( errno != ENOENT ) { - log_info("cannot read lockfile\n"); - return -1; - } - log_info( "lockfile disappeared\n"); - continue; - } - else if( pid == getpid() ) { - log_info( "Oops: lock already held by us\n"); - h->locked = 1; - return 0; /* okay */ - } - else if( kill(pid, 0) && errno == ESRCH ) { -#ifndef __riscos__ - maybe_dead = " - probably dead"; -#if 0 /* we should not do this without checking the permissions */ - /* and the hostname */ - log_info( "removing stale lockfile (created by %d)", pid ); -#endif -#else /* __riscos__ */ - /* we are *pretty* sure that the other task is dead and therefore - we remove the other lock file */ - maybe_dead = " - probably dead - removing lock"; - unlink(h->lockname); -#endif /* __riscos__ */ - } - if( timeout == -1 ) { - struct timeval tv; - log_info( "waiting for lock (held by %d%s) %s...\n", - pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); - - - /* can't use sleep, cause signals may be blocked */ - tv.tv_sec = 1 + backoff; - tv.tv_usec = 0; - select(0, NULL, NULL, NULL, &tv); - if( backoff < 10 ) - backoff++ ; - } - else - return -1; - } - /*not reached */ -#endif /* !HAVE_DOSISH_SYSTEM */ -} - - -/**************** - * release a lock - * Returns: 0 := success - */ -int -release_dotlock( DOTLOCK h ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int pid; - - if( h->disable ) { - return 0; - } - - if( !h->locked ) { - log_debug("oops, `%s' is not locked\n", h->lockname ); - return 0; - } - - pid = read_lockfile( h->lockname ); - if( pid == -1 ) { - log_error( "release_dotlock: lockfile error\n"); - return -1; - } - if( pid != getpid() ) { - log_error( "release_dotlock: not our lock (pid=%d)\n", pid); - return -1; - } -#ifndef __riscos__ - if( unlink( h->lockname ) ) { - log_error( "release_dotlock: error removing lockfile `%s'", - h->lockname); - return -1; - } -#else /* __riscos__ */ - if( renamefile(h->lockname, h->tname) ) { - log_error( "release_dotlock: error renaming lockfile `%s' to `%s'", - h->lockname, h->tname); - return -1; - } -#endif /* __riscos__ */ - /* fixme: check that the link count is now 1 */ - h->locked = 0; - return 0; -#endif /* !HAVE_DOSISH_SYSTEM */ -} - - -/**************** - * Read the lock file and return the pid, returns -1 on error. - */ -static int -read_lockfile( const char *name ) -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else - int fd, pid; - char pidstr[16]; - - if( (fd = open(name, O_RDONLY)) == -1 ) { - int e = errno; - log_debug("error opening lockfile `%s': %s\n", name, strerror(errno) ); - errno = e; - return -1; - } - if( read(fd, pidstr, 10 ) != 10 ) { /* Read 10 digits w/o newline */ - log_debug("error reading lockfile `%s'", name ); - close(fd); - errno = 0; - return -1; - } - pidstr[10] = 0; /* terminate pid string */ - close(fd); - pid = atoi(pidstr); -#ifndef __riscos__ - if( !pid || pid == -1 ) { -#else /* __riscos__ */ - if( (!pid && riscos_getpid()) || pid == -1 ) { -#endif /* __riscos__ */ - log_error("invalid pid %d in lockfile `%s'", pid, name ); - errno = 0; - return -1; - } - return pid; -#endif -} - - -void -dotlock_remove_lockfiles() -{ -#ifndef HAVE_DOSISH_SYSTEM - DOTLOCK h, h2; - - h = all_lockfiles; - all_lockfiles = NULL; - - while( h ) { - h2 = h->next; - if (!h->disable ) { - if( h->locked ) - unlink( h->lockname ); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h->lockname); - } - jnlib_free(h); - h = h2; - } -#endif -} - diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h deleted file mode 100644 index 9235687df..000000000 --- a/jnlib/dotlock.h +++ /dev/null @@ -1,36 +0,0 @@ -/* dotlock.h - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_DOTLOCK_H -#define LIBJNLIB_DOTLOCK_H - -struct dotlock_handle; -typedef struct dotlock_handle *DOTLOCK; - -void disable_dotlock (void); -DOTLOCK create_dotlock(const char *file_to_lock); -int make_dotlock (DOTLOCK h, long timeout); -int release_dotlock (DOTLOCK h); -void dotlock_remove_lockfiles (void); - -#endif /*LIBJNLIB_DOTLOCK_H*/ - - - diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h deleted file mode 100644 index ad7e353fd..000000000 --- a/jnlib/libjnlib-config.h +++ /dev/null @@ -1,72 +0,0 @@ -/* libjnlib-config.h - local configuration of the jnlib functions - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/**************** - * This header is to be included only by the files in this directory - * it should not be used by other modules. - */ - -#ifndef LIBJNLIB_CONFIG_H -#define LIBJNLIB_CONFIG_H - -#include <gcrypt.h> /* gcry_malloc & Cie. */ -#include "logging.h" - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); - - #define _(a) gettext (a) - #define N_(a) (a) - -#else -#ifdef HAVE_LOCALE_H - #include <locale.h> -#endif - -#ifdef ENABLE_NLS - #include <libintl.h> - #define _(a) gettext (a) - #ifdef gettext_noop - #define N_(a) gettext_noop (a) - #else - #define N_(a) (a) - #endif -#else - #define _(a) (a) - #define N_(a) (a) -#endif -#endif /* !USE_SIMPLE_GETTEXT */ - - -#define jnlib_xmalloc(a) gcry_xmalloc( (a) ) -#define jnlib_xcalloc(a,b) gcry_xcalloc( (a), (b) ) -#define jnlib_xrealloc(a,n) gcry_xrealloc( (a), (n) ) -#define jnlib_xstrdup(a) gcry_xstrdup( (a) ) -#define jnlib_free(a) gcry_free( (a) ) - -#define jnlib_log_debug log_debug -#define jnlib_log_info log_info -#define jnlib_log_error log_error -#define jnlib_log_fatal log_fatal -#define jnlib_log_bug log_bug - - -#endif /*LIBJNUTIL_CONFIG_H*/ diff --git a/jnlib/logging.c b/jnlib/logging.c deleted file mode 100644 index c75efaf85..000000000 --- a/jnlib/logging.c +++ /dev/null @@ -1,558 +0,0 @@ -/* logging.c - useful logging functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* This file should replace logger.c in the future - for now it is not - * used by GnuPG but by GPA. - * It is a quite simple implemenation but sufficient for most purposes. - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stddef.h> -#include <errno.h> -#include <time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#ifdef __MINGW32__ -# include <io.h> -#endif - -#define JNLIB_NEED_LOG_LOGV 1 -#include "libjnlib-config.h" -#include "logging.h" - - -static FILE *logstream; -static int log_socket = -1; -static char prefix_buffer[80]; -static int with_time; -static int with_prefix; -static int with_pid; -static int running_detached; -static int force_prefixes; - -static int missing_lf; -static int errorcount; - -#if 0 -static void -write2stderr( const char *s ) -{ - write( 2, s, strlen(s) ); -} - - -static void -do_die(int rc, const char *text ) -{ - write2stderr("\nFatal error: "); - write2stderr(text); - write2stderr("\n"); - abort(); -} -#endif - -int -log_get_errorcount (int clear) -{ - int n = errorcount; - if( clear ) - errorcount = 0; - return n; -} - -void -log_inc_errorcount (void) -{ - errorcount++; -} - - -/* The follwing 3 functions are used by funopen to write logs to a - socket. */ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) -struct fun_cookie_s { - int fd; - int quiet; - char name[1]; -}; - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const unsigned char *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { - nwritten = write (fd, buf, nleft); - if (nwritten < 0 && errno == EINTR) - continue; - if (nwritten < 0) - return -1; - nleft -= nwritten; - buf = buf + nwritten; - } - - return 0; -} - - -static int -fun_writer (void *cookie_arg, const char *buffer, size_t size) -{ - struct fun_cookie_s *cookie = cookie_arg; - - /* Note that we always try to reconnect to the socket but print - error messages only the first time an error occured. IF - RUNNING_DETACHED is set we don't fall back to stderr and even do - not print any error messages. This is needed becuase detached - processes often close stderr and my printing to fiel descriptor 2 - we might send the log message to a file not intended for logging - (e.g. a pipe or network connection). */ - if (cookie->fd == -1) - { - /* Note yet open or meanwhile closed due to an error. */ - struct sockaddr_un addr; - size_t addrlen; - - cookie->fd = socket (PF_LOCAL, SOCK_STREAM, 0); - if (cookie->fd == -1) - { - if (!cookie->quiet && !running_detached) - fprintf (stderr, "failed to create socket for logging: %s\n", - strerror(errno)); - goto failure; - } - log_socket = cookie->fd; - - memset (&addr, 0, sizeof addr); - addr.sun_family = PF_LOCAL; - strncpy (addr.sun_path, cookie->name, sizeof (addr.sun_path)-1); - addr.sun_path[sizeof (addr.sun_path)-1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (addr.sun_path) + 1); - - if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) - { - log_socket = -1; - if (!cookie->quiet && !running_detached) - fprintf (stderr, "can't connect to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; - goto failure; - } - /* Connection established. */ - cookie->quiet = 0; - } - - if (!writen (cookie->fd, buffer, size)) - return size; /* Okay. */ - - log_socket = -1; - if (!running_detached) - fprintf (stderr, "error writing to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; - - failure: - if (!running_detached) - { - if (!cookie->quiet) - { - fputs ("switching logging to stderr\n", stderr); - cookie->quiet = 1; - } - - fwrite (buffer, size, 1, stderr); - } - return size; -} - -static int -fun_closer (void *cookie_arg) -{ - struct fun_cookie_s *cookie = cookie_arg; - - if (cookie->fd != -1) - close (cookie->fd); - jnlib_free (cookie); - return 0; -} -#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */ - - - - -/* Set the file to write log to. The special names NULL and "-" may - be used to select stderr and names formatted like - "socket:///home/foo/mylogs" may be used to write the logging to the - socket "/home/foo/mylogs". If the connection to the socket fails - or a write error is detected, the function writes to stderr and - tries the next time again to connect the socket. - */ -void -log_set_file (const char *name) -{ - FILE *fp; - - force_prefixes = 0; - if (name && !strncmp (name, "socket://", 9) && name[9]) - { -#if defined (HAVE_FOPENCOOKIE)|| defined (HAVE_FUNOPEN) - struct fun_cookie_s *cookie; - - cookie = jnlib_xmalloc (sizeof *cookie + strlen (name+9)); - cookie->fd = -1; - cookie->quiet = 0; - strcpy (cookie->name, name+9); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = fun_writer; - io.close = fun_closer; - - fp = fopencookie (cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (cookie, NULL, fun_writer, NULL, fun_closer); - } -#endif /*!HAVE_FOPENCOOKIE*/ -#else /* Neither fopencookie nor funopen. */ - { - fprintf (stderr, "system does not support logging to a socket - " - "using stderr\n"); - fp = stderr; - } -#endif /* Neither fopencookie nor funopen. */ - - /* We always need to print the prefix and the pid, so that the - server reading the socket can do something meanigful. */ - force_prefixes = 1; - /* On success close the old logstream right now, so that we are - really sure it has been closed. */ - if (fp && logstream) - { - fclose (logstream); - logstream = NULL; - } - } - else - fp = (name && strcmp(name,"-"))? fopen (name, "a") : stderr; - if (!fp) - { - fprintf (stderr, "failed to open log file `%s': %s\n", - name? name:"[stderr]", strerror(errno)); - return; - } - setvbuf (fp, NULL, _IOLBF, 0); - - if (logstream && logstream != stderr && logstream != stdout) - fclose (logstream); - logstream = fp; - missing_lf = 0; -} - - -void -log_set_fd (int fd) -{ - FILE *fp; - - force_prefixes = 0; - if (fd == 1) - fp = stdout; - else if (fd == 2) - fp = stderr; - else - fp = fdopen (fd, "a"); - if (!fp) - { - fprintf (stderr, "failed to fdopen log fd %d: %s\n", - fd, strerror(errno)); - return; - } - setvbuf (fp, NULL, _IOLBF, 0); - - if (logstream && logstream != stderr && logstream != stdout) - fclose( logstream); - logstream = fp; - missing_lf = 0; -} - - -void -log_set_prefix (const char *text, unsigned int flags) -{ - if (text) - { - strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); - prefix_buffer[sizeof (prefix_buffer)-1] = 0; - } - - with_prefix = (flags & JNLIB_LOG_WITH_PREFIX); - with_time = (flags & JNLIB_LOG_WITH_TIME); - with_pid = (flags & JNLIB_LOG_WITH_PID); - running_detached = (flags & JNLIB_LOG_RUN_DETACHED); -} - - -const char * -log_get_prefix (unsigned int *flags) -{ - if (flags) - { - *flags = 0; - if (with_prefix) - *flags |= JNLIB_LOG_WITH_PREFIX; - if (with_time) - *flags |= JNLIB_LOG_WITH_TIME; - if (with_pid) - *flags |= JNLIB_LOG_WITH_PID; - if (running_detached) - *flags |= JNLIB_LOG_RUN_DETACHED; - } - return prefix_buffer; -} - -/* This function returns true if the file descriptor FD is in use for - logging. This is preferable over a test using log_get_fd in that - it allows the logging code to use more then one file descriptor. */ -int -log_test_fd (int fd) -{ - if (fileno (logstream?logstream:stderr) == fd) - return 1; - if (log_socket == fd) - return 1; - return 0; -} - -int -log_get_fd () -{ - return fileno(logstream?logstream:stderr); -} - -FILE * -log_get_stream () -{ - return logstream?logstream:stderr; -} - - -static void -do_logv (int level, const char *fmt, va_list arg_ptr) -{ - if (!logstream) - logstream = stderr; - - if (missing_lf && level != JNLIB_LOG_CONT) - putc('\n', logstream ); - missing_lf = 0; - - if (level != JNLIB_LOG_CONT) - { /* Note this does not work for multiple line logging as we would - * need to print to a buffer first */ - if (with_time && !force_prefixes) - { - struct tm *tp; - time_t atime = time (NULL); - - tp = localtime (&atime); - fprintf (logstream, "%04d-%02d-%02d %02d:%02d:%02d ", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec ); - } - if (with_prefix || force_prefixes) - fputs (prefix_buffer, logstream); - if (with_pid || force_prefixes) - fprintf (logstream, "[%u]", (unsigned int)getpid ()); - if (!with_time || force_prefixes) - putc (':', logstream); - /* A leading backspace suppresses the extra space so that we can - correctly output, programname, filename and linenumber. */ - if (fmt && *fmt == '\b') - fmt++; - else - putc (' ', logstream); - } - - switch (level) - { - case JNLIB_LOG_BEGIN: break; - case JNLIB_LOG_CONT: break; - case JNLIB_LOG_INFO: break; - case JNLIB_LOG_WARN: break; - case JNLIB_LOG_ERROR: break; - case JNLIB_LOG_FATAL: fputs("Fatal: ",logstream ); break; - case JNLIB_LOG_BUG: fputs("Ohhhh jeeee: ", logstream); break; - case JNLIB_LOG_DEBUG: fputs("DBG: ", logstream ); break; - default: fprintf(logstream,"[Unknown log level %d]: ", level ); break; - } - - - if (fmt) - { - vfprintf(logstream,fmt,arg_ptr) ; - if (*fmt && fmt[strlen(fmt)-1] != '\n') - missing_lf = 1; - } - - if (level == JNLIB_LOG_FATAL) - exit(2); - if (level == JNLIB_LOG_BUG) - abort(); -} - -static void -do_log( int level, const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( level, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -log_logv (int level, const char *fmt, va_list arg_ptr) -{ - do_logv (level, fmt, arg_ptr); -} - -void -log_info( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_INFO, fmt, arg_ptr ); - va_end(arg_ptr); -} - -void -log_error( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_ERROR, fmt, arg_ptr ); - va_end(arg_ptr); - /* protect against counter overflow */ - if( errorcount < 30000 ) - errorcount++; -} - - -void -log_fatal( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_FATAL, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -log_bug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_BUG, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -log_debug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - do_logv( JNLIB_LOG_DEBUG, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -log_printf (const char *fmt, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - do_logv (fmt ? JNLIB_LOG_CONT : JNLIB_LOG_BEGIN, fmt, arg_ptr); - va_end (arg_ptr); -} - -/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw - dump, with TEXT just an empty string, print a trailing linefeed, - otherwise print an entire debug line. */ -void -log_printhex (const char *text, const void *buffer, size_t length) -{ - if (text && *text) - log_debug ("%s ", text); - if (length) - { - const unsigned char *p = buffer; - log_printf ("%02X", *p); - for (length--, p++; length--; p++) - log_printf (" %02X", *p); - } - if (text) - log_printf ("\n"); -} - - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -void -bug_at( const char *file, int line, const char *func ) -{ - do_log( JNLIB_LOG_BUG, - ("... this is a bug (%s:%d:%s)\n"), file, line, func ); - abort(); /* never called, but it makes the compiler happy */ -} -#else -void -bug_at( const char *file, int line ) -{ - do_log( JNLIB_LOG_BUG, - _("you found a bug ... (%s:%d)\n"), file, line); - abort(); /* never called, but it makes the compiler happy */ -} -#endif - diff --git a/jnlib/logging.h b/jnlib/logging.h deleted file mode 100644 index b5c0bd741..000000000 --- a/jnlib/logging.h +++ /dev/null @@ -1,83 +0,0 @@ -/* logging.h - * Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_LOGGING_H -#define LIBJNLIB_LOGGING_H - -#include <stdio.h> -#include "mischelp.h" - -/* Flag values for log_set_prefix. */ -#define JNLIB_LOG_WITH_PREFIX 1 -#define JNLIB_LOG_WITH_TIME 2 -#define JNLIB_LOG_WITH_PID 4 -#define JNLIB_LOG_RUN_DETACHED 256 - -int log_get_errorcount (int clear); -void log_inc_errorcount (void); -void log_set_file( const char *name ); -void log_set_fd (int fd); -void log_set_prefix (const char *text, unsigned int flags); -const char *log_get_prefix (unsigned int *flags); -int log_test_fd (int fd); -int log_get_fd(void); -FILE *log_get_stream (void); - -#ifdef JNLIB_GCC_M_FUNCTION - void bug_at( const char *file, int line, const char *func ) JNLIB_GCC_A_NR; -# define BUG() bug_at( __FILE__ , __LINE__, __FUNCTION__ ) -#else - void bug_at( const char *file, int line ); -# define BUG() bug_at( __FILE__ , __LINE__ ) -#endif - -/* To avoid mandatory inclusion of stdarg and other stuff, do it only - if explicitly requested to do so. */ -#ifdef JNLIB_NEED_LOG_LOGV -#include <stdarg.h> -enum jnlib_log_levels { - JNLIB_LOG_BEGIN, - JNLIB_LOG_CONT, - JNLIB_LOG_INFO, - JNLIB_LOG_WARN, - JNLIB_LOG_ERROR, - JNLIB_LOG_FATAL, - JNLIB_LOG_BUG, - JNLIB_LOG_DEBUG -}; -void log_logv (int level, const char *fmt, va_list arg_ptr); -#endif /*JNLIB_NEED_LOG_LOGV*/ - - -void log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void log_printhex (const char *text, const void *buffer, size_t length); - - -#endif /*LIBJNLIB_LOGGING_H*/ - - - - - diff --git a/jnlib/mischelp.h b/jnlib/mischelp.h deleted file mode 100644 index 54da4cc1f..000000000 --- a/jnlib/mischelp.h +++ /dev/null @@ -1,54 +0,0 @@ -/* mischelp.h - * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_MISCHELP_H -#define LIBJNLIB_MISCHHELP_H - - -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -# define JNLIB_GCC_M_FUNCTION 1 -# define JNLIB_GCC_A_NR __attribute__ ((noreturn)) -# define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) -# define JNLIB_GCC_A_NR_PRINTF( f, a ) \ - __attribute__ ((noreturn, format (printf,f,a))) -#else -# define JNLIB_GCC_A_NR -# define JNLIB_GCC_A_PRINTF( f, a ) -# define JNLIB_GCC_A_NR_PRINTF( f, a ) -#endif - - -/* To avoid that a compiler optimizes certain memset calls away, these - macros may be used instead. */ -#define wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - - - - -#endif /*LIBJNLIB_MISCHELP_H*/ diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c deleted file mode 100644 index 4c8ab314b..000000000 --- a/jnlib/stringhelp.c +++ /dev/null @@ -1,627 +0,0 @@ -/* stringhelp.c - standard string helper functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> - -#include "libjnlib-config.h" -#include "utf8conv.h" -#include "stringhelp.h" - - -/**************** - * look for the substring SUB in buffer and return a pointer to that - * substring in BUF or NULL if not found. - * Comparison is case-insensitive. - */ -const char * -memistr( const char *buf, size_t buflen, const char *sub ) -{ - const byte *t, *s ; - size_t n; - - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( toupper(*t) == toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && toupper(*t) == toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; - } - - return NULL ; -} - -const char * -ascii_memistr( const char *buf, size_t buflen, const char *sub ) -{ - const byte *t, *s ; - size_t n; - - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( ascii_toupper(*t) == ascii_toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && ascii_toupper(*t) == ascii_toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; - } - - return NULL ; -} - -/**************** - * Wie strncpy(), aber es werden maximal n-1 zeichen kopiert und ein - * '\0' angehängt. Ist n = 0, so geschieht nichts, ist Destination - * gleich NULL, so wird via jnlib_xmalloc Speicher besorgt, ist dann nicht - * genügend Speicher vorhanden, so bricht die funktion ab. - */ -char * -mem2str( char *dest , const void *src , size_t n ) -{ - char *d; - const char *s; - - if( n ) { - if( !dest ) - dest = jnlib_xmalloc( n ) ; - d = dest; - s = src ; - for(n--; n && *s; n-- ) - *d++ = *s++; - *d = '\0' ; - } - - return dest ; -} - - -/**************** - * remove leading and trailing white spaces - */ -char * -trim_spaces( char *str ) -{ - char *string, *p, *mark; - - string = str; - /* find first non space character */ - for( p=string; *p && isspace( *(byte*)p ) ; p++ ) - ; - /* move characters */ - for( (mark = NULL); (*string = *p); string++, p++ ) - if( isspace( *(byte*)p ) ) { - if( !mark ) - mark = string ; - } - else - mark = NULL ; - if( mark ) - *mark = '\0' ; /* remove trailing spaces */ - - return str ; -} - -/**************** - * remove trailing white spaces - */ -char * -trim_trailing_spaces( char *string ) -{ - char *p, *mark; - - for( mark = NULL, p = string; *p; p++ ) { - if( isspace( *(byte*)p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - if( mark ) - *mark = '\0' ; - - return string ; -} - - -unsigned -trim_trailing_chars( byte *line, unsigned len, const char *trimchars ) -{ - byte *p, *mark; - unsigned n; - - for(mark=NULL, p=line, n=0; n < len; n++, p++ ) { - if( strchr(trimchars, *p ) ) { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if( mark ) { - *mark = 0; - return mark - line; - } - return len; -} - -/**************** - * remove trailing white spaces and return the length of the buffer - */ -unsigned -trim_trailing_ws( byte *line, unsigned len ) -{ - return trim_trailing_chars( line, len, " \t\r\n" ); -} - -size_t -length_sans_trailing_chars (const unsigned char *line, size_t len, - const char *trimchars ) -{ - const unsigned char *p, *mark; - size_t n; - - for( mark=NULL, p=line, n=0; n < len; n++, p++ ) - { - if (strchr (trimchars, *p )) - { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if (mark) - return mark - line; - return len; -} - -/**************** - * remove trailing white spaces and return the length of the buffer - */ -size_t -length_sans_trailing_ws (const unsigned char *line, size_t len) -{ - return length_sans_trailing_chars (line, len, " \t\r\n"); -} - - - -/*************** - * Extract from a given path the filename component. - * - */ -char * -make_basename(const char *filepath) -{ - char *p; - - if ( !(p=strrchr(filepath, '/')) ) - #ifdef HAVE_DRIVE_LETTERS - if ( !(p=strrchr(filepath, '\\')) ) - if ( !(p=strrchr(filepath, ':')) ) - #endif - { - return jnlib_xstrdup(filepath); - } - - return jnlib_xstrdup(p+1); -} - - - -/*************** - * Extract from a given filename the path prepended to it. - * If their isn't a path prepended to the filename, a dot - * is returned ('.'). - * - */ -char * -make_dirname(const char *filepath) -{ - char *dirname; - int dirname_length; - char *p; - - if ( !(p=strrchr(filepath, '/')) ) - #ifdef HAVE_DRIVE_LETTERS - if ( !(p=strrchr(filepath, '\\')) ) - if ( !(p=strrchr(filepath, ':')) ) - #endif - { - return jnlib_xstrdup("."); - } - - dirname_length = p-filepath; - dirname = jnlib_xmalloc(dirname_length+1); - strncpy(dirname, filepath, dirname_length); - dirname[dirname_length] = 0; - - return dirname; -} - - - -/**************** - * Construct a filename from the NULL terminated list of parts. - * Tilde expansion is done here. - */ -char * -make_filename( const char *first_part, ... ) -{ - va_list arg_ptr ; - size_t n; - const char *s; - char *name, *home, *p; - - va_start( arg_ptr, first_part ) ; - n = strlen(first_part)+1; - while( (s=va_arg(arg_ptr, const char *)) ) - n += strlen(s) + 1; - va_end(arg_ptr); - - home = NULL; - if( *first_part == '~' && first_part[1] == '/' - && (home = getenv("HOME")) && *home ) - n += strlen(home); - - name = jnlib_xmalloc(n); - p = home ? stpcpy(stpcpy(name,home), first_part+1) - : stpcpy(name, first_part); - va_start( arg_ptr, first_part ) ; - while( (s=va_arg(arg_ptr, const char *)) ) - p = stpcpy(stpcpy(p,"/"), s); - va_end(arg_ptr); - - return name; -} - - -int -compare_filenames( const char *a, const char *b ) -{ - /* ? check whether this is an absolute filename and - * resolve symlinks? - */ -#ifdef HAVE_DRIVE_LETTERS - return stricmp(a,b); -#else - return strcmp(a,b); -#endif -} - -/* Print a BUFFER to stream FP while replacing all control characters - and the character DELIM with standard C escape sequences. Returns - the number of characters printed. */ -size_t -print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim) -{ - const unsigned char *p = buffer; - size_t count = 0; - - for (; length; length--, p++, count++) - { - if (*p < 0x20 || *p == 0x7f || *p == delim) - { - putc ('\\', fp); - count++; - if (*p == '\n') - putc ('n', fp); - else if (*p == '\r') - putc ('r', fp); - else if (*p == '\f') - putc ('f', fp); - else if (*p == '\v') - putc ('v', fp); - else if (*p == '\b') - putc ('b', fp); - else if (!*p) - putc('0', fp); - else - { - fprintf (fp, "x%02x", *p); - count += 2; - } - } - else - putc (*p, fp); - } - - return count; -} - -size_t -print_sanitized_utf8_buffer (FILE *fp, const void *buffer, - size_t length, int delim) -{ - const char *p = buffer; - size_t i; - - /* We can handle plain ascii simpler, so check for it first. */ - for (i=0; i < length; i++ ) - { - if ( (p[i] & 0x80) ) - break; - } - if (i < length) - { - char *buf = utf8_to_native (p, length, delim); - /*(utf8 conversion already does the control character quoting)*/ - i = strlen (buf); - fputs (buf, fp); - jnlib_free (buf); - return i; - } - else - return print_sanitized_buffer (fp, p, length, delim); -} - - -size_t -print_sanitized_string (FILE *fp, const char *string, int delim) -{ - return string? print_sanitized_buffer (fp, string, strlen (string), delim):0; -} - -size_t -print_sanitized_utf8_string (FILE *fp, const char *string, int delim) -{ - /* FIXME: convert to local characterset */ - return print_sanitized_string (fp, string, delim); -} - -/* Create a string from the buffer P of length N which is suitable for - printing. Caller must release the created string using xfree. */ -char * -sanitize_buffer (const unsigned char *p, size_t n, int delim) -{ - size_t save_n, buflen; - const byte *save_p; - char *buffer, *d; - - /* first count length */ - for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) - { - if ( *p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) - { - if ( *p=='\n' || *p=='\r' || *p=='\f' - || *p=='\v' || *p=='\b' || !*p ) - buflen += 2; - else - buflen += 4; - } - else - buflen++; - } - p = save_p; - n = save_n; - /* and now make the string */ - d = buffer = jnlib_xmalloc( buflen ); - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) { - *d++ = '\\'; - if( *p == '\n' ) - *d++ = 'n'; - else if( *p == '\r' ) - *d++ = 'r'; - else if( *p == '\f' ) - *d++ = 'f'; - else if( *p == '\v' ) - *d++ = 'v'; - else if( *p == '\b' ) - *d++ = 'b'; - else if( !*p ) - *d++ = '0'; - else { - sprintf(d, "x%02x", *p ); - d += 2; - } - } - else - *d++ = *p; - } - *d = 0; - return buffer; -} - -/**************************************************** - ******** locale insensitive ctype functions ******** - ****************************************************/ -/* FIXME: replace them by a table lookup and macros */ -int -ascii_isupper (int c) -{ - return c >= 'A' && c <= 'Z'; -} - -int -ascii_islower (int c) -{ - return c >= 'a' && c <= 'z'; -} - -int -ascii_toupper (int c) -{ - if (c >= 'a' && c <= 'z') - c &= ~0x20; - return c; -} - -int -ascii_tolower (int c) -{ - if (c >= 'A' && c <= 'Z') - c |= 0x20; - return c; -} - - -int -ascii_strcasecmp( const char *a, const char *b ) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) { - if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b)) - break; - } - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); -} - -int -ascii_strncasecmp (const char *a, const char *b, size_t n) -{ - const unsigned char *p1 = (const unsigned char *)a; - const unsigned char *p2 = (const unsigned char *)b; - unsigned char c1, c2; - - if (p1 == p2 || !n ) - return 0; - - do - { - c1 = ascii_tolower (*p1); - c2 = ascii_tolower (*p2); - - if ( !--n || c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - return c1 - c2; -} - - -int -ascii_memcasecmp( const char *a, const char *b, size_t n ) -{ - if (a == b) - return 0; - for ( ; n; n--, a++, b++ ) { - if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); - } - return 0; -} - -int -ascii_strcmp( const char *a, const char *b ) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) { - if (*a != *b ) - break; - } - return *a == *b? 0 : (*(signed char *)a - *(signed char *)b); -} - - -void * -ascii_memcasemem (const void *haystack, size_t nhaystack, - const void *needle, size_t nneedle) -{ - - if (!nneedle) - return (void*)haystack; /* finding an empty needle is really easy */ - if (nneedle <= nhaystack) - { - const unsigned char *a = haystack; - const unsigned char *b = a + nhaystack - nneedle; - - for (; a <= b; a++) - { - if ( !ascii_memcasecmp (a, needle, nneedle) ) - return (void *)a; - } - } - return NULL; -} - -/********************************************* - ********** missing string functions ********* - *********************************************/ - -#ifndef HAVE_STPCPY -char * -stpcpy(char *a,const char *b) -{ - while( *b ) - *a++ = *b++; - *a = 0; - - return (char*)a; -} -#endif - -#ifndef HAVE_STRLWR -char * -strlwr(char *s) -{ - char *p; - for(p=s; *p; p++ ) - *p = tolower(*p); - return s; -} -#endif - - -#ifndef HAVE_STRCASECMP -int -strcasecmp( const char *a, const char *b ) -{ - for( ; *a && *b; a++, b++ ) { - if( *a != *b && toupper(*a) != toupper(*b) ) - break; - } - return *(const byte*)a - *(const byte*)b; -} -#endif - - -/**************** - * mingw32/cpd has a memicmp() - */ -#ifndef HAVE_MEMICMP -int -memicmp( const char *a, const char *b, size_t n ) -{ - for( ; n; n--, a++, b++ ) - if( *a != *b && toupper(*(const byte*)a) != toupper(*(const byte*)b) ) - return *(const byte *)a - *(const byte*)b; - return 0; -} -#endif diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h deleted file mode 100644 index fe5786e59..000000000 --- a/jnlib/stringhelp.h +++ /dev/null @@ -1,90 +0,0 @@ -/* stringhelp.h - * Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_STRINGHELP_H -#define LIBJNLIB_STRINGHELP_H - -#include "types.h" - -const char *memistr( const char *buf, size_t buflen, const char *sub ); -char *mem2str( char *, const void *, size_t); -char *trim_spaces( char *string ); -char *trim_trailing_spaces( char *string ); -unsigned int trim_trailing_chars( unsigned char *line, unsigned len, - const char *trimchars); -unsigned int trim_trailing_ws( unsigned char *line, unsigned len ); -size_t length_sans_trailing_chars (const unsigned char *line, size_t len, - const char *trimchars ); -size_t length_sans_trailing_ws (const unsigned char *line, size_t len); - - -char *make_basename(const char *filepath); -char *make_dirname(const char *filepath); -char *make_filename( const char *first_part, ... ); -int compare_filenames( const char *a, const char *b ); - -size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim); -size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, - size_t length, int delim); -size_t print_sanitized_string (FILE *fp, const char *string, int delim); -size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); -char *sanitize_buffer (const unsigned char *p, size_t n, int delim); - - -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); -int ascii_isupper (int c); -int ascii_islower (int c); -int ascii_toupper (int c); -int ascii_tolower (int c); -int ascii_strcasecmp( const char *a, const char *b ); -int ascii_strncasecmp (const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n ); -const char *ascii_memistr ( const char *buf, size_t buflen, const char *sub); -void *ascii_memcasemem (const void *haystack, size_t nhaystack, - const void *needle, size_t nneedle); - - -#ifndef HAVE_MEMICMP -int memicmp( const char *a, const char *b, size_t n ); -#endif -#ifndef HAVE_STPCPY -char *stpcpy(char *a,const char *b); -#endif -#ifndef HAVE_STRLWR -char *strlwr(char *a); -#endif -#ifndef HAVE_STRTOUL - #define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) -#endif -#ifndef HAVE_MEMMOVE - #define memmove(d, s, n) bcopy((s), (d), (n)) -#endif -#ifndef HAVE_STRICMP - #define stricmp(a,b) strcasecmp( (a), (b) ) -#endif - -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - - -#endif /*LIBJNLIB_STRINGHELP_H*/ diff --git a/jnlib/strlist.c b/jnlib/strlist.c deleted file mode 100644 index 49b510666..000000000 --- a/jnlib/strlist.c +++ /dev/null @@ -1,172 +0,0 @@ -/* strlist.c - string helpers - * Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> - -#include "libjnlib-config.h" -#include "strlist.h" - - -void -free_strlist( strlist_t sl ) -{ - strlist_t sl2; - - for(; sl; sl = sl2 ) { - sl2 = sl->next; - jnlib_free(sl); - } -} - - -strlist_t -add_to_strlist( strlist_t *list, const char *string ) -{ - strlist_t sl; - - sl = jnlib_xmalloc( sizeof *sl + strlen(string)); - sl->flags = 0; - strcpy(sl->d, string); - sl->next = *list; - *list = sl; - return sl; -} - -#if 0 -/**************** - * same as add_to_strlist() but if is_utf8 is *not* set a conversion - * to UTF8 is done - */ -strlist_t -add_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) -{ - strlist_t sl; - - if( is_utf8 ) - sl = add_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = add_to_strlist( list, p ); - m_free( p ); - } - return sl; -} -#endif - -strlist_t -append_to_strlist( strlist_t *list, const char *string ) -{ - strlist_t r, sl; - - sl = jnlib_xmalloc( sizeof *sl + strlen(string)); - sl->flags = 0; - strcpy(sl->d, string); - sl->next = NULL; - if( !*list ) - *list = sl; - else { - for( r = *list; r->next; r = r->next ) - ; - r->next = sl; - } - return sl; -} - -#if 0 -strlist_t -append_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) -{ - strlist_t sl; - - if( is_utf8 ) - sl = append_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = append_to_strlist( list, p ); - m_free( p ); - } - return sl; -} -#endif - - -/* Return a copy of LIST. */ -strlist_t -strlist_copy (strlist_t list) -{ - strlist_t newlist = NULL, sl, *last; - - last = &newlist; - for (; list; list = list->next) - { - sl = jnlib_xmalloc (sizeof *sl + strlen (list->d)); - sl->flags = list->flags; - strcpy(sl->d, list->d); - sl->next = NULL; - *last = sl; - last = &sl; - } - return newlist; -} - - - -strlist_t -strlist_prev( strlist_t head, strlist_t node ) -{ - strlist_t n; - - for(n=NULL; head && head != node; head = head->next ) - n = head; - return n; -} - -strlist_t -strlist_last( strlist_t node ) -{ - if( node ) - for( ; node->next ; node = node->next ) - ; - return node; -} - - -char * -strlist_pop (strlist_t *list) -{ - char *str=NULL; - strlist_t sl=*list; - - if(sl) - { - str=jnlib_xmalloc(strlen(sl->d)+1); - strcpy(str,sl->d); - - *list=sl->next; - jnlib_free(sl); - } - - return str; -} - diff --git a/jnlib/strlist.h b/jnlib/strlist.h deleted file mode 100644 index 72da241bc..000000000 --- a/jnlib/strlist.h +++ /dev/null @@ -1,51 +0,0 @@ -/* strlist.h - * Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_STRLIST_H -#define LIBJNLIB_STRLIST_H - -struct string_list { - struct string_list *next; - unsigned int flags; - char d[1]; -}; -typedef struct string_list *STRLIST; /* Deprecated. */ -typedef struct string_list *strlist_t; - -void free_strlist (strlist_t sl); -strlist_t add_to_strlist (strlist_t *list, const char *string); - -/*strlist_t add_to_strlist2( strlist_t *list, - const char *string, int is_utf8);*/ - -strlist_t append_to_strlist (strlist_t *list, const char *string); - -strlist_t strlist_copy (strlist_t list); - -/*strlist_t append_to_strlist2( strlist_t *list, const char *string, - int is_utf8);*/ -strlist_t strlist_prev (strlist_t head, strlist_t node); -strlist_t strlist_last (strlist_t node); -char * strlist_pop (strlist_t *list); - -#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) - - -#endif /*LIBJNLIB_STRLIST_H*/ diff --git a/jnlib/types.h b/jnlib/types.h deleted file mode 100644 index 230d1502f..000000000 --- a/jnlib/types.h +++ /dev/null @@ -1,101 +0,0 @@ -/* types.h - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_TYPES_H -#define LIBJNLIB_TYPES_H - -/* The AC_CHECK_SIZEOF() in configure fails for some machines. - * we provide some fallback values here */ -#if !SIZEOF_UNSIGNED_SHORT - #undef SIZEOF_UNSIGNED_SHORT - #define SIZEOF_UNSIGNED_SHORT 2 -#endif -#if !SIZEOF_UNSIGNED_INT - #undef SIZEOF_UNSIGNED_INT - #define SIZEOF_UNSIGNED_INT 4 -#endif -#if !SIZEOF_UNSIGNED_LONG - #undef SIZEOF_UNSIGNED_LONG - #define SIZEOF_UNSIGNED_LONG 4 -#endif - - -#include <sys/types.h> - - -#ifndef HAVE_BYTE_TYPEDEF - #undef byte /* maybe there is a macro with this name */ - typedef unsigned char byte; - #define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_USHORT_TYPEDEF - #undef ushort /* maybe there is a macro with this name */ - typedef unsigned short ushort; - #define HAVE_USHORT_TYPEDEF -#endif - -#ifndef HAVE_ULONG_TYPEDEF - #undef ulong /* maybe there is a macro with this name */ - typedef unsigned long ulong; - #define HAVE_ULONG_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF - #undef u16 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 2 - typedef unsigned int u16; - #elif SIZEOF_UNSIGNED_SHORT == 2 - typedef unsigned short u16; - #else - #error no typedef for u16 - #endif - #define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF - #undef u32 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 4 - typedef unsigned int u32; - #elif SIZEOF_UNSIGNED_LONG == 4 - typedef unsigned long u32; - #else - #error no typedef for u32 - #endif - #define HAVE_U32_TYPEDEF -#endif - -#ifndef HAVE_U64_TYPEDEF - #undef u64 /* maybe there is a macro with this name */ - #if SIZEOF_UNSIGNED_INT == 8 - typedef unsigned int u64; - #define HAVE_U64_TYPEDEF - #elif SIZEOF_UNSIGNED_LONG == 8 - typedef unsigned long u64; - #define HAVE_U64_TYPEDEF - #elif __GNUC__ >= 2 || defined(__SUNPRO_C) - typedef unsigned long long u64; - #define HAVE_U64_TYPEDEF - #endif -#endif - - - -#endif /*LIBJNLIB_TYPES_H*/ diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c deleted file mode 100644 index 691176766..000000000 --- a/jnlib/utf8conv.c +++ /dev/null @@ -1,448 +0,0 @@ -/* utf8conf.c - UTF8 character set conversion - * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "libjnlib-config.h" -#include "stringhelp.h" -#include "utf8conv.h" - - -static ushort koi8_unicode[128] = { - 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, - 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, - 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, - 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, - 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, - 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, - 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, - 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, - 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, - 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, - 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, - 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, - 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, - 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a -}; - -static ushort latin2_unicode[128] = { - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, - 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, - 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, - 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, - 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, - 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, - 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, - 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, - 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, - 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, - 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, - 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 -}; - - -static const char *active_charset_name = "iso-8859-1"; -static ushort *active_charset = NULL; -static int no_translation = 0; - -int -set_native_charset (const char *newset) -{ - if (!newset) -#ifdef HAVE_LANGINFO_CODESET - newset = nl_langinfo (CODESET); -#else - newset = "8859-1"; -#endif - - if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3)) - { - newset += 3; - if (*newset == '-' || *newset == '_') - newset++; - } - - if (!*newset - || !ascii_strcasecmp (newset, "8859-1") - || !ascii_strcasecmp (newset, "8859-15")) - { - active_charset_name = "iso-8859-1"; - no_translation = 0; - active_charset = NULL; - } - else if (!ascii_strcasecmp (newset, "8859-2")) - { - active_charset_name = "iso-8859-2"; - no_translation = 0; - active_charset = latin2_unicode; - } - else if (!ascii_strcasecmp (newset, "koi8-r")) - { - active_charset_name = "koi8-r"; - no_translation = 0; - active_charset = koi8_unicode; - } - else if (!ascii_strcasecmp (newset, "utf8") - || !ascii_strcasecmp (newset, "utf-8")) - { - active_charset_name = "utf-8"; - no_translation = 1; - active_charset = NULL; - } - else - return -1; - return 0; -} - -const char * -get_native_charset () -{ - return active_charset_name; -} - -/**************** - * Convert string, which is in native encoding to UTF8 and return the - * new allocated UTF8 string. - */ -char * -native_to_utf8 (const char *string) -{ - const byte *s; - char *buffer; - byte *p; - size_t length = 0; - - if (no_translation) - { - buffer = jnlib_xstrdup (string); - } - else if (active_charset) - { - for (s = string; *s; s++) - { - length++; - if (*s & 0x80) - length += 2; /* we may need 3 bytes */ - } - buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) - { - if ((*s & 0x80)) - { - ushort val = active_charset[*s & 0x7f]; - if (val < 0x0800) - { - *p++ = 0xc0 | ((val >> 6) & 0x1f); - *p++ = 0x80 | (val & 0x3f); - } - else - { - *p++ = 0xe0 | ((val >> 12) & 0x0f); - *p++ = 0x80 | ((val >> 6) & 0x3f); - *p++ = 0x80 | (val & 0x3f); - } - } - else - *p++ = *s; - } - *p = 0; - } - else - { - for (s = string; *s; s++) - { - length++; - if (*s & 0x80) - length++; - } - buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) - { - if (*s & 0x80) - { - *p++ = 0xc0 | ((*s >> 6) & 3); - *p++ = 0x80 | (*s & 0x3f); - } - else - *p++ = *s; - } - *p = 0; - } - return buffer; -} - - -/* Convert string, which is in UTF8 to native encoding. Replace - * illegal encodings by some "\xnn" and quote all control - * characters. A character with value DELIM will always be quoted, it - * must be a vanilla ASCII character. */ -char * -utf8_to_native (const char *string, size_t length, int delim) -{ - int nleft; - int i; - byte encbuf[8]; - int encidx; - const byte *s; - size_t n; - byte *buffer = NULL, *p = NULL; - unsigned long val = 0; - size_t slen; - int resync = 0; - - /* 1. pass (p==NULL): count the extended utf-8 characters */ - /* 2. pass (p!=NULL): create string */ - for (;;) - { - for (slen = length, nleft = encidx = 0, n = 0, s = string; slen; - s++, slen--) - { - if (resync) - { - if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd))) - { - /* still invalid */ - if (p) - { - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4; - continue; - } - resync = 0; - } - if (!nleft) - { - if (!(*s & 0x80)) - { /* plain ascii */ - if (*s < 0x20 || *s == 0x7f || *s == delim || - (delim && *s == '\\')) - { - n++; - if (p) - *p++ = '\\'; - switch (*s) - { - case '\n': - n++; - if (p) - *p++ = 'n'; - break; - case '\r': - n++; - if (p) - *p++ = 'r'; - break; - case '\f': - n++; - if (p) - *p++ = 'f'; - break; - case '\v': - n++; - if (p) - *p++ = 'v'; - break; - case '\b': - n++; - if (p) - *p++ = 'b'; - break; - case 0: - n++; - if (p) - *p++ = '0'; - break; - default: - n += 3; - if (p) - { - sprintf (p, "x%02x", *s); - p += 3; - } - break; - } - } - else - { - if (p) - *p++ = *s; - n++; - } - } - else if ((*s & 0xe0) == 0xc0) - { /* 110x xxxx */ - val = *s & 0x1f; - nleft = 1; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xf0) == 0xe0) - { /* 1110 xxxx */ - val = *s & 0x0f; - nleft = 2; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xf8) == 0xf0) - { /* 1111 0xxx */ - val = *s & 0x07; - nleft = 3; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xfc) == 0xf8) - { /* 1111 10xx */ - val = *s & 0x03; - nleft = 4; - encidx = 0; - encbuf[encidx++] = *s; - } - else if ((*s & 0xfe) == 0xfc) - { /* 1111 110x */ - val = *s & 0x01; - nleft = 5; - encidx = 0; - encbuf[encidx++] = *s; - } - else - { /* invalid encoding: print as \xnn */ - if (p) - { - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4; - resync = 1; - } - } - else if (*s < 0x80 || *s >= 0xc0) - { /* invalid */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - sprintf (p, "\\x%02x", *s); - p += 4; - } - n += 4 + 4 * encidx; - nleft = 0; - encidx = 0; - resync = 1; - } - else - { - encbuf[encidx++] = *s; - val <<= 6; - val |= *s & 0x3f; - if (!--nleft) - { /* ready */ - if (no_translation) - { - if (p) - { - for (i = 0; i < encidx; i++) - *p++ = encbuf[i]; - } - n += encidx; - encidx = 0; - } - else if (active_charset) - { /* table lookup */ - for (i = 0; i < 128; i++) - { - if (active_charset[i] == val) - break; - } - if (i < 128) - { /* we can print this one */ - if (p) - *p++ = i + 128; - n++; - } - else - { /* we do not have a translation: print utf8 */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - } - n += encidx * 4; - encidx = 0; - } - } - else - { /* native set */ - if (val >= 0x80 && val < 256) - { - n++; /* we can simply print this character */ - if (p) - *p++ = val; - } - else - { /* we do not have a translation: print utf8 */ - if (p) - { - for (i = 0; i < encidx; i++) - { - sprintf (p, "\\x%02x", encbuf[i]); - p += 4; - } - } - n += encidx * 4; - encidx = 0; - } - } - } - - } - } - if (!buffer) - { /* allocate the buffer after the first pass */ - buffer = p = jnlib_xmalloc (n + 1); - } - else - { - *p = 0; /* make a string */ - return buffer; - } - } -} diff --git a/jnlib/utf8conv.h b/jnlib/utf8conv.h deleted file mode 100644 index 6e2ce9944..000000000 --- a/jnlib/utf8conv.h +++ /dev/null @@ -1,31 +0,0 @@ -/* utf8conf.h - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_UTF8CONF_H -#define LIBJNLIB_UTF8CONF_H - -int set_native_charset (const char *newset); -const char *get_native_charset (void); - -char *native_to_utf8 (const char *string); -char *utf8_to_native (const char *string, size_t length, int delim); - - -#endif /*LIBJNLIB_UTF8CONF_H*/ diff --git a/jnlib/xmalloc.c b/jnlib/xmalloc.c deleted file mode 100644 index 1cfaab9f7..000000000 --- a/jnlib/xmalloc.c +++ /dev/null @@ -1,88 +0,0 @@ -/* xmalloc.c - standard malloc wrappers - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "libjnlib-config.h" -#include "xmalloc.h" - -static void -out_of_core(void) -{ - fputs("\nfatal: out of memory\n", stderr ); - exit(2); -} - - -void * -xmalloc( size_t n ) -{ - void *p = malloc( n ); - if( !p ) - out_of_core(); - return p; -} - -void * -xrealloc( void *a, size_t n ) -{ - void *p = realloc( a, n ); - if( !p ) - out_of_core(); - return p; -} - -void * -xcalloc( size_t n, size_t m ) -{ - void *p = calloc( n, m ); - if( !p ) - out_of_core(); - return p; -} - -char * -xstrdup( const char *string ) -{ - void *p = xmalloc( strlen(string)+1 ); - strcpy( p, string ); - return p; -} - - -char * -xstrcat2( const char *a, const char *b ) -{ - size_t n1; - char *p; - - if( !b ) - return xstrdup( a ); - - n1 = strlen(a); - p = xmalloc( n1 + strlen(b) + 1 ); - memcpy(p, a, n1 ); - strcpy(p+n1, b ); - return p; -} - diff --git a/jnlib/xmalloc.h b/jnlib/xmalloc.h deleted file mode 100644 index 150ef3664..000000000 --- a/jnlib/xmalloc.h +++ /dev/null @@ -1,31 +0,0 @@ -/* xmalloc.h - * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef LIBJNLIB_XMALLOC_H -#define LIBJNLIB_XMALLOC_H - -void *xmalloc( size_t n ); -void *xrealloc( void *a, size_t n ); -void *xcalloc( size_t n, size_t m ); -char *xstrdup( const char *string ); -char *xstrcat2( const char *a, const char *b ); - - -#endif /*LIBJNLIB_XMALLOC_H*/ diff --git a/kbx/ChangeLog b/kbx/ChangeLog deleted file mode 100644 index 1c3b9e3a1..000000000 --- a/kbx/ChangeLog +++ /dev/null @@ -1,166 +0,0 @@ -2004-06-18 Werner Koch <wk@gnupg.org> - - * keybox-dump.c (_keybox_dump_file): New arg STATS_ONLY. - (update_stats): New. - * kbxutil.c (main): New command --stats. - -2004-04-23 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (_keybox_update_header_blob): New. - * keybox-update.c (blob_filecopy): Handle header blob. - * keybox-file.c (_keybox_read_blob2): New. Moved code from - _keybox_read_blob to there. - * keybox-dump.c (dump_header_blob): Print header info. - -2004-04-21 Werner Koch <wk@gnupg.org> - - * keybox-search.c (_keybox_get_flag_location): Add flag - KEYBOX_FLAG_CREATED_AT. - * keybox-update.c (keybox_compress): New. - - * keybox-search.c (get32, get16, blob_get_type) - (blob_get_blob_flags, has_short_kid, has_long_kid) - (has_fingerprint, has_issuer, has_issuer_sn, has_sn, has_subject) - (has_subject_or_alt, has_mail): inline them. - - * keybox-update.c (blob_filecopy): Fixed an error/eof check - (s/if(fread)/if(nread)/). - - * keybox-dump.c (_keybox_dump_blob): Really print the timestamps. - -2004-04-20 Werner Koch <wk@gnupg.org> - - * keybox-defs.h: Include jnlib/types.h and remove our own - definitions for byte.u16 and u32. - -2004-02-02 Werner Koch <wk@gnupg.org> - - * keybox.h (keybox_flag_t): New. - * keybox-search.c (get_flag_from_image, keybox_get_flags): New. - (_keybox_get_flag_location): New. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - - * keybox-blob.c: Include time.h - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * keybox-defs.h: Include gpg-error.h . - (KeyboxError): Removed. - * Makefile.am: Removed keybox-error.c stuff. - -2002-11-14 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name) <compare all names>: Fixed - length compare; there is no 0 stored since nearly a year. - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (AM_CPPFLAGS): Fix ytpo. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_fpr_part): New. - (has_short_kid, has_long_kid): Implemented. - -2002-07-22 Werner Koch <wk@gnupg.org> - - * keybox-defs.h: New BLOBTYPTE_EMPTY. - * keybox-dump.c (_keybox_dump_blob): Handle new type. - * keybox-file.c (_keybox_read_blob): Skip over empty blobs. Store - the file offset. - * keybox-blob.c (_keybox_new_blob): Add new arg OFF. - (_keybox_get_blob_fileoffset): New. - * keybox-update.c (keybox_delete): Implemented. - -2002-06-19 Werner Koch <wk@gnupg.org> - - * keybox-init.c (keybox_set_ephemeral): New. - * keybox-blob.c (create_blob_header): Store ephemeral flag. - (_keybox_create_x509_blob): Pass epheermal flag on. - * keybox-update.c (keybox_insert_cert): Ditto. - * keybox-search.c (blob_get_blob_flags): New. - (keybox_search): Ignore ephemeral blobs when not in ephemeral mode. - - * keybox-dump.c (_keybox_dump_blob): Print blob flags as strings. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_mail): Use case-insensitive compare - because mail addresses are in general case insensitive (well - RFC2822 allows for case sensitive mailbox parts, but this is in - general considired a Bad Thing). Add additional substr parameter - to allow for substring matches within the mail address. Change - all callers to pass this along. - (blob_cmp_name): Likewise but do the case-insensitive search only - in sub string mode. - (keybox_search): Implement MAILSUB and SUBSTR mode. - -2002-01-21 Werner Koch <wk@gnupg.org> - - * keybox-search.c (keybox_search): Allow KEYDB_SEARCH_MODE_FPR20. - -2002-01-15 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_fpr): New. - (has_fingerprint): Implemented; - -2001-12-20 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (_keybox_create_x509_blob): Skip the leading - parenthesis of the serial number's S-exp. - (_keybox_create_x509_blob): And fixed length calculation. - (create_blob_header): Don't add an offset when writing the serial. - -2001-12-18 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CPPFLAGS): Add flags for libksba - - * keybox-blob.c (_keybox_create_x509_blob): Use - gcry_sexp_canon_len to get the length of the serial number. - (_keybox_release_blob): Need to use a new serialbuf to free the memory. - -2001-12-17 Werner Koch <wk@gnupg.org> - - * keybox-search.c: Changed the way the serial number is - represented. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name): There is no terminating 0 stored - for the uid; fixed length compare. - -2001-12-14 Werner Koch <wk@gnupg.org> - - * keybox-blob.c (x509_email_kludge): New. - (_keybox_create_x509_blob): Insert an extra email address if the - subject's DN has an email part. - * keybox-defs.h: Added the xtoi_2 and digitp macros. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * keybox-search.c (blob_cmp_name): Kludge to allow searching for - more than one name. - (has_subject_or_alt): New. - (blob_cmp_mail): New. - (has_mail): New. - (keybox_search): Implemented exact search and exact mail search. - - * kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate - names. - - - Copyright 2001 g10 Code GmbH - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - \ No newline at end of file diff --git a/kbx/Makefile.am b/kbx/Makefile.am deleted file mode 100644 index 4f0c40043..000000000 --- a/kbx/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -# Keybox Makefile -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -EXTRA_DIST = mkerrors -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl \ - $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) - -noinst_LIBRARIES = libkeybox.a -bin_PROGRAMS = kbxutil - -common_sources = \ - keybox.h keybox-defs.h keybox-search-desc.h \ - keybox-util.c \ - keybox-init.c \ - keybox-blob.c \ - keybox-file.c \ - keybox-search.c \ - keybox-update.c \ - keybox-dump.c - - -libkeybox_a_SOURCES = $(common_sources) - -kbxutil_SOURCES = kbxutil.c $(common_sources) -kbxutil_LDADD = ../jnlib/libjnlib.a $(KSBA_LIBS) $(LIBGCRYPT_LIBS) \ - -lgpg-error @INTLLIBS@ - - - - - diff --git a/kbx/Manifest b/kbx/Manifest deleted file mode 100644 index 95f48d73f..000000000 --- a/kbx/Manifest +++ /dev/null @@ -1,8 +0,0 @@ - -keybox-update.c -keybox-file.c - - - - -$names$ diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c deleted file mode 100644 index 37c19130b..000000000 --- a/kbx/kbxutil.c +++ /dev/null @@ -1,357 +0,0 @@ -/* kbxutil.c - The Keybox utility - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> - -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../common/i18n.h" -#include "keybox-defs.h" - -#include <gcrypt.h> - - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oVerbose = 'v', - - aNoSuchCmd = 500, /* force other values not to be a letter */ - aFindByFpr, - aFindByKid, - aFindByUid, - aStats, - - oDebug, - oDebugAll, - - oNoArmor, - - - aTest -}; - - -static ARGPARSE_OPTS opts[] = { - { 300, NULL, 0, N_("@Commands:\n ") }, - -/* { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */ -/* { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, */ -/* { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, */ - { aStats, "stats", 0, "show key statistics" }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - -/* { oArmor, "armor", 0, N_("create ascii armored output")}, */ -/* { oArmor, "armour", 0, "@" }, */ -/* { oOutput, "output", 2, N_("use as output file")}, */ - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - - { oDebug, "debug" ,4|16, N_("set debugging flags")}, - { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, - - {0} /* end of list */ -}; - - -void myexit (int rc); - -int keybox_errors_seen = 0; - - -static const char * -my_strusage( int level ) -{ - const char *p; - switch( level ) { - case 11: p = "kbxutil (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); - break; - case 1: - case 40: p = - _("Usage: kbxutil [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: kbxutil [options] [files]\n" - "list, export, import Keybox data\n"); - break; - - - default: p = NULL; - } - return p; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - #ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); - #else - setlocale( LC_ALL, "" ); - #endif - bindtextdomain( PACKAGE_GT, LOCALEDIR ); - textdomain( PACKAGE_GT ); -#endif -#endif -} - - -/* static void */ -/* wrong_args( const char *text ) */ -/* { */ -/* log_error("usage: kbxutil %s\n", text); */ -/* myexit ( 1 ); */ -/* } */ - - -#if 0 -static int -hextobyte( const byte *s ) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} -#endif - -#if 0 -static char * -format_fingerprint ( const char *s ) -{ - int i, c; - byte fpr[20]; - - for (i=0; i < 20 && *s; ) { - if ( *s == ' ' || *s == '\t' ) { - s++; - continue; - } - c = hextobyte(s); - if (c == -1) { - return NULL; - } - fpr[i++] = c; - s += 2; - } - return gcry_xstrdup ( fpr ); -} -#endif - -#if 0 -static int -format_keyid ( const char *s, u32 *kid ) -{ - char helpbuf[9]; - switch ( strlen ( s ) ) { - case 8: - kid[0] = 0; - kid[1] = strtoul( s, NULL, 16 ); - return 10; - - case 16: - mem2str( helpbuf, s, 9 ); - kid[0] = strtoul( helpbuf, NULL, 16 ); - kid[1] = strtoul( s+8, NULL, 16 ); - return 11; - } - return 0; /* error */ -} -#endif - - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - enum cmd_and_opt_values cmd = 0; - - set_strusage( my_strusage ); - /*log_set_name("kbxutil"); fixme */ -#if 0 - /* check that the libraries are suitable. Do it here because - * the option parse may need services of the library */ - if ( !gcry_check_version ( "1.1.4" ) ) - { - log_fatal(_("libgcrypt is too old (need %s, have %s)\n"), - "1.1.4", gcry_check_version(NULL) ); - } -#endif - - /*create_dotlock(NULL); register locking cleanup */ - i18n_init(); - - /* We need to use the gcry malloc function because jnlib does use them */ - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse( &pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: - /*opt.verbose++;*/ - /*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/ - break; - case oDebug: - /*opt.debug |= pargs.r.ret_ulong; */ - break; - case oDebugAll: - /*opt.debug = ~0;*/ - break; - - case aFindByFpr: - case aFindByKid: - case aFindByUid: - case aStats: - cmd = pargs.r_opt; - break; - - default: - pargs.err = 2; - break; - } - } - if (log_get_errorcount(0) ) - myexit(2); - - if (!cmd) - { /* default is to list a KBX file */ - if (!argc) - _keybox_dump_file (NULL, 0, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, 0, stdout); - } - } - else if (cmd == aStats ) - { - if (!argc) - _keybox_dump_file (NULL, 1, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, 1, stdout); - } - } -#if 0 - else if ( cmd == aFindByFpr ) - { - char *fpr; - if ( argc != 2 ) - wrong_args ("kbxfile foingerprint"); - fpr = format_fingerprint ( argv[1] ); - if ( !fpr ) - log_error ("invalid formatted fingerprint\n"); - else - { - kbxfile_search_by_fpr ( argv[0], fpr ); - gcry_free ( fpr ); - } - } - else if ( cmd == aFindByKid ) - { - u32 kid[2]; - int mode; - - if ( argc != 2 ) - wrong_args ("kbxfile short-or-long-keyid"); - mode = format_keyid ( argv[1], kid ); - if ( !mode ) - log_error ("invalid formatted keyID\n"); - else - { - kbxfile_search_by_kid ( argv[0], kid, mode ); - } - } - else if ( cmd == aFindByUid ) - { - if ( argc != 2 ) - wrong_args ("kbxfile userID"); - kbxfile_search_by_uid ( argv[0], argv[1] ); - } -#endif - else - log_error ("unsupported action\n"); - - myexit(0); - return 8; /*NEVER REACHED*/ -} - - -void -myexit( int rc ) -{ - /* if( opt.debug & DBG_MEMSTAT_VALUE ) {*/ -/* gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); */ -/* gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); */ - /* }*/ -/* if( opt.debug ) */ -/* gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); */ - rc = rc? rc : log_get_errorcount(0)? 2 : - keybox_errors_seen? 1 : 0; - exit(rc ); -} - - diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c deleted file mode 100644 index 48bce28e2..000000000 --- a/kbx/keybox-blob.c +++ /dev/null @@ -1,1031 +0,0 @@ -/* keybox-blob.c - KBX Blob handling - * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* The keybox data formats - -The KeyBox uses an augmented OpenPGP/X.509 key format. This makes -random access to a keyblock/Certificate easier and also gives the -opportunity to store additional information (e.g. the fingerprint) -along with the key. All integers are stored in network byte order, -offsets are counted from the beginning of the Blob. - -The first record of a plain KBX file has a special format: - - u32 length of the first record - byte Blob type (1) - byte version number (1) - byte reserved - byte reserved - u32 magic 'KBXf' - u32 reserved - u32 file_created_at - u32 last_maintenance_run - u32 reserved - u32 reserved - -The OpenPGP and X.509 blob are very similiar, things which are -X.509 specific are noted like [X.509: xxx] - - u32 length of this blob (including these 4 bytes) - byte Blob type (2) [X509: 3] - byte version number of this blob type (1) - u16 Blob flags - bit 0 = contains secret key material - bit 1 = ephemeral blob (e.g. used while quering external resources) - - u32 offset to the OpenPGP keyblock or X509 DER encoded certificate - u32 and its length - u16 number of keys (at least 1!) [X509: always 1] - u16 size of additional key information - n times: - b20 The keys fingerprint - (fingerprints are always 20 bytes, MD5 left padded with zeroes) - u32 offset to the n-th key's keyID (a keyID is always 8 byte) - or 0 if not known which is the case only for X509. - u16 special key flags - bit 0 = - u16 reserved - u16 size of serialnumber(may be zero) - n u16 (see above) bytes of serial number - u16 number of user IDs - u16 size of additional user ID information - n times: - u32 offset to the n-th user ID - u32 length of this user ID. - u16 special user ID flags. - bit 0 = - byte validity - byte reserved - [For X509, the first user ID is the Issuer, the second the Subject - and the others are subjectAltNames] - u16 number of signatures - u16 size of signature information (4) - u32 expiration time of signature with some special values: - 0x00000000 = not checked - 0x00000001 = missing key - 0x00000002 = bad signature - 0x10000000 = valid and expires at some date in 1978. - 0xffffffff = valid and does not expire - u8 assigned ownertrust [X509: not used] - u8 all_validity - OpenPGP: see ../g10/trustdb/TRUST_* [not yet used] - X509: Bit 4 set := key has been revoked. Note that this value - matches TRUST_FLAG_REVOKED - u16 reserved - u32 recheck_after - u32 Newest timestamp in the keyblock (useful for KS syncronsiation?) - u32 Blob created at - u32 size of reserved space (not including this field) - reserved space - - Here we might want to put other data - - Here comes the keyblock - - maybe we put a signature here later. - - b16 MD5 checksum (useful for KS syncronisation), we might also want to use - a mac here. - b4 resevered - -*/ - - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <time.h> - -#include "keybox-defs.h" -#include <gcrypt.h> - -#ifdef KEYBOX_WITH_OPENPGP -/* include stuff to parse the packets */ -#endif -#ifdef KEYBOX_WITH_X509 -#include <ksba.h> -#endif - - - -/* special values of the signature status */ -#define SF_NONE(a) ( !(a) ) -#define SF_NOKEY(a) ((a) & (1<<0)) -#define SF_BAD(a) ((a) & (1<<1)) -#define SF_VALID(a) ((a) & (1<<29)) - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - -/* #if MAX_FINGERPRINT_LEN < 20 */ -/* #error fingerprints are 20 bytes */ -/* #endif */ - -struct keyboxblob_key { - char fpr[20]; - u32 off_kid; - ulong off_kid_addr; - u16 flags; -}; -struct keyboxblob_uid { - ulong off_addr; - char *name; /* used only with x509 */ - u32 len; - u16 flags; - byte validity; -}; - -struct keyid_list { - struct keyid_list *next; - int seqno; - byte kid[8]; -}; - -struct fixup_list { - struct fixup_list *next; - u32 off; - u32 val; -}; - - -struct keyboxblob { - byte *blob; - size_t bloblen; - off_t fileoffset; - - /* stuff used only by keybox_create_blob */ - unsigned char *serialbuf; - const unsigned char *serial; - size_t seriallen; - int nkeys; - struct keyboxblob_key *keys; - int nuids; - struct keyboxblob_uid *uids; - int nsigs; - u32 *sigs; - struct fixup_list *fixups; - int fixup_out_of_core; - - struct keyid_list *temp_kids; - struct membuf bufbuf; /* temporary store for the blob */ - struct membuf *buf; -}; - - - -/* A simple implemention of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - -static void -put8 (struct membuf *mb, byte a ) -{ - put_membuf (mb, &a, 1); -} - -static void -put16 (struct membuf *mb, u16 a ) -{ - unsigned char tmp[2]; - tmp[0] = a>>8; - tmp[1] = a; - put_membuf (mb, tmp, 2); -} - -static void -put32 (struct membuf *mb, u32 a ) -{ - unsigned char tmp[4]; - tmp[0] = a>>24; - tmp[1] = a>>16; - tmp[2] = a>>8; - tmp[3] = a; - put_membuf (mb, tmp, 4); -} - - -/* Store a value in the fixup list */ -static void -add_fixup (KEYBOXBLOB blob, u32 off, u32 val) -{ - struct fixup_list *fl; - - if (blob->fixup_out_of_core) - return; - - fl = xtrycalloc(1, sizeof *fl); - if (!fl) - blob->fixup_out_of_core = 1; - else - { - fl->off = off; - fl->val = val; - fl->next = blob->fixups; - blob->fixups = fl; - } -} - - -/* - Some wrappers -*/ - -static u32 -make_timestamp (void) -{ - return time(NULL); -} - - - -#ifdef KEYBOX_WITH_OPENPGP -/* - OpenPGP specific stuff -*/ - - -/* - We must store the keyid at some place because we can't calculate the - offset yet. This is only used for v3 keyIDs. Function returns an - index value for later fixup or -1 for out of core. The value must be - a non-zero value */ -static int -pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) -{ - struct keyid_list *k, *r; - - k = xtrymalloc (sizeof *k); - if (!k) - return -1; - k->kid[0] = pk->keyid[0] >> 24 ; - k->kid[1] = pk->keyid[0] >> 16 ; - k->kid[2] = pk->keyid[0] >> 8 ; - k->kid[3] = pk->keyid[0] ; - k->kid[4] = pk->keyid[0] >> 24 ; - k->kid[5] = pk->keyid[0] >> 16 ; - k->kid[6] = pk->keyid[0] >> 8 ; - k->kid[7] = pk->keyid[0] ; - k->seqno = 0; - k->next = blob->temp_kids; - blob->temp_kids = k; - for (r=k; r; r = r->next) - k->seqno++; - - return k->seqno; -} - -static int -pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - size_t fprlen; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if ( node->pkt->pkttype == PKT_PUBLIC_KEY - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) - { - PKT_public_key *pk = node->pkt->pkt.public_key; - char tmp[20]; - - fingerprint_from_pk (pk, tmp , &fprlen); - memcpy (blob->keys[n].fpr, tmp, 20); - if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/ - { - assert (fprlen == 16); - memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16); - memset (blob->keys[n].fpr, 0, 4); - blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk); - } - else - { - blob->keys[n].off_kid = 0; /* will be fixed up later */ - } - blob->keys[n].flags = 0; - n++; - } - else if ( node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - { - never_reached (); /* actually not yet implemented */ - } - } - assert (n == blob->nkeys); - return 0; -} - -static int -pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *u = node->pkt->pkt.user_id; - - blob->uids[n].len = u->len; - blob->uids[n].flags = 0; - blob->uids[n].validity = 0; - n++; - } - } - assert (n == blob->nuids); - return 0; -} - -static int -pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *sig = node->pkt->pkt.signature; - - blob->sigs[n] = 0; /* FIXME: check the signature here */ - n++; - } - } - assert( n == blob->nsigs ); - return 0; -} - -static int -pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock) -{ - struct membuf *a = blob->buf; - KBNODE node; - int rc; - int n; - u32 kbstart = a->len; - - add_fixup (blob, kbstart); - - for (n = 0, node = keyblock; node; node = node->next) - { - rc = build_packet ( a, node->pkt ); - if ( rc ) { - gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - return GPGERR_WRITE_FILE; - } - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *u = node->pkt->pkt.user_id; - /* build_packet has set the offset of the name into u ; - * now we can do the fixup */ - add_fixup (blob, blob->uids[n].off_addr, u->stored_at); - n++; - } - } - assert (n == blob->nuids); - - add_fixup (blob, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_OPENPGP*/ - - -#ifdef KEYBOX_WITH_X509 -/* - X.509 specific stuff - */ - -/* Write the raw certificate out */ -static int -x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert) -{ - struct membuf *a = blob->buf; - const unsigned char *image; - size_t length; - u32 kbstart = a->len; - - /* Store our offset for later fixup */ - add_fixup (blob, 8, kbstart); - - image = ksba_cert_get_image (cert, &length); - if (!image) - return gpg_error (GPG_ERR_GENERAL); - put_membuf (a, image, length); - - add_fixup (blob, 12, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ - -/* Write a stored keyID out to the buffer */ -static void -write_stored_kid (KEYBOXBLOB blob, int seqno) -{ - struct keyid_list *r; - - for ( r = blob->temp_kids; r; r = r->next ) - { - if (r->seqno == seqno ) - { - put_membuf (blob->buf, r->kid, 8); - return; - } - } - never_reached (); -} - -/* Release a list of key IDs */ -static void -release_kid_list (struct keyid_list *kl) -{ - struct keyid_list *r, *r2; - - for ( r = kl; r; r = r2 ) - { - r2 = r->next; - xfree (r); - } -} - - - -static int -create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) -{ - struct membuf *a = blob->buf; - int i; - - put32 ( a, 0 ); /* blob length, needs fixup */ - put8 ( a, blobtype); - put8 ( a, 1 ); /* blob type version */ - put16 ( a, as_ephemeral? 2:0 ); /* blob flags */ - - put32 ( a, 0 ); /* offset to the raw data, needs fixup */ - put32 ( a, 0 ); /* length of the raw data, needs fixup */ - - put16 ( a, blob->nkeys ); - put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */ - for ( i=0; i < blob->nkeys; i++ ) - { - put_membuf (a, blob->keys[i].fpr, 20); - blob->keys[i].off_kid_addr = a->len; - put32 ( a, 0 ); /* offset to keyid, fixed up later */ - put16 ( a, blob->keys[i].flags ); - put16 ( a, 0 ); /* reserved */ - } - - put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/ - if (blob->serial) - put_membuf (a, blob->serial, blob->seriallen); - - put16 ( a, blob->nuids ); - put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].off_addr = a->len; - put32 ( a, 0 ); /* offset to userid, fixed up later */ - put32 ( a, blob->uids[i].len ); - put16 ( a, blob->uids[i].flags ); - put8 ( a, 0 ); /* validity */ - put8 ( a, 0 ); /* reserved */ - } - - put16 ( a, blob->nsigs ); - put16 ( a, 4 ); /* size of sig info */ - for (i=0; i < blob->nsigs; i++) - { - put32 ( a, blob->sigs[i]); - } - - put8 ( a, 0 ); /* assigned ownertrust */ - put8 ( a, 0 ); /* validity of all user IDs */ - put16 ( a, 0 ); /* reserved */ - put32 ( a, 0 ); /* time of next recheck */ - put32 ( a, 0 ); /* newest timestamp (none) */ - put32 ( a, make_timestamp() ); /* creation time */ - put32 ( a, 0 ); /* size of reserved space */ - /* reserved space (which is currently of size 0) */ - - /* space where we write keyIDs and and other stuff so that the - pointers can actually point to somewhere */ - if (blobtype == BLOBTYPE_PGP) - { - /* We need to store the keyids for all pgp v3 keys because those key - IDs are not part of the fingerprint. While we are doing that, we - fixup all the keyID offsets */ - for (i=0; i < blob->nkeys; i++ ) - { - if (blob->keys[i].off_kid) - { /* this is a v3 one */ - add_fixup (blob, blob->keys[i].off_kid_addr, a->len); - write_stored_kid (blob, blob->keys[i].off_kid); - } - else - { /* the better v4 key IDs - just store an offset 8 bytes back */ - add_fixup (blob, blob->keys[i].off_kid_addr, - blob->keys[i].off_kid_addr - 8); - } - } - } - - if (blobtype == BLOBTYPE_X509) - { - /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to - the utf-8 string represenation of them */ - for (i=0; i < blob->nuids; i++ ) - { - if (blob->uids[i].name) - { /* this is a v3 one */ - add_fixup (blob, blob->uids[i].off_addr, a->len); - put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len); - } - } - } - - return 0; -} - - - -static int -create_blob_trailer (KEYBOXBLOB blob) -{ - return 0; -} - - -static int -create_blob_finish (KEYBOXBLOB blob) -{ - struct membuf *a = blob->buf; - byte *p; - char *pp; - int i; - size_t n; - - /* write a placeholder for the checksum */ - for (i = 0; i < 16; i++ ) - put32 (a, 0); /* Hmmm: why put32() ?? */ - - /* get the memory area */ - p = get_membuf (a, &n); - if (!p) - return gpg_error (GPG_ERR_ENOMEM); - assert (n >= 20); - - /* fixup the length */ - add_fixup (blob, 0, n); - - /* do the fixups */ - if (blob->fixup_out_of_core) - return gpg_error (GPG_ERR_ENOMEM); - - { - struct fixup_list *fl; - for (fl = blob->fixups; fl; fl = fl->next) - { - assert (fl->off+4 <= n); - p[fl->off+0] = fl->val >> 24; - p[fl->off+1] = fl->val >> 16; - p[fl->off+2] = fl->val >> 8; - p[fl->off+3] = fl->val; - } - } - - /* calculate and store the MD5 checksum */ - gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16); - - pp = xtrymalloc (n); - if ( !pp ) - return gpg_error (gpg_err_code_from_errno (errno)); - memcpy (pp , p, n); - blob->blob = pp; - blob->bloblen = n; - - return 0; -} - - -#ifdef KEYBOX_WITH_OPENPGP - -int -_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) -{ - int rc = 0; - KBNODE node; - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if (!blob) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* fixme: Do some sanity checks on the keyblock */ - - /* count userids and keys so that we can allocate the arrays */ - for (node = keyblock; node; node = node->next) - { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: blob->nkeys++; break; - case PKT_USER_ID: blob->nuids++; break; - case PKT_SIGNATURE: blob->nsigs++; break; - default: break; - } - } - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = gpg_error (GPG_ERR_ENOMEM); - goto leave; - } - - rc = pgp_create_key_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_uid_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_sig_part ( blob, keyblock ); - if (rc) - goto leave; - - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral); - if (rc) - goto leave; - rc = pgp_create_blob_keyblock (blob, keyblock); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (rc) - { - keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_OPENPGP*/ - -#ifdef KEYBOX_WITH_X509 - -/* return an allocated string with the email address extracted from a - DN */ -static char * -x509_email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - -/* Note: We should move calculation of the digest into libksba and - remove that parameter */ -int -_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, - unsigned char *sha1_digest, int as_ephemeral) -{ - int i, rc = 0; - KEYBOXBLOB blob; - unsigned char *p; - unsigned char **names = NULL; - size_t max_names; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if( !blob ) - return gpg_error (gpg_err_code_from_errno (errno)); - - p = ksba_cert_get_serial (cert); - if (p) - { - size_t n, len; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (n < 2) - { - xfree (p); - return gpg_error (GPG_ERR_GENERAL); - } - blob->serialbuf = p; - p++; n--; /* skip '(' */ - for (len=0; n && *p && *p != ':' && digitp (p); n--, p++) - len = len*10 + atoi_1 (p); - if (*p != ':') - { - xfree (blob->serialbuf); - blob->serialbuf = NULL; - return gpg_error (GPG_ERR_GENERAL); - } - p++; - blob->serial = p; - blob->seriallen = len; - } - - blob->nkeys = 1; - - /* create list of names */ - blob->nuids = 0; - max_names = 100; - names = xtrymalloc (max_names * sizeof *names); - if (!names) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - p = ksba_cert_get_issuer (cert, 0); - if (!p) - { - rc = gpg_error (GPG_ERR_MISSING_VALUE); - goto leave; - } - names[blob->nuids++] = p; - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - - if (blob->nuids >= max_names) - { - unsigned char **tmp; - - max_names += 100; - tmp = xtryrealloc (names, max_names * sizeof *names); - if (!tmp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - names[blob->nuids++] = p; - if (!i && (p=x509_email_kludge (p))) - names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/ - } - - /* space for signature information */ - blob->nsigs = 1; - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = gpg_error (GPG_ERR_ENOMEM); - goto leave; - } - - memcpy (blob->keys[0].fpr, sha1_digest, 20); - blob->keys[0].off_kid = 0; /* We don't have keyids */ - blob->keys[0].flags = 0; - - /* issuer and subject names */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].name = names[i]; - blob->uids[i].len = strlen(names[i]); - names[i] = NULL; - blob->uids[i].flags = 0; - blob->uids[i].validity = 0; - } - xfree (names); - names = NULL; - - /* signatures */ - blob->sigs[0] = 0; /* not yet checked */ - - /* Create a temporary buffer for further processing */ - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - /* write out what we already have */ - rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral); - if (rc) - goto leave; - rc = x509_create_blob_cert (blob, cert); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (blob && names) - { - for (i=0; i < blob->nuids; i++) - xfree (names[i]); - } - xfree (names); - if (rc) - { - _keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_X509*/ - - - -int -_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off) -{ - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if (!blob) - return gpg_error (gpg_err_code_from_errno (errno)); - - blob->blob = image; - blob->bloblen = imagelen; - blob->fileoffset = off; - *r_blob = blob; - return 0; -} - - -void -_keybox_release_blob (KEYBOXBLOB blob) -{ - int i; - if (!blob) - return; - /* hmmm: release membuf here?*/ - xfree (blob->keys ); - xfree (blob->serialbuf); - for (i=0; i < blob->nuids; i++) - xfree (blob->uids[i].name); - xfree (blob->uids ); - xfree (blob->sigs ); - xfree (blob->blob ); - xfree (blob ); -} - - - -const char * -_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) -{ - *n = blob->bloblen; - return blob->blob; -} - -off_t -_keybox_get_blob_fileoffset (KEYBOXBLOB blob) -{ - return blob->fileoffset; -} - - - -void -_keybox_update_header_blob (KEYBOXBLOB blob) -{ - if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER) - { - u32 val = make_timestamp (); - - /* Update the last maintenance run times tamp. */ - blob->blob[20] = (val >> 24); - blob->blob[20+1] = (val >> 16); - blob->blob[20+2] = (val >> 8); - blob->blob[20+3] = (val ); - } -} diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h deleted file mode 100644 index 759289a0e..000000000 --- a/kbx/keybox-defs.h +++ /dev/null @@ -1,191 +0,0 @@ -/* keybox-defs.h - interal Keybox defintions - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef KEYBOX_DEFS_H -#define KEYBOX_DEFS_H 1 - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_KEYBOX - -#include <gpg-error.h> -#include <sys/types.h> /* off_t */ - -/* We include the type defintions from jnlib instead of defining our - owns here. This will not allow us build KBX in a standalone way - but tehre is currently no need for it anyway. */ -#include "../jnlib/types.h" - -#include "keybox.h" - - -enum { - BLOBTYPE_EMPTY = 0, - BLOBTYPE_HEADER = 1, - BLOBTYPE_PGP = 2, - BLOBTYPE_X509 = 3 -}; - - -typedef struct keyboxblob *KEYBOXBLOB; - - -typedef struct keybox_name *KB_NAME; -typedef struct keybox_name const * CONST_KB_NAME; -struct keybox_name { - struct keybox_name *next; - int secret; - /*DOTLOCK lockhd;*/ - int is_locked; - int did_full_scan; - char fname[1]; -}; - - - -struct keybox_handle { - CONST_KB_NAME kb; - int secret; /* this is for a secret keybox */ - FILE *fp; - int eof; - int error; - int ephemeral; - struct { - KEYBOXBLOB blob; - off_t offset; - size_t pk_no; - size_t uid_no; - unsigned int n_packets; /*used for delete and update*/ - } found; - struct { - char *name; - char *pattern; - } word_match; -}; - - -/* Don't know whether this is needed: */ -/* static struct { */ -/* const char *homedir; */ -/* int dry_run; */ -/* int quiet; */ -/* int verbose; */ -/* int preserve_permissions; */ -/* } keybox_opt; */ - - -/*-- keybox-blob.c --*/ -#ifdef KEYBOX_WITH_OPENPGP - /* fixme */ -#endif /*KEYBOX_WITH_OPENPGP*/ -#ifdef KEYBOX_WITH_X509 -int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, - unsigned char *sha1_digest, int as_ephemeral); -#endif /*KEYBOX_WITH_X509*/ - -int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, - off_t off); -void _keybox_release_blob (KEYBOXBLOB blob); -const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); -off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); -void _keybox_update_header_blob (KEYBOXBLOB blob); - -/*-- keybox-file.c --*/ -int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); -int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted); -int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_write_header_blob (FILE *fp); - -/*-- keybox-search.c --*/ -gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer, - size_t length, - int what, - size_t *flag_off, size_t *flag_size); - -/*-- keybox-dump.c --*/ -int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp); - - -/*-- keybox-util.c --*/ -void *_keybox_malloc (size_t n); -void *_keybox_calloc (size_t n, size_t m); -void *_keybox_realloc (void *p, size_t n); -void _keybox_free (void *p); - -#define xtrymalloc(a) _keybox_malloc ((a)) -#define xtrycalloc(a,b) _keybox_calloc ((a),(b)) -#define xtryrealloc(a,b) _keybox_realloc((a),(b)) -#define xfree(a) _keybox_free ((a)) - - -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - -/* - a couple of handy macros -*/ - -#define return_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return; \ - } } while (0) -#define return_null_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return NULL; \ - } } while (0) -#define return_val_if_fail(expr,val) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return (val); \ - } } while (0) -#define never_reached() do { \ - fprintf (stderr, "%s:%d: oops; should never get here\n", \ - __FILE__, __LINE__ ); \ - } while (0) - - -/* some macros to replace ctype ones and avoid locale problems */ -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - -#endif /*KEYBOX_DEFS_H*/ - - diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c deleted file mode 100644 index 495fb249e..000000000 --- a/kbx/keybox-dump.c +++ /dev/null @@ -1,484 +0,0 @@ -/* keybox-dump.c - Debug helpers - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "keybox-defs.h" - -static ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - -void -print_string (FILE *fp, const byte *p, size_t n, int delim) -{ - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim) - { - putc('\\', fp); - if( *p == '\n' ) - putc('n', fp); - else if( *p == '\r' ) - putc('r', fp); - else if( *p == '\f' ) - putc('f', fp); - else if( *p == '\v' ) - putc('v', fp); - else if( *p == '\b' ) - putc('b', fp); - else if( !*p ) - putc('0', fp); - else - fprintf(fp, "x%02x", *p ); - } - else - putc(*p, fp); - } -} - - -static int -dump_header_blob (const byte *buffer, size_t length, FILE *fp) -{ - unsigned long n; - - if (length < 32) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - fprintf (fp, "Version: %d\n", buffer[5]); - if ( memcmp (buffer+8, "KBXf", 4)) - fprintf (fp, "[Error: invalid magic number]\n"); - - n = get32 (buffer+16); - fprintf( fp, "created-at: %lu\n", n ); - n = get32 (buffer+20); - fprintf( fp, "last-maint: %lu\n", n ); - - return 0; -} - - -/* Dump one block to FP */ -int -_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) -{ - const byte *buffer; - size_t length; - int type; - ulong n, nkeys, keyinfolen; - ulong nuids, uidinfolen; - ulong nsigs, siginfolen; - ulong rawdata_off, rawdata_len; - ulong nserial; - const byte *p; - - buffer = _keybox_get_blob_image (blob, &length); - - if (length < 32) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - - n = get32( buffer ); - if (n > length) - fprintf (fp, "[blob larger than length - output truncated]\n"); - else - length = n; /* ignore the rest */ - - fprintf (fp, "Length: %lu\n", n ); - type = buffer[4]; - switch (type) - { - case BLOBTYPE_EMPTY: - fprintf (fp, "Type: Empty\n"); - return 0; - - case BLOBTYPE_HEADER: - fprintf (fp, "Type: Header\n"); - return dump_header_blob (buffer, length, fp); - case BLOBTYPE_PGP: - fprintf (fp, "Type: OpenPGP\n"); - break; - case BLOBTYPE_X509: - fprintf (fp, "Type: X.509\n"); - break; - default: - fprintf (fp, "Type: %d\n", type); - fprintf (fp, "[can't dump this blob type]\n"); - return 0; - } - fprintf (fp, "Version: %d\n", buffer[5]); - - if (length < 40) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - - n = get16 (buffer + 6); - fprintf( fp, "Blob-Flags: %04lX", n); - if (n) - { - int any = 0; - - fputs (" (", fp); - if ((n & 1)) - { - fputs ("secret", fp); - any++; - } - if ((n & 2)) - { - if (any) - putc (',', fp); - fputs ("ephemeral", fp); - any++; - } - putc (')', fp); - } - putc ('\n', fp); - - rawdata_off = get32 (buffer + 8); - rawdata_len = get32 (buffer + 12); - - fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); - fprintf( fp, "Data-Length: %lu\n", rawdata_len ); - - nkeys = get16 (buffer + 16); - fprintf (fp, "Key-Count: %lu\n", nkeys ); - if (!nkeys) - fprintf (fp, "[Error: no keys]\n"); - if (nkeys > 1 && type == BLOBTYPE_X509) - fprintf (fp, "[Error: only one key allowed for X509]\n"); - - keyinfolen = get16 (buffer + 18 ); - fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen); - /* fixme: check bounds */ - p = buffer + 20; - for (n=0; n < nkeys; n++, p += keyinfolen) - { - int i; - ulong kidoff, kflags; - - fprintf (fp, "Key-Fpr[%lu]: ", n ); - for (i=0; i < 20; i++ ) - fprintf (fp, "%02X", p[i]); - kidoff = get32 (p + 20); - fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff ); - fprintf (fp, "Key-Kid[%lu]: ", n ); - /* fixme: check bounds */ - for (i=0; i < 8; i++ ) - fprintf (fp, "%02X", buffer[kidoff+i] ); - kflags = get16 (p + 24 ); - fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags); - } - - /* serial number */ - fputs ("Serial-No: ", fp); - nserial = get16 (p); - p += 2; - if (!nserial) - fputs ("none", fp); - else - { - for (; nserial; nserial--, p++) - fprintf (fp, "%02X", *p); - } - putc ('\n', fp); - - /* user IDs */ - nuids = get16 (p); - fprintf (fp, "Uid-Count: %lu\n", nuids ); - uidinfolen = get16 (p + 2); - fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nuids; n++, p += uidinfolen) - { - ulong uidoff, uidlen, uflags; - - uidoff = get32( p ); - uidlen = get32( p+4 ); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Off: %lu\n", uidoff ); - fprintf (fp, "Issuer-Len: %lu\n", uidlen ); - fprintf (fp, "Issuer: \""); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Off: %lu\n", uidoff ); - fprintf (fp, "Subject-Len: %lu\n", uidlen ); - fprintf (fp, "Subject: \""); - } - else - { - fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff ); - fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen ); - fprintf (fp, "Uid[%lu]: \"", n ); - } - print_string (fp, buffer+uidoff, uidlen, '\"'); - fputs ("\"\n", fp); - uflags = get16 (p + 8); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Flags: %04lX\n", uflags ); - fprintf (fp, "Issuer-Validity: %d\n", p[10] ); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Flags: %04lX\n", uflags ); - fprintf (fp, "Subject-Validity: %d\n", p[10] ); - } - else - { - fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags ); - fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] ); - } - } - - nsigs = get16 (p); - fprintf (fp, "Sig-Count: %lu\n", nsigs ); - siginfolen = get16 (p + 2); - fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen ); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nsigs; n++, p += siginfolen) - { - ulong sflags; - - sflags = get32 (p); - fprintf (fp, "Sig-Expire[%lu]: ", n ); - if (!sflags) - fputs ("[not checked]", fp); - else if (sflags == 1 ) - fputs ("[missing key]", fp); - else if (sflags == 2 ) - fputs ("[bad signature]", fp); - else if (sflags < 0x10000000) - fprintf (fp, "[bad flag %0lx]", sflags); - else if (sflags == 0xffffffff) - fputs ("0", fp ); - else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); - putc ('\n', fp ); - } - - fprintf (fp, "Ownertrust: %d\n", p[0] ); - fprintf (fp, "All-Validity: %d\n", p[1] ); - p += 4; - n = get32 (p); p += 4; - fprintf (fp, "Recheck-After: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf( fp, "Latest-Timestamp: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf (fp, "Created-At: %lu\n", n ); - n = get32 (p ); p += 4; - fprintf (fp, "Reserved-Space: %lu\n", n ); - - /* check that the keyblock is at the correct offset and other bounds */ - /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/ - return 0; -} - - -struct file_stats_s -{ - unsigned long too_short_blobs; - unsigned long too_large_blobs; - unsigned long total_blob_count; - unsigned long empty_blob_count; - unsigned long header_blob_count; - unsigned long pgp_blob_count; - unsigned long x509_blob_count; - unsigned long unknown_blob_count; - unsigned long non_flagged; - unsigned long secret_flagged; - unsigned long ephemeral_flagged; -}; - -static int -update_stats (KEYBOXBLOB blob, struct file_stats_s *s) -{ - const unsigned char *buffer; - size_t length; - int type; - unsigned long n; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 32) - { - s->too_short_blobs++; - return -1; - } - - n = get32( buffer ); - if (n > length) - s->too_large_blobs++; - else - length = n; /* ignore the rest */ - - s->total_blob_count++; - type = buffer[4]; - switch (type) - { - case BLOBTYPE_EMPTY: - s->empty_blob_count++; - return 0; - case BLOBTYPE_HEADER: - s->header_blob_count++; - return 0; - case BLOBTYPE_PGP: - s->pgp_blob_count++; - break; - case BLOBTYPE_X509: - s->x509_blob_count++; - break; - default: - s->unknown_blob_count++; - return 0; - } - - if (length < 40) - { - s->too_short_blobs++; - return -1; - } - - n = get16 (buffer + 6); - if (n) - { - if ((n & 1)) - s->secret_flagged++; - if ((n & 2)) - s->ephemeral_flagged++; - } - else - s->non_flagged++; - - return 0; -} - - - -int -_keybox_dump_file (const char *filename, int stats_only, FILE *outfp) -{ - FILE *fp; - KEYBOXBLOB blob; - int rc; - unsigned long count = 0; - struct file_stats_s stats; - - memset (&stats, 0, sizeof stats); - - if (!filename) - { - filename = "-"; - fp = stdin; - } - else - fp = fopen (filename, "rb"); - if (!fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno)); - return tmperr; - } - - while ( !(rc = _keybox_read_blob (&blob, fp)) ) - { - if (stats_only) - { - update_stats (blob, &stats); - } - else - { - fprintf (outfp, "BEGIN-RECORD: %lu\n", count ); - _keybox_dump_blob (blob, outfp); - fprintf (outfp, "END-RECORD\n"); - } - _keybox_release_blob (blob); - count++; - } - if (rc == -1) - rc = 0; - if (rc) - fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc)); - - if (fp != stdin) - fclose (fp); - - if (stats_only) - { - fprintf (outfp, - "Total number of blobs: %8lu\n" - " header: %8lu\n" - " empty: %8lu\n" - " openpgp: %8lu\n" - " x509: %8lu\n" - " non flagged: %8lu\n" - " secret flagged: %8lu\n" - " ephemeral flagged: %8lu\n", - stats.total_blob_count, - stats.header_blob_count, - stats.empty_blob_count, - stats.pgp_blob_count, - stats.x509_blob_count, - stats.non_flagged, - stats.secret_flagged, - stats.ephemeral_flagged); - if (stats.unknown_blob_count) - fprintf (outfp, " unknown blob types: %8lu\n", - stats.unknown_blob_count); - if (stats.too_short_blobs) - fprintf (outfp, " too short blobs: %8lu\n", - stats.too_short_blobs); - if (stats.too_large_blobs) - fprintf (outfp, " too large blobs: %8lu\n", - stats.too_large_blobs); - } - - return rc; -} diff --git a/kbx/keybox-errors.c b/kbx/keybox-errors.c deleted file mode 100644 index e11efc10b..000000000 --- a/kbx/keybox-errors.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Generated automatically by mkerrors */ -/* Do not edit! */ - -#include <stdio.h> -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { - case KEYBOX_No_Error: s="no error"; break; - case KEYBOX_General_Error: s="general error"; break; - case KEYBOX_Out_Of_Core: s="out of core"; break; - case KEYBOX_Invalid_Value: s="invalid value"; break; - case KEYBOX_Timeout: s="timeout"; break; - case KEYBOX_Read_Error: s="read error"; break; - case KEYBOX_Write_Error: s="write error"; break; - case KEYBOX_File_Error: s="file error"; break; - case KEYBOX_Blob_Too_Short: s="blob too short"; break; - case KEYBOX_Blob_Too_Large: s="blob too large"; break; - case KEYBOX_Invalid_Handle: s="invalid handle"; break; - case KEYBOX_File_Create_Error: s="file create error"; break; - case KEYBOX_File_Open_Error: s="file open error"; break; - case KEYBOX_File_Close_Error: s="file close error"; break; - case KEYBOX_Nothing_Found: s="nothing found"; break; - case KEYBOX_Wrong_Blob_Type: s="wrong blob type"; break; - case KEYBOX_Missing_Value: s="missing value"; break; - default: sprintf (buf, "ec=%d", err ); s=buf; break; - } - - return s; -} - diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c deleted file mode 100644 index db3164fef..000000000 --- a/kbx/keybox-file.c +++ /dev/null @@ -1,146 +0,0 @@ -/* keybox-file.c - file oeprations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <time.h> - -#include "keybox-defs.h" - -/* Read a block at the current postion and return it in r_blob. - r_blob may be NULL to simply skip the current block */ -int -_keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) -{ - char *image; - size_t imagelen = 0; - int c1, c2, c3, c4, type; - int rc; - off_t off; - - *skipped_deleted = 0; - again: - *r_blob = NULL; - off = ftello (fp); - if (off == (off_t)-1) - return gpg_error (gpg_err_code_from_errno (errno)); - - if ((c1 = getc (fp)) == EOF - || (c2 = getc (fp)) == EOF - || (c3 = getc (fp)) == EOF - || (c4 = getc (fp)) == EOF - || (type = getc (fp)) == EOF) - { - if ( c1 == EOF && !ferror (fp) ) - return -1; /* eof */ - return gpg_error (gpg_err_code_from_errno (errno)); - } - - imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; - if (imagelen > 500000) /* Sanity check. */ - return gpg_error (GPG_ERR_TOO_LARGE); - - if (imagelen < 5) - return gpg_error (GPG_ERR_TOO_SHORT); - - if (!type) - { - /* Special treatment for empty blobs. */ - if (fseek (fp, imagelen-5, SEEK_CUR)) - return gpg_error (gpg_err_code_from_errno (errno)); - *skipped_deleted = 1; - goto again; - } - - image = xtrymalloc (imagelen); - if (!image) - return gpg_error (gpg_err_code_from_errno (errno)); - - image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type; - if (fread (image+5, imagelen-5, 1, fp) != 1) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (image); - return tmperr; - } - - rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0; - if (rc || !r_blob) - xfree (image); - return rc; -} - -int -_keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp) -{ - int dummy; - return _keybox_read_blob2 (r_blob, fp, &dummy); -} - - -/* Write the block to the current file position */ -int -_keybox_write_blob (KEYBOXBLOB blob, FILE *fp) -{ - const char *image; - size_t length; - - image = _keybox_get_blob_image (blob, &length); - if (fwrite (image, length, 1, fp) != 1) - return gpg_error (gpg_err_code_from_errno (errno)); - return 0; -} - - -/* Write a fresh header type blob. */ -int -_keybox_write_header_blob (FILE *fp) -{ - unsigned char image[32]; - u32 val; - - memset (image, 0, sizeof image); - /* Length of this blob. */ - image[3] = 32; - - image[4] = BLOBTYPE_HEADER; - image[5] = 1; /* Version */ - - memcpy (image+8, "KBXf", 4); - val = time (NULL); - /* created_at and last maintenance run. */ - image[16] = (val >> 24); - image[16+1] = (val >> 16); - image[16+2] = (val >> 8); - image[16+3] = (val ); - image[20] = (val >> 24); - image[20+1] = (val >> 16); - image[20+2] = (val >> 8); - image[20+3] = (val ); - - if (fwrite (image, 32, 1, fp) != 1) - return gpg_error (gpg_err_code_from_errno (errno)); - return 0; -} - - diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c deleted file mode 100644 index e11c4f09c..000000000 --- a/kbx/keybox-init.c +++ /dev/null @@ -1,127 +0,0 @@ -/* keybox-init.c - Initalization of the library - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> - -#include "keybox-defs.h" - -#define compare_filenames strcmp - -static KB_NAME kb_names; - - -/* - Register a filename for plain keybox files. Returns a pointer to be - used to create a handles etc or NULL to indicate that it has already - been registered */ -void * -keybox_register_file (const char *fname, int secret) -{ - KB_NAME kr; - - for (kr=kb_names; kr; kr = kr->next) - { - if ( !compare_filenames (kr->fname, fname) ) - return NULL; /* already registered */ - } - - kr = xtrymalloc (sizeof *kr + strlen (fname)); - if (!kr) - return NULL; - strcpy (kr->fname, fname); - kr->secret = !!secret; - /* kr->lockhd = NULL;*/ - kr->is_locked = 0; - kr->did_full_scan = 0; - /* keep a list of all issued pointers */ - kr->next = kb_names; - kb_names = kr; - - /* create the offset table the first time a function here is used */ -/* if (!kb_offtbl) */ -/* kb_offtbl = new_offset_hash_table (); */ - - return kr; -} - -int -keybox_is_writable (void *token) -{ - KB_NAME r = token; - - return r? !access (r->fname, W_OK) : 0; -} - - - -/* Create a new handle for the resource associated with TOKEN. SECRET - is just a cross-check. - - The returned handle must be released using keybox_release (). */ -KEYBOX_HANDLE -keybox_new (void *token, int secret) -{ - KEYBOX_HANDLE hd; - KB_NAME resource = token; - - assert (resource && !resource->secret == !secret); - hd = xtrycalloc (1, sizeof *hd); - if (hd) - { - hd->kb = resource; - hd->secret = !!secret; - } - return hd; -} - -void -keybox_release (KEYBOX_HANDLE hd) -{ - if (!hd) - return; - _keybox_release_blob (hd->found.blob); - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - xfree (hd); -} - - -const char * -keybox_get_resource_name (KEYBOX_HANDLE hd) -{ - if (!hd || !hd->kb) - return NULL; - return hd->kb->fname; -} - -int -keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - hd->ephemeral = yes; - return 0; -} - diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h deleted file mode 100644 index 4be59c27d..000000000 --- a/kbx/keybox-search-desc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-search-desc.h - Keybox serch description - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* - This file is a temporary kludge until we can come up with solution - to share this description between keybox and the application - specific keydb -*/ - -#ifndef KEYBOX_SEARCH_DESC_H -#define KEYBOX_SEARCH_DESC_H 1 - -typedef enum { - KEYDB_SEARCH_MODE_NONE, - KEYDB_SEARCH_MODE_EXACT, - KEYDB_SEARCH_MODE_SUBSTR, - KEYDB_SEARCH_MODE_MAIL, - KEYDB_SEARCH_MODE_MAILSUB, - KEYDB_SEARCH_MODE_MAILEND, - KEYDB_SEARCH_MODE_WORDS, - KEYDB_SEARCH_MODE_SHORT_KID, - KEYDB_SEARCH_MODE_LONG_KID, - KEYDB_SEARCH_MODE_FPR16, - KEYDB_SEARCH_MODE_FPR20, - KEYDB_SEARCH_MODE_FPR, - KEYDB_SEARCH_MODE_ISSUER, - KEYDB_SEARCH_MODE_ISSUER_SN, - KEYDB_SEARCH_MODE_SN, - KEYDB_SEARCH_MODE_SUBJECT, - KEYDB_SEARCH_MODE_FIRST, - KEYDB_SEARCH_MODE_NEXT -} KeydbSearchMode; - -struct keydb_search_desc { - KeydbSearchMode mode; - int (*skipfnc)(void *,void*); /* used to be: void*, u32* */ - void *skipfncvalue; - const unsigned char *sn; - int snlen; /* -1 := sn is a hex string */ - union { - const char *name; - unsigned char fpr[24]; - unsigned char kid[8]; - } u; -}; - - -struct keydb_search_desc; -typedef struct keydb_search_desc KEYDB_SEARCH_DESC; - -typedef struct keydb_search_desc KEYBOX_SEARCH_DESC; - - - -#endif /*KEYBOX_SEARCH_DESC_H*/ diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c deleted file mode 100644 index 2ce3c1923..000000000 --- a/kbx/keybox-search.c +++ /dev/null @@ -1,944 +0,0 @@ -/* keybox-search.c - Search operations - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <errno.h> - -#include "../jnlib/stringhelp.h" /* ascii_xxxx() */ - -#include "keybox-defs.h" - - -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - - -struct sn_array_s { - int snlen; - unsigned char *sn; -}; - - - -static inline ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static inline ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - - - -static inline int -blob_get_type (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 32) - return -1; /* blob too short */ - - return buffer[4]; -} - -static inline unsigned int -blob_get_blob_flags (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 8) - return 0; /* oops */ - - return get16 (buffer + 6); -} - - -/* Return information on the flag WHAT within the blob BUFFER,LENGTH. - Return the offset and the length (in bytes) of the flag in - FLAGOFF,FLAG_SIZE. */ -gpg_err_code_t -_keybox_get_flag_location (const unsigned char *buffer, size_t length, - int what, size_t *flag_off, size_t *flag_size) -{ - size_t pos; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - size_t nsigs, siginfolen; - - switch (what) - { - case KEYBOX_FLAG_BLOB: - if (length < 8) - return GPG_ERR_INV_OBJ; - *flag_off = 6; - *flag_size = 2; - break; - - case KEYBOX_FLAG_OWNERTRUST: - case KEYBOX_FLAG_VALIDITY: - case KEYBOX_FLAG_CREATED_AT: - if (length < 20) - return GPG_ERR_INV_OBJ; - /* Key info. */ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return GPG_ERR_INV_OBJ; - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return GPG_ERR_INV_OBJ; /* Out of bounds. */ - /* Serial number. */ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return GPG_ERR_INV_OBJ; /* Out of bounds. */ - /* User IDs. */ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 ) - return GPG_ERR_INV_OBJ; - pos += uidinfolen*nuids; - if (pos+4 > length) - return GPG_ERR_INV_OBJ ; /* Out of bounds. */ - /* Signature info. */ - nsigs = get16 (buffer + pos); pos += 2; - siginfolen = get16 (buffer + pos); pos += 2; - if (siginfolen < 4 ) - return GPG_ERR_INV_OBJ; - pos += siginfolen*nsigs; - if (pos+1+1+2+4+4+4+4 > length) - return GPG_ERR_INV_OBJ ; /* Out of bounds. */ - *flag_size = 1; - *flag_off = pos; - switch (what) - { - case KEYBOX_FLAG_VALIDITY: - *flag_off += 1; - break; - case KEYBOX_FLAG_CREATED_AT: - *flag_size = 4; - *flag_off += 1+2+4+4+4; - break; - default: - break; - } - break; - - default: - return GPG_ERR_INV_FLAG; - } - return 0; -} - - - -/* Return one of the flags WHAT in VALUE from teh blob BUFFER of - LENGTH bytes. Return 0 on success or an raw error code. */ -static gpg_err_code_t -get_flag_from_image (const unsigned char *buffer, size_t length, - int what, unsigned int *value) -{ - gpg_err_code_t ec; - size_t pos, size; - - *value = 0; - ec = _keybox_get_flag_location (buffer, length, what, &pos, &size); - if (!ec) - switch (size) - { - case 1: *value = buffer[pos]; break; - case 2: *value = get16 (buffer + pos); break; - case 4: *value = get32 (buffer + pos); break; - default: ec = GPG_ERR_BUG; break; - } - - return ec; -} - - -static int -blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - off = pos + 2; - if (off+nserial > length) - return 0; /* out of bounds */ - - return nserial == snlen && !memcmp (buffer+off, sn, snlen); -} - - -static int -blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off, fpr, 20)) - return 1; /* found */ - } - return 0; /* not found */ -} - -static int -blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, - int fproff, int fprlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off + fproff, fpr, fprlen)) - return 1; /* found */ - } - return 0; /* not found */ -} - - -static int -blob_cmp_name (KEYBOXBLOB blob, int idx, - const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (idx < 0) - { /* compare all names starting with that (negated) index */ - idx = -idx; - - for ( ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 1) - continue; /* empty name */ - if (substr) - { - if (ascii_memcasemem (buffer+off, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !memcmp (buffer+off, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ - } - else - { - if (idx > nuids) - return 0; /* no user ID with that idx */ - pos += idx*uidinfolen; - off = get32 (buffer+pos); - len = get32 (buffer+pos+4); - if (off+len > length) - return 0; /* out of bounds */ - if (len < 1) - return 0; /* empty name */ - - if (substr) - { - return !!ascii_memcasemem (buffer+off, len, name, namelen); - } - else - { - return len == namelen && !memcmp (buffer+off, name, len); - } - } -} - - -/* compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address */ -static int -blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - int idx; - - /* fixme: this code is common to blob_cmp_mail */ - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (namelen < 1) - return 0; - - for (idx=1 ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 2 || buffer[off] != '<') - continue; /* empty name or trailing 0 not stored */ - len--; /* one back */ - if ( len < 3 || buffer[off+len] != '>') - continue; /* not a proper email address */ - len--; - if (substr) - { - if (ascii_memcasemem (buffer+off+1, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ -} - - - - -/* - The has_foo functions are used as helpers for search -*/ -static inline int -has_short_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid+4, 16, 4); -} - -static inline int -has_long_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid, 12, 8); -} - -static inline int -has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr) -{ - return blob_cmp_fpr (blob, fpr); -} - - -static inline int -has_issuer (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0); -} - -static inline int -has_issuer_sn (KEYBOXBLOB blob, const char *name, - const unsigned char *sn, int snlen) -{ - size_t namelen; - - return_val_if_fail (name, 0); - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - - return (blob_cmp_sn (blob, sn, snlen) - && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0)); -} - -static inline int -has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - return blob_cmp_sn (blob, sn, snlen); -} - -static inline int -has_subject (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0); -} - -static inline int -has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, -1 /* all subject names*/, name, - namelen, substr); -} - - -static inline int -has_mail (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - if (namelen && name[namelen-1] == '>') - namelen--; - return blob_cmp_mail (blob, name, namelen, substr); -} - - -static void -release_sn_array (struct sn_array_s *array, size_t size) -{ - size_t n; - - for (n=0; n < size; n++) - xfree (array[n].sn); - xfree (array); -} - - -/* - - The search API - -*/ - -int -keybox_search_reset (KEYBOX_HANDLE hd) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - hd->error = 0; - hd->eof = 0; - return 0; -} - - -/* Note: When in ephemeral mode the search function does visit all - blobs but in standard mode, blobs flagged as ephemeral are ignored. */ -int -keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) -{ - int rc; - size_t n; - int need_words, any_skip; - KEYBOXBLOB blob = NULL; - struct sn_array_s *sn_array = NULL; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - /* clear last found result */ - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->error) - return hd->error; /* still in error state */ - if (hd->eof) - return -1; /* still EOF */ - - /* figure out what information we need */ - need_words = any_skip = 0; - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_WORDS: - need_words = 1; - break; - case KEYDB_SEARCH_MODE_FIRST: - /* always restart the search in this mode */ - keybox_search_reset (hd); - break; - default: - break; - } - if (desc[n].skipfnc) - any_skip = 1; - if (desc[n].snlen == -1 && !sn_array) - { - sn_array = xtrycalloc (ndesc, sizeof *sn_array); - if (!sn_array) - return (hd->error = gpg_error (gpg_err_code_from_errno (errno))); - } - } - - if (!hd->fp) - { - hd->fp = fopen (hd->kb->fname, "rb"); - if (!hd->fp) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - xfree (sn_array); - return hd->error; - } - } - - /* kludge: we need to convert an SN given as hexstring to it's - binary representation - in some cases we are not able to store it - in the search descriptor, because due to its usage it is not - possible to free allocated memory */ - if (sn_array) - { - const unsigned char *s; - int i, odd; - size_t snlen; - - for (n=0; n < ndesc; n++) - { - if (!desc[n].sn) - ; - else if (desc[n].snlen == -1) - { - unsigned char *sn; - - s = desc[n].sn; - for (i=0; *s && *s != '/'; s++, i++) - ; - odd = (i & 1); - snlen = (i+1)/2; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - release_sn_array (sn_array, n); - return hd->error; - } - sn_array[n].snlen = snlen; - sn = sn_array[n].sn; - s = desc[n].sn; - if (odd) - { - *sn++ = xtoi_1 (s); - s++; - } - for (; *s && *s != '/'; s += 2) - *sn++ = xtoi_2 (s); - } - else - { - const unsigned char *sn; - - sn = desc[n].sn; - snlen = desc[n].snlen; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - hd->error = gpg_error (gpg_err_code_from_errno (errno)); - release_sn_array (sn_array, n); - return hd->error; - } - sn_array[n].snlen = snlen; - memcpy (sn_array[n].sn, sn, snlen); - } - } - } - - - for (;;) - { - unsigned int blobflags; - - _keybox_release_blob (blob); blob = NULL; - rc = _keybox_read_blob (&blob, hd->fp); - if (rc) - break; - - if (blob_get_type (blob) == BLOBTYPE_HEADER) - continue; - - - blobflags = blob_get_blob_flags (blob); - if (!hd->ephemeral && (blobflags & 2)) - continue; /* not in ephemeral mode but blob is flagged ephemeral */ - - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_NONE: - never_reached (); - break; - case KEYDB_SEARCH_MODE_EXACT: - if (has_subject_or_alt (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAIL: - if (has_mail (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILSUB: - if (has_mail (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBSTR: - if (has_subject_or_alt (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: - never_reached (); /* not yet implemented */ - break; - case KEYDB_SEARCH_MODE_ISSUER: - if (has_issuer (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_ISSUER_SN: - if (has_issuer_sn (blob, desc[n].u.name, - sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SN: - if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBJECT: - if (has_subject (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_SHORT_KID: - if (has_short_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if (has_long_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR: - case KEYDB_SEARCH_MODE_FPR20: - if (has_fingerprint (blob, desc[n].u.fpr)) - goto found; - break; - case KEYDB_SEARCH_MODE_FIRST: - goto found; - break; - case KEYDB_SEARCH_MODE_NEXT: - goto found; - break; - default: - rc = gpg_error (GPG_ERR_INV_VALUE); - goto found; - } - } - continue; - found: - for (n=any_skip?0:ndesc; n < ndesc; n++) - { -/* if (desc[n].skipfnc */ -/* && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */ -/* break; */ - } - if (n == ndesc) - break; /* got it */ - } - - if (!rc) - { - hd->found.blob = blob; - } - else if (rc == -1) - { - _keybox_release_blob (blob); - hd->eof = 1; - } - else - { - _keybox_release_blob (blob); - hd->error = rc; - } - - if (sn_array) - release_sn_array (sn_array, ndesc); - - return rc; -} - - - - -/* - Functions to return a certificate or a keyblock. To be used after - a successful search operation. -*/ -#ifdef KEYBOX_WITH_X509 -/* - Return the last found cert. Caller must free it. - */ -int -keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *r_cert) -{ - const unsigned char *buffer; - size_t length; - size_t cert_off, cert_len; - ksba_reader_t reader = NULL; - ksba_cert_t cert = NULL; - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - if (blob_get_type (hd->found.blob) != BLOBTYPE_X509) - return gpg_error (GPG_ERR_WRONG_BLOB_TYPE); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - if (length < 40) - return gpg_error (GPG_ERR_TOO_SHORT); - cert_off = get32 (buffer+8); - cert_len = get32 (buffer+12); - if (cert_off+cert_len > length) - return gpg_error (GPG_ERR_TOO_SHORT); - - rc = ksba_reader_new (&reader); - if (rc) - return rc; - rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len); - if (rc) - { - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return gpg_error (GPG_ERR_GENERAL); - } - - rc = ksba_cert_new (&cert); - if (rc) - { - ksba_reader_release (reader); - return rc; - } - - rc = ksba_cert_read_der (cert, reader); - if (rc) - { - ksba_cert_release (cert); - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return gpg_error (GPG_ERR_GENERAL); - } - - *r_cert = cert; - ksba_reader_release (reader); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ - -/* Return the flags named WHAT at the address of VALUE. IDX is used - only for certain flags and should be 0 if not required. */ -int -keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value) -{ - const unsigned char *buffer; - size_t length; - gpg_err_code_t ec; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - ec = get_flag_from_image (buffer, length, what, value); - return ec? gpg_error (ec):0; -} - diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c deleted file mode 100644 index 16955502f..000000000 --- a/kbx/keybox-update.c +++ /dev/null @@ -1,698 +0,0 @@ -/* keybox-update.c - keybox update operations - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <unistd.h> - -#include "keybox-defs.h" - -#define EXTSEP_S "." - - -static int -create_tmp_file (const char *template, - char **r_bakfname, char **r_tmpfname, FILE **r_fp) -{ - char *bakfname, *tmpfname; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.kbx.tmp", "pubring.kbx"); - * but rename("pubring.kbx.tmp", "pubring.aaa"); - * works. So we replace .kbx by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") ) - { - bakfname = xtrymalloc (strlen (template) + 1); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); - - tmpfname = xtrymalloc (strlen (template) + 1); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (tmpfname,template); - strcpy (tmpfname + strlen (template)-4, EXTSEP_S "tmp"); - } - else - { /* file does not end with kbx; hmmm */ - bakfname = xtrymalloc ( strlen (template) + 5); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (stpcpy (bakfname, template), EXTSEP_S "bak"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (stpcpy (tmpfname, template), EXTSEP_S "tmp"); - } -# else /* Posix file names */ - bakfname = xtrymalloc (strlen (template) + 2); - if (!bakfname) - return gpg_error (gpg_err_code_from_errno (errno)); - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (bakfname); - return tmperr; - } - strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - *r_fp = fopen (tmpfname, "wb"); - if (!*r_fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - xfree (tmpfname); - xfree (bakfname); - return tmperr; - } - - *r_bakfname = bakfname; - *r_tmpfname = tmpfname; - return 0; -} - - -static int -rename_tmp_file (const char *bakfname, const char *tmpfname, - const char *fname, int secret ) -{ - int rc=0; - - /* restrict the permissions for secret keyboxs */ -#ifndef HAVE_DOSISH_SYSTEM -/* if (secret && !opt.preserve_permissions) */ -/* { */ -/* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */ -/* { */ -/* log_debug ("chmod of `%s' failed: %s\n", */ -/* tmpfname, strerror(errno) ); */ -/* return KEYBOX_Write_File; */ -/* } */ -/* } */ -#endif - - /* fixme: invalidate close caches (not used with stdio)*/ -/* iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); */ -/* iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); */ -/* iobuf_ioctl (NULL, 2, 0, (char*)fname ); */ - - /* first make a backup file except for secret keyboxs */ - if (!secret) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - return gpg_error (gpg_err_code_from_errno (errno)); - } - } - - /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (fname); -#endif - if (rename (tmpfname, fname) ) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - if (secret) - { -/* log_info ("WARNING: 2 files with confidential" */ -/* " information exists.\n"); */ -/* log_info ("%s is the unchanged one\n", fname ); */ -/* log_info ("%s is the new one\n", tmpfname ); */ -/* log_info ("Please fix this possible security flaw\n"); */ - } - return rc; - } - - return 0; -} - - - -/* Perform insert/delete/update operation. - mode 1 = insert - 2 = delete - 3 = update -*/ -static int -blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, - int secret, off_t start_offset, unsigned int n_packets ) -{ - FILE *fp, *newfp; - int rc=0; - char *bakfname = NULL; - char *tmpfname = NULL; - char buffer[4096]; - int nread, nbytes; - - /* Open the source file. Because we do a rename, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error (gpg_err_code_from_errno (errno)); - - fp = fopen (fname, "rb"); - if (mode == 1 && !fp && errno == ENOENT) - { - /* Insert mode but file does not exist: - Create a new keybox file. */ - newfp = fopen (fname, "wb"); - if (!newfp ) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = _keybox_write_header_blob (newfp); - if (rc) - return rc; - - rc = _keybox_write_blob (blob, newfp); - if (rc) - return rc; - - if ( fclose (newfp) ) - return gpg_error (gpg_err_code_from_errno (errno)); - -/* if (chmod( fname, S_IRUSR | S_IWUSR )) */ -/* { */ -/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */ -/* return KEYBOX_File_Error; */ -/* } */ - return 0; /* Ready. */ - } - - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - /* Create the new file. */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) - { - fclose(fp); - goto leave; - } - - /* prepare for insert */ - if (mode == 1) - { - /* Copy everything to the new file. */ - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - - /* Prepare for delete or update. */ - if ( mode == 2 || mode == 3 ) - { - off_t current = 0; - - /* Copy first part to the new file. */ - while ( current < start_offset ) - { - nbytes = DIM(buffer); - if (current + nbytes > start_offset) - nbytes = start_offset - current; - nread = fread (buffer, 1, nbytes, fp); - if (!nread) - break; - current += nread; - - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - /* Skip this blob. */ - rc = _keybox_read_blob (NULL, fp); - if (rc) - return rc; - } - - /* Do an insert or update. */ - if ( mode == 1 || mode == 3 ) - { - rc = _keybox_write_blob (blob, newfp); - if (rc) - return rc; - } - - /* Copy the rest of the packet for an delete or update. */ - if (mode == 2 || mode == 3) - { - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - } - - /* Close both files. */ - if (fclose(fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - fclose (newfp); - goto leave; - } - if (fclose(newfp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - rc = rename_tmp_file (bakfname, tmpfname, fname, secret); - - leave: - xfree(bakfname); - xfree(tmpfname); - return rc; -} - - - -#ifdef KEYBOX_WITH_X509 -int -keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest) -{ - int rc; - const char *fname; - KEYBOXBLOB blob; - - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - /* Close this one otherwise we will mess up the position for a next - search. Fixme: it would be better to adjust the position after - the write opertions. */ - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral); - if (!rc) - { - rc = blob_filecopy (1, fname, blob, hd->secret, 0, 0 ); - _keybox_release_blob (blob); - /* if (!rc && !hd->secret && kb_offtbl) */ - /* { */ - /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ - /* } */ - } - return rc; -} - -int -keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest) -{ - return -1; -} - - -#endif /*KEYBOX_WITH_X509*/ - -/* Note: We assume that the keybox has been locked before the current - search was executed. This is needed so that we can depend on the - offset information of the flags. */ -int -keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value) -{ - off_t off; - const char *fname; - FILE *fp; - gpg_err_code_t ec; - size_t flag_pos, flag_size; - const unsigned char *buffer; - size_t length; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - off = _keybox_get_blob_fileoffset (hd->found.blob); - if (off == (off_t)-1) - return gpg_error (GPG_ERR_GENERAL); - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - ec = _keybox_get_flag_location (buffer, length, what, &flag_pos, &flag_size); - if (ec) - return gpg_error (ec); - - off += flag_pos; - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - fp = fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error (gpg_err_code_from_errno (errno)); - - ec = 0; - if (fseeko (fp, off, SEEK_SET)) - ec = gpg_error (gpg_err_code_from_errno (errno)); - else - { - unsigned char tmp[4]; - - tmp[0] = value >> 24; - tmp[1] = value >> 16; - tmp[2] = value >> 8; - tmp[3] = value; - - switch (flag_size) - { - case 1: - case 2: - case 4: - if (fwrite (tmp+4-flag_size, flag_size, 1, fp) != 1) - ec = gpg_err_code_from_errno (errno); - break; - default: - ec = GPG_ERR_BUG; - break; - } - } - - if (fclose (fp)) - { - if (!ec) - ec = gpg_err_code_from_errno (errno); - } - - return gpg_error (ec); -} - - - -int -keybox_delete (KEYBOX_HANDLE hd) -{ - off_t off; - const char *fname; - FILE *fp; - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - if (!hd->found.blob) - return gpg_error (GPG_ERR_NOTHING_FOUND); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - off = _keybox_get_blob_fileoffset (hd->found.blob); - if (off == (off_t)-1) - return gpg_error (GPG_ERR_GENERAL); - off += 4; - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - fp = fopen (hd->kb->fname, "r+b"); - if (!fp) - return gpg_error (gpg_err_code_from_errno (errno)); - - if (fseeko (fp, off, SEEK_SET)) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else if (putc (0, fp) == EOF) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - rc = 0; - - if (fclose (fp)) - { - if (!rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - } - - return rc; -} - - -/* Compress the keybox file. This should be run with the file - locked. */ -int -keybox_compress (KEYBOX_HANDLE hd) -{ - int read_rc, rc; - const char *fname; - FILE *fp, *newfp; - char *bakfname = NULL; - char *tmpfname = NULL; - int first_blob; - KEYBOXBLOB blob = NULL; - u32 cut_time; - int any_changes = 0; - int skipped_deleted; - - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (!hd->kb) - return gpg_error (GPG_ERR_INV_HANDLE); - if (hd->secret) - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - fname = hd->kb->fname; - if (!fname) - return gpg_error (GPG_ERR_INV_HANDLE); - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - /* Open the source file. Because we do a rename, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return gpg_error (gpg_err_code_from_errno (errno)); - - fp = fopen (fname, "rb"); - if (!fp && errno == ENOENT) - return 0; /* Ready. File has been deleted right after the access above. */ - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - return rc; - } - - /* A quick test to see if we need to compress the file at all. We - schedule a compress run after 3 hours. */ - if ( !_keybox_read_blob (&blob, fp) ) - { - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - u32 last_maint = ((buffer[20] << 24) | (buffer[20+1] << 16) - | (buffer[20+2] << 8) | (buffer[20+3])); - - if ( (last_maint + 3*3600) > time (NULL) ) - { - fclose (fp); - _keybox_release_blob (blob); - return 0; /* Compress run not yet needed. */ - } - } - _keybox_release_blob (blob); - rewind (fp); - } - - /* Create the new file. */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) - { - fclose(fp); - return rc;; - } - - - /* Processing loop. By reading using _keybox_read_blob we - automagically skip and blobs flagged as deleted. Thus what we - only have to do is to check all ephemeral flagged blocks whether - their time has come and write out all other blobs. */ - cut_time = time(NULL) - 86400; - first_blob = 1; - skipped_deleted = 0; - for (rc=0; !(read_rc = _keybox_read_blob2 (&blob, fp, &skipped_deleted)); - _keybox_release_blob (blob), blob = NULL ) - { - unsigned int blobflags; - const unsigned char *buffer; - size_t length, pos, size; - u32 created_at; - - if (skipped_deleted) - any_changes = 1; - buffer = _keybox_get_blob_image (blob, &length); - if (first_blob) - { - first_blob = 0; - if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - /* Write out the blob with an updated maintenance time stamp. */ - _keybox_update_header_blob (blob); - rc = _keybox_write_blob (blob, newfp); - if (rc) - break; - continue; - } - - /* The header blob is missing. Insert it. */ - rc = _keybox_write_header_blob (newfp); - if (rc) - break; - any_changes = 1; - } - else if (length > 4 && buffer[4] == BLOBTYPE_HEADER) - { - /* Oops: There is another header record - remove it. */ - any_changes = 1; - continue; - } - - if (_keybox_get_flag_location (buffer, length, - KEYBOX_FLAG_BLOB, &pos, &size) - || size != 2) - { - rc = gpg_error (GPG_ERR_BUG); - break; - } - blobflags = ((buffer[pos] << 8) | (buffer[pos+1])); - if ((blobflags & 2)) - { - /* This is an ephemeral blob. */ - if (_keybox_get_flag_location (buffer, length, - KEYBOX_FLAG_CREATED_AT, &pos, &size) - || size != 4) - created_at = 0; /* oops. */ - else - created_at = ((buffer[pos] << 24) | (buffer[pos+1] << 16) - | (buffer[pos+2] << 8) | (buffer[pos+3])); - - if (created_at && created_at < cut_time) - { - any_changes = 1; - continue; /* Skip this blob. */ - } - } - - rc = _keybox_write_blob (blob, newfp); - if (rc) - break; - } - if (skipped_deleted) - any_changes = 1; - _keybox_release_blob (blob); blob = NULL; - if (!rc && read_rc == -1) - rc = 0; - else if (!rc) - rc = read_rc; - - /* Close both files. */ - if (fclose(fp) && !rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - if (fclose(newfp) && !rc) - rc = gpg_error (gpg_err_code_from_errno (errno)); - - /* Rename or remove the temporary file. */ - if (rc || !any_changes) - remove (tmpfname); - else - rc = rename_tmp_file (bakfname, tmpfname, fname, hd->secret); - - xfree(bakfname); - xfree(tmpfname); - return rc; -} - diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c deleted file mode 100644 index ed5d93de0..000000000 --- a/kbx/keybox-util.c +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-util.c - Utility functions for Keybox - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "keybox-defs.h" - - -static void *(*alloc_func)(size_t n) = malloc; -static void *(*realloc_func)(void *p, size_t n) = realloc; -static void (*free_func)(void*) = free; - - - -void -keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ) -{ - alloc_func = new_alloc_func; - realloc_func = new_realloc_func; - free_func = new_free_func; -} - -void * -_keybox_malloc (size_t n) -{ - return alloc_func (n); -} - -void * -_keybox_realloc (void *a, size_t n) -{ - return realloc_func (a, n); -} - -void * -_keybox_calloc (size_t n, size_t m) -{ - void *p = _keybox_malloc (n*m); - if (p) - memset (p, 0, n* m); - return p; -} - -void -_keybox_free (void *p) -{ - if (p) - free_func (p); -} - diff --git a/kbx/keybox.h b/kbx/keybox.h deleted file mode 100644 index af1fc4516..000000000 --- a/kbx/keybox.h +++ /dev/null @@ -1,115 +0,0 @@ -/* keybox.h - Keybox operations - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef KEYBOX_H -#define KEYBOX_H 1 -#ifdef __cplusplus -extern "C" { -#if 0 - } -#endif -#endif - -#include "keybox-search-desc.h" - -#define KEYBOX_WITH_OPENPGP 1 -#define KEYBOX_WITH_X509 1 - - -#ifdef KEYBOX_WITH_OPENPGP -# undef KEYBOX_WITH_OPENPGP -/*#include <lib-to-handle-gpg-data-structs.h>*/ -#endif - -#ifdef KEYBOX_WITH_X509 -# include <ksba.h> -#endif - -typedef struct keybox_handle *KEYBOX_HANDLE; - - -typedef enum - { - KEYBOX_FLAG_BLOB, /* The blob flags. */ - KEYBOX_FLAG_VALIDITY, /* The validity of the entire key. */ - KEYBOX_FLAG_OWNERTRUST, /* The assigned ownertrust. */ - KEYBOX_FLAG_KEY, /* The key flags; requires a key index. */ - KEYBOX_FLAG_UID, /* The user ID flags; requires an uid index. */ - KEYBOX_FLAG_UID_VALIDITY,/* The validity of a specific uid, requires - an uid index. */ - KEYBOX_FLAG_CREATED_AT /* The date the block was created. */ - } keybox_flag_t; - - -/*-- keybox-init.c --*/ -void *keybox_register_file (const char *fname, int secret); -int keybox_is_writable (void *token); - -KEYBOX_HANDLE keybox_new (void *token, int secret); -void keybox_release (KEYBOX_HANDLE hd); -const char *keybox_get_resource_name (KEYBOX_HANDLE hd); -int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); - - -/*-- keybox-search.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_get_cert (KEYBOX_HANDLE hd, ksba_cert_t *ret_cert); -#endif /*KEYBOX_WITH_X509*/ -int keybox_get_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int *value); - -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); - - -/*-- keybox-update.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_insert_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest); -int keybox_update_cert (KEYBOX_HANDLE hd, ksba_cert_t cert, - unsigned char *sha1_digest); -#endif /*KEYBOX_WITH_X509*/ -int keybox_set_flags (KEYBOX_HANDLE hd, int what, int idx, unsigned int value); - -int keybox_delete (KEYBOX_HANDLE hd); -int keybox_compress (KEYBOX_HANDLE hd); - - -/*-- --*/ - -#if 0 -int keybox_lock (KEYBOX_HANDLE hd, int yes); -int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); -int keybox_locate_writable (KEYBOX_HANDLE hd); -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keybox_rebuild_cache (void *); -#endif - - -/*-- keybox-util.c --*/ -void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ); - - -#ifdef __cplusplus -} -#endif -#endif /*KEYBOX_H*/ diff --git a/kbx/mkerrors b/kbx/mkerrors deleted file mode 100755 index 5adb7bfdf..000000000 --- a/kbx/mkerrors +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from assuan.h -# and create C source for assuan_strerror -# Copyright (C) 2001 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -cat <<EOF -/* Generated automatically by mkerrors */ -/* Do not edit! */ - -#include <stdio.h> -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/KEYBOX_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/KEYBOX_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,8)); -} -' - -cat <<EOF - default: sprintf (buf, "ec=%d", err ); s=buf; break; - } - - return s; -} - -EOF diff --git a/m4/ChangeLog b/m4/ChangeLog deleted file mode 100644 index efcded757..000000000 --- a/m4/ChangeLog +++ /dev/null @@ -1,30 +0,0 @@ -2004-03-06 Werner Koch <wk@gnupg.org> - - * libgcrypt.m4: Updated. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpg-error.m4, libgcrypt.m4, libassuan.m4, ksba.m4: New. - * Makefile.am: Distribute them - -2003-04-29 gettextize <bug-gnu-gettext@gnu.org> - - * codeset.m4: New file, from gettext-0.11.5. - * gettext.m4: New file, from gettext-0.11.5. - * glibc21.m4: New file, from gettext-0.11.5. - * iconv.m4: New file, from gettext-0.11.5. - * intdiv0.m4: New file, from gettext-0.11.5. - * inttypes.m4: New file, from gettext-0.11.5. - * inttypes_h.m4: New file, from gettext-0.11.5. - * inttypes-pri.m4: New file, from gettext-0.11.5. - * isc-posix.m4: New file, from gettext-0.11.5. - * lcmessage.m4: New file, from gettext-0.11.5. - * lib-ld.m4: New file, from gettext-0.11.5. - * lib-link.m4: New file, from gettext-0.11.5. - * lib-prefix.m4: New file, from gettext-0.11.5. - * progtest.m4: New file, from gettext-0.11.5. - * stdint_h.m4: New file, from gettext-0.11.5. - * uintmax_t.m4: New file, from gettext-0.11.5. - * ulonglong.m4: New file, from gettext-0.11.5. - * Makefile.am: New file. - diff --git a/m4/Makefile.am b/m4/Makefile.am deleted file mode 100644 index 0eb02f694..000000000 --- a/m4/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -EXTRA_DIST = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 - -EXTRA_DIST += gpg-error.m4 libgcrypt.m4 libassuan.m4 ksba.m4 diff --git a/m4/codeset.m4 b/m4/codeset.m4 deleted file mode 100644 index 59535ebcf..000000000 --- a/m4/codeset.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# codeset.m4 serial AM1 (gettext-0.10.40) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([AM_LANGINFO_CODESET], -[ - AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, - [AC_TRY_LINK([#include <langinfo.h>], - [char* cs = nl_langinfo(CODESET);], - am_cv_langinfo_codeset=yes, - am_cv_langinfo_codeset=no) - ]) - if test $am_cv_langinfo_codeset = yes; then - AC_DEFINE(HAVE_LANGINFO_CODESET, 1, - [Define if you have <langinfo.h> and nl_langinfo(CODESET).]) - fi -]) diff --git a/m4/gettext.m4 b/m4/gettext.m4 deleted file mode 100644 index 16070b40a..000000000 --- a/m4/gettext.m4 +++ /dev/null @@ -1,415 +0,0 @@ -# gettext.m4 serial 20 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -dnl Macro to add for using GNU gettext. - -dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. -dnl If INTLSYMBOL is 'use-libtool', then a libtool library -dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, -dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. -dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext -dnl implementations (in libc or libintl) without the ngettext() function -dnl will be ignored. If NEEDSYMBOL is specified and is -dnl 'need-formatstring-macros', then GNU gettext implementations that don't -dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. -dnl INTLDIR is used to find the intl libraries. If empty, -dnl the value `$(top_builddir)/intl/' is used. -dnl -dnl The result of the configuration is one of three cases: -dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled -dnl and used. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 2) GNU gettext has been found in the system's C library. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 3) No internationalization, always use English msgid. -dnl Catalog format: none -dnl Catalog extension: none -dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. -dnl The use of .gmo is historical (it was needed to avoid overwriting the -dnl GNU format catalogs when building on a platform with an X/Open gettext), -dnl but we keep it in order not to force irrelevant filename changes on the -dnl maintainers. -dnl -AC_DEFUN([AM_GNU_GETTEXT], -[ - dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , - [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) - ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , - [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT -])])])]) - define(gt_included_intl, ifelse([$1], [external], [no], [yes])) - define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) - - AC_REQUIRE([AM_PO_SUBDIRS])dnl - ifelse(gt_included_intl, yes, [ - AC_REQUIRE([AM_INTL_SUBDIR])dnl - ]) - - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Sometimes libintl requires libiconv, so first search for libiconv. - dnl Ideally we would do this search only after the - dnl if test "$USE_NLS" = "yes"; then - dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT - dnl the configure script would need to contain the same shell code - dnl again, outside any 'if'. There are two solutions: - dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. - dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. - ifelse(gt_included_intl, yes, , [ - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - ]) - - dnl Set USE_NLS. - AM_NLS - - ifelse(gt_included_intl, yes, [ - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - ]) - LIBINTL= - LTLIBINTL= - POSUB= - - dnl If we use NLS figure out what method - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - ifelse(gt_included_intl, yes, [ - AC_MSG_CHECKING([whether included gettext is requested]) - AC_ARG_WITH(included-gettext, - [ --with-included-gettext use the GNU gettext library included here], - nls_cv_force_use_gnu_gettext=$withval, - nls_cv_force_use_gnu_gettext=no) - AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) - - nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" - if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - ]) - dnl User does not insist on using GNU NLS library. Figure out what - dnl to use. If GNU gettext is available we use this. Else we have - dnl to fall back to GNU NLS library. - - dnl Add a version number to the cache macros. - define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) - define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) - define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) - - AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, - [AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings;], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], - gt_cv_func_gnugettext_libc=yes, - gt_cv_func_gnugettext_libc=no)]) - - if test "$gt_cv_func_gnugettext_libc" != "yes"; then - dnl Sometimes libintl requires libiconv, so first search for libiconv. - ifelse(gt_included_intl, yes, , [ - AM_ICONV_LINK - ]) - dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL - dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) - dnl because that would add "-liconv" to LIBINTL and LTLIBINTL - dnl even if libiconv doesn't exist. - AC_LIB_LINKFLAGS_BODY([intl]) - AC_CACHE_CHECK([for GNU gettext in libintl], - gt_cv_func_gnugettext_libintl, - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - dnl Now see whether libintl exists and does not depend on libiconv. - AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - gt_cv_func_gnugettext_libintl=yes, - gt_cv_func_gnugettext_libintl=no) - dnl Now see whether libintl exists and depends on libiconv. - if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include <libintl.h> -]ifelse([$2], [need-formatstring-macros], -[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], - [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], - [LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - gt_cv_func_gnugettext_libintl=yes - ]) - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - fi - - dnl If an already present or preinstalled GNU gettext() is found, - dnl use it. But if this macro is used in GNU gettext, and GNU - dnl gettext is already preinstalled in libintl, we update this - dnl libintl. (Cf. the install rule in intl/Makefile.in.) - if test "$gt_cv_func_gnugettext_libc" = "yes" \ - || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - dnl Reset the values set by searching for libintl. - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - ifelse(gt_included_intl, yes, [ - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - dnl GNU gettext is not found in the C library. - dnl Fall back on included GNU gettext library. - nls_cv_use_gnu_gettext=yes - fi - fi - - if test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions used to generate GNU NLS library. - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions to use GNU gettext tools. - CATOBJEXT=.gmo - fi - ]) - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - AC_DEFINE(ENABLE_NLS, 1, - [Define to 1 if translation of program messages to the user's native language - is requested.]) - else - USE_NLS=no - fi - fi - - AC_MSG_CHECKING([whether to use NLS]) - AC_MSG_RESULT([$USE_NLS]) - if test "$USE_NLS" = "yes"; then - AC_MSG_CHECKING([where the gettext function comes from]) - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - AC_MSG_RESULT([$gt_source]) - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if test "$gt_cv_func_gnugettext_libintl" = "yes"; then - AC_MSG_CHECKING([how to link with libintl]) - AC_MSG_RESULT([$LIBINTL]) - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) - fi - - dnl For backward compatibility. Some packages may be using this. - AC_DEFINE(HAVE_GETTEXT, 1, - [Define if the GNU gettext() function is already present or preinstalled.]) - AC_DEFINE(HAVE_DCGETTEXT, 1, - [Define if the GNU dcgettext() function is already present or preinstalled.]) - fi - - dnl We need to process the po/ directory. - POSUB=po - fi - - ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi - - dnl Make all variables we use known to autoconf. - AC_SUBST(BUILD_INCLUDED_LIBINTL) - AC_SUBST(USE_INCLUDED_LIBINTL) - AC_SUBST(CATOBJEXT) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST(DATADIRNAME) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST(INSTOBJEXT) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST(GENCAT) - - dnl For backward compatibility. Some Makefiles may be using this. - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - AC_SUBST(INTLOBJS) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) - ]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLLIBS="$LIBINTL" - AC_SUBST(INTLLIBS) - - dnl Make all documented variables known to autoconf. - AC_SUBST(LIBINTL) - AC_SUBST(LTLIBINTL) - AC_SUBST(POSUB) -]) - - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([AC_ISC_POSIX])dnl - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_C_CONST])dnl - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_OFF_T])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([jm_GLIBC21])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - - AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ -stdlib.h string.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ -geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ -strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next \ -__fsetlocking]) - - AM_ICONV - AM_LANGINFO_CODESET - if test $ac_cv_header_locale_h = yes; then - AM_LC_MESSAGES - fi - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) - - -dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) -AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 deleted file mode 100644 index 9c9f3db30..000000000 --- a/m4/glibc21.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -# Test for the GNU C Library, version 2.1 or newer. -# From Bruno Haible. - -AC_DEFUN([jm_GLIBC21], - [ - AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, - ac_cv_gnu_library_2_1, - [AC_EGREP_CPP([Lucky GNU user], - [ -#include <features.h> -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif - ], - ac_cv_gnu_library_2_1=yes, - ac_cv_gnu_library_2_1=no) - ] - ) - AC_SUBST(GLIBC21) - GLIBC21="$ac_cv_gnu_library_2_1" - ] -) diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 deleted file mode 100644 index 931630b14..000000000 --- a/m4/gpg-error.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl Autoconf macros for libgpg-error - -dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS -dnl -AC_DEFUN(AM_PATH_GPG_ERROR, -[ AC_ARG_WITH(gpg-error-prefix, - AC_HELP_STRING([--with-gpg-error-prefix=PFX], - [prefix where GPG Error is installed (optional)]), - gpg_error_config_prefix="$withval", gpg_error_config_prefix="") - if test x$gpg_error_config_prefix != x ; then - if test x${GPG_ERROR_CONFIG+set} != xset ; then - GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config - fi - fi - - AC_PATH_PROG(GPG_ERROR_CONFIG, gpg-error-config, no) - min_gpg_error_version=ifelse([$1], ,0.0,$1) - AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version) - ok=no - if test "$GPG_ERROR_CONFIG" != "no" ; then - req_major=`echo $min_gpg_error_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_gpg_error_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version` - major=`echo $gpg_error_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $gpg_error_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -ge "$req_minor"; then - ok=yes - fi - fi - fi - fi - if test $ok = yes; then - GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags` - GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - GPG_ERROR_CFLAGS="" - GPG_ERROR_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(GPG_ERROR_CFLAGS) - AC_SUBST(GPG_ERROR_LIBS) -]) - diff --git a/m4/iconv.m4 b/m4/iconv.m4 deleted file mode 100644 index c5f357982..000000000 --- a/m4/iconv.m4 +++ /dev/null @@ -1,103 +0,0 @@ -# iconv.m4 serial AM4 (gettext-0.11.3) -dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_TRY_LINK([#include <stdlib.h> -#include <iconv.h>], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_func_iconv=yes) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_TRY_LINK([#include <stdlib.h> -#include <iconv.h>], - [iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);], - am_cv_lib_iconv=yes - am_cv_func_iconv=yes) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST(LIBICONV) - AC_SUBST(LTLIBICONV) -]) - -AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL(am_cv_proto_iconv, [ - AC_TRY_COMPILE([ -#include <stdlib.h> -#include <iconv.h> -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif -], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([$]{ac_t:- - }[$]am_cv_proto_iconv) - AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, - [Define as const if the declaration of iconv() needs const.]) - fi -]) diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4 deleted file mode 100644 index 55dddcf1c..000000000 --- a/m4/intdiv0.m4 +++ /dev/null @@ -1,72 +0,0 @@ -# intdiv0.m4 serial 1 (gettext-0.11.3) -dnl Copyright (C) 2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([gt_INTDIV0], -[ - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - - AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], - gt_cv_int_divbyzero_sigfpe, - [ - AC_TRY_RUN([ -#include <stdlib.h> -#include <signal.h> - -static void -#ifdef __cplusplus -sigfpe_handler (int sig) -#else -sigfpe_handler (sig) int sig; -#endif -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (1); -} -], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, - [ - # Guess based on the CPU. - case "$host_cpu" in - alpha* | i[34567]86 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac - ]) - ]) - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, - [Define if integer division by zero raises signal SIGFPE.]) -]) diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4 deleted file mode 100644 index fd007c312..000000000 --- a/m4/inttypes-pri.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# inttypes-pri.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -# Define PRI_MACROS_BROKEN if <inttypes.h> exists and defines the PRI* -# macros to non-string values. This is the case on AIX 4.3.3. - -AC_DEFUN([gt_INTTYPES_PRI], -[ - AC_REQUIRE([gt_HEADER_INTTYPES_H]) - if test $gt_cv_header_inttypes_h = yes; then - AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], - gt_cv_inttypes_pri_broken, - [ - AC_TRY_COMPILE([#include <inttypes.h> -#ifdef PRId32 -char *p = PRId32; -#endif -], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) - ]) - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, - [Define if <inttypes.h> exists and defines unusable PRI* macros.]) - fi -]) diff --git a/m4/inttypes.m4 b/m4/inttypes.m4 deleted file mode 100644 index ab370ffe0..000000000 --- a/m4/inttypes.m4 +++ /dev/null @@ -1,27 +0,0 @@ -# inttypes.m4 serial 1 (gettext-0.11.4) -dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H if <inttypes.h> exists and doesn't clash with -# <sys/types.h>. - -AC_DEFUN([gt_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, - [ - AC_TRY_COMPILE( - [#include <sys/types.h> -#include <inttypes.h>], - [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) - ]) - if test $gt_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, - [Define if <inttypes.h> exists and doesn't clash with <sys/types.h>.]) - fi -]) diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 deleted file mode 100644 index f342eba39..000000000 --- a/m4/inttypes_h.m4 +++ /dev/null @@ -1,28 +0,0 @@ -# inttypes_h.m4 serial 5 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H_WITH_UINTMAX if <inttypes.h> exists, -# doesn't clash with <sys/types.h>, and declares uintmax_t. - -AC_DEFUN([jm_AC_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, - [AC_TRY_COMPILE( - [#include <sys/types.h> -#include <inttypes.h>], - [uintmax_t i = (uintmax_t) -1;], - jm_ac_cv_header_inttypes_h=yes, - jm_ac_cv_header_inttypes_h=no)]) - if test $jm_ac_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, - [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, - and declares uintmax_t. ]) - fi -]) diff --git a/m4/isc-posix.m4 b/m4/isc-posix.m4 deleted file mode 100644 index 1319dd1c7..000000000 --- a/m4/isc-posix.m4 +++ /dev/null @@ -1,26 +0,0 @@ -# isc-posix.m4 serial 2 (gettext-0.11.2) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. - -# This test replaces the one in autoconf. -# Currently this macro should have the same name as the autoconf macro -# because gettext's gettext.m4 (distributed in the automake package) -# still uses it. Otherwise, the use in gettext.m4 makes autoheader -# give these diagnostics: -# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX -# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX - -undefine([AC_ISC_POSIX]) - -AC_DEFUN([AC_ISC_POSIX], - [ - dnl This test replaces the obsolescent AC_ISC_POSIX kludge. - AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) - ] -) diff --git a/m4/ksba.m4 b/m4/ksba.m4 deleted file mode 100644 index c59ac8024..000000000 --- a/m4/ksba.m4 +++ /dev/null @@ -1,76 +0,0 @@ -# ksba.m4 - autoconf macro to detect ksba -# Copyright (C) 2002 g10 Code GmbH -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_KSBA([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS -dnl -AC_DEFUN(AM_PATH_KSBA, -[ AC_ARG_WITH(ksba-prefix, - AC_HELP_STRING([--with-ksba-prefix=PFX], - [prefix where KSBA is installed (optional)]), - ksba_config_prefix="$withval", ksba_config_prefix="") - if test x$ksba_config_prefix != x ; then - ksba_config_args="$ksba_config_args --prefix=$ksba_config_prefix" - if test x${KSBA_CONFIG+set} != xset ; then - KSBA_CONFIG=$ksba_config_prefix/bin/ksba-config - fi - fi - - AC_PATH_PROG(KSBA_CONFIG, ksba-config, no) - min_ksba_version=ifelse([$1], ,0.4.4,$1) - AC_MSG_CHECKING(for KSBA - version >= $min_ksba_version) - ok=no - if test "$KSBA_CONFIG" != "no" ; then - req_major=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_ksba_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - ksba_config_version=`$KSBA_CONFIG $ksba_config_args --version` - major=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $ksba_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - KSBA_CFLAGS=`$KSBA_CONFIG $ksba_config_args --cflags` - KSBA_LIBS=`$KSBA_CONFIG $ksba_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - KSBA_CFLAGS="" - KSBA_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(KSBA_CFLAGS) - AC_SUBST(KSBA_LIBS) -]) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 deleted file mode 100644 index ffd4008b8..000000000 --- a/m4/lcmessage.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# lcmessage.m4 serial 3 (gettext-0.11.3) -dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995. - -# Check whether LC_MESSAGES is available in <locale.h>. - -AC_DEFUN([AM_LC_MESSAGES], -[ - AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, - [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], - am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) - if test $am_cv_val_LC_MESSAGES = yes; then - AC_DEFINE(HAVE_LC_MESSAGES, 1, - [Define if your <locale.h> file defines LC_MESSAGES.]) - fi -]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 deleted file mode 100644 index 11d0ce773..000000000 --- a/m4/lib-ld.m4 +++ /dev/null @@ -1,110 +0,0 @@ -# lib-ld.m4 serial 2 (gettext-0.12) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then - acl_cv_prog_gnu_ld=yes -else - acl_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$acl_cv_prog_gnu_ld -]) - -dnl From libtool-1.4. Sets the variable LD. -AC_DEFUN([AC_LIB_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(acl_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU -]) diff --git a/m4/lib-link.m4 b/m4/lib-link.m4 deleted file mode 100644 index eeb200d26..000000000 --- a/m4/lib-link.m4 +++ /dev/null @@ -1,551 +0,0 @@ -# lib-link.m4 serial 4 (gettext-0.12) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - undefine([Name]) - undefine([NAME]) -]) - -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. If found, it -dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and -dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - define([Name],[translit([$1],[./-], [___])]) - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIB[]NAME" - AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - undefine([Name]) - undefine([NAME]) -]) - -dnl Determine the platform dependent parameters needed to use rpath: -dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, -dnl hardcode_direct, hardcode_minus_L. -AC_DEFUN([AC_LIB_RPATH], -[ - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - libext="$acl_cv_libext" - shlibext="$acl_cv_shlibext" - hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - hardcode_direct="$acl_cv_hardcode_direct" - hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE(rpath, - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib$1-prefix], -[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib - --without-lib$1-prefix don't search for lib$1 in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - else - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - else - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 deleted file mode 100644 index c719bc809..000000000 --- a/m4/lib-prefix.m4 +++ /dev/null @@ -1,155 +0,0 @@ -# lib-prefix.m4 serial 2 (gettext-0.12) -dnl Copyright (C) 2001-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) diff --git a/m4/libassuan.m4 b/m4/libassuan.m4 deleted file mode 100644 index 2afc69737..000000000 --- a/m4/libassuan.m4 +++ /dev/null @@ -1,76 +0,0 @@ -dnl Autoconf macros for libassuan -dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS -dnl -AC_DEFUN(AM_PATH_LIBASSUAN, -[ AC_ARG_WITH(libassuan-prefix, - AC_HELP_STRING([--with-libassuan-prefix=PFX], - [prefix where LIBASSUAN is installed (optional)]), - libassuan_config_prefix="$withval", libassuan_config_prefix="") - if test x$libassuan_config_prefix != x ; then - libassuan_config_args="$libassuan_config_args --prefix=$libassuan_config_prefix" - if test x${LIBASSUAN_CONFIG+set} != xset ; then - LIBASSUAN_CONFIG=$libassuan_config_prefix/bin/libassuan-config - fi - fi - - AC_PATH_PROG(LIBASSUAN_CONFIG, libassuan-config, no) - min_libassuan_version=ifelse([$1], ,0.0.1,$1) - AC_MSG_CHECKING(for LIBASSUAN - version >= $min_libassuan_version) - ok=no - if test "$LIBASSUAN_CONFIG" != "no" ; then - req_major=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libassuan_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libassuan_config_version=`$LIBASSUAN_CONFIG $libassuan_config_args --version` - major=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libassuan_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags` - LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs` - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - LIBASSUAN_CFLAGS="" - LIBASSUAN_LIBS="" - AC_MSG_RESULT(no) - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBASSUAN_CFLAGS) - AC_SUBST(LIBASSUAN_LIBS) -]) diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 deleted file mode 100644 index e5f2a43c0..000000000 --- a/m4/libgcrypt.m4 +++ /dev/null @@ -1,108 +0,0 @@ -dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed -dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed -dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt -dnl with a changed API. -dnl -AC_DEFUN(AM_PATH_LIBGCRYPT, -[ AC_ARG_WITH(libgcrypt-prefix, - AC_HELP_STRING([--with-libgcrypt-prefix=PFX], - [prefix where LIBGCRYPT is installed (optional)]), - libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") - if test x$libgcrypt_config_prefix != x ; then - if test x${LIBGCRYPT_CONFIG+set} != xset ; then - LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config - fi - fi - - AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) - tmp=ifelse([$1], ,1:1.2.0,$1) - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` - else - req_libgcrypt_api=0 - min_libgcrypt_version="$tmp" - fi - - AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) - ok=no - if test "$LIBGCRYPT_CONFIG" != "no" ; then - req_major=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` - major=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - if test $ok = yes; then - # If we have a recent libgcrypt, we should also check that the - # API is compatible - if test "$req_libgcrypt_api" -gt 0 ; then - tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` - if test "$tmp" -gt 0 ; then - AC_MSG_CHECKING([LIBGCRYPT API version]) - if test "$req_libgcrypt_api" -eq "$tmp" ; then - AC_MSG_RESULT(okay) - else - ok=no - AC_MSG_RESULT([does not match (want=$req_libgcrypt_api got=$tmp)]) - fi - fi - fi - fi - if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - ifelse([$2], , :, [$2]) - else - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBGCRYPT_CFLAGS) - AC_SUBST(LIBGCRYPT_LIBS) -]) diff --git a/m4/nls.m4 b/m4/nls.m4 deleted file mode 100644 index 36bc49317..000000000 --- a/m4/nls.m4 +++ /dev/null @@ -1,49 +0,0 @@ -# nls.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -AC_DEFUN([AM_NLS], -[ - AC_MSG_CHECKING([whether NLS is requested]) - dnl Default is enabled NLS - AC_ARG_ENABLE(nls, - [ --disable-nls do not use Native Language Support], - USE_NLS=$enableval, USE_NLS=yes) - AC_MSG_RESULT($USE_NLS) - AC_SUBST(USE_NLS) -]) - -AC_DEFUN([AM_MKINSTALLDIRS], -[ - dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly - dnl find the mkinstalldirs script in another subdir but $(top_srcdir). - dnl Try to locate it. - MKINSTALLDIRS= - if test -n "$ac_aux_dir"; then - case "$ac_aux_dir" in - /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; - *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; - esac - fi - if test -z "$MKINSTALLDIRS"; then - MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" - fi - AC_SUBST(MKINSTALLDIRS) -]) diff --git a/m4/po.m4 b/m4/po.m4 deleted file mode 100644 index 861e3dec3..000000000 --- a/m4/po.m4 +++ /dev/null @@ -1,197 +0,0 @@ -# po.m4 serial 1 (gettext-0.12) -dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. -dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. - -dnl Checks for all prerequisites of the po subdirectory. -AC_DEFUN([AM_PO_SUBDIRS], -[ - AC_REQUIRE([AC_PROG_MAKE_SET])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AM_MKINSTALLDIRS])dnl - AC_REQUIRE([AM_NLS])dnl - - dnl Perform the following tests also if --disable-nls has been given, - dnl because they are needed for "make dist" to work. - - dnl Search for GNU msgfmt in the PATH. - dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. - dnl The second test excludes FreeBSD msgfmt. - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) - - dnl Search for GNU xgettext 0.12 or newer in the PATH. - dnl The first test excludes Solaris xgettext and early GNU xgettext versions. - dnl The second test excludes FreeBSD xgettext. - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - - dnl Search for GNU msgmerge 0.11 or newer in the PATH. - AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, - [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU msgfmt. - if test "$GMSGFMT" != ":"; then - dnl If it is no GNU msgfmt we define it as : so that the - dnl Makefiles still can work. - if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && - (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` - AC_MSG_RESULT( - [found $GMSGFMT program is not GNU msgfmt; ignore it]) - GMSGFMT=":" - fi - fi - - dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. - dnl Test whether we really found GNU xgettext. - if test "$XGETTEXT" != ":"; then - dnl If it is no GNU xgettext we define it as : so that the - dnl Makefiles still can work. - if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && - (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - : ; - else - AC_MSG_RESULT( - [found xgettext program is not GNU xgettext; ignore it]) - XGETTEXT=":" - fi - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - fi - - AC_OUTPUT_COMMANDS([ - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assigment from automake. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - GMOFILES= - UPDATEPOFILES= - DUMMYPOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done], - [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it - # from automake. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - ]) -]) diff --git a/m4/progtest.m4 b/m4/progtest.m4 deleted file mode 100644 index 8fe527cec..000000000 --- a/m4/progtest.m4 +++ /dev/null @@ -1,91 +0,0 @@ -# progtest.m4 serial 3 (gettext-0.12) -dnl Copyright (C) 1996-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper <drepper@cygnus.com>, 1996. - -# Search path for a program which passes the given test. - -dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN([AM_PATH_PROG_WITH_TEST], -[ -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL(ac_cv_path_$1, -[case "[$]$1" in - [[\\/]]* | ?:[[\\/]]*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in ifelse([$5], , $PATH, [$5]); do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$]$1) -else - AC_MSG_RESULT(no) -fi -AC_SUBST($1)dnl -]) diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 deleted file mode 100644 index 32ba7ae77..000000000 --- a/m4/stdint_h.m4 +++ /dev/null @@ -1,28 +0,0 @@ -# stdint_h.m4 serial 3 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -# Define HAVE_STDINT_H_WITH_UINTMAX if <stdint.h> exists, -# doesn't clash with <sys/types.h>, and declares uintmax_t. - -AC_DEFUN([jm_AC_HEADER_STDINT_H], -[ - AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, - [AC_TRY_COMPILE( - [#include <sys/types.h> -#include <stdint.h>], - [uintmax_t i = (uintmax_t) -1;], - jm_ac_cv_header_stdint_h=yes, - jm_ac_cv_header_stdint_h=no)]) - if test $jm_ac_cv_header_stdint_h = yes; then - AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, - [Define if <stdint.h> exists, doesn't clash with <sys/types.h>, - and declares uintmax_t. ]) - fi -]) diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4 deleted file mode 100644 index b5f28d440..000000000 --- a/m4/uintmax_t.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# uintmax_t.m4 serial 7 (gettext-0.12) -dnl Copyright (C) 1997-2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -AC_PREREQ(2.13) - -# Define uintmax_t to 'unsigned long' or 'unsigned long long' -# if it is not already defined in <stdint.h> or <inttypes.h>. - -AC_DEFUN([jm_AC_TYPE_UINTMAX_T], -[ - AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([jm_AC_HEADER_STDINT_H]) - if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then - AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) - test $ac_cv_type_unsigned_long_long = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, - [Define to unsigned long or unsigned long long - if <stdint.h> and <inttypes.h> don't define.]) - else - AC_DEFINE(HAVE_UINTMAX_T, 1, - [Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>.]) - fi -]) diff --git a/m4/ulonglong.m4 b/m4/ulonglong.m4 deleted file mode 100644 index c375e474c..000000000 --- a/m4/ulonglong.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) -dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Paul Eggert. - -AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], -[ - AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, - [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], - [unsigned long long ullmax = (unsigned long long) -1; - return ull << i | ull >> i | ullmax / ull | ullmax % ull;], - ac_cv_type_unsigned_long_long=yes, - ac_cv_type_unsigned_long_long=no)]) - if test $ac_cv_type_unsigned_long_long = yes; then - AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, - [Define if you have the unsigned long long type.]) - fi -]) diff --git a/po/ChangeLog b/po/ChangeLog deleted file mode 100644 index 97e68c730..000000000 --- a/po/ChangeLog +++ /dev/null @@ -1,44 +0,0 @@ -2004-04-06 Werner Koch <wk@gnupg.org> - - * Makevars (DOMAIN): Init from PACKAGE_GT - -2003-12-09 Werner Koch <wk@gnupg.org> - - * Makevars (MSGID_BUGS_ADDRESS): New. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * LINUGAS: NEW. - -2003-04-29 gettextize <bug-gnu-gettext@gnu.org> - - * Rules-quot: New file, from gettext-0.11.5. - * boldquot.sed: New file, from gettext-0.11.5. - * en@boldquot.header: New file, from gettext-0.11.5. - * en@quot.header: New file, from gettext-0.11.5. - * insert-header.sin: New file, from gettext-0.11.5. - * quot.sed: New file, from gettext-0.11.5. - * remove-potcdate.sin: New file, from gettext-0.11.5. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * de.po: Updated the translation. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * Makefile.in.in: Installed from gettext-0.10.40. - * POTFILES.in: New. - * de.po: New. - - - Copyright 2002 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index 2d1cafec8..000000000 --- a/po/LINGUAS +++ /dev/null @@ -1,5 +0,0 @@ -# Set of available languages. -de - - - diff --git a/po/Makefile.in.in b/po/Makefile.in.in deleted file mode 100644 index 27b721aa8..000000000 --- a/po/Makefile.in.in +++ /dev/null @@ -1,353 +0,0 @@ -# Makefile for PO directory in any package using GNU gettext. -# Copyright (C) 1995-1997, 2000-2003 by Ulrich Drepper <drepper@gnu.ai.mit.edu> -# -# This file can be copied and used freely without restrictions. It can -# be used in projects which are not available under the GNU General Public -# License but which still want to provide support for the GNU gettext -# functionality. -# Please note that the actual code of GNU gettext is covered by the GNU -# General Public License and is *not* in the public domain. - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ - -SHELL = /bin/sh -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datadir = @datadir@ -localedir = $(datadir)/locale -gettextsrcdir = $(datadir)/gettext/po - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -mkinstalldirs = $(SHELL) $(MKINSTALLDIRS) - -GMSGFMT = @GMSGFMT@ -MSGFMT = @MSGFMT@ -XGETTEXT = @XGETTEXT@ -MSGMERGE = msgmerge -MSGMERGE_UPDATE = @MSGMERGE@ --update -MSGINIT = msginit -MSGCONV = msgconv -MSGFILTER = msgfilter - -POFILES = @POFILES@ -GMOFILES = @GMOFILES@ -UPDATEPOFILES = @UPDATEPOFILES@ -DUMMYPOFILES = @DUMMYPOFILES@ -DISTFILES.common = Makefile.in.in remove-potcdate.sin \ -$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) -DISTFILES = $(DISTFILES.common) Makevars POTFILES.in $(DOMAIN).pot stamp-po \ -$(POFILES) $(GMOFILES) \ -$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) - -POTFILES = \ - -CATALOGS = @CATALOGS@ - -# Makevars gets inserted here. (Don't remove this line!) - -.SUFFIXES: -.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-update - -.po.mo: - @echo "$(MSGFMT) -c -o $@ $<"; \ - $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ - -.po.gmo: - @lang=`echo $* | sed -e 's,.*/,,'`; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ - cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo - -.sin.sed: - sed -e '/^#/d' $< > t-$@ - mv t-$@ $@ - - -all: all-@USE_NLS@ - -all-yes: stamp-po -all-no: - -# stamp-po is a timestamp denoting the last time at which the CATALOGS have -# been loosely updated. Its purpose is that when a developer or translator -# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, -# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent -# invocations of "make" will do nothing. This timestamp would not be necessary -# if updating the $(CATALOGS) would always touch them; however, the rule for -# $(POFILES) has been designed to not touch files that don't need to be -# changed. -stamp-po: $(srcdir)/$(DOMAIN).pot - test -z "$(CATALOGS)" || $(MAKE) $(CATALOGS) - @echo "touch stamp-po" - @echo timestamp > stamp-poT - @mv stamp-poT stamp-po - -# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', -# otherwise packages like GCC can not be built if only parts of the source -# have been downloaded. - -# This target rebuilds $(DOMAIN).pot; it is an expensive operation. -# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. -$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed - $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ - --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ - --files-from=$(srcdir)/POTFILES.in \ - --copyright-holder='$(COPYRIGHT_HOLDER)' \ - --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' - test ! -f $(DOMAIN).po || { \ - if test -f $(srcdir)/$(DOMAIN).pot; then \ - sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ - sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ - if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ - else \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - else \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - } - -# This rule has no dependencies: we don't need to update $(DOMAIN).pot at -# every "make" invocation, only create it when it is missing. -# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. -$(srcdir)/$(DOMAIN).pot: - $(MAKE) $(DOMAIN).pot-update - -# This target rebuilds a PO file if $(DOMAIN).pot has changed. -# Note that a PO file is not touched if it doesn't need to be changed. -$(POFILES): $(srcdir)/$(DOMAIN).pot - @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ - cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot - - -install: install-exec install-data -install-exec: -install-data: install-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - for file in $(DISTFILES.common) Makevars.template; do \ - $(INSTALL_DATA) $(srcdir)/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - for file in Makevars; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -install-data-no: all -install-data-yes: all - $(mkinstalldirs) $(DESTDIR)$(datadir) - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkinstalldirs) $(DESTDIR)$$dir; \ - if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ - $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ - echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ - fi; \ - done; \ - done - -install-strip: install - -installdirs: installdirs-exec installdirs-data -installdirs-exec: -installdirs-data: installdirs-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkinstalldirs) $(DESTDIR)$(gettextsrcdir); \ - else \ - : ; \ - fi -installdirs-data-no: -installdirs-data-yes: - $(mkinstalldirs) $(DESTDIR)$(datadir) - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkinstalldirs) $(DESTDIR)$$dir; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - fi; \ - done; \ - done - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: uninstall-exec uninstall-data -uninstall-exec: -uninstall-data: uninstall-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - for file in $(DISTFILES.common) Makevars.template; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -uninstall-data-no: -uninstall-data-yes: - catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - done; \ - done - -check: all - -info dvi ps pdf html tags TAGS ctags CTAGS ID: - -mostlyclean: - rm -f remove-potcdate.sed - rm -f stamp-poT - rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po - rm -fr *.o - -clean: mostlyclean - -distclean: clean - rm -f Makefile Makefile.in POTFILES *.mo - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - rm -f stamp-po $(GMOFILES) - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: - $(MAKE) update-po - @$(MAKE) dist2 -# This is a separate target because 'update-po' must be executed before. -dist2: $(DISTFILES) - dists="$(DISTFILES)"; \ - if test "$(PACKAGE)" = "gettext-tools"; then \ - dists="$$dists Makevars.template"; \ - fi; \ - if test -f $(srcdir)/ChangeLog; then \ - dists="$$dists ChangeLog"; \ - fi; \ - for i in 0 1 2 3 4 5 6 7 8 9; do \ - if test -f $(srcdir)/ChangeLog.$$i; then \ - dists="$$dists ChangeLog.$$i"; \ - fi; \ - done; \ - if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ - for file in $$dists; do \ - if test -f $$file; then \ - cp -p $$file $(distdir); \ - else \ - cp -p $(srcdir)/$$file $(distdir); \ - fi; \ - done - -update-po: Makefile - $(MAKE) $(DOMAIN).pot-update - test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) - $(MAKE) update-gmo - -# General rule for updating PO files. - -.nop.po-update: - @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ - if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ - cd $(srcdir); \ - if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "msgmerge for $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -$(DUMMYPOFILES): - -update-gmo: Makefile $(GMOFILES) - @: - -Makefile: Makefile.in.in $(top_builddir)/config.status @POMAKEFILEDEPS@ - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ - $(SHELL) ./config.status - -force: - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/po/Makevars b/po/Makevars deleted file mode 100644 index b99cd466c..000000000 --- a/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = gnupg2 - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = Free Software Foundation, Inc. - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = translations@gnupg.org - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index ae54716ac..000000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,36 +0,0 @@ -# List of files with translatable strings. - -agent/gpg-agent.c -agent/protect-tool.c -agent/divert-scd.c -agent/genkey.c -agent/query.c - -common/sysutils.c -common/simple-pwquery.c - -jnlib/argparse.c -jnlib/logging.c - -kbx/kbxutil.c - -scd/scdaemon.c - -sm/base64.c -sm/call-agent.c -sm/call-dirmngr.c -sm/certdump.c -sm/certlist.c -sm/certchain.c -sm/decrypt.c -sm/delete.c -sm/encrypt.c -sm/gpgsm.c -sm/import.c -sm/keydb.c -sm/keylist.c -sm/sign.c -sm/verify.c - -tools/gpgconf.c -tools/gpgconf-comp.c diff --git a/po/Rules-quot b/po/Rules-quot deleted file mode 100644 index 5f46d237d..000000000 --- a/po/Rules-quot +++ /dev/null @@ -1,42 +0,0 @@ -# Special Makefile rules for English message catalogs with quotation marks. - -DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot - -.SUFFIXES: .insert-header .po-update-en - -en@quot.po-update: en@quot.po-update-en -en@boldquot.po-update: en@boldquot.po-update-en - -.insert-header.po-update-en: - @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ - if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - ll=`echo $$lang | sed -e 's/@.*//'`; \ - LC_ALL=C; export LC_ALL; \ - cd $(srcdir); \ - if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "creation of $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -en@quot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header - -en@boldquot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header - -mostlyclean: mostlyclean-quot -mostlyclean-quot: - rm -f *.insert-header diff --git a/po/boldquot.sed b/po/boldquot.sed deleted file mode 100644 index 4b937aa51..000000000 --- a/po/boldquot.sed +++ /dev/null @@ -1,10 +0,0 @@ -s/"\([^"]*\)"/“\1â€/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“â€/""/g -s/“/“/g -s/â€/â€/g -s/‘/‘/g -s/’/’/g diff --git a/po/de.po b/po/de.po deleted file mode 100644 index 2cf41ddb0..000000000 --- a/po/de.po +++ /dev/null @@ -1,1193 +0,0 @@ -# German translation for GnuPG 1.9.x -# Copyright (C) 2002, 2004 Free Software Foundation, Inc. -# Werner Koch <wk@gnupg.org>, 2002. -# -# -# Note that we use "gnupg2" as the domain to avoid conflicts with -# already installed domains "gnupg" from GnuPG < 1.9. -# -msgid "" -msgstr "" -"Project-Id-Version: gnupg2 1.9.7\n" -"Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-04-29 19:50+0200\n" -"PO-Revision-Date: 2004-04-06 11:47+0200\n" -"Last-Translator: Werner Koch <wk@gnupg.org>\n" -"Language-Team: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=iso-8859-1\n" -"Content-Transfer-Encoding: 8bit\n" - -#: agent/gpg-agent.c:94 agent/protect-tool.c:92 scd/scdaemon.c:92 -msgid "" -"@Options:\n" -" " -msgstr "" -"@Optionen:\n" -" " - -#: agent/gpg-agent.c:96 scd/scdaemon.c:94 -msgid "run in server mode (foreground)" -msgstr "Im Server Modus ausführen" - -#: agent/gpg-agent.c:97 scd/scdaemon.c:95 -msgid "run in daemon mode (background)" -msgstr "Im Daemon Modus ausführen" - -#: agent/gpg-agent.c:98 kbx/kbxutil.c:73 scd/scdaemon.c:96 sm/gpgsm.c:312 -#: tools/gpgconf.c:62 -msgid "verbose" -msgstr "ausführlich" - -#: agent/gpg-agent.c:99 kbx/kbxutil.c:74 scd/scdaemon.c:97 sm/gpgsm.c:313 -msgid "be somewhat more quiet" -msgstr "etwas weniger Aussageb erzeugen" - -#: agent/gpg-agent.c:100 scd/scdaemon.c:98 -msgid "sh-style command output" -msgstr "Ausgabe für /bin/sh" - -#: agent/gpg-agent.c:101 scd/scdaemon.c:99 -msgid "csh-style command output" -msgstr "Ausgabe für /bin/csh" - -#: agent/gpg-agent.c:102 -msgid "|FILE|read options from FILE" -msgstr "|DATEI|Konfigurationsoptionen aus DATEI lesen" - -#: agent/gpg-agent.c:107 scd/scdaemon.c:106 -msgid "do not detach from the console" -msgstr "Im Vordergrund laufen lassen" - -#: agent/gpg-agent.c:108 -msgid "do not grab keyboard and mouse" -msgstr "Tastatur und Maus nicht \"grabben\"" - -#: agent/gpg-agent.c:109 scd/scdaemon.c:107 sm/gpgsm.c:315 -msgid "use a log file for the server" -msgstr "Logausgaben in eine Datei umlenken" - -#: agent/gpg-agent.c:110 -msgid "do not allow multiple connections" -msgstr "Nicht mehr als eine Verbindung erlauben" - -#: agent/gpg-agent.c:124 -msgid "ignore requests to change the TTY" -msgstr "Ignoriere Anfragen, das TTY zu wechseln" - -#: agent/gpg-agent.c:126 -msgid "ignore requests to change the X display" -msgstr "Ignoriere Anfragen, das X-Display zu wechseln" - -#: agent/gpg-agent.c:180 agent/protect-tool.c:124 scd/scdaemon.c:165 -#: sm/gpgsm.c:479 tools/gpgconf.c:85 -msgid "Please report bugs to <" -msgstr "Fehlerberichte bitte an <" - -#: agent/gpg-agent.c:180 agent/protect-tool.c:124 scd/scdaemon.c:165 -#: sm/gpgsm.c:479 tools/gpgconf.c:85 -msgid ">.\n" -msgstr ">.\n" - -#: agent/gpg-agent.c:183 -msgid "Usage: gpg-agent [options] (-h for help)" -msgstr "Gebrauch: gpg-agent [Optionen] (-h für Hilfe)" - -#: agent/gpg-agent.c:185 -msgid "" -"Syntax: gpg-agent [options] [command [args]]\n" -"Secret key management for GnuPG\n" -msgstr "" -"Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n" -"Verwaltung von geheimen Schlüssel für GnuPG\n" - -#: agent/gpg-agent.c:256 scd/scdaemon.c:239 sm/gpgsm.c:602 -#, c-format -msgid "invalid debug-level `%s' given\n" -msgstr "ungültige Debugebene `%s' angegeben\n" - -#: agent/gpg-agent.c:414 agent/protect-tool.c:1035 kbx/kbxutil.c:230 -#: scd/scdaemon.c:352 sm/gpgsm.c:725 -#, c-format -msgid "libgcrypt is too old (need %s, have %s)\n" -msgstr "" -"Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n" - -#: agent/gpg-agent.c:487 scd/scdaemon.c:432 sm/gpgsm.c:823 -#, c-format -msgid "NOTE: no default option file `%s'\n" -msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n" - -#: agent/gpg-agent.c:492 agent/gpg-agent.c:955 scd/scdaemon.c:437 -#: sm/gpgsm.c:827 -#, c-format -msgid "option file `%s': %s\n" -msgstr "Konfigurationsdatei `%s': %s\n" - -#: agent/gpg-agent.c:500 scd/scdaemon.c:445 sm/gpgsm.c:834 -#, c-format -msgid "reading options from `%s'\n" -msgstr "Optionen werden aus `%s' gelesen\n" - -#: agent/gpg-agent.c:641 scd/scdaemon.c:619 -msgid "please use the option `--daemon' to run the program in the background\n" -msgstr "" -"Bitte die Option `--daemon' nutzen um das Programm im Hintergund " -"auszuführen\n" - -#: agent/gpg-agent.c:988 agent/gpg-agent.c:1022 -#, c-format -msgid "can't create directory `%s': %s\n" -msgstr "Das Verzeichniss `%s' kann nicht erstell werden: %s\n" - -#: agent/gpg-agent.c:991 agent/gpg-agent.c:1027 -#, c-format -msgid "directory `%s' created\n" -msgstr "Verzeichniss `%s' wurde erstellt\n" - -#: agent/protect-tool.c:127 -msgid "Usage: gpg-protect-tool [options] (-h for help)\n" -msgstr "Gebrauch: gpg-protect-tool [Optionen] (-h für Hilfe)\n" - -#: agent/protect-tool.c:129 -msgid "" -"Syntax: gpg-protect-tool [options] [args]]\n" -"Secret key maintenance tool\n" -msgstr "" -"Syntax: gpg-protect-tool [Optionen] [Argumente]\n" -"Werkzeug zum Bearbeiten von geheimen Schlüsseln\n" - -#: agent/protect-tool.c:1142 -msgid "" -"Please enter the passphrase or the PIN\n" -"needed to complete this operation." -msgstr "" -"Die Eingabe des Mantras (Passphrase) bzw. der PIN\n" -"wird benötigt um diese Aktion auszuführen." - -#: agent/protect-tool.c:1145 -msgid "Passphrase:" -msgstr "Passphrase:" - -#: agent/divert-scd.c:200 -#, c-format -msgid "Please enter the PIN%s%s%s to unlock the card" -msgstr "Bitte geben Sie die PIN%s%s%s ein um die Karte zu entsperren" - -#: agent/genkey.c:108 -#, c-format -msgid "Please enter the passphrase to%0Ato protect your new key" -msgstr "" -"Bitte geben Sie das Mantra (Passphrase) ein%0Aum Ihren Schlüssel zu schützen" - -#: agent/genkey.c:110 agent/genkey.c:224 -msgid "Please re-enter this passphrase" -msgstr "Bitte geben Sie das Mantra (Passphrase) noch einmal ein:" - -#: agent/genkey.c:131 agent/genkey.c:244 -msgid "does not match - try again" -msgstr "Keine Übereinstimmung - bitte nochmal versuchen" - -#: agent/genkey.c:223 -msgid "Please enter the new passphrase" -msgstr "Bitte geben Sie das Mantra (Passphrase) ein:" - -#: agent/query.c:268 -msgid "" -"Please enter your PIN, so that the secret key can be unlocked for this " -"session" -msgstr "" -"Bitte geben Sie Ihre PIN ein, so daß der geheime Schlüssel benutzt werden " -"kann" - -#: agent/query.c:271 -msgid "" -"Please enter your passphrase, so that the secret key can be unlocked for " -"this session" -msgstr "" -"Bitte geben Sie Ihr Mantra (Passphrase) ein, so daß der geheime Schlüssel " -"benutzt werden kann" - -#: agent/query.c:326 agent/query.c:338 -msgid "PIN too long" -msgstr "Die PIN ist zu lang" - -#: agent/query.c:327 -msgid "Passphrase too long" -msgstr "Das Matra (Passphrase) ist zu lang" - -#: agent/query.c:335 -msgid "Invalid characters in PIN" -msgstr "Ungültige Zeichen in der PIN" - -#: agent/query.c:340 -msgid "PIN too short" -msgstr "Die PIN ist zu kurz" - -#: agent/query.c:352 -msgid "Bad PIN" -msgstr "Falsche PIN" - -#: agent/query.c:353 -msgid "Bad Passphrase" -msgstr "Falsches Mantra (Passphrase)" - -#: agent/query.c:392 -msgid "Passphrase" -msgstr "Mantra" - -#: common/sysutils.c:84 -#, c-format -msgid "can't disable core dumps: %s\n" -msgstr "" -"Das Erstellen eines Speicherabzugs (core-dump) kann nicht verhindert werden: " -"%s\n" - -#: common/sysutils.c:159 -#, c-format -msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "WARNUNG: Unsichere Besitzrechte für %s \"%s\"\n" - -#: common/sysutils.c:191 -#, c-format -msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "WARNUNG: Unsichere Zugriffsrechte für %s \"%s\"\n" - -#: common/simple-pwquery.c:272 -msgid "gpg-agent is not available in this session\n" -msgstr "Der gpg-agent ist nicht verfügbar\n" - -#: common/simple-pwquery.c:286 sm/call-agent.c:128 -msgid "malformed GPG_AGENT_INFO environment variable\n" -msgstr "Die Variable GPG_AGENT_INFO ist fehlerhaft\n" - -#: common/simple-pwquery.c:298 sm/call-agent.c:140 -#, c-format -msgid "gpg-agent protocol version %d is not supported\n" -msgstr "Das gpg-agent Protocol %d wird nicht unterstützt\n" - -#: common/simple-pwquery.c:320 -#, c-format -msgid "can't connect to `%s': %s\n" -msgstr "Verbindung zu `%s' kann nicht aufgebaut werden: %s\n" - -#: common/simple-pwquery.c:331 -msgid "communication problem with gpg-agent\n" -msgstr "Kommunikationsproblem mit gpg-agent\n" - -#: common/simple-pwquery.c:341 -msgid "problem setting the gpg-agent options\n" -msgstr "Beim setzen der gpg-agent Optionen ist ein problem aufgetreten\n" - -#: common/simple-pwquery.c:473 -msgid "canceled by user\n" -msgstr "Vom Benutzer abgebrochen\n" - -#: common/simple-pwquery.c:480 -msgid "problem with the agent\n" -msgstr "Problem mit dem Agenten\n" - -#: jnlib/logging.c:547 -#, c-format -msgid "you found a bug ... (%s:%d)\n" -msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n" - -#: kbx/kbxutil.c:62 sm/gpgsm.c:223 tools/gpgconf.c:53 -msgid "" -"@Commands:\n" -" " -msgstr "" -"@Kommandos:\n" -" " - -#: kbx/kbxutil.c:68 sm/gpgsm.c:258 tools/gpgconf.c:59 -msgid "" -"@\n" -"Options:\n" -" " -msgstr "" -"@\n" -"Optionen:\n" -" " - -#: kbx/kbxutil.c:70 sm/gpgsm.c:260 -msgid "create ascii armored output" -msgstr "Ausgabe mit ASCII Hülle wird erzeugt" - -#: kbx/kbxutil.c:72 sm/gpgsm.c:311 tools/gpgconf.c:61 -msgid "use as output file" -msgstr "als Ausgabedatei benutzen" - -#: kbx/kbxutil.c:75 sm/gpgsm.c:320 tools/gpgconf.c:64 -msgid "do not make any changes" -msgstr "Keine Änderungen durchführen" - -#: kbx/kbxutil.c:77 -msgid "set debugging flags" -msgstr "Debug Flags setzen" - -#: kbx/kbxutil.c:78 -msgid "enable full debugging" -msgstr "Alle Debug Flags setzen" - -#: kbx/kbxutil.c:99 -msgid "Please report bugs to " -msgstr "Bite richten sie Berichte über Bugs (Softwarefehler) an " - -#: kbx/kbxutil.c:99 -msgid ".\n" -msgstr ".\n" - -#: kbx/kbxutil.c:103 -msgid "Usage: kbxutil [options] [files] (-h for help)" -msgstr "Gebrauch: kbxutil [Optionen] [Dateien] (-h für Hilfe)" - -#: kbx/kbxutil.c:106 -msgid "" -"Syntax: kbxutil [options] [files]\n" -"list, export, import Keybox data\n" -msgstr "" -"Syntax: kbxutil [Optionen] [Dateien]\n" -"Anlistem exportieren und Importieren von KeyBox Dateien\n" - -#: scd/scdaemon.c:100 sm/gpgsm.c:332 -msgid "read options from file" -msgstr "Konfigurationsoptionen aus Datei lesen" - -#: scd/scdaemon.c:105 -msgid "|N|set OpenSC debug level to N" -msgstr "|N|Den OpenSC Debugstufe auf N setzen" - -#: scd/scdaemon.c:108 -msgid "|N|connect to reader at port N" -msgstr "|N|Verbinde mit dem Leser auf Port N" - -#: scd/scdaemon.c:109 -msgid "|NAME|use NAME as ct-API driver" -msgstr "|NAME|Benutze NAME als CT-API Treiber" - -#: scd/scdaemon.c:110 -msgid "|NAME|use NAME as PC/SC driver" -msgstr "|NAME|Benutze NAME als PC/SC Treiber" - -#: scd/scdaemon.c:113 -msgid "do not use the internal CCID driver" -msgstr "Den internen CCID Treiber nicht benutzen" - -#: scd/scdaemon.c:120 -msgid "do not use the OpenSC layer" -msgstr "Den OpenSC basierten Kartenzugriff nicht nutzen" - -#: scd/scdaemon.c:125 -msgid "allow the use of admin card commands" -msgstr "Erlaube die Benuztung von \"Admin\" Kommandos" - -#: scd/scdaemon.c:168 -msgid "Usage: scdaemon [options] (-h for help)" -msgstr "Gebrauch: scdaemon [Optionen] (-h für Hilfe)" - -#: scd/scdaemon.c:170 -msgid "" -"Syntax: scdaemon [options] [command [args]]\n" -"Smartcard daemon for GnuPG\n" -msgstr "" -"Synatx: scdaemon [Optionen] [Kommando [Argumente]]\n" -"Smartcard Daemon für GnuPG\n" - -#: sm/base64.c:315 -#, c-format -msgid "invalid radix64 character %02x skipped\n" -msgstr "Ungültiges Basis-64 Zeichen %02X wurde übergangen\n" - -#: sm/call-agent.c:88 -msgid "no running gpg-agent - starting one\n" -msgstr "Kein aktiver gpg-agent - es wird einer gestarted\n" - -#: sm/call-agent.c:151 -msgid "can't connect to the agent - trying fall back\n" -msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n" - -#: sm/call-dirmngr.c:164 -msgid "no running dirmngr - starting one\n" -msgstr "Kein aktiver Dirmngr - es wird einer gestartet\n" - -#: sm/call-dirmngr.c:202 -msgid "malformed DIRMNGR_INFO environment variable\n" -msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n" - -#: sm/call-dirmngr.c:214 -#, c-format -msgid "dirmngr protocol version %d is not supported\n" -msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n" - -#: sm/call-dirmngr.c:225 -msgid "can't connect to the dirmngr - trying fall back\n" -msgstr "" -"Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird " -"versucht\n" - -#: sm/certdump.c:59 sm/certdump.c:142 -msgid "none" -msgstr "keine" - -#: sm/certdump.c:151 -msgid "[none]" -msgstr "[keine]" - -#: sm/certdump.c:490 -msgid "[Error - No name]" -msgstr "[Fehler - Kein Name]" - -#: sm/certdump.c:499 -msgid "[Error - unknown encoding]" -msgstr "[Fehler - Unbekannte Kodierung]" - -#: sm/certdump.c:503 -msgid "[Error - invalid encoding]" -msgstr "[Fehler - Ungültige Kodierung]" - -#: sm/certdump.c:508 -msgid "[Error - invalid DN]" -msgstr "[Fehler - Ungültiger DN]" - -#: sm/certdump.c:652 -#, c-format -msgid "" -"Please enter the passphrase to unlock the secret key for:\n" -"\"%s\"\n" -"S/N %s, ID %08lX, created %s" -msgstr "" -"Bitte geben Sie die Passphrase an, um den \n" -"geheimen Schlüssels von\n" -"\"%s\"\n" -"S/N %s, ID %08lX, erzeugt %s\n" -"zu entsperren" - -#: sm/certlist.c:113 -msgid "no key usage specified - assuming all usages\n" -msgstr "" -"Schlüsselverwendungszweck nicht vorhanden - für alle Zwecke akzeptiert\n" - -#: sm/certlist.c:123 sm/keylist.c:224 -#, c-format -msgid "error getting key usage information: %s\n" -msgstr "Fehler beim holen der Schlüsselbenutzungsinformationen: %s\n" - -#: sm/certlist.c:133 -msgid "certificate should have not been used for certification\n" -msgstr "Das Zertifikat hätte nicht zum Zertifizieren benutzt werden sollen\n" - -#: sm/certlist.c:144 -msgid "certificate should have not been used for encryption\n" -msgstr "Das Zertifikat hatte nicht zum Verschlüsseln benutzt werden sollen\n" - -#: sm/certlist.c:145 -msgid "certificate should have not been used for signing\n" -msgstr "Das Zertifikat hatte nicht zum Signieren benutzt werden sollen\n" - -#: sm/certlist.c:146 -msgid "certificate is not usable for encryption\n" -msgstr "Das Zertifikat kann nicht zum Verschlüsseln benutzt werden\n" - -#: sm/certlist.c:147 -msgid "certificate is not usable for signing\n" -msgstr "Das Zertifikat kann nicht zum Signieren benutzt werden\n" - -#: sm/certchain.c:109 -#, c-format -msgid "critical certificate extension %s is not supported" -msgstr "Die kritische Zertifikaterweiterung %s wird nicht unterstützt" - -#: sm/certchain.c:131 -msgid "issuer certificate is not marked as a CA" -msgstr "Das Herausgeberzertifikat ist nicht für eine CA gekennzeichnet" - -#: sm/certchain.c:169 -msgid "critical marked policy without configured policies" -msgstr "kritische Richtlinie ohne konfigurierte Richtlinien" - -#: sm/certchain.c:185 sm/certchain.c:214 -msgid "note: non-critical certificate policy not allowed" -msgstr "Notiz: Die unkritische Zertifikatrichtlinie ist nicht erlaubt" - -#: sm/certchain.c:189 sm/certchain.c:218 -msgid "certificate policy not allowed" -msgstr "Die Zertifikatrichtlinie ist nicht erlaubt" - -#: sm/certchain.c:349 -msgid "looking up issuer at external location\n" -msgstr "Der Herausgeber wird von einer externen Stelle gesucht\n" - -#: sm/certchain.c:367 -#, c-format -msgid "number of issuers matching: %d\n" -msgstr "Anzahl der übereinstimmenden Heruasgeber: %d\n" - -#: sm/certchain.c:403 sm/certchain.c:561 sm/certchain.c:909 sm/decrypt.c:260 -#: sm/encrypt.c:341 sm/sign.c:324 sm/verify.c:107 -msgid "failed to allocated keyDB handle\n" -msgstr "Ein keyDB Handle konnte nicht bereitgestellt werden\n" - -#: sm/certchain.c:492 -msgid "certificate has been revoked" -msgstr "Das Zertifikat wurde widerrufen" - -#: sm/certchain.c:501 -msgid "no CRL found for certificate" -msgstr "Keine CRL für das Zertifikat gefunden" - -#: sm/certchain.c:505 -msgid "the available CRL is too old" -msgstr "Die vorhandene CRL ist zu alt" - -#: sm/certchain.c:507 -msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "" -"Bite vergewissern Sie sich das der \"dirmngr\" richtig installierrt ist\n" - -#: sm/certchain.c:512 -#, c-format -msgid "checking the CRL failed: %s" -msgstr "Die CRL konnte nicht geprüft werden: %s" - -#: sm/certchain.c:581 -msgid "no issuer found in certificate" -msgstr "Im Zertifikat ist kein Herausgeber enthalten" - -#: sm/certchain.c:594 -#, c-format -msgid "certificate with invalid validity: %s" -msgstr "Zertifikat mit unzulässiger Gültigkeit: %s" - -#: sm/certchain.c:610 -msgid "certificate not yet valid" -msgstr "Das Zertifikat ist noch nicht gültig" - -#: sm/certchain.c:623 -msgid "certificate has expired" -msgstr "Das Zertifikat ist abgelaufen" - -#: sm/certchain.c:660 -msgid "selfsigned certificate has a BAD signature" -msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur" - -#: sm/certchain.c:674 -msgid "root certificate is not marked trusted" -msgstr "Das Wurzelzertifikat ist nicht als vertrauenswürdig markiert" - -#: sm/certchain.c:680 -#, c-format -msgid "fingerprint=%s\n" -msgstr "Fingerprint=%s\n" - -#: sm/certchain.c:685 -msgid "root certificate has now been marked as trusted\n" -msgstr "Das Wurzelzertifikat wurde nun als vertrauenswürdig markiert\n" - -#: sm/certchain.c:700 -#, c-format -msgid "checking the trust list failed: %s\n" -msgstr "Fehler beim Prüfen der vertrauenswürdigen Zertifikate: %s\n" - -#: sm/certchain.c:721 sm/import.c:145 -msgid "certificate chain too long\n" -msgstr "Der Zertifikatkette ist zu lang\n" - -#: sm/certchain.c:733 -msgid "issuer certificate not found" -msgstr "Herausgeberzertifikat nicht gefunden" - -#: sm/certchain.c:766 -msgid "certificate has a BAD signature" -msgstr "Das Zertifikat hat eine FALSCHE Signatur" - -#: sm/certchain.c:789 -msgid "found another possible matching CA certificate - trying again" -msgstr "" -"Eine anderes möglicherweise passendes CA-Zertifikat gefunden - versuche " -"nochmal" - -#: sm/certchain.c:812 -#, c-format -msgid "certificate chain longer than allowed by CA (%d)" -msgstr "Die Zertifikatkette ist länger als von der CA erlaubt (%d)" - -#: sm/decrypt.c:127 -msgid "" -"WARNING: message was encrypted with a weak key in the symmetric cipher.\n" -msgstr "" -"WARNUNG: Die Nachricht wurde mich einem schwachen Schlüssel (Weak Key) " -"erzeugt\n" - -#: sm/decrypt.c:325 -msgid "(this is the RC2 algorithm)\n" -msgstr "(Dies ist der RC-2 Algorithmus)\n" - -#: sm/decrypt.c:327 -msgid "(this does not seem to be an encrypted message)\n" -msgstr "(dies is wahrscheinlich keine verschlüsselte Nachricht)\n" - -#: sm/delete.c:51 sm/delete.c:102 -#, c-format -msgid "certificate `%s' not found: %s\n" -msgstr "Zertifikat `%s' nicht gefunden: %s\n" - -#: sm/delete.c:112 sm/keydb.c:1403 sm/keydb.c:1496 -#, c-format -msgid "error locking keybox: %s\n" -msgstr "Fehler beim Sperren der Keybox: %s\n" - -#: sm/delete.c:133 -#, c-format -msgid "duplicated certificate `%s' deleted\n" -msgstr "Doppeltes Zertifikat `%s' gelöscht\n" - -#: sm/delete.c:135 -#, c-format -msgid "certificate `%s' deleted\n" -msgstr "Zertifikat `%s' gelöscht\n" - -#: sm/delete.c:165 -#, c-format -msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "Fehler beim Löschen des Zertifikats \"%s\": %s\n" - -#: sm/encrypt.c:120 -msgid "weak key created - retrying\n" -msgstr "Schwacher Schlüssel - es wird erneut versucht\n" - -#: sm/encrypt.c:332 -msgid "no valid recipients given\n" -msgstr "Keine gültigen Empfänger angegeben\n" - -#: sm/gpgsm.c:225 -msgid "|[FILE]|make a signature" -msgstr "|[DATEI]|Erzeuge eine Signatur" - -#: sm/gpgsm.c:226 -msgid "|[FILE]|make a clear text signature" -msgstr "|[DATEI]|Erzeuge eine Klartextsignatur" - -#: sm/gpgsm.c:227 -msgid "make a detached signature" -msgstr "Erzeuge eine abgetrennte Signatur" - -#: sm/gpgsm.c:228 -msgid "encrypt data" -msgstr "Verschlüssele die Daten" - -#: sm/gpgsm.c:229 -msgid "encryption only with symmetric cipher" -msgstr "Verschlüsselung nur mit symmetrischem Algrithmus" - -#: sm/gpgsm.c:230 -msgid "decrypt data (default)" -msgstr "Enschlüssele die Daten" - -#: sm/gpgsm.c:231 -msgid "verify a signature" -msgstr "Überprüfen einer Signatur" - -#: sm/gpgsm.c:233 -msgid "list keys" -msgstr "Schlüssel anzeigen" - -#: sm/gpgsm.c:234 -msgid "list external keys" -msgstr "Externe Schlüssel anzeigen" - -#: sm/gpgsm.c:235 -msgid "list secret keys" -msgstr "Geheime Schlüssel anzeigen" - -#: sm/gpgsm.c:236 -msgid "list certificate chain" -msgstr "Schlüssel mit Zertifikatekette anzeigen" - -#: sm/gpgsm.c:238 -msgid "list keys and fingerprints" -msgstr "Schlüssel und Fingerprint anzeigen" - -#: sm/gpgsm.c:239 -msgid "generate a new key pair" -msgstr "Neues Schlüsselpaar erzeugen" - -#: sm/gpgsm.c:240 -msgid "remove key from the public keyring" -msgstr "Schlüssel aus dem öffentlichen Schlüsselbund löschen" - -#: sm/gpgsm.c:241 -msgid "export keys to a key server" -msgstr "Schlüssen an eine Schlüsselserver exportieren" - -#: sm/gpgsm.c:242 -msgid "import keys from a key server" -msgstr "Schlüssel von einem Schlüsselserver importieren" - -#: sm/gpgsm.c:243 -msgid "import certificates" -msgstr "Zertifikate importieren" - -#: sm/gpgsm.c:244 -msgid "export certificates" -msgstr "Zertifikate exportieren" - -#: sm/gpgsm.c:245 -msgid "register a smartcard" -msgstr "Smartcard registrieren" - -#: sm/gpgsm.c:246 -msgid "run in server mode" -msgstr "Im Server Modus ausführen" - -#: sm/gpgsm.c:247 -msgid "pass a command to the dirmngr" -msgstr "Das Kommand an den Dirmngr durchreichen" - -#: sm/gpgsm.c:249 -msgid "invoke gpg-protect-tool" -msgstr "Rufe das gpg-protect-tool auf" - -#: sm/gpgsm.c:250 -msgid "change a passphrase" -msgstr "Das Mantra (Passphrase) ändern" - -#: sm/gpgsm.c:262 -msgid "create base-64 encoded output" -msgstr "Ausgabe im Basis-64 format erzeugen" - -#: sm/gpgsm.c:264 -msgid "assume input is in PEM format" -msgstr "Eingabedaten sind im PEM Format" - -#: sm/gpgsm.c:266 -msgid "assume input is in base-64 format" -msgstr "Eingabedaten sin im Basis-64 Format" - -#: sm/gpgsm.c:268 -msgid "assume input is in binary format" -msgstr "Eingabedaten sind im Binärformat" - -#: sm/gpgsm.c:270 -msgid "|NAME|encrypt for NAME" -msgstr "|NAME|Verschlüsseln für NAME" - -#: sm/gpgsm.c:273 -msgid "never consult a CRL" -msgstr "Niemals eine CRL konsultieren" - -#: sm/gpgsm.c:278 -msgid "check validity using OCSP" -msgstr "Die Gültigkeit mittels OCSP prüfen" - -#: sm/gpgsm.c:281 -msgid "|N|number of certificates to include" -msgstr "|N|Sende N Zertifikate mit" - -#: sm/gpgsm.c:284 -msgid "|FILE|take policy information from FILE" -msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen" - -#: sm/gpgsm.c:287 -msgid "do not check certificate policies" -msgstr "Zertikikatrichtlinien nicht überprüfen" - -#: sm/gpgsm.c:291 -msgid "fetch missing issuer certificates" -msgstr "Fehlende Zertifikate automatisch holen" - -#: sm/gpgsm.c:295 -msgid "|NAME|use NAME as default recipient" -msgstr "|NAME|Benutze NAME als voreingestellten Empfänger" - -#: sm/gpgsm.c:297 -msgid "use the default key as default recipient" -msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger" - -#: sm/gpgsm.c:303 -msgid "use this user-id to sign or decrypt" -msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln" - -#: sm/gpgsm.c:306 -msgid "|N|set compress level N (0 disables)" -msgstr "|N|Benutze Komprimierungsstufe N" - -#: sm/gpgsm.c:308 -msgid "use canonical text mode" -msgstr "Kanonischen Textmodus benutzen" - -#: sm/gpgsm.c:314 -msgid "don't use the terminal at all" -msgstr "Das Terminal überhaupt nicht benutzen" - -#: sm/gpgsm.c:317 -msgid "force v3 signatures" -msgstr "Version 3 Signaturen erzwingen" - -#: sm/gpgsm.c:318 -msgid "always use a MDC for encryption" -msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen" - -#: sm/gpgsm.c:323 -msgid "batch mode: never ask" -msgstr "Stapelverarbeitungs Modus: Nie nachfragen" - -#: sm/gpgsm.c:324 -msgid "assume yes on most questions" -msgstr "\"Ja\" auf die meisten Anfragen annehmen" - -#: sm/gpgsm.c:325 -msgid "assume no on most questions" -msgstr "\"Nein\" auf die meisten Anfragen annehmen" - -#: sm/gpgsm.c:327 -msgid "add this keyring to the list of keyrings" -msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen" - -#: sm/gpgsm.c:328 -msgid "add this secret keyring to the list" -msgstr "Diese geheimen Keyring in die Liste aufnehmen" - -#: sm/gpgsm.c:329 -msgid "|NAME|use NAME as default secret key" -msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel" - -#: sm/gpgsm.c:330 -msgid "|HOST|use this keyserver to lookup keys" -msgstr "|HOST|Benutze HOST als Schlüsselserver" - -#: sm/gpgsm.c:331 -msgid "|NAME|set terminal charset to NAME" -msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen" - -#: sm/gpgsm.c:340 -msgid "|FD|write status info to this FD" -msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben" - -#: sm/gpgsm.c:347 -msgid "|FILE|load extension module FILE" -msgstr "|DATEI|Das Erweiterungsmodul DATEI laden" - -#: sm/gpgsm.c:353 -msgid "|NAME|use cipher algorithm NAME" -msgstr "|NAME|Den Verhsclüsselungsalgrithmus NAME benutzen" - -#: sm/gpgsm.c:355 -msgid "|NAME|use message digest algorithm NAME" -msgstr "|NAME|Den Hashalgorithmus NAME benutzen" - -#: sm/gpgsm.c:357 -msgid "|N|use compress algorithm N" -msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen" - -#: sm/gpgsm.c:365 -msgid "" -"@\n" -"(See the man page for a complete listing of all commands and options)\n" -msgstr "" -"@\n" -"(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n" - -#: sm/gpgsm.c:368 -msgid "" -"@\n" -"Examples:\n" -"\n" -" -se -r Bob [file] sign and encrypt for user Bob\n" -" --clearsign [file] make a clear text signature\n" -" --detach-sign [file] make a detached signature\n" -" --list-keys [names] show keys\n" -" --fingerprint [names] show fingerprints\n" -msgstr "" -"@\n" -"Beispiele:\n" -"\n" -" -se -r Bob [Datei] Signieren und verschlüsseln für Benutzer Bob\\n\n" -" --clearsign [Datei] Eine Klartextsignatur erzeugen\\n\n" -" --detach-sign [Datei] Eine abgetrennte Signatur erzeugen\\n\n" -" --list-keys [Namen] Schlüssel anzeigenn\n" -" --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\\n\n" - -#: sm/gpgsm.c:482 -msgid "Usage: gpgsm [options] [files] (-h for help)" -msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)" - -#: sm/gpgsm.c:485 -msgid "" -"Syntax: gpgsm [options] [files]\n" -"sign, check, encrypt or decrypt using the S/MIME protocol\n" -"default operation depends on the input data\n" -msgstr "" -"Gebrauch: gpgsm [Optionen] [Dateien]\n" -"Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n" - -#: sm/gpgsm.c:492 -msgid "" -"\n" -"Supported algorithms:\n" -msgstr "" -"\n" -"Unterstützte Algorithmen:\n" - -#: sm/gpgsm.c:573 -msgid "usage: gpgsm [options] " -msgstr "Gebrauch: gpgsm [Optionen] " - -#: sm/gpgsm.c:639 -msgid "conflicting commands\n" -msgstr "Widersprechende Kommandos\n" - -#: sm/gpgsm.c:655 -#, c-format -msgid "can't encrypt to `%s': %s\n" -msgstr "Verschlüsseln für `%s' nicht möglich: %s\n" - -#: sm/gpgsm.c:730 -#, c-format -msgid "libksba is too old (need %s, have %s)\n" -msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" - -#: sm/gpgsm.c:1169 -msgid "WARNING: program may create a core file!\n" -msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" - -#: sm/gpgsm.c:1181 -msgid "WARNING: running with faked system time: " -msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " - -#: sm/gpgsm.c:1201 -msgid "selected cipher algorithm is invalid\n" -msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" - -#: sm/gpgsm.c:1209 -msgid "selected digest algorithm is invalid\n" -msgstr "Das ausgewählte Hashverfahren ist ungültig\n" - -#: sm/gpgsm.c:1239 -#, c-format -msgid "can't sign using `%s': %s\n" -msgstr "Signieren mit `%s' nicht möglich: %s\n" - -#: sm/gpgsm.c:1406 -msgid "this command has not yet been implemented\n" -msgstr "Diee Kommando wurde noch nicht implementiert\n" - -#: sm/gpgsm.c:1629 sm/gpgsm.c:1662 -#, c-format -msgid "can't open `%s': %s\n" -msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" - -#: sm/import.c:114 -#, c-format -msgid "total number processed: %lu\n" -msgstr "gesamte verarbeitete Anzahl: %lu\n" - -#: sm/import.c:117 -#, c-format -msgid " imported: %lu" -msgstr " importiert: %lu" - -#: sm/import.c:121 -#, c-format -msgid " unchanged: %lu\n" -msgstr " nicht geändert: %lu\n" - -#: sm/import.c:123 -#, c-format -msgid " not imported: %lu\n" -msgstr " nicht importiert: %lu\n" - -#: sm/import.c:204 -msgid "error storing certificate\n" -msgstr "Fehler beim speichern des Zertifikats\n" - -#: sm/import.c:211 -msgid "basic certificate checks failed - not imported\n" -msgstr "Grundlegende Zertifikatprüfungen fehlgeschlagen - nicht importiert\n" - -#: sm/import.c:396 sm/import.c:428 -#, c-format -msgid "error importing certificate: %s\n" -msgstr "Fehler beim Importieren des Zertifikats: %s\n" - -#: sm/import.c:457 -#, c-format -msgid "error creating a pipe: %s\n" -msgstr "Fehler beim Erzeugen einer \"Pipe\": %s\n" - -#: sm/import.c:465 -#, c-format -msgid "error forking process: %s\n" -msgstr "Fehler beim \"Forken\" des Prozess: %s\n" - -#: sm/import.c:562 sm/import.c:587 -#, c-format -msgid "error creating temporary file: %s\n" -msgstr "Fehler beim Erstellen einer temporären Datei: %s\n" - -#: sm/import.c:570 -#, c-format -msgid "error writing to temporary file: %s\n" -msgstr "Fehler beim Schreiben auf eine temporäre Datei: %s\n" - -#: sm/import.c:579 -#, c-format -msgid "error reading input: %s\n" -msgstr "Fehler beim Lesen der Eingabe: %s\n" - -#: sm/import.c:649 -#, c-format -msgid "waiting for protect-tool to terminate failed: %s\n" -msgstr "" -"Das Warten auf die Beendigung des protect-tools ist fehlgeschlagen: %s\n" - -#: sm/import.c:652 -#, c-format -msgid "error running `%s': probably not installed\n" -msgstr "Feler bei Ausführung von `%s': wahrscheinlich nicht installiert\n" - -#: sm/import.c:654 -#, c-format -msgid "error running `%s': exit status %d\n" -msgstr "Fehler bei Ausführung von `%s': Endestatus %d\n" - -#: sm/import.c:657 -#, c-format -msgid "error running `%s': terminated\n" -msgstr "Fehler beim Ausführen von `%s': beendet\n" - -#: sm/keydb.c:189 -#, c-format -msgid "error creating keybox `%s': %s\n" -msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n" - -#: sm/keydb.c:192 -msgid "you may want to start the gpg-agent first\n" -msgstr "Sie sollten zuerst den gpg-agent starten\n" - -#: sm/keydb.c:197 -#, c-format -msgid "keybox `%s' created\n" -msgstr "Die \"Keybox\" `%s' wurde erstellt\n" - -#: sm/keydb.c:220 -#, c-format -msgid "can't create lock for `%s'\n" -msgstr "Datei `%s' konnte nicht gesperrt werden\n" - -#: sm/keydb.c:1327 sm/keydb.c:1389 -msgid "failed to get the fingerprint\n" -msgstr "Kann den Fingerprint nicht ermitteln\n" - -#: sm/keydb.c:1334 sm/keydb.c:1396 -msgid "failed to allocate keyDB handle\n" -msgstr "Kann keinen KeyDB Handler bereitstellen\n" - -#: sm/keydb.c:1351 -#, c-format -msgid "problem looking for existing certificate: %s\n" -msgstr "Problem bei der Suche nach vorhandenem Zertifikat: %s\n" - -#: sm/keydb.c:1359 -#, c-format -msgid "error finding writable keyDB: %s\n" -msgstr "Fehler bei der Suche nach einer schreibbaren KeyDB: %s\n" - -#: sm/keydb.c:1367 -#, c-format -msgid "error storing certificate: %s\n" -msgstr "Fehler beim Speichern des Zertifikats: %s\n" - -#: sm/keydb.c:1411 -#, c-format -msgid "problem re-searching certificate: %s\n" -msgstr "Problem bei Wiederfinden des Zertifikats: %s\n" - -#: sm/keydb.c:1420 sm/keydb.c:1508 -#, c-format -msgid "error getting stored flags: %s\n" -msgstr "Fehler beim Holen der gespeicherten Flags: %s\n" - -#: sm/keydb.c:1429 sm/keydb.c:1519 -#, c-format -msgid "error storing flags: %s\n" -msgstr "Fehler beim Speichern der Flags: %s\n" - -#: sm/verify.c:387 -msgid "Signature made " -msgstr "Signatur erzeugt am " - -#: sm/verify.c:391 -msgid "[date not given]" -msgstr "[Datum nicht vorhanden]" - -#: sm/verify.c:392 -#, c-format -msgid " using certificate ID %08lX\n" -msgstr "mittels Zertifikat ID %08lX\n" - -#: sm/verify.c:505 -msgid "Good signature from" -msgstr "Korrekte Signatur von" - -#: sm/verify.c:506 -msgid " aka" -msgstr " alias" - -#: tools/gpgconf.c:55 -msgid "list all components" -msgstr "Liste aller Komponenten" - -#: tools/gpgconf.c:56 -msgid "|COMPONENT|list options" -msgstr "|KOMPONENTE|Zeige die Optionen an" - -#: tools/gpgconf.c:57 -msgid "|COMPONENT|change options" -msgstr "|KOMPONENTE|Ändere die Optionen" - -#: tools/gpgconf.c:63 -msgid "quiet" -msgstr "Weniger Ausgaben" - -#: tools/gpgconf.c:65 -msgid "activate changes at runtime, if possible" -msgstr "Aktiviere Änderungen zur Laufzeit; falls möglich" - -#: tools/gpgconf.c:88 -msgid "Usage: gpgconf [options] (-h for help)" -msgstr "Gebrauch: gpgconf [Optionen] (-h für Hilfe)" - -#: tools/gpgconf.c:91 -msgid "" -"Syntax: gpgconf [options]\n" -"Manage configuration options for tools of the GnuPG system\n" -msgstr "" -"Syntax: gpgconf {Optionen]\n" -"Verwalte Konfigurationsoptionen für Programme des GnuPG Systems\n" - -#: tools/gpgconf.c:180 -msgid "usage: gpgconf [options] " -msgstr "Gebrauch: gpgconf [Optionen] " - -#: tools/gpgconf.c:181 -msgid "Need one component argument" -msgstr "Benötige ein Komponenten Argument" - -#: tools/gpgconf.c:190 -msgid "Component not found" -msgstr "Komponente nicht gefunden" - -#~ msgid "Enter passphrase:" -#~ msgstr "Bitte das Mantra (Passphrase) eingeben:" - -#~ msgid "[error]" -#~ msgstr "[Fehler]" - -#~ msgid "no key usage specified - accepted for encryption\n" -#~ msgstr "" -#~ "Schlüsselverwendungszweck nicht vorhanden - wird zum Verschlüsseln " -#~ "akzeptiert\n" - -#~ msgid " skipped new keys: %lu\n" -#~ msgstr " übersprungene Schlüssel: %lu\n" diff --git a/po/en@boldquot.header b/po/en@boldquot.header deleted file mode 100644 index fedb6a06d..000000000 --- a/po/en@boldquot.header +++ /dev/null @@ -1,25 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# -# This catalog furthermore displays the text between the quotation marks in -# bold face, assuming the VT100/XTerm escape sequences. -# diff --git a/po/en@quot.header b/po/en@quot.header deleted file mode 100644 index a9647fc35..000000000 --- a/po/en@quot.header +++ /dev/null @@ -1,22 +0,0 @@ -# All this catalog "translates" are quotation characters. -# The msgids must be ASCII and therefore cannot contain real quotation -# characters, only substitutes like grave accent (0x60), apostrophe (0x27) -# and double quote (0x22). These substitutes look strange; see -# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html -# -# This catalog translates grave accent (0x60) and apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019). -# It also translates pairs of apostrophe (0x27) to -# left single quotation mark (U+2018) and right single quotation mark (U+2019) -# and pairs of quotation mark (0x22) to -# left double quotation mark (U+201C) and right double quotation mark (U+201D). -# -# When output to an UTF-8 terminal, the quotation characters appear perfectly. -# When output to an ISO-8859-1 terminal, the single quotation marks are -# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to -# grave/acute accent (by libiconv), and the double quotation marks are -# transliterated to 0x22. -# When output to an ASCII terminal, the single quotation marks are -# transliterated to apostrophes, and the double quotation marks are -# transliterated to 0x22. -# diff --git a/po/insert-header.sin b/po/insert-header.sin deleted file mode 100644 index b26de01f6..000000000 --- a/po/insert-header.sin +++ /dev/null @@ -1,23 +0,0 @@ -# Sed script that inserts the file called HEADER before the header entry. -# -# At each occurrence of a line starting with "msgid ", we execute the following -# commands. At the first occurrence, insert the file. At the following -# occurrences, do nothing. The distinction between the first and the following -# occurrences is achieved by looking at the hold space. -/^msgid /{ -x -# Test if the hold space is empty. -s/m/m/ -ta -# Yes it was empty. First occurrence. Read the file. -r HEADER -# Output the file's contents by reading the next line. But don't lose the -# current line while doing this. -g -N -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/po/quot.sed b/po/quot.sed deleted file mode 100644 index 0122c4631..000000000 --- a/po/quot.sed +++ /dev/null @@ -1,6 +0,0 @@ -s/"\([^"]*\)"/“\1â€/g -s/`\([^`']*\)'/‘\1’/g -s/ '\([^`']*\)' / ‘\1’ /g -s/ '\([^`']*\)'$/ ‘\1’/g -s/^'\([^`']*\)' /‘\1’ /g -s/“â€/""/g diff --git a/po/remove-potcdate.sed b/po/remove-potcdate.sed deleted file mode 100644 index edb38d704..000000000 --- a/po/remove-potcdate.sed +++ /dev/null @@ -1,11 +0,0 @@ -/^"POT-Creation-Date: .*"$/{ -x -s/P/P/ -ta -g -d -bb -:a -x -:b -} diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin deleted file mode 100644 index 2436c49e7..000000000 --- a/po/remove-potcdate.sin +++ /dev/null @@ -1,19 +0,0 @@ -# Sed script that remove the POT-Creation-Date line in the header entry -# from a POT file. -# -# The distinction between the first and the following occurrences of the -# pattern is achieved by looking at the hold space. -/^"POT-Creation-Date: .*"$/{ -x -# Test if the hold space is empty. -s/P/P/ -ta -# Yes it was empty. First occurrence. Remove the line. -g -d -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} diff --git a/scd/ChangeLog b/scd/ChangeLog deleted file mode 100644 index e04575c75..000000000 --- a/scd/ChangeLog +++ /dev/null @@ -1,659 +0,0 @@ -2004-06-16 Werner Koch <wk@gnupg.org> - - * apdu.c (osc_get_status): Fixed type in function name. Noted by - Axel Thimm. Yes, I didn't tested it with OpenSC :-(. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Sync FORCE_CHV1. - -2004-04-27 Werner Koch <wk@gnupg.org> - - * app-common.h: Do not include ksba.h for gnupg 1. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * app-common.h: New members FNC.DEINIT and APP_LOCAL. - * app.c (release_application): Call new deconstructor. - * app-openpgp.c (do_deinit): New. - (get_cached_data, flush_cache_item, flush_cache_after_error) - (flush_cache): New. - (get_one_do): Replaced arg SLOT by APP. Make used of cached data. - (verify_chv2, verify_chv3): Flush some cache item after error. - (do_change_pin): Ditto. - (do_sign): Ditto. - (do_setattr): Flush cache item. - (do_genkey): Flush the entire cache. - (compare_fingerprint): Use cached data. - - * scdaemon.c (main): Do the last change the usual way. This is so - that we can easily test for versioned config files above. - -2004-04-26 Marcus Brinkmann <marcus@g10code.de> - - * scdaemon.c (main): For now, always print default filename for - --gpgconf-list, and never /dev/null. - -2004-04-21 Werner Koch <wk@gnupg.org> - - * command.c (scd_update_reader_status_file): Send a signal back to - the client. - (option_handler): Parse the new event-signal option. - - * scdaemon.c (handle_signal): Do not use SIGUSR{1,2} anymore for - changing the verbosity. - -2004-04-20 Werner Koch <wk@gnupg.org> - - * command.c (scd_update_reader_status_file): Write status files. - - * app-help.c (app_help_read_length_of_cert): Fixed calculation of - R_CERTOFF. - - * pcsc-wrapper.c: New. - * Makefile.am (pkglib_PROGRAMS): Install it here. - * apdu.c (writen, readn): New. - (open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the - pcsc-wrapper if we are using Pth. - (apdu_send_le): Reinitialize RESULTLEN. Handle SW_EOF_REACHED - like SW_SUCCESS. - -2004-04-19 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (parse_ccid_descriptor): Store some of the reader - features away. New arg HANDLE - (read_device_info): New arg HANDLE. Changed caller. - (bulk_in): Handle time extension requests. - (ccid_get_atr): Setup parameters and the IFSD. - (compute_edc): New. Factored out code. - (ccid_transceive): Use default NADs when required. - -2004-04-14 Werner Koch <wk@gnupg.org> - - * scdaemon.h (server_control_s): Add member READER_SLOT. - * scdaemon.c (scd_init_default_ctrl): Initialize READER_SLOT to -1. - * command.c (open_card): Reuse an open slot. - (reset_notify): Just reset the slot if supported by the reader. - (do_reset): Factored code from above out. - (scd_command_handler): Use it for cleanup. - - * apdu.h: New pseudo stati SW_HOST_NOT_SUPPORTED, - SW_HOST_LOCKING_FAILED and SW_HOST_BUSY. - * iso7816.c (map_sw): Map it. - - * ccid-driver.c (ccid_slot_status): Add arg STATUSBITS. - * apdu.c (apdu_get_status): New. - (ct_get_status, pcsc_get_status, ocsc_get_status): New stubs. - (get_status_ccid): New. - (apdu_reset): New. - (reset_ct_reader, reset_pcsc_reader, reset_osc_reader): New stubs. - (reset_ccid_reader): New. - (apdu_enum_reader): New. - - * apdu.c (lock_slot, trylock_slot, unlock_slot): New helpers. - (new_reader_slot) [USE_GNU_PTH]: Init mutex. - (apdu_reset, apdu_get_status, apdu_send_le): Run functions - in locked mode. - - * command.c (scd_update_reader_status_file): New. - * scdaemon.c (handle_tick): Call it. - -2004-04-13 Werner Koch <wk@gnupg.org> - - * scdaemon.c: Convert to a Pth application. - (handle_signal, ticker_thread, handle_tick): New. - (main): Fire up the ticker thread in server mode. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main) <gpgconf_list>: Fixed output for pcsc_driver. - -2004-03-17 Werner Koch <wk@gnupg.org> - - * tlv.c (parse_ber_header): Do not check for tag overflow - it - does not make sense. Simplified the check for length overflow. - - * scdaemon.c (main) <gpgconf>: Fixed default value quoting. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * app-dinsig.c: Implemented. Based on app-nks.c and card-dinsig.c - * app-nks.c (get_length_of_cert): Removed. - * app-help.c: New. - (app_help_read_length_of_cert): New. Code taken from above. New - optional arg R_CERTOFF. - - * card-dinsig.c: Removed. - * card.c (card_get_serial_and_stamp): Do not bind to the old and - never finsiged card-dinsig.c. - - * iso7816.c (iso7816_read_binary): Allow for an NMAX > 254. - -2004-03-11 Werner Koch <wk@gnupg.org> - - * scdaemon.h (out_of_core): Removed. Replaced callers by standard - gpg_error function. - - * apdu.c, iso7816.c, ccid-driver.c [GNUPG_SCD_MAIN_HEADER]: Allow - to include a header defined by the compiler. This helps us to - reuse the source in other software. - -2004-03-10 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_read_record): New arg SHORT_EF. Changed all - callers. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * sc-investigate.c (main): Setup the used character set. - * scdaemon.c (main): Ditto. - - * scdaemon.c (set_debug): New. Add option --debug-level. - (main): Add option --gpgconf-list. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * Makefile.am: Include cmacros.am for common flags. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * command.c (reset_notify): Release the application context and - close the reader. - -2004-01-28 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_manage_security_env): New. - (iso7816_decipher): Add PADIND argument. - -2004-01-27 Werner Koch <wk@gnupg.org> - - * command.c (cmd_readcert, cmd_readkey): Work on a copy of LINE. - - * app-common.h (app_ctx_s): Added readcert field. - * app.c (app_readcert): New. - * tlv.c (parse_ber_header): Added; taken from libksba. - -2004-01-26 Werner Koch <wk@gnupg.org> - - * card.c (map_sc_err): Use SCD as the error source. - - * command.c (open_card): ADD arg NAME to allow requesting a - specific application. Changed all callers. - (cmd_serialno): Allow optional argument to select the desired - application. - - * app-nks.c: New. - - * scdaemon.h (opt): Add READER_PORT. - * scdaemon.c (main): Set it here. - * app.c (app_set_default_reader_port): Removed. - (select_application): Add NAME arg and figure out a - default serial number from the GDO. Add SLOT arg and remove all - reader management. - (release_application): New. - (app_write_learn_status): Output an APPTYPE status line. - * command.c (open_card): Adapt for select_application change. - * app-openpgp.c (app_select_openpgp): Removed SN and SNLEN args - and set it directly. Changed all callers. - -2004-01-25 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_select_application): P1 kludge for OpenPGP - card. - * app-openpgp.c (find_tlv): Factor out this function to .. - * tlv.c, tlv.h: .. new. - - * scdaemon.h: Introduced app_t and ctrl_t as the new types for APP - and CTRL. - -2004-01-21 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_le): Treat SW_EOF_REACHED as a warning. - -2004-01-20 Werner Koch <wk@gnupg.org> - - * iso7816.c (iso7816_read_binary): New. - (iso7816_select_file): New. - (iso7816_list_directory): New. - - * sc-investigate.c: Add option -i. - (select_app, read_line, interactive_shell): New. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * apdu.h: Add SW_FILE_NOT_FOUND. - * iso7816.c (map_sw): Map it to GPG_ERR_ENOENT. - * iso7816.c (iso7816_select_file): New. - - * app-dinsig.c: New file w/o any real code yet. - * Makefile.am (scdaemon_SOURCES,sc_investigate_SOURCES): Add file. - - * sc-investigate.c: Add option --disable-ccid. - -2003-12-19 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_le): Send a get_response with the indicated - length and not the 64 bytes we used for testing. - - * app-openpgp.c (verify_chv2, verify_chv3, do_sign): Check the - minimum length of the passphrase, so that we don't need to - decrement the retry counter. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * card-p15.c (p15_enum_keypairs): Replaced KRC by RC. - * card-dinsig.c (dinsig_enum_keypairs): Ditto. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): Set the prefixes for assuan logging. - -2003-11-17 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New options --allow-admin and --deny-admin. - * app-openpgp.c (verify_chv3): Check it here. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - -2003-10-30 Werner Koch <wk@gnupg.org> - - * apdu.c (close_ct_reader, close_pcsc_reader): Implemented. - (get_ccid_error_string): New. Not very useful messages, though. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_open_reader): Return an error if no USB - devices are found. - - * command.c (cmd_genkey, cmd_passwd): Fixed faulty use of - !spacep(). - - * apdu.c (apdu_open_reader): Hacks for PC/SC under Windows. - -2003-10-20 Werner Koch <wk@gnupg.org> - - * command.c (cmd_checkpin): New. - (register_commands): Add command CHECKPIN. - * app.c (app_check_pin): New. - * app-openpgp.c (check_against_given_fingerprint): New. Factored - out that code elsewhere. - (do_check_pin): New. - -2003-10-10 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_close_reader): New. - - * apdu.c (close_ccid_reader, close_ct_reader, close_csc_reader) - (close_osc_reader, apdu_close_reader): New. Not all are properly - implemented yet. - -2003-10-09 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (ccid_transceive): Add T=1 chaining for sending. - -2003-10-08 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_getattr): Support SERIALNO and AID. - -2003-10-01 Werner Koch <wk@gnupg.org> - - * ccid-driver.c: Detect GnuPG 1.3 and include appropriate files. - * apdu.c: Ditto. - * app-openpgp.c: Ditto. - * iso7816.c: Ditto. - (generate_keypair): Renamed to .. - (do_generate_keypair): .. this. - * app-common.h [GNUPG_MAJOR_VERSION]: New. - * iso7816.h [GNUPG_MAJOR_VERSION]: Include cardglue.h - -2003-09-30 Werner Koch <wk@gnupg.org> - - * command.c (cmd_getattr): New command GETATTR. - * app.c (app_setattr): New. - (do_getattr): New. - (do_learn_status): Reimplemented in terms of do_getattr. - - * app-openpgp.c (do_change_pin): Make sure CVH1 and CHV2 are - always synced. - (verify_chv2, verify_chv3): New. Factored out common code. - (do_setattr, do_sign, do_auth, do_decipher): Change the names of - the prompts to match that we have only 2 different PINs. - (app_select_openpgp): Check whether the card enforced CHV1. - (convert_sig_counter_value): New. Factor out code from - get_sig_counter. - -2003-09-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (dump_all_do): Use gpg_err_code and not gpg_error. - -2003-09-19 Werner Koch <wk@gnupg.org> - - * ccid-driver.c (parse_ccid_descriptor): New. - (read_device_info): New. - (ccid_open_reader): Check that the device has all required features. - -2003-09-06 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): --pcsc-driver again defaults to pcsclite. - David Corcoran was so kind to remove the GPL incompatible - advertisng clause from pcsclite. - * apdu.c (apdu_open_reader): Actually make pcsc-driver option work. - -2003-09-05 Werner Koch <wk@gnupg.org> - - * ccid-driver.c: More work, data can now actually be retrieved. - * ccid-driver.c, ccid-driver.h: Alternativley allow use under BSD - conditions. - -2003-09-02 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New option --pcsc-ccid. - * ccid-driver.c, ccid-driver.h: New but far from being useful. - * Makefile.am: Add above. - * apdu.c: Add support for that ccid driver. - -2003-08-26 Timo Schulz <twoaday@freakmail.de> - - * apdu.c (new_reader_slot): Only set 'is_osc' when OpenSC - is used. - -2003-08-25 Werner Koch <wk@gnupg.org> - - * command.c (cmd_setattr): Use a copy of LINE. - (cmd_genkey): Use a copy of KEYNO. - (cmd_passwd): Use a copy of CHVNOSTR. - (cmd_pksign, cmd_pkauth, cmd_pkdecrypt): s/strdup/xtrystrdup/. - -2003-08-19 Werner Koch <wk@gnupg.org> - - * scdaemon.c, scdaemon.h: New option --pcsc-driver. - * apdu.c (apdu_open_reader): Use that option here instead of a - hardcoded one. - -2003-08-18 Werner Koch <wk@gnupg.org> - - * Makefile.am: Add OPENSC_LIBS to all programs. - - * scdaemon.c, scdaemon.h: New option --disable-opensc. - * card.c (card_open): Implement it. - * apdu.c (open_osc_reader, osc_send_apdu): New. - (apdu_open_reader) [HAVE_OPENSC]: Use the opensc driver if not - disabled. - (error_string) [HAVE_OPENSC]: Use sc_strerror. - (send_apdu) [HAVE_OPENSC]: Call osc_apdu_send. - - * card-p15.c (p15_enum_keypairs, p15_prepare_key): Adjusted for - libgpg-error. - -2003-08-14 Timo Schulz <twoaday@freakmail.de> - - * apdu.c (ct_activate_card): Change the code a little to avoid - problems with other readers. - * Always use 'dynload.h' instead of 'dlfcn.h'. - -2003-08-05 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (dump_all_do): Don't analyze constructed DOs after - an error. - -2003-08-04 Werner Koch <wk@gnupg.org> - - * app.c (app_set_default_reader_port): New. - (select_application): Use it here. - * scdaemon.c (main): and here. - * sc-copykeys.c: --reader-port does now take a string. - * sc-investigate.c, scdaemon.c: Ditto. - * apdu.c (apdu_open_reader): Ditto. Load pcsclite if no ctapi - driver is configured. Always include code for ctapi. - (new_reader_slot): Don't test for already used ports and remove - port arg. - (open_pcsc_reader, pcsc_send_apdu, pcsc_error_string): New. - (apdu_send_le): Changed RC to long to cope with PC/SC. - - * scdaemon.c, scdaemon.h: New option --ctapi-driver. - * sc-investigate.c, sc-copykeys.c: Ditto. - -2003-07-31 Werner Koch <wk@gnupg.org> - - * Makefile.am (scdaemon_LDADD): Added INTLLIBS. - -2003-07-28 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Change implementation. Allow all - useful DOs. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-07-24 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_learn_status): Print more status information. - (app_select_openpgp): Store the card version. - (store_fpr): Add argument card_version and fix DOs for old cards. - (app_openpgp_storekey): Likewise. - -2003-07-23 Werner Koch <wk@gnupg.org> - - * command.c (cmd_pkauth): New. - (cmd_setdata): Check whether data was given at all to avoid - passing 0 to malloc. - - * app.c (app_auth): New. - * app-openpgp.c (do_auth): New. - -2003-07-22 Werner Koch <wk@gnupg.org> - - * command.c (cmd_passwd): New. - * app.c (app_change_pin): New. - * app-openpgp.c (do_change_pin): New. - * iso7816.c (iso7816_reset_retry_counter): Implemented. - - * sc-investigate.c (main): New option --gen-random. - * iso7816.c (iso7816_get_challenge): Don't create APDUs with a - length larger than 255. - -2003-07-17 Werner Koch <wk@gnupg.org> - - * command.c (cmd_random): New command RANDOM. - - * iso7816.c (map_sw): New. Use it in this file to return - meaningful error messages. Changed all public fucntions to return - a gpg_error_t. - (iso7816_change_reference_data): New. - * apdu.c (apdu_open_reader): Use faked status words for soem - system errors. - -2003-07-16 Werner Koch <wk@gnupg.org> - - * apdu.c (apdu_send_simple): Use apdu_send_le so that we can - specify not to send Le as it should be. - -2003-07-15 Werner Koch <wk@gnupg.org> - - * Makefile.am: Add sc-copykeys program. - * sc-copykeys.c: New. - * app-openpgp.c (app_openpgp_storekey): New. - (app_openpgp_cardinfo): New. - (count_bits): New. - (store_fpr): And use it here to get the actual length in bit. - -2003-07-03 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (do_setattr): Add setting of the URL. - (app_select_openpgp): Dump card data only in very verbose mode. - (do_decipher): New. - -2003-07-02 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (get_sig_counter): New. - (do_sign): Print the signature counter and enable the PIN callback. - (do_genkey): Implement the PIN callback. - -2003-07-01 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (store_fpr): Fixed fingerprint calculation. - -2003-06-26 Werner Koch <wk@gnupg.org> - - * app-openpgp.c (find_tlv): Fixed length header parsing. - - * app.c (app_genkey): New. - * command.c (cmd_genkey): New. - -2003-06-25 Werner Koch <wk@gnupg.org> - - * command.c (percent_plus_unescape): New. - (cmd_setattr): New. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * command.c (send_status_info): New. - - * app-openpgp.c (app_select_openpgp): Replace SLOT arg by APP arg - and setup the function pointers in APP on success. Changed callers. - * app.c: New. - * app-common.h: New. - * scdaemon.h (APP): New type to handle applications. - (server_control_s): Add an APP context field. - - * command.c (cmd_serialno): Handle applications. - (cmd_pksign): Ditto. - (cmd_pkdecrypt): Ditto. - (reset_notify): Ditto. - (cmd_learn): For now return error for application contexts. - (cmd_readcert): Ditto. - (cmd_readkey): Ditto. - -2003-06-04 Werner Koch <wk@gnupg.org> - - * card.c (map_sc_err): Renamed gpg_make_err to gpg_err_make. - - Renamed error codes from INVALID to INV and removed _ERROR suffixes. - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * scdaemon.h: Include gpg-error.h and errno.h - * card.c (map_sc_err): Use unknown for the error source. - * Makefile.am: Link with libgpg-error - -2003-05-14 Werner Koch <wk@gnupg.org> - - * atr.c, atr.h: New. - * sc-investigate.c: Dump the ATR in a human readable format. - -2003-05-08 Werner Koch <wk@gnupg.org> - - * scdaemon.h (DBG_CARD_IO_VALUE): New. - - * sc-investigate.c: New. - * scdaemon.c (main): Removed --print-atr option. - - * iso7816.c, iso7816.h, app-openpgp.c: New. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * scdaemon.c: New options --print-atr and --reader-port - * apdu.c, apdu.h: New - - * card.c, card-p15.c, card-dinsig.c: Allow build without OpenSC. - - * Makefile.am (LDFLAGS): Removed. - - * command.c (register_commands): Adjusted for new Assuan semantics. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): New option --daemon so that the program is - not accidently started in the background. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * scdaemon.c: Include i18n.h. - - * card-common.h (struct p15_private_s): Forward declaration. Add - it to card_ctx_s. - * card.c (card_close): Make sure private data is released. - (card_enum_certs): New. - * card-p15.c (p15_release_private_data): New. - (init_private_data): New to work around an OpenSC weirdness. - (p15_enum_keypairs): Do an OpenSC get_objects only once. - (p15_enum_certs): New. - (card_p15_bind): Bind new function. - * command.c (cmd_learn): Return information about the certificates. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * card.c (card_get_serial_and_stamp): Use the tokeinfo serial - number as a fallback. Add a special prefix for serial numbers. - -2002-07-30 Werner Koch <wk@gnupg.org> - - Changes to cope with OpenSC 0.7.0: - - * card.c: Removed the check for the packed opensc version. - Changed include file names of opensc. - (map_sc_err): Adjusted error codes for new opensc version. - * card-p15.c: Changed include filename of opensc. - * card-dinsig.c: Ditto. - - * card-p15.c (p15_decipher): Add flags argument to OpenSC call. - -2002-07-24 Werner Koch <wk@gnupg.org> - - * card.c (find_simple_tlv, find_iccsn): New. - (card_get_serial_and_stamp): Improved serial number parser. - -2002-06-27 Werner Koch <wk@gnupg.org> - - * scdaemon.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - -2002-06-15 Werner Koch <wk@gnupg.org> - - * card-dinsig.c: Documented some stuff from the DIN norm. - -2002-04-15 Werner Koch <wk@gnupg.org> - - * command.c (cmd_pksign, cmd_pkdecrypt): Use a copy of the key ID. - -2002-04-12 Werner Koch <wk@gnupg.org> - - * scdaemon.c: New option --debug-sc N. - * card.c (card_open): set it here. - - * card-p15.c (p15_prepare_key): Factored out common code from ... - (p15_sign, p15_decipher): here and made the decryption work the - regular way. - -2002-04-10 Werner Koch <wk@gnupg.org> - - * card.c (card_open): Return immediately when no reader is available. - -2002-03-27 Werner Koch <wk@gnupg.org> - - * card.c (card_open, card_close): Adjusted for changes in OpenSC. - -2002-03-10 Werner Koch <wk@gnupg.org> - - * card-p15.c, card-dinsig.c, card-common.h: New. - * card.c: Factored most code out to the new modules, so that we - can better support different types of card applications. - -2002-01-26 Werner Koch <wk@gnupg.org> - - * scdaemon.c scdaemon.h, command.c: New. Based on the code from - the gpg-agent. - - Copyright 2002 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/scd/Makefile.am b/scd/Makefile.am deleted file mode 100644 index c3c603d28..000000000 --- a/scd/Makefile.am +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -bin_PROGRAMS = scdaemon sc-investigate sc-copykeys -pkglib_PROGRAMS = pcsc-wrapper - -AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/common - -include $(top_srcdir)/am/cmacros.am - -AM_CFLAGS = $(OPENSC_CFLAGS) $(LIBGCRYPT_CFLAGS) \ - $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) - - -card_apps = app-openpgp.c app-nks.c app-dinsig.c - -scdaemon_SOURCES = \ - scdaemon.c scdaemon.h \ - command.c card.c \ - card-common.h \ - card-p15.c \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - app.c app-common.h app-help.c $(card_apps) - - -scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ - $(LIBUSB_LIBS) -lgpg-error @INTLLIBS@ -ldl - -sc_investigate_SOURCES = \ - sc-investigate.c scdaemon.h \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - atr.c atr.h \ - app.c app-common.h app-help.c $(card_apps) - -sc_investigate_LDADD = \ - ../jnlib/libjnlib.a ../common/libcommon.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBUSB_LIBS) \ - @INTLLIBS@ -lgpg-error -ldl - - -sc_copykeys_SOURCES = \ - sc-copykeys.c scdaemon.h \ - apdu.c apdu.h \ - ccid-driver.c ccid-driver.h \ - iso7816.c iso7816.h \ - tlv.c tlv.h \ - atr.c atr.h \ - app.c app-common.h app-help.c $(card_apps) - -sc_copykeys_LDADD = \ - ../jnlib/libjnlib.a ../common/libcommon.a \ - ../common/libsimple-pwquery.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(PTH_LIBS) \ - $(KSBA_LIBS) $(LIBUSB_LIBS) \ - -lgpg-error @INTLLIBS@ -ldl - -pcsc_wrapper_SOURCES = pcsc-wrapper.c -pcsc_wrapper_LDADD = -ldl -pcsc_wrapper_CFLAGS = \ No newline at end of file diff --git a/scd/apdu.c b/scd/apdu.c deleted file mode 100644 index 9742be760..000000000 --- a/scd/apdu.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* apdu.c - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#ifdef USE_GNU_PTH -# include <pth.h> -# include <unistd.h> -# include <fcntl.h> -#endif -#ifdef HAVE_OPENSC -# include <opensc/opensc.h> -#endif - -#if defined(GNUPG_SCD_MAIN_HEADER) -#include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cardglue.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "apdu.h" -#include "dynload.h" -#include "ccid-driver.h" - -#ifdef USE_GNU_PTH -#define NEED_PCSC_WRAPPER 1 -#endif - - -#define MAX_READER 4 /* Number of readers we support concurrently. */ -#define CARD_CONNECT_TIMEOUT 1 /* Number of seconds to wait for - insertion of the card (1 = don't wait). */ - - -#ifdef _WIN32 -#define DLSTDCALL __stdcall -#else -#define DLSTDCALL -#endif - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -/* A structure to collect information pertaining to one reader - slot. */ -struct reader_table_s { - int used; /* True if slot is used. */ - unsigned short port; /* Port number: 0 = unused, 1 - dev/tty */ - int is_ccid; /* Uses the internal CCID driver. */ - struct { - ccid_driver_t handle; - } ccid; - int is_ctapi; /* This is a ctAPI driver. */ - struct { - unsigned long context; - unsigned long card; - unsigned long protocol; -#ifdef NEED_PCSC_WRAPPER - int req_fd; - int rsp_fd; - pid_t pid; -#endif /*NEED_PCSC_WRAPPER*/ - } pcsc; -#ifdef HAVE_OPENSC - int is_osc; /* We are using the OpenSC driver layer. */ - struct { - struct sc_context *ctx; - struct sc_card *scard; - } osc; -#endif /*HAVE_OPENSC*/ - int status; - unsigned char atr[33]; - size_t atrlen; - unsigned int change_counter; -#ifdef USE_GNU_PTH - int lock_initialized; - pth_mutex_t lock; -#endif -}; -typedef struct reader_table_s *reader_table_t; - -/* A global table to keep track of active readers. */ -static struct reader_table_s reader_table[MAX_READER]; - - -/* ct API function pointer. */ -static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn); -static char (* DLSTDCALL CT_data) (unsigned short ctn, unsigned char *dad, - unsigned char *sad, unsigned short lc, - unsigned char *cmd, unsigned short *lr, - unsigned char *rsp); -static char (* DLSTDCALL CT_close) (unsigned short ctn); - -/* PC/SC constants and function pointer. */ -#define PCSC_SCOPE_USER 0 -#define PCSC_SCOPE_TERMINAL 1 -#define PCSC_SCOPE_SYSTEM 2 -#define PCSC_SCOPE_GLOBAL 3 - -#define PCSC_PROTOCOL_T0 1 -#define PCSC_PROTOCOL_T1 2 -#define PCSC_PROTOCOL_RAW 4 - -#define PCSC_SHARE_EXCLUSIVE 1 -#define PCSC_SHARE_SHARED 2 -#define PCSC_SHARE_DIRECT 3 - -#define PCSC_LEAVE_CARD 0 -#define PCSC_RESET_CARD 1 -#define PCSC_UNPOWER_CARD 2 -#define PCSC_EJECT_CARD 3 - -struct pcsc_io_request_s { - unsigned long protocol; - unsigned long pci_len; -}; - -typedef struct pcsc_io_request_s *pcsc_io_request_t; - -long (* DLSTDCALL pcsc_establish_context) (unsigned long scope, - const void *reserved1, - const void *reserved2, - unsigned long *r_context); -long (* DLSTDCALL pcsc_release_context) (unsigned long context); -long (* DLSTDCALL pcsc_list_readers) (unsigned long context, - const char *groups, - char *readers, unsigned long*readerslen); -long (* DLSTDCALL pcsc_connect) (unsigned long context, - const char *reader, - unsigned long share_mode, - unsigned long preferred_protocols, - unsigned long *r_card, - unsigned long *r_active_protocol); -long (* DLSTDCALL pcsc_disconnect) (unsigned long card, - unsigned long disposition); -long (* DLSTDCALL pcsc_status) (unsigned long card, - char *reader, unsigned long *readerlen, - unsigned long *r_state, - unsigned long *r_protocol, - unsigned char *atr, unsigned long *atrlen); -long (* DLSTDCALL pcsc_begin_transaction) (unsigned long card); -long (* DLSTDCALL pcsc_end_transaction) (unsigned long card); -long (* DLSTDCALL pcsc_transmit) (unsigned long card, - const pcsc_io_request_t send_pci, - const unsigned char *send_buffer, - unsigned long send_len, - pcsc_io_request_t recv_pci, - unsigned char *recv_buffer, - unsigned long *recv_len); -long (* DLSTDCALL pcsc_set_timeout) (unsigned long context, - unsigned long timeout); - - - - - -/* - Helper - */ - - -/* Find an unused reader slot for PORTSTR and put it into the reader - table. Return -1 on error or the index into the reader table. */ -static int -new_reader_slot (void) -{ - int i, reader = -1; - - for (i=0; i < MAX_READER; i++) - { - if (!reader_table[i].used && reader == -1) - reader = i; - } - if (reader == -1) - { - log_error ("new_reader_slot: out of slots\n"); - return -1; - } -#ifdef USE_GNU_PTH - if (!reader_table[reader].lock_initialized) - { - if (!pth_mutex_init (&reader_table[reader].lock)) - { - log_error ("error initializing mutex: %s\n", strerror (errno)); - return -1; - } - reader_table[reader].lock_initialized = 1; - } -#endif /*USE_GNU_PTH*/ - reader_table[reader].used = 1; - reader_table[reader].is_ccid = 0; - reader_table[reader].is_ctapi = 0; -#ifdef HAVE_OPENSC - reader_table[reader].is_osc = 0; -#endif -#ifdef NEED_PCSC_WRAPPER - reader_table[reader].pcsc.req_fd = -1; - reader_table[reader].pcsc.rsp_fd = -1; - reader_table[reader].pcsc.pid = (pid_t)(-1); -#endif - return reader; -} - - -static void -dump_reader_status (int reader) -{ - if (reader_table[reader].is_ccid) - log_info ("reader slot %d: using ccid driver\n", reader); - else if (reader_table[reader].is_ctapi) - { - log_info ("reader slot %d: %s\n", reader, - reader_table[reader].status == 1? "Processor ICC present" : - reader_table[reader].status == 0? "Memory ICC present" : - "ICC not present" ); - } - else - { - log_info ("reader slot %d: active protocol:", reader); - if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_T0)) - log_printf (" T0"); - else if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_T1)) - log_printf (" T1"); - else if ((reader_table[reader].pcsc.protocol & PCSC_PROTOCOL_RAW)) - log_printf (" raw"); - log_printf ("\n"); - } - - if (reader_table[reader].status != -1) - { - log_info ("reader %d: ATR=", reader); - log_printhex ("", reader_table[reader].atr, - reader_table[reader].atrlen); - } -} - - - -/* - ct API Interface - */ - -static const char * -ct_error_string (long err) -{ - switch (err) - { - case 0: return "okay"; - case -1: return "invalid data"; - case -8: return "ct error"; - case -10: return "transmission error"; - case -11: return "memory allocation error"; - case -128: return "HTSI error"; - default: return "unknown CT-API error"; - } -} - -/* Wait for the card in READER and activate it. Return -1 on error or - 0 on success. */ -static int -ct_activate_card (int reader) -{ - int rc, count; - - for (count = 0; count < CARD_CONNECT_TIMEOUT; count++) - { - unsigned char dad[1], sad[1], cmd[11], buf[256]; - unsigned short buflen; - - if (count) - ; /* FIXME: we should use a more reliable timer than sleep. */ - - /* Check whether card has been inserted. */ - dad[0] = 1; /* Destination address: CT. */ - sad[0] = 2; /* Source address: Host. */ - - cmd[0] = 0x20; /* Class byte. */ - cmd[1] = 0x13; /* Request status. */ - cmd[2] = 0x00; /* From kernel. */ - cmd[3] = 0x80; /* Return card's DO. */ - cmd[4] = 0x00; - - buflen = DIM(buf); - - rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf); - if (rc || buflen < 2 || buf[buflen-2] != 0x90) - { - log_error ("ct_activate_card: can't get status of reader %d: %s\n", - reader, ct_error_string (rc)); - return -1; - } - - /* Connected, now activate the card. */ - dad[0] = 1; /* Destination address: CT. */ - sad[0] = 2; /* Source address: Host. */ - - cmd[0] = 0x20; /* Class byte. */ - cmd[1] = 0x12; /* Request ICC. */ - cmd[2] = 0x01; /* From first interface. */ - cmd[3] = 0x01; /* Return card's ATR. */ - cmd[4] = 0x00; - - buflen = DIM(buf); - - rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf); - if (rc || buflen < 2 || buf[buflen-2] != 0x90) - { - log_error ("ct_activate_card(%d): activation failed: %s\n", - reader, ct_error_string (rc)); - if (!rc) - log_printhex (" received data:", buf, buflen); - return -1; - } - - /* Store the type and the ATR. */ - if (buflen - 2 > DIM (reader_table[0].atr)) - { - log_error ("ct_activate_card(%d): ATR too long\n", reader); - return -1; - } - - reader_table[reader].status = buf[buflen - 1]; - memcpy (reader_table[reader].atr, buf, buflen - 2); - reader_table[reader].atrlen = buflen - 2; - return 0; - } - - log_info ("ct_activate_card(%d): timeout waiting for card\n", reader); - return -1; -} - - -/* Open a reader and return an internal handle for it. PORT is a - non-negative value with the port number of the reader. USB readers - do have port numbers starting at 32769. */ -static int -open_ct_reader (int port) -{ - int rc, reader; - - if (port < 0 || port > 0xffff) - { - log_error ("open_ct_reader: invalid port %d requested\n", port); - return -1; - } - reader = new_reader_slot (); - if (reader == -1) - return reader; - reader_table[reader].port = port; - - rc = CT_init (reader, (unsigned short)port); - if (rc) - { - log_error ("apdu_open_ct_reader failed on port %d: %s\n", - port, ct_error_string (rc)); - reader_table[reader].used = 0; - return -1; - } - - rc = ct_activate_card (reader); - if (rc) - { - reader_table[reader].used = 0; - return -1; - } - - reader_table[reader].is_ctapi = 1; - dump_reader_status (reader); - return reader; -} - -static int -close_ct_reader (int slot) -{ - CT_close (slot); - reader_table[slot].used = 0; - return 0; -} - -static int -reset_ct_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -static int -ct_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual retruned size will be - set to BUFLEN. Returns: CT API error code. */ -static int -ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - int rc; - unsigned char dad[1], sad[1]; - unsigned short ctbuflen; - - dad[0] = 0; /* Destination address: Card. */ - sad[0] = 2; /* Source address: Host. */ - ctbuflen = *buflen; - if (DBG_CARD_IO) - log_printhex (" CT_data:", apdu, apdulen); - rc = CT_data (slot, dad, sad, apdulen, apdu, &ctbuflen, buffer); - *buflen = ctbuflen; - - /* FIXME: map the errorcodes to GNUPG ones, so that they can be - shared between CTAPI and PCSC. */ - return rc; -} - - - -#ifdef NEED_PCSC_WRAPPER -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - -/* log_printhex (" writen:", buf, nbytes); */ - - while (nleft > 0) - { -#ifdef USE_GNU_PTH - nwritten = pth_write (fd, buf, nleft); -#else - nwritten = write (fd, buf, nleft); -#endif - if (nwritten < 0 && errno == EINTR) - continue; - if (nwritten < 0) - return -1; - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - return 0; -} - -/* Read up to BUFLEN bytes from FD and return the number of bytes - actually read in NREAD. Returns -1 on error or 0 on success. */ -static int -readn (int fd, void *buf, size_t buflen, size_t *nread) -{ - size_t nleft = buflen; - int n; -/* void *orig_buf = buf; */ - - while (nleft > 0) - { -#ifdef USE_GNU_PTH - n = pth_read (fd, buf, nleft); -#else - n = read (fd, buf, nleft); -#endif - if (n < 0 && errno == EINTR) - continue; - if (n < 0) - return -1; /* read error. */ - if (!n) - break; /* EOF */ - nleft -= n; - buf = (char*)buf + n; - } - if (nread) - *nread = buflen - nleft; - -/* log_printhex (" readn:", orig_buf, *nread); */ - - return 0; -} -#endif /*NEED_PCSC_WRAPPER*/ - -static const char * -pcsc_error_string (long err) -{ - const char *s; - - if (!err) - return "okay"; - if ((err & 0x80100000) != 0x80100000) - return "invalid PC/SC error code"; - err &= 0xffff; - switch (err) - { - case 0x0002: s = "cancelled"; break; - case 0x000e: s = "can't dispose"; break; - case 0x0008: s = "insufficient buffer"; break; - case 0x0015: s = "invalid ATR"; break; - case 0x0003: s = "invalid handle"; break; - case 0x0004: s = "invalid parameter"; break; - case 0x0005: s = "invalid target"; break; - case 0x0011: s = "invalid value"; break; - case 0x0006: s = "no memory"; break; - case 0x0013: s = "comm error"; break; - case 0x0001: s = "internal error"; break; - case 0x0014: s = "unknown error"; break; - case 0x0007: s = "waited too long"; break; - case 0x0009: s = "unknown reader"; break; - case 0x000a: s = "timeout"; break; - case 0x000b: s = "sharing violation"; break; - case 0x000c: s = "no smartcard"; break; - case 0x000d: s = "unknown card"; break; - case 0x000f: s = "proto mismatch"; break; - case 0x0010: s = "not ready"; break; - case 0x0012: s = "system cancelled"; break; - case 0x0016: s = "not transacted"; break; - case 0x0017: s = "reader unavailable"; break; - case 0x0065: s = "unsupported card"; break; - case 0x0066: s = "unresponsive card"; break; - case 0x0067: s = "unpowered card"; break; - case 0x0068: s = "reset card"; break; - case 0x0069: s = "removed card"; break; - case 0x006a: s = "inserted card"; break; - case 0x001f: s = "unsupported feature"; break; - case 0x0019: s = "PCI too small"; break; - case 0x001a: s = "reader unsupported"; break; - case 0x001b: s = "duplicate reader"; break; - case 0x001c: s = "card unsupported"; break; - case 0x001d: s = "no service"; break; - case 0x001e: s = "service stopped"; break; - default: s = "unknown PC/SC error code"; break; - } - return s; -} - -/* - PC/SC Interface - */ - -static int -open_pcsc_reader (const char *portstr) -{ -#ifdef NEED_PCSC_WRAPPER -/* Open the PC/SC reader using the pcsc_wrapper program. This is - needed to cope with different thread models and other peculiarities - of libpcsclite. */ - int slot; - reader_table_t slotp; - int fd, rp[2], wp[2]; - int n, i; - pid_t pid; - size_t len; - unsigned char msgbuf[9]; - int err; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - /* Fire up the pcsc wrapper. We don't use any fork/exec code from - the common directy but implement it direclty so that this file - may still be source copied. */ - - if (pipe (rp) == -1) - { - log_error ("error creating a pipe: %s\n", strerror (errno)); - slotp->used = 0; - return -1; - } - if (pipe (wp) == -1) - { - log_error ("error creating a pipe: %s\n", strerror (errno)); - close (rp[0]); - close (rp[1]); - slotp->used = 0; - return -1; - } - - pid = fork (); - if (pid == -1) - { - log_error ("error forking process: %s\n", strerror (errno)); - close (rp[0]); - close (rp[1]); - close (wp[0]); - close (wp[1]); - slotp->used = 0; - return -1; - } - slotp->pcsc.pid = pid; - - if (!pid) - { /* - === Child === - */ - - /* Double fork. */ - pid = fork (); - if (pid == -1) - _exit (31); - if (pid) - _exit (0); /* Immediate exit this parent, so that the child - gets cleaned up by the init process. */ - - /* Connect our pipes. */ - if (wp[0] != 0 && dup2 (wp[0], 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - if (rp[1] != 1 && dup2 (rp[1], 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Send stderr to the bit bucket. */ - fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - log_fatal ("can't open `/dev/null': %s", strerror (errno)); - if (fd != 2 && dup2 (fd, 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - execl (GNUPG_LIBDIR "/pcsc-wrapper", - "pcsc-wrapper", - "--", - "1", /* API version */ - opt.pcsc_driver, /* Name of the PC/SC library. */ - NULL); - _exit (31); - } - - /* - === Parent === - */ - close (wp[0]); - close (rp[1]); - slotp->pcsc.req_fd = wp[1]; - slotp->pcsc.rsp_fd = rp[0]; - - /* Wait for the intermediate child to terminate. */ - while ( (i=pth_waitpid (pid, NULL, 0)) == -1 && errno == EINTR) - ; - - /* Now send the open request. */ - msgbuf[0] = 0x01; /* OPEN command. */ - len = portstr? strlen (portstr):0; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) - || (portstr && writen (slotp->pcsc.req_fd, portstr, len))) - { - log_error ("error sending PC/SC OPEN request: %s\n", - strerror (errno)); - goto command_failed; - } - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC OPEN response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - if (len > DIM (slotp->atr)) - { - log_error ("PC/SC returned a too large ATR (len=%x)\n", len); - goto command_failed; - } - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - { - log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); - goto command_failed; - } - n = len; - if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n) - { - log_error ("error receiving PC/SC OPEN response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - slotp->atrlen = len; - - dump_reader_status (slot); - return slot; - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return -1; -#else /*!NEED_PCSC_WRAPPER */ - long err; - int slot; - char *list = NULL; - unsigned long nreader, listlen, atrlen; - char *p; - unsigned long card_state, card_protocol; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - - err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, - &reader_table[slot].pcsc.context); - if (err) - { - log_error ("pcsc_establish_context failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - reader_table[slot].used = 0; - return -1; - } - - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, NULL, &nreader); - if (!err) - { - list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */ - if (!list) - { - log_error ("error allocating memory for reader list\n"); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1; - } - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, list, &nreader); - } - if (err) - { - log_error ("pcsc_list_readers failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - xfree (list); - return -1; - } - - listlen = nreader; - p = list; - while (nreader) - { - if (!*p && !p[1]) - break; - log_info ("detected reader `%s'\n", p); - if (nreader < (strlen (p)+1)) - { - log_error ("invalid response from pcsc_list_readers\n"); - break; - } - nreader -= strlen (p)+1; - p += strlen (p) + 1; - } - - err = pcsc_connect (reader_table[slot].pcsc.context, - portstr? portstr : list, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &reader_table[slot].pcsc.card, - &reader_table[slot].pcsc.protocol); - if (err) - { - log_error ("pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - xfree (list); - return -1; - } - - atrlen = 32; - /* (We need to pass a dummy buffer. We use LIST because it ought to - be large enough.) */ - err = pcsc_status (reader_table[slot].pcsc.card, - list, &listlen, - &card_state, &card_protocol, - reader_table[slot].atr, &atrlen); - xfree (list); - if (err) - { - log_error ("pcsc_status failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1; - } - if (atrlen >= DIM (reader_table[0].atr)) - log_bug ("ATR returned by pcsc_status is too large\n"); - reader_table[slot].atrlen = atrlen; -/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */ -/* log_debug ("protocol from pcsc_status: 0x%lx\n", card_protocol); */ - - dump_reader_status (slot); - return slot; -#endif /*!NEED_PCSC_WRAPPER */ -} - - -static int -pcsc_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: CT API error code. */ -static int -pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ -#ifdef NEED_PCSC_WRAPPER - long err; - reader_table_t slotp; - size_t len, full_len; - int i, n; - unsigned char msgbuf[9]; - - if (DBG_CARD_IO) - log_printhex (" PCSC_data:", apdu, apdulen); - - slotp = reader_table + slot; - - if (slotp->pcsc.req_fd == -1 - || slotp->pcsc.rsp_fd == -1 - || slotp->pcsc.pid == (pid_t)(-1) ) - { - log_error ("pcsc_send_apdu: pcsc-wrapper not running\n"); - return -1; - } - - msgbuf[0] = 0x03; /* TRANSMIT command. */ - len = apdulen; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) - || writen (slotp->pcsc.req_fd, apdu, len)) - { - log_error ("error sending PC/SC TRANSMIT request: %s\n", - strerror (errno)); - goto command_failed; - } - - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - { - log_error ("pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - return -1; - } - - full_len = len; - - n = *buflen < len ? *buflen : len; - if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - *buflen = n; - - full_len -= len; - if (full_len) - { - log_error ("pcsc_send_apdu: provided buffer too short - truncated\n"); - err = -1; - } - /* We need to read any rest of the response, to keep the - protocol runnng. */ - while (full_len) - { - unsigned char dummybuf[128]; - - n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf); - if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n) - { - log_error ("error receiving PC/SC TRANSMIT response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - full_len -= n; - } - - return err; - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return -1; - -#else /*!NEED_PCSC_WRAPPER*/ - - long err; - struct pcsc_io_request_s send_pci; - unsigned long recv_len; - - if (DBG_CARD_IO) - log_printhex (" PCSC_data:", apdu, apdulen); - - if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) - send_pci.protocol = PCSC_PROTOCOL_T1; - else - send_pci.protocol = PCSC_PROTOCOL_T0; - send_pci.pci_len = sizeof send_pci; - recv_len = *buflen; - err = pcsc_transmit (reader_table[slot].pcsc.card, - &send_pci, apdu, apdulen, - NULL, buffer, &recv_len); - *buflen = recv_len; - if (err) - log_error ("pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - - return err? -1:0; /* FIXME: Return appropriate error code. */ -#endif /*!NEED_PCSC_WRAPPER*/ -} - - -static int -close_pcsc_reader (int slot) -{ -#ifdef NEED_PCSC_WRAPPER - long err; - reader_table_t slotp; - size_t len; - int i; - unsigned char msgbuf[9]; - - slotp = reader_table + slot; - - if (slotp->pcsc.req_fd == -1 - || slotp->pcsc.rsp_fd == -1 - || slotp->pcsc.pid == (pid_t)(-1) ) - { - log_error ("close_pcsc_reader: pcsc-wrapper not running\n"); - return 0; - } - - msgbuf[0] = 0x02; /* CLOSE command. */ - len = 0; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) ) - { - log_error ("error sending PC/SC CLOSE request: %s\n", - strerror (errno)); - goto command_failed; - } - - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC CLOSE response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; - if (err) - log_error ("pcsc_close failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - - /* We will the wrapper in any case - errors are merely - informational. */ - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return 0; - -#else /*!NEED_PCSC_WRAPPER*/ - - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return 0; -#endif /*!NEED_PCSC_WRAPPER*/ -} - -static int -reset_pcsc_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - - - - -#ifdef HAVE_LIBUSB -/* - Internal CCID driver interface. - */ - -static const char * -get_ccid_error_string (long err) -{ - if (!err) - return "okay"; - else - return "unknown CCID error"; -} - -static int -open_ccid_reader (void) -{ - int err; - int slot; - reader_table_t slotp; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - err = ccid_open_reader (&slotp->ccid.handle, 0); - if (err) - { - slotp->used = 0; - return -1; - } - - err = ccid_get_atr (slotp->ccid.handle, - slotp->atr, sizeof slotp->atr, &slotp->atrlen); - if (err) - { - slotp->used = 0; - return -1; - } - - slotp->is_ccid = 1; - - dump_reader_status (slot); - return slot; -} - -static int -close_ccid_reader (int slot) -{ - ccid_close_reader (reader_table[slot].ccid.handle); - reader_table[slot].used = 0; - return 0; -} - - -static int -reset_ccid_reader (int slot) -{ - int err; - reader_table_t slotp = reader_table + slot; - unsigned char atr[33]; - size_t atrlen; - - err = ccid_get_atr (slotp->ccid.handle, atr, sizeof atr, &atrlen); - if (err) - return -1; - /* If the reset was successful, update the ATR. */ - assert (sizeof slotp->atr >= sizeof atr); - slotp->atrlen = atrlen; - memcpy (slotp->atr, atr, atrlen); - dump_reader_status (slot); - return 0; -} - - -static int -get_status_ccid (int slot, unsigned int *status) -{ - int rc; - int bits; - - rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits); - if (rc) - return -1; - - if (bits == 0) - *status = 1|2|4; - else if (bits == 1) - *status = 2; - else - *status = 0; - - return 0; -} - - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: Internal CCID driver error code. */ -static int -send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - long err; - size_t maxbuflen; - - if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); - - maxbuflen = *buflen; - err = ccid_transceive (reader_table[slot].ccid.handle, - apdu, apdulen, - buffer, maxbuflen, buflen); - if (err) - log_error ("ccid_transceive failed: (0x%lx)\n", - err); - - return err? -1:0; /* FIXME: Return appropriate error code. */ -} - -#endif /* HAVE_LIBUSB */ - - - -#ifdef HAVE_OPENSC -/* - OpenSC Interface. - - This uses the OpenSC primitives to send APDUs. We need this - because we can't mix OpenSC and native (i.e. ctAPI or PC/SC) - access to a card for resource conflict reasons. - */ - -static int -open_osc_reader (int portno) -{ - int err; - int slot; - reader_table_t slotp; - - slot = new_reader_slot (); - if (slot == -1) - return -1; - slotp = reader_table + slot; - - err = sc_establish_context (&slotp->osc.ctx, "scdaemon"); - if (err) - { - log_error ("failed to establish SC context: %s\n", sc_strerror (err)); - slotp->used = 0; - return -1; - } - if (portno < 0 || portno >= slotp->osc.ctx->reader_count) - { - log_error ("no card reader available\n"); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* Redirect to our logging facility. */ - slotp->osc.ctx->error_file = log_get_stream (); - slotp->osc.ctx->debug = opt.debug_sc; - slotp->osc.ctx->debug_file = log_get_stream (); - - if (sc_detect_card_presence (slotp->osc.ctx->reader[portno], 0) != 1) - { - log_error ("no card present\n"); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* We want the standard ISO driver. */ - /*FIXME: OpenSC does not like "iso7816", so we use EMV for now. */ - err = sc_set_card_driver(slotp->osc.ctx, "emv"); - if (err) - { - log_error ("failed to select the iso7816 driver: %s\n", - sc_strerror (err)); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - /* Now connect the card and hope that OpenSC won't try to be too - smart. */ - err = sc_connect_card (slotp->osc.ctx->reader[portno], 0, - &slotp->osc.scard); - if (err) - { - log_error ("failed to connect card in reader %d: %s\n", - portno, sc_strerror (err)); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - if (opt.verbose) - log_info ("connected to card in opensc reader %d using driver `%s'\n", - portno, slotp->osc.scard->driver->name); - - err = sc_lock (slotp->osc.scard); - if (err) - { - log_error ("can't lock card in reader %d: %s\n", - portno, sc_strerror (err)); - sc_disconnect_card (slotp->osc.scard, 0); - sc_release_context (slotp->osc.ctx); - slotp->used = 0; - return -1; - } - - if (slotp->osc.scard->atr_len >= DIM (slotp->atr)) - log_bug ("ATR returned by opensc is too large\n"); - slotp->atrlen = slotp->osc.scard->atr_len; - memcpy (slotp->atr, slotp->osc.scard->atr, slotp->atrlen); - - slotp->is_osc = 1; - - dump_reader_status (slot); - return slot; -} - - -static int -close_osc_reader (int slot) -{ - /* FIXME: Implement. */ - reader_table[slot].used = 0; - return 0; -} - -static int -reset_osc_reader (int slot) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -static int -osc_get_status (int slot, unsigned int *status) -{ - return SW_HOST_NOT_SUPPORTED; -} - - -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: OpenSC error code. */ -static int -osc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - long err; - struct sc_apdu a; - unsigned char data[SC_MAX_APDU_BUFFER_SIZE]; - unsigned char result[SC_MAX_APDU_BUFFER_SIZE]; - - if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); - - if (apdulen < 4) - { - log_error ("osc_send_apdu: APDU is too short\n"); - return SC_ERROR_CMD_TOO_SHORT; - } - - memset(&a, 0, sizeof a); - a.cla = *apdu++; - a.ins = *apdu++; - a.p1 = *apdu++; - a.p2 = *apdu++; - apdulen -= 4; - - if (!apdulen) - a.cse = SC_APDU_CASE_1; - else if (apdulen == 1) - { - a.le = *apdu? *apdu : 256; - apdu++; apdulen--; - a.cse = SC_APDU_CASE_2_SHORT; - } - else - { - a.lc = *apdu++; apdulen--; - if (apdulen < a.lc) - { - log_error ("osc_send_apdu: APDU shorter than specified in Lc\n"); - return SC_ERROR_CMD_TOO_SHORT; - - } - memcpy(data, apdu, a.lc); - apdu += a.lc; apdulen -= a.lc; - - a.data = data; - a.datalen = a.lc; - - if (!apdulen) - a.cse = SC_APDU_CASE_3_SHORT; - else - { - a.le = *apdu? *apdu : 256; - apdu++; apdulen--; - if (apdulen) - { - log_error ("osc_send_apdu: APDU larger than specified\n"); - return SC_ERROR_CMD_TOO_LONG; - } - a.cse = SC_APDU_CASE_4_SHORT; - } - } - - a.resp = result; - a.resplen = DIM(result); - - err = sc_transmit_apdu (reader_table[slot].osc.scard, &a); - if (err) - { - log_error ("sc_apdu_transmit failed: %s\n", sc_strerror (err)); - return err; - } - - if (*buflen < 2 || a.resplen > *buflen - 2) - { - log_error ("osc_send_apdu: provided buffer too short to store result\n"); - return SC_ERROR_BUFFER_TOO_SMALL; - } - memcpy (buffer, a.resp, a.resplen); - buffer[a.resplen] = a.sw1; - buffer[a.resplen+1] = a.sw2; - *buflen = a.resplen + 2; - return 0; -} - -#endif /* HAVE_OPENSC */ - - - -/* - Driver Access - */ - - -static int -lock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, 0, NULL)) - { - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_GNU_PTH*/ - return 0; -} - -static int -trylock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, TRUE, NULL)) - { - if (errno == EBUSY) - return SW_HOST_BUSY; - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); - return SW_HOST_LOCKING_FAILED; - } -#endif /*USE_GNU_PTH*/ - return 0; -} - -static void -unlock_slot (int slot) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_release (&reader_table[slot].lock)) - log_error ("failed to release apdu lock: %s\n", strerror (errno)); -#endif /*USE_GNU_PTH*/ -} - - -/* Open the reader and return an internal slot number or -1 on - error. If PORTSTR is NULL we default to a suitable port (for ctAPI: - the first USB reader. For PC/SC the first listed reader). If - OpenSC support is compiled in, we first try to use OpenSC. */ -int -apdu_open_reader (const char *portstr) -{ - static int pcsc_api_loaded, ct_api_loaded; - -#ifdef HAVE_LIBUSB - if (!opt.disable_ccid) - { - int slot; - - slot = open_ccid_reader (); - if (slot != -1) - return slot; /* got one */ - } -#endif /* HAVE_LIBUSB */ - -#ifdef HAVE_OPENSC - if (!opt.disable_opensc) - { - int port = portstr? atoi (portstr) : 0; - - return open_osc_reader (port); - } -#endif /* HAVE_OPENSC */ - - - if (opt.ctapi_driver && *opt.ctapi_driver) - { - int port = portstr? atoi (portstr) : 32768; - - if (!ct_api_loaded) - { - void *handle; - - handle = dlopen (opt.ctapi_driver, RTLD_LAZY); - if (!handle) - { - log_error ("apdu_open_reader: failed to open driver: %s\n", - dlerror ()); - return -1; - } - CT_init = dlsym (handle, "CT_init"); - CT_data = dlsym (handle, "CT_data"); - CT_close = dlsym (handle, "CT_close"); - if (!CT_init || !CT_data || !CT_close) - { - log_error ("apdu_open_reader: invalid CT-API driver\n"); - dlclose (handle); - return -1; - } - ct_api_loaded = 1; - } - return open_ct_reader (port); - } - - - /* No ctAPI configured, so lets try the PC/SC API */ - if (!pcsc_api_loaded) - { -#ifndef NEED_PCSC_WRAPPER - void *handle; - - handle = dlopen (opt.pcsc_driver, RTLD_LAZY); - if (!handle) - { - log_error ("apdu_open_reader: failed to open driver `%s': %s\n", - opt.pcsc_driver, dlerror ()); - return -1; - } - - pcsc_establish_context = dlsym (handle, "SCardEstablishContext"); - pcsc_release_context = dlsym (handle, "SCardReleaseContext"); - pcsc_list_readers = dlsym (handle, "SCardListReaders"); -#ifdef _WIN32 - if (!pcsc_list_readers) - pcsc_list_readers = dlsym (handle, "SCardListReadersA"); -#endif - pcsc_connect = dlsym (handle, "SCardConnect"); -#ifdef _WIN32 - if (!pcsc_connect) - pcsc_connect = dlsym (handle, "SCardConnectA"); -#endif - pcsc_disconnect = dlsym (handle, "SCardDisconnect"); - pcsc_status = dlsym (handle, "SCardStatus"); -#ifdef _WIN32 - if (!pcsc_status) - pcsc_status = dlsym (handle, "SCardStatusA"); -#endif - pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction"); - pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); - pcsc_transmit = dlsym (handle, "SCardTransmit"); - pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); - - if (!pcsc_establish_context - || !pcsc_release_context - || !pcsc_list_readers - || !pcsc_connect - || !pcsc_disconnect - || !pcsc_status - || !pcsc_begin_transaction - || !pcsc_end_transaction - || !pcsc_transmit - /* || !pcsc_set_timeout */) - { - /* Note that set_timeout is currently not used and also not - available under Windows. */ - log_error ("apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d)\n", - !!pcsc_establish_context, - !!pcsc_release_context, - !!pcsc_list_readers, - !!pcsc_connect, - !!pcsc_disconnect, - !!pcsc_status, - !!pcsc_begin_transaction, - !!pcsc_end_transaction, - !!pcsc_transmit, - !!pcsc_set_timeout ); - dlclose (handle); - return -1; - } -#endif /*!NEED_PCSC_WRAPPER*/ - pcsc_api_loaded = 1; - } - - return open_pcsc_reader (portstr); -} - - -int -apdu_close_reader (int slot) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - if (reader_table[slot].is_ctapi) - return close_ct_reader (slot); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return close_ccid_reader (slot); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return close_osc_reader (slot); -#endif - else - return close_pcsc_reader (slot); -} - -/* Enumerate all readers and return information on whether this reader - is in use. The caller should start with SLOT set to 0 and - increment it with each call until an error is returned. */ -int -apdu_enum_reader (int slot, int *used) -{ - if (slot < 0 || slot >= MAX_READER) - return SW_HOST_NO_DRIVER; - *used = reader_table[slot].used; - return 0; -} - -/* Do a reset for the card in reader at SLOT. */ -int -apdu_reset (int slot) -{ - int sw; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if ((sw = lock_slot (slot))) - return sw; - - if (reader_table[slot].is_ctapi) - sw = reset_ct_reader (slot); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - sw = reset_ccid_reader (slot); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - sw = reset_osc_reader (slot); -#endif - else - sw = reset_pcsc_reader (slot); - - unlock_slot (slot); - return sw; -} - - -unsigned char * -apdu_get_atr (int slot, size_t *atrlen) -{ - char *buf; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return NULL; - - buf = xtrymalloc (reader_table[slot].atrlen); - if (!buf) - return NULL; - memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen); - *atrlen = reader_table[slot].atrlen; - return buf; -} - - - -static const char * -error_string (int slot, long rc) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return "[invalid slot]"; - if (reader_table[slot].is_ctapi) - return ct_error_string (rc); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return get_ccid_error_string (rc); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return sc_strerror (rc); -#endif - else - return pcsc_error_string (rc); -} - - -/* Retrieve the status for SLOT. The function does obnly wait fot the - card to become available if HANG is set to true. On success the - bits in STATUS will be set to - - bit 0 = card present and usable - bit 1 = card present - bit 2 = card active - bit 3 = card access locked [not yet implemented] - - For must application, tetsing bit 0 is sufficient. - - CHANGED will receive the value of the counter tracking the number - of card insertions. This value may be used to detect a card - change. -*/ -int -apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed) -{ - int sw; - unsigned int s; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if ((sw = hang? lock_slot (slot) : trylock_slot (slot))) - return sw; - - if (reader_table[slot].is_ctapi) - sw = ct_get_status (slot, &s); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - sw = get_status_ccid (slot, &s); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - sw = osc_get_status (slot, &s); -#endif - else - sw = pcsc_get_status (slot, &s); - - unlock_slot (slot); - - if (sw) - return sw; - - if (status) - *status = s; - if (changed) - *changed = reader_table[slot].change_counter; - return 0; -} - - -/* Dispatcher for the actual send_apdu function. Note, that this - function should be called in locked state. */ -static int -send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) -{ - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - if (reader_table[slot].is_ctapi) - return ct_send_apdu (slot, apdu, apdulen, buffer, buflen); -#ifdef HAVE_LIBUSB - else if (reader_table[slot].is_ccid) - return send_apdu_ccid (slot, apdu, apdulen, buffer, buflen); -#endif -#ifdef HAVE_OPENSC - else if (reader_table[slot].is_osc) - return osc_send_apdu (slot, apdu, apdulen, buffer, buflen); -#endif - else - return pcsc_send_apdu (slot, apdu, apdulen, buffer, buflen); -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1 - for LC won't sent this field and the data field; in this case DATA - must also be passed as NULL. The return value is the status word - or -1 for an invalid SLOT or other non card related error. If - RETBUF is not NULL, it will receive an allocated buffer with the - returned data. The length of that data will be put into - *RETBUFLEN. The caller is reponsible for releasing the buffer even - in case of errors. */ -int -apdu_send_le(int slot, int class, int ins, int p0, int p1, - int lc, const char *data, int le, - unsigned char **retbuf, size_t *retbuflen) -{ -#define RESULTLEN 256 - unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in - the driver. */ - size_t resultlen; - unsigned char apdu[5+256+1]; - size_t apdulen; - int sw; - long rc; /* we need a long here due to PC/SC. */ - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if (DBG_CARD_IO) - log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d\n", - class, ins, p0, p1, lc, le); - - if (lc != -1 && (lc > 255 || lc < 0)) - return SW_WRONG_LENGTH; - if (le != -1 && (le > 256 || le < 1)) - return SW_WRONG_LENGTH; - if ((!data && lc != -1) || (data && lc == -1)) - return SW_HOST_INV_VALUE; - - if ((sw = lock_slot (slot))) - return sw; - - apdulen = 0; - apdu[apdulen++] = class; - apdu[apdulen++] = ins; - apdu[apdulen++] = p0; - apdu[apdulen++] = p1; - if (lc != -1) - { - apdu[apdulen++] = lc; - memcpy (apdu+apdulen, data, lc); - apdulen += lc; - } - if (le != -1) - apdu[apdulen++] = le; /* Truncation is okay becuase 0 means 256. */ - assert (sizeof (apdu) >= apdulen); - /* As safeguard don't pass any garbage from the stack to the driver. */ - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); - if (rc || resultlen < 2) - { - log_error ("apdu_send_simple(%d) failed: %s\n", - slot, error_string (slot, rc)); - unlock_slot (slot); - return SW_HOST_INCOMPLETE_CARD_RESPONSE; - } - sw = (result[resultlen-2] << 8) | result[resultlen-1]; - /* store away the returned data but strip the statusword. */ - resultlen -= 2; - if (DBG_CARD_IO) - { - log_debug (" response: sw=%04X datalen=%d\n", sw, resultlen); - if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA)) - log_printhex (" dump: ", result, resultlen); - } - - if (sw == SW_SUCCESS || sw == SW_EOF_REACHED) - { - if (retbuf) - { - *retbuf = xtrymalloc (resultlen? resultlen : 1); - if (!*retbuf) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - *retbuflen = resultlen; - memcpy (*retbuf, result, resultlen); - } - } - else if ((sw & 0xff00) == SW_MORE_DATA) - { - unsigned char *p = NULL, *tmp; - size_t bufsize = 4096; - - /* It is likely that we need to return much more data, so we - start off with a large buffer. */ - if (retbuf) - { - *retbuf = p = xtrymalloc (bufsize); - if (!*retbuf) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - assert (resultlen < bufsize); - memcpy (p, result, resultlen); - p += resultlen; - } - - do - { - int len = (sw & 0x00ff); - - if (DBG_CARD_IO) - log_debug ("apdu_send_simple(%d): %d more bytes available\n", - slot, len); - apdulen = 0; - apdu[apdulen++] = class; - apdu[apdulen++] = 0xC0; - apdu[apdulen++] = 0; - apdu[apdulen++] = 0; - apdu[apdulen++] = len; - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); - if (rc || resultlen < 2) - { - log_error ("apdu_send_simple(%d) for get response failed: %s\n", - slot, error_string (slot, rc)); - unlock_slot (slot); - return SW_HOST_INCOMPLETE_CARD_RESPONSE; - } - sw = (result[resultlen-2] << 8) | result[resultlen-1]; - resultlen -= 2; - if (DBG_CARD_IO) - { - log_debug (" more: sw=%04X datalen=%d\n", sw, resultlen); - if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA)) - log_printhex (" dump: ", result, resultlen); - } - - if ((sw & 0xff00) == SW_MORE_DATA - || sw == SW_SUCCESS - || sw == SW_EOF_REACHED ) - { - if (retbuf && resultlen) - { - if (p - *retbuf + resultlen > bufsize) - { - bufsize += resultlen > 4096? resultlen: 4096; - tmp = xtryrealloc (*retbuf, bufsize); - if (!tmp) - { - unlock_slot (slot); - return SW_HOST_OUT_OF_CORE; - } - p = tmp + (p - *retbuf); - *retbuf = tmp; - } - memcpy (p, result, resultlen); - p += resultlen; - } - } - else - log_info ("apdu_send_simple(%d) " - "got unexpected status %04X from get response\n", - slot, sw); - } - while ((sw & 0xff00) == SW_MORE_DATA); - - if (retbuf) - { - *retbuflen = p - *retbuf; - tmp = xtryrealloc (*retbuf, *retbuflen); - if (tmp) - *retbuf = tmp; - } - } - - unlock_slot (slot); - - if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS) - log_printhex (" dump: ", *retbuf, *retbuflen); - - return sw; -#undef RESULTLEN -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for - LC won't sent this field and the data field; in this case DATA must - also be passed as NULL. The return value is the status word or -1 - for an invalid SLOT or other non card related error. If RETBUF is - not NULL, it will receive an allocated buffer with the returned - data. The length of that data will be put into *RETBUFLEN. The - caller is reponsible for releasing the buffer even in case of - errors. */ -int -apdu_send (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, unsigned char **retbuf, size_t *retbuflen) -{ - return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256, - retbuf, retbuflen); -} - -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for - LC won't sent this field and the data field; in this case DATA must - also be passed as NULL. The return value is the status word or -1 - for an invalid SLOT or other non card related error. No data will be - returned. */ -int -apdu_send_simple (int slot, int class, int ins, int p0, int p1, - int lc, const char *data) -{ - return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL); -} - - - - diff --git a/scd/apdu.h b/scd/apdu.h deleted file mode 100644 index f74bab7fe..000000000 --- a/scd/apdu.h +++ /dev/null @@ -1,85 +0,0 @@ -/* apdu.h - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef APDU_H -#define APDU_H - -/* ISO 7816 values for the statusword are defined here because they - should not be visible to the users of the actual ISO command - API. */ -enum { - SW_MORE_DATA = 0x6100, /* Note: that the low byte must be - masked of.*/ - SW_EOF_REACHED = 0x6282, - SW_EEPROM_FAILURE = 0x6581, - SW_WRONG_LENGTH = 0x6700, - SW_CHV_WRONG = 0x6982, - SW_CHV_BLOCKED = 0x6983, - SW_USE_CONDITIONS = 0x6985, - SW_BAD_PARAMETER = 0x6a80, /* (in the data field) */ - SW_NOT_SUPPORTED = 0x6a81, - SW_FILE_NOT_FOUND = 0x6a82, - SW_RECORD_NOT_FOUND = 0x6a83, - SW_REF_NOT_FOUND = 0x6a88, - SW_BAD_P0_P1 = 0x6b00, - SW_INS_NOT_SUP = 0x6d00, - SW_CLA_NOT_SUP = 0x6e00, - SW_SUCCESS = 0x9000, - - /* The follwoing statuswords are no real ones but used to map host - OS errors into status words. A status word is 16 bit so that - those values can't be issued by a card. */ - SW_HOST_OUT_OF_CORE = 0x10001, /* No way yet to differentiate - between errnos on a failed malloc. */ - SW_HOST_INV_VALUE = 0x10002, - SW_HOST_INCOMPLETE_CARD_RESPONSE = 0x10003, - SW_HOST_NO_DRIVER = 0x10004, - SW_HOST_NOT_SUPPORTED = 0x10005, - SW_HOST_LOCKING_FAILED= 0x10006, - SW_HOST_BUSY = 0x10007 -}; - - - -/* Note , that apdu_open_reader returns no status word but -1 on error. */ -int apdu_open_reader (const char *portstr); -int apdu_close_reader (int slot); -int apdu_enum_reader (int slot, int *used); -unsigned char *apdu_get_atr (int slot, size_t *atrlen); - - -/* The apdu send functions do return status words. */ -int apdu_reset (int slot); -int apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed); -int apdu_send_simple (int slot, int class, int ins, int p0, int p1, - int lc, const char *data); -int apdu_send (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, - unsigned char **retbuf, size_t *retbuflen); -int apdu_send_le (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, int le, - unsigned char **retbuf, size_t *retbuflen); - - -#endif /*APDU_H*/ - - - diff --git a/scd/app-common.h b/scd/app-common.h deleted file mode 100644 index c61bcca60..000000000 --- a/scd/app-common.h +++ /dev/null @@ -1,170 +0,0 @@ -/* app-common.h - Common declarations for all card applications - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_SCD_APP_COMMON_H -#define GNUPG_SCD_APP_COMMON_H - -#if GNUPG_MAJOR_VERSION != 1 -#include <ksba.h> -#endif - -struct app_local_s; /* Defined by all app-*.c. */ - -struct app_ctx_s { - int initialized; /* The application has been initialied and the - function pointers may be used. Note that for - unsupported operations the particular - function pointer is set to NULL */ - int slot; /* Used reader. */ - unsigned char *serialno; /* Serialnumber in raw form, allocated. */ - size_t serialnolen; /* Length in octets of serialnumber. */ - const char *apptype; - unsigned int card_version; - int did_chv1; - int force_chv1; /* True if the card does not cache CHV1. */ - int did_chv2; - int did_chv3; - struct app_local_s *app_local; /* Local to the application. */ - struct { - void (*deinit) (app_t app); - int (*learn_status) (app_t app, ctrl_t ctrl); - int (*readcert) (app_t app, const char *certid, - unsigned char **cert, size_t *certlen); - int (*getattr) (app_t app, ctrl_t ctrl, const char *name); - int (*setattr) (app_t app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen); - int (*sign) (app_t app, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); - int (*auth) (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - int (*decipher) (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - int (*genkey) (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - int (*change_pin) (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - int (*check_pin) (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg); - } fnc; - -}; - -#if GNUPG_MAJOR_VERSION == 1 -int app_select_openpgp (app_t app); -int app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); -#else -/*-- app-help.c --*/ -gpg_error_t app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip); -size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); - - -/*-- app.c --*/ -app_t select_application (ctrl_t ctrl, int slot, const char *name); -void release_application (app_t app); -int app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); -int app_write_learn_status (app_t app, ctrl_t ctrl); -int app_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen); -int app_getattr (app_t app, ctrl_t ctrl, const char *name); -int app_setattr (app_t app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen); -int app_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int app_auth (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); -int app_decipher (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int app_genkey (app_t app, ctrl_t ctrl, - const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer); -int app_change_pin (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_check_pin (app_t app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); - - -/*-- app-openpgp.c --*/ -int app_select_openpgp (app_t app); - -int app_openpgp_cardinfo (app_t app, - char **serialno, - char **disp_name, - char **pubkey_url, - unsigned char **fpr1, - unsigned char **fpr2, - unsigned char **fpr3); -int app_openpgp_storekey (app_t app, int keyno, - unsigned char *template, size_t template_len, - time_t created_at, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - int (*pincb)(void*, const char *, char **), - void *pincb_arg); -int app_openpgp_readkey (app_t app, int keyno, - unsigned char **m, size_t *mlen, - unsigned char **e, size_t *elen); -/*-- app-nks.c --*/ -int app_select_nks (app_t app); - -/*-- app-dinsig.c --*/ -int app_select_dinsig (app_t app); - - -#endif - - - -#endif /*GNUPG_SCD_APP_COMMON_H*/ - - - diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c deleted file mode 100644 index 38fbc79ee..000000000 --- a/scd/app-dinsig.c +++ /dev/null @@ -1,427 +0,0 @@ -/* app-dinsig.c - The DINSIG (DIN V 66291-1) card application. - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* The German signature law and its bylaw (SigG and SigV) is currently - used with an interface specification described in DIN V 66291-1. - The AID to be used is: 'D27600006601'. - - The file IDs for certificates utilize the generic format: - Cxyz - C being the hex digit 'C' (12). - x being the service indicator: - '0' := SigG conform digital signature. - '1' := entity authentication. - '2' := key encipherment. - '3' := data encipherment. - '4' := key agreement. - other values are reserved for future use. - y being the security environment number using '0' for cards - not supporting a SE number. - z being the certificate type: - '0' := C.CH (base certificate of card holder) or C.ICC. - '1' .. '7' := C.CH (business or professional certificate - of card holder. - '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA). - 'E' := C.RCA (self certified certificate of the Root-CA). - 'F' := reserved. - - The file IDs used by default are: - '1F00' EF.SSD (security service descriptor). [o,o] - '2F02' EF.GDO (global data objects) [m,m] - 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte. - Read and update after user authentication. [o,o] - 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size - of keys. [m (unless a 'C00E' is present),m] - 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size - of keys. [o,o] - 'C00n' EF.C.CH.DS (digital signature certificate of card holder) - with n := 0 .. 7. Size is 2k or size of cert. Read and - update allowed after user authentication. [m,m] - 'C00m' EF.C.CA.DS (digital signature certificate of CA) - with m := 8 .. E. Size is 1k or size of cert. Read always - allowed, update after user authentication. [o,o] - 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m] - 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m] - 'D000' EF.DM (display message) [-,m] - - The letters in brackets indicate optional or mandatory files: The - first for card terminals under full control and the second for - "business" card terminals. -*/ - - - - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "scdaemon.h" - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - - -static int -do_learn_status (app_t app, ctrl_t ctrl) -{ - gpg_error_t err; - char ct_buf[100], id_buf[100]; - char hexkeygrip[41]; - size_t len, certoff; - unsigned char *der; - size_t derlen; - ksba_cert_t cert; - int fid; - - /* Return the certificate of the card holder. */ - fid = 0xC000; - len = app_help_read_length_of_cert (app->slot, fid, &certoff); - if (!len) - return 0; /* Card has not been personalized. */ - - sprintf (ct_buf, "%d", 101); - sprintf (id_buf, "DINSIG.%04X", fid); - send_status_info (ctrl, "CERTINFO", - ct_buf, strlen (ct_buf), - id_buf, strlen (id_buf), - NULL, (size_t)0); - - /* Now we need to read the certificate, so that we can get the - public key out of it. */ - err = iso7816_read_binary (app->slot, certoff, len-certoff, &der, &derlen); - if (err) - { - log_info ("error reading entire certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return 0; - } - - err = ksba_cert_new (&cert); - if (err) - { - xfree (der); - return err; - } - err = ksba_cert_init_from_mem (cert, der, derlen); - xfree (der); der = NULL; - if (err) - { - log_error ("failed to parse the certificate at FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - ksba_cert_release (cert); - return err; - } - err = app_help_get_keygrip_string (cert, hexkeygrip); - if (err) - { - log_error ("failed to calculate the keygrip for FID 0x%04X\n", fid); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - sprintf (id_buf, "DINSIG.%04X", fid); - send_status_info (ctrl, "KEYPAIRINFO", - hexkeygrip, 40, - id_buf, strlen (id_buf), - NULL, (size_t)0); - return 0; -} - - - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. - - FIXME: This needs some cleanups and caching with do_learn_status. -*/ -static int -do_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - int fid; - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t totobjlen, objlen, hdrlen; - int rootca = 0; - - *cert = NULL; - *certlen = 0; - if (strncmp (certid, "DINSIG.", 7) ) - return gpg_error (GPG_ERR_INV_ID); - certid += 7; - if (!hexdigitp (certid) || !hexdigitp (certid+1) - || !hexdigitp (certid+2) || !hexdigitp (certid+3) - || certid[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (certid); - if (fid != 0xC000 ) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* Read the entire file. fixme: This could be optimized by first - reading the header to figure out how long the certificate - actually is. */ - err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); - if (err) - { - log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return err; - } - - err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); - if (err) - { - log_error ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return err; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - err = gpg_error (GPG_ERR_NOT_FOUND); - goto leave; - } - - /* Now figure something out about the object. */ - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed ) - ; - else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed ) - rootca = 1; - else - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (totobjlen <= buflen); - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - - if (rootca) - ; - else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - const unsigned char *save_p; - - /* The certificate seems to be contained in a userCertificate - container. Skip this and assume the following sequence is - the certificate. */ - if (n < objlen) - { - err = gpg_error (GPG_ERR_INV_OBJ); - goto leave; - } - p += objlen; - n -= objlen; - save_p = p; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) ) - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (save_p + totobjlen <= buffer + buflen); - memmove (buffer, save_p, totobjlen); - } - - *cert = buffer; - buffer = NULL; - *certlen = totobjlen; - - leave: - xfree (buffer); - return err; -} - - -/* Verify the PIN if required. */ -static int -verify_pin (app_t app, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - if (!app->did_chv1 || app->force_chv1 ) - { - char *pinvalue; - int rc; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - /* We require the PIN to be at least 6 and at max 8 bytes. - According to the specs, this should all be ASCII but we don't - check this. */ - if (strlen (pinvalue) < 6) - { - log_error ("PIN is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - else if (strlen (pinvalue) > 8) - { - log_error ("PIN is too large; maximum length is 8\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; - xfree (pinvalue); - } - - return 0; -} - - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; - that callback should return the PIN in an allocated buffer and - store that in the 3rd argument. */ -static int -do_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc; - int fid; - unsigned char data[35]; /* Must be large enough for a SHA-1 digest - + the largest OID _prefix above. */ - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20 && indatalen != 16 && indatalen != 35) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. This is not really needed - but we do it to to enforce correct usage by the caller. */ - if (strncmp (keyidstr, "DINSIG.", 7) ) - return gpg_error (GPG_ERR_INV_ID); - keyidstr += 7; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - if (fid != 0xC000) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* Prepare the DER object from INDATA. */ - if (indatalen == 35) - { - /* Alright, the caller was so kind to send us an already - prepared DER object. Check that it is what we want and that - it matches the hash algorithm. */ - if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15)) - ; - else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15)) - ; - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data, indata, indatalen); - } - else - { - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - } - - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - - - -/* Select the DINSIG application on the card in SLOT. This function - must be used before any other DINSIG application functions. */ -int -app_select_dinsig (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 }; - int slot = app->slot; - int rc; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "DINSIG"; - - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; - app->fnc.setattr = NULL; - app->fnc.genkey = NULL; - app->fnc.sign = do_sign; - app->fnc.auth = NULL; - app->fnc.decipher = NULL; - app->fnc.change_pin = NULL; - app->fnc.check_pin = NULL; - - app->force_chv1 = 1; - } - - return rc; -} diff --git a/scd/app-help.c b/scd/app-help.c deleted file mode 100644 index 1c3c52b15..000000000 --- a/scd/app-help.c +++ /dev/null @@ -1,162 +0,0 @@ -/* app-help.c - Application helper functions - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "scdaemon.h" -#include "app-common.h" -#include "iso7816.h" -#include "tlv.h" - -/* Return the KEYGRIP for the certificate CERT as an hex encoded - string in the user provided buffer HEXKEYGRIP which must be of at - least 41 bytes. */ -gpg_error_t -app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip) -{ - gpg_error_t err; - gcry_sexp_t s_pkey; - ksba_sexp_t p; - size_t n; - unsigned char array[20]; - int i; - - p = ksba_cert_get_public_key (cert); - if (!p) - return gpg_error (GPG_ERR_BUG); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); - err = gcry_sexp_sscan (&s_pkey, NULL, p, n); - xfree (p); - if (err) - return err; /* Can't parse that S-expression. */ - if (!gcry_pk_get_keygrip (s_pkey, array)) - { - gcry_sexp_release (s_pkey); - return gpg_error (GPG_ERR_GENERAL); /* Failed to calculate the keygrip.*/ - } - gcry_sexp_release (s_pkey); - - for (i=0; i < 20; i++) - sprintf (hexkeygrip+i*2, "%02X", array[i]); - - return 0; -} - - - -/* Given the SLOT and the File ID FID, return the length of the - certificate contained in that file. Returns 0 if the file does not - exists or does not contain a certificate. If R_CERTOFF is not - NULL, the length the header will be stored at this address; thus to - parse the X.509 certificate a read should start at that offset. - - On success the file is still selected. -*/ -size_t -app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff) -{ - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t resultlen, objlen, hdrlen; - - err = iso7816_select_file (slot, fid, 0, NULL, NULL); - if (err) - { - log_info ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return 0; - } - - err = iso7816_read_binary (slot, 0, 32, &buffer, &buflen); - if (err) - { - log_info ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return 0; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - xfree (buffer); - return 0; - } - - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - { - log_info ("error parsing certificate in FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - xfree (buffer); - return 0; - } - - /* All certificates should commence with a SEQUENCE except for the - special ROOT CA which are enclosed in a SET. */ - if ( !(class == CLASS_UNIVERSAL && constructed - && (tag == TAG_SEQUENCE || tag == TAG_SET))) - { - log_info ("contents of FID 0x%04X does not look like a certificate\n", - fid); - return 0; - } - - resultlen = objlen + hdrlen; - if (r_certoff) - { - /* The callers want the offset to the actual certificate. */ - *r_certoff = hdrlen; - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - return 0; - - if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - /* The certificate seems to be contained in a - userCertificate container. Assume the following sequence - is the certificate. */ - *r_certoff += hdrlen + objlen; - if (*r_certoff > resultlen) - { - *r_certoff = 0; - return 0; /* That should never happen. */ - } - } - else - *r_certoff = 0; - } - - return resultlen; -} - - diff --git a/scd/app-nks.c b/scd/app-nks.c deleted file mode 100644 index e69b59879..000000000 --- a/scd/app-nks.c +++ /dev/null @@ -1,515 +0,0 @@ -/* app-nks.c - The Telesec NKS 2.0 card application. - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "scdaemon.h" - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - -static struct { - int fid; /* File ID. */ - int certtype; /* Type of certificate or 0 if it is not a certificate. */ - int iskeypair; /* If true has the FID of the correspoding certificate. */ - int issignkey; /* True if file is a key usable for signing. */ - int isenckey; /* True if file is a key usable for decryption. */ -} filelist[] = { - { 0x4531, 0, 0xC000, 1, 0 }, - { 0xC000, 101 }, - { 0x4331, 100 }, - { 0x4332, 100 }, - { 0xB000, 110 }, - { 0x45B1, 0, 0xC200, 0, 1 }, - { 0xC200, 101 }, - { 0x43B1, 100 }, - { 0x43B2, 100 }, - { 0, 0 } -}; - - - -/* Read the file with FID, assume it contains a public key and return - its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */ -static gpg_error_t -keygripstr_from_pk_file (int slot, int fid, char *r_gripstr) -{ - gpg_error_t err; - unsigned char grip[20]; - unsigned char *buffer[2]; - size_t buflen[2]; - gcry_sexp_t sexp; - int i; - - err = iso7816_select_file (slot, fid, 0, NULL, NULL); - if (err) - return err; - err = iso7816_read_record (slot, 1, 1, 0, &buffer[0], &buflen[0]); - if (err) - return err; - err = iso7816_read_record (slot, 2, 1, 0, &buffer[1], &buflen[1]); - if (err) - { - xfree (buffer[0]); - return err; - } - - for (i=0; i < 2; i++) - { - /* Check that the value appears like an integer encoded as - Simple-TLV. We don't check the tag because the tests cards I - have use 1 for both, the modulus and the exponent - the - example in the documentation gives 2 for the exponent. */ - if (buflen[i] < 3) - err = gpg_error (GPG_ERR_TOO_SHORT); - else if (buffer[i][1] != buflen[i]-2 ) - err = gpg_error (GPG_ERR_INV_OBJ); - } - - if (!err) - err = gcry_sexp_build (&sexp, NULL, - "(public-key (rsa (n %b) (e %b)))", - (int)buflen[0]-2, buffer[0]+2, - (int)buflen[1]-2, buffer[1]+2); - - xfree (buffer[0]); - xfree (buffer[1]); - if (err) - return err; - - if (!gcry_pk_get_keygrip (sexp, grip)) - { - err = gpg_error (GPG_ERR_INTERNAL); /* i.e. RSA not supported by - libgcrypt. */ - } - else - { - for (i=0; i < 20; i++) - sprintf (r_gripstr+i*2, "%02X", grip[i]); - } - gcry_sexp_release (sexp); - return err; -} - - - -static int -do_learn_status (APP app, CTRL ctrl) -{ - gpg_error_t err; - char ct_buf[100], id_buf[100]; - int i; - - /* Output information about all useful objects. */ - for (i=0; filelist[i].fid; i++) - { - if (filelist[i].certtype) - { - size_t len; - - len = app_help_read_length_of_cert (app->slot, - filelist[i].fid, NULL); - if (len) - { - /* FIXME: We should store the length in the application's - context so that a following readcert does only need to - read that many bytes. */ - sprintf (ct_buf, "%d", filelist[i].certtype); - sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid); - send_status_info (ctrl, "CERTINFO", - ct_buf, strlen (ct_buf), - id_buf, strlen (id_buf), - NULL, (size_t)0); - } - } - else if (filelist[i].iskeypair) - { - char gripstr[40+1]; - - err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr); - if (err) - log_error ("can't get keygrip from FID 0x%04X: %s\n", - filelist[i].fid, gpg_strerror (err)); - else - { - sprintf (id_buf, "NKS-DF01.%04X", filelist[i].fid); - send_status_info (ctrl, "KEYPAIRINFO", - gripstr, 40, - id_buf, strlen (id_buf), - NULL, (size_t)0); - } - } - } - - return 0; -} - - - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. */ -static int -do_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - int i, fid; - gpg_error_t err; - unsigned char *buffer; - const unsigned char *p; - size_t buflen, n; - int class, tag, constructed, ndef; - size_t totobjlen, objlen, hdrlen; - int rootca = 0; - - *cert = NULL; - *certlen = 0; - if (strncmp (certid, "NKS-DF01.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - certid += 9; - if (!hexdigitp (certid) || !hexdigitp (certid+1) - || !hexdigitp (certid+2) || !hexdigitp (certid+3) - || certid[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (certid); - for (i=0; filelist[i].fid; i++) - if ((filelist[i].certtype || filelist[i].iskeypair) - && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - - /* If the requested objects is a plain public key, redirect it to - the corresponding certificate. The whole system is a bit messy - becuase we sometime use the key directly or let the caller - retrieve the key from the certificate. The valid point behind - that is to support not-yet stored certificates. */ - if (filelist[i].iskeypair) - fid = filelist[i].iskeypair; - - - /* Read the entire file. fixme: This could be optimized by first - reading the header to figure out how long the certificate - actually is. */ - err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); - if (err) - { - log_error ("error selecting FID 0x%04X: %s\n", fid, gpg_strerror (err)); - return err; - } - - err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); - if (err) - { - log_error ("error reading certificate from FID 0x%04X: %s\n", - fid, gpg_strerror (err)); - return err; - } - - if (!buflen || *buffer == 0xff) - { - log_info ("no certificate contained in FID 0x%04X\n", fid); - err = gpg_error (GPG_ERR_NOT_FOUND); - goto leave; - } - - /* Now figure something out about the object. */ - p = buffer; - n = buflen; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed ) - ; - else if ( class == CLASS_UNIVERSAL && tag == TAG_SET && constructed ) - rootca = 1; - else - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (totobjlen <= buflen); - - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - - if (rootca) - ; - else if (class == CLASS_UNIVERSAL && tag == TAG_OBJECT_ID && !constructed) - { - const unsigned char *save_p; - - /* The certificate seems to be contained in a userCertificate - container. Skip this and assume the following sequence is - the certificate. */ - if (n < objlen) - { - err = gpg_error (GPG_ERR_INV_OBJ); - goto leave; - } - p += objlen; - n -= objlen; - save_p = p; - err = parse_ber_header (&p, &n, &class, &tag, &constructed, - &ndef, &objlen, &hdrlen); - if (err) - goto leave; - if ( !(class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE && constructed) ) - return gpg_error (GPG_ERR_INV_OBJ); - totobjlen = objlen + hdrlen; - assert (save_p + totobjlen <= buffer + buflen); - memmove (buffer, save_p, totobjlen); - } - - *cert = buffer; - buffer = NULL; - *certlen = totobjlen; - - leave: - xfree (buffer); - return err; -} - - -/* Verify the PIN if required. */ -static int -verify_pin (app_t app, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - /* Note that force_chv1 is never set but we do it here anyway so - that other applications may euse this function. For example it - makes sense to set force_chv1 for German signature law cards. - NKS is very similar to the DINSIG draft standard. */ - if (!app->did_chv1 || app->force_chv1 ) - { - char *pinvalue; - int rc; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - /* The follwoing limits are due to TCOS but also defined in the - NKS specs. */ - if (strlen (pinvalue) < 6) - { - log_error ("PIN is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - else if (strlen (pinvalue) > 16) - { - log_error ("PIN is too large; maximum length is 16\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - /* Also it is possible to use a local PIN, we use the gloabl - PIN for this application. */ - rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify PIN failed\n"); - xfree (pinvalue); - return rc; - } - app->did_chv1 = 1; - xfree (pinvalue); - } - - return 0; -} - - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; - that callback should return the PIN in an allocated buffer and - store that in the 3rd argument. */ -static int -do_sign (app_t app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc, i; - int fid; - unsigned char data[35]; /* Must be large enough for a SHA-1 digest - + the largest OID _prefix above. */ - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20 && indatalen != 16 && indatalen != 35) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. This is not really needed - but we do it to to enforce correct usage by the caller. */ - if (strncmp (keyidstr, "NKS-DF01.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - keyidstr += 9; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - for (i=0; filelist[i].fid; i++) - if (filelist[i].iskeypair && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - if (!filelist[i].issignkey) - return gpg_error (GPG_ERR_INV_ID); - - /* Prepare the DER object from INDATA. */ - if (indatalen == 35) - { - /* Alright, the caller was so kind to send us an already - prepared DER object. Check that it is waht we want and that - it matches the hash algorithm. */ - if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha1_prefix, 15)) - ; - else if (hashalgo == GCRY_MD_RMD160 && !memcmp (indata, rmd160_prefix,15)) - ; - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data, indata, indatalen); - } - else - { - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - } - - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - - - - -/* Decrypt the data in INDATA and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -static int -do_decipher (app_t app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static const unsigned char mse_parm[] = { - 0x80, 1, 0x10, /* Select algorithm RSA. */ - 0x84, 1, 0x81 /* Select locak secret key 1 for descryption. */ - }; - int rc, i; - int fid; - - if (!keyidstr || !*keyidstr || !indatalen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check that the provided ID is vaid. This is not really needed - but we do it to to enforce correct usage by the caller. */ - if (strncmp (keyidstr, "NKS-DF01.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - keyidstr += 9; - if (!hexdigitp (keyidstr) || !hexdigitp (keyidstr+1) - || !hexdigitp (keyidstr+2) || !hexdigitp (keyidstr+3) - || keyidstr[4]) - return gpg_error (GPG_ERR_INV_ID); - fid = xtoi_4 (keyidstr); - for (i=0; filelist[i].fid; i++) - if (filelist[i].iskeypair && filelist[i].fid == fid) - break; - if (!filelist[i].fid) - return gpg_error (GPG_ERR_NOT_FOUND); - if (!filelist[i].isenckey) - return gpg_error (GPG_ERR_INV_ID); - - /* Do the TCOS specific MSE. */ - rc = iso7816_manage_security_env (app->slot, - 0xC1, 0xB8, - mse_parm, sizeof mse_parm); - if (!rc) - rc = verify_pin (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_decipher (app->slot, indata, indatalen, 0x81, - outdata, outdatalen); - return rc; -} - - - -/* Select the NKS 2.0 application on the card in SLOT. */ -int -app_select_nks (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 }; - int slot = app->slot; - int rc; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "NKS"; - - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; - app->fnc.setattr = NULL; - app->fnc.genkey = NULL; - app->fnc.sign = do_sign; - app->fnc.auth = NULL; - app->fnc.decipher = do_decipher; - app->fnc.change_pin = NULL; - app->fnc.check_pin = NULL; - } - - return rc; -} - - diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c deleted file mode 100644 index f40951941..000000000 --- a/scd/app-openpgp.c +++ /dev/null @@ -1,1640 +0,0 @@ -/* app-openpgp.c - The OpenPGP card application. - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#if GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#include "cardglue.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "iso7816.h" -#include "app-common.h" -#include "tlv.h" - - -static struct { - int tag; - int constructed; - int get_from; /* Constructed DO with this DO or 0 for direct access. */ - int binary; - int dont_cache; - int flush_on_error; - char *desc; -} data_objects[] = { - { 0x005E, 0, 0, 1, 0, 0, "Login Data" }, - { 0x5F50, 0, 0, 0, 0, 0, "URL" }, - { 0x0065, 1, 0, 1, 0, 0, "Cardholder Related Data"}, - { 0x005B, 0, 0x65, 0, 0, 0, "Name" }, - { 0x5F2D, 0, 0x65, 0, 0, 0, "Language preferences" }, - { 0x5F35, 0, 0x65, 0, 0, 0, "Sex" }, - { 0x006E, 1, 0, 1, 0, 0, "Application Related Data" }, - { 0x004F, 0, 0x6E, 1, 0, 0, "AID" }, - { 0x0073, 1, 0, 1, 0, 0, "Discretionary Data Objects" }, - { 0x0047, 0, 0x6E, 1, 0, 0, "Card Capabilities" }, - { 0x00C0, 0, 0x6E, 1, 0, 0, "Extended Card Capabilities" }, - { 0x00C1, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Signature" }, - { 0x00C2, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Decryption" }, - { 0x00C3, 0, 0x6E, 1, 0, 0, "Algorithm Attributes Authentication" }, - { 0x00C4, 0, 0x6E, 1, 0, 1, "CHV Status Bytes" }, - { 0x00C5, 0, 0x6E, 1, 0, 0, "Fingerprints" }, - { 0x00C6, 0, 0x6E, 1, 0, 0, "CA Fingerprints" }, - { 0x007A, 1, 0, 1, 0, 0, "Security Support Template" }, - { 0x0093, 0, 0x7A, 1, 1, 0, "Digital Signature Counter" }, - { 0 } -}; - - -struct cache_s { - struct cache_s *next; - int tag; - size_t length; - unsigned char data[1]; -}; - -struct app_local_s { - struct cache_s *cache; -}; - - -static unsigned long convert_sig_counter_value (const unsigned char *value, - size_t valuelen); -static unsigned long get_sig_counter (APP app); - -/* Deconstructor. */ -static void -do_deinit (app_t app) -{ - if (app && app->app_local) - { - struct cache_s *c, *c2; - - for (c = app->app_local->cache; c; c = c2) - { - c2 = c->next; - xfree (c); - } - xfree (app->app_local); - app->app_local = NULL; - } -} - - -/* Wrapper around iso7816_get_data which first tries to get the data - from the cache. */ -static gpg_error_t -get_cached_data (app_t app, int tag, - unsigned char **result, size_t *resultlen) -{ - gpg_error_t err; - int i; - unsigned char *p; - size_t len; - struct cache_s *c; - - - *result = NULL; - *resultlen = 0; - - if (app->app_local) - { - for (c=app->app_local->cache; c; c = c->next) - if (c->tag == tag) - { - p = xtrymalloc (c->length); - if (!p) - return gpg_error (gpg_err_code_from_errno (errno)); - memcpy (p, c->data, c->length); - *resultlen = c->length; - *result = p; - return 0; - } - } - - err = iso7816_get_data (app->slot, tag, &p, &len); - if (err) - return err; - *result = p; - *resultlen = len; - - /* Check whether we should cache this object. */ - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].tag == tag) - { - if (data_objects[i].dont_cache) - return 0; - break; - } - - /* No, cache it. */ - if (!app->app_local) - app->app_local = xtrycalloc (1, sizeof *app->app_local); - - /* Note that we can safely ignore out of core errors. */ - if (app->app_local) - { - for (c=app->app_local->cache; c; c = c->next) - assert (c->tag != tag); - - c = xtrymalloc (sizeof *c + len); - if (c) - { - memcpy (c->data, p, len); - c->length = len; - c->tag = tag; - c->next = app->app_local->cache; - app->app_local->cache = c; - } - } - - return 0; -} - -/* Remove DO at TAG from the cache. */ -static void -flush_cache_item (app_t app, int tag) -{ - struct cache_s *c, *cprev; - int i; - - if (!app->app_local) - return; - - for (c=app->app_local->cache, cprev=NULL; c ; cprev=c, c = c->next) - if (c->tag == tag) - { - if (cprev) - cprev->next = c->next; - else - app->app_local->cache = c->next; - xfree (c); - - for (c=app->app_local->cache; c ; c = c->next) - assert (c->tag != tag); /* Oops: duplicated entry. */ - return; - } - - /* Try again if we have an outer tag. */ - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].tag == tag && data_objects[i].get_from - && data_objects[i].get_from != tag) - flush_cache_item (app, data_objects[i].get_from); -} - -/* Flush all entries from the cache which might be out of sync after - an error. */ -static void -flush_cache_after_error (app_t app) -{ - int i; - - for (i=0; data_objects[i].tag; i++) - if (data_objects[i].flush_on_error) - flush_cache_item (app, data_objects[i].tag); -} - - -/* Flush the entire cache. */ -static void -flush_cache (app_t app) -{ - if (app && app->app_local) - { - struct cache_s *c, *c2; - - for (c = app->app_local->cache; c; c = c2) - { - c2 = c->next; - xfree (c); - } - app->app_local->cache = NULL; - } -} - - -/* Get the DO identified by TAG from the card in SLOT and return a - buffer with its content in RESULT and NBYTES. The return value is - NULL if not found or a pointer which must be used to release the - buffer holding value. */ -static void * -get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes) -{ - int rc, i; - unsigned char *buffer; - size_t buflen; - unsigned char *value; - size_t valuelen; - - *result = NULL; - *nbytes = 0; - for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++) - ; - - value = NULL; - rc = -1; - if (data_objects[i].tag && data_objects[i].get_from) - { - rc = get_cached_data (app, data_objects[i].get_from, - &buffer, &buflen); - if (!rc) - { - const unsigned char *s; - - s = find_tlv (buffer, buflen, tag, &valuelen); - if (!s) - value = NULL; /* not found */ - else if (valuelen > buflen - (s - buffer)) - { - log_error ("warning: constructed DO too short\n"); - value = NULL; - xfree (buffer); buffer = NULL; - } - else - value = buffer + (s - buffer); - } - } - - if (!value) /* Not in a constructed DO, try simple. */ - { - rc = get_cached_data (app, tag, &buffer, &buflen); - if (!rc) - { - value = buffer; - valuelen = buflen; - } - } - - if (!rc) - { - *nbytes = valuelen; - *result = value; - return buffer; - } - return NULL; -} - - -static void -dump_all_do (int slot) -{ - int rc, i, j; - unsigned char *buffer; - size_t buflen; - - for (i=0; data_objects[i].tag; i++) - { - if (data_objects[i].get_from) - continue; - - rc = iso7816_get_data (slot, data_objects[i].tag, &buffer, &buflen); - if (gpg_err_code (rc) == GPG_ERR_NO_OBJ) - ; - else if (rc) - log_info ("DO `%s' not available: %s\n", - data_objects[i].desc, gpg_strerror (rc)); - else - { - if (data_objects[i].binary) - { - log_info ("DO `%s': ", data_objects[i].desc); - log_printhex ("", buffer, buflen); - } - else - log_info ("DO `%s': `%.*s'\n", - data_objects[i].desc, - (int)buflen, buffer); /* FIXME: sanitize */ - - if (data_objects[i].constructed) - { - for (j=0; data_objects[j].tag; j++) - { - const unsigned char *value; - size_t valuelen; - - if (j==i || data_objects[i].tag != data_objects[j].get_from) - continue; - value = find_tlv (buffer, buflen, - data_objects[j].tag, &valuelen); - if (!value) - ; /* not found */ - else if (valuelen > buflen - (value - buffer)) - log_error ("warning: constructed DO too short\n"); - else - { - if (data_objects[j].binary) - { - log_info ("DO `%s': ", data_objects[j].desc); - log_printhex ("", value, valuelen); - } - else - log_info ("DO `%s': `%.*s'\n", - data_objects[j].desc, - (int)valuelen, value); /* FIXME: sanitize */ - } - } - } - } - xfree (buffer); buffer = NULL; - } -} - - -/* Count the number of bits, assuming the A represents an unsigned big - integer of length LEN bytes. */ -static unsigned int -count_bits (const unsigned char *a, size_t len) -{ - unsigned int n = len * 8; - int i; - - for (; len && !*a; len--, a++, n -=8) - ; - if (len) - { - for (i=7; i && !(*a & (1<<i)); i--) - n--; - } - return n; -} - -/* Note, that FPR must be at least 20 bytes. */ -static int -store_fpr (int slot, int keynumber, u32 timestamp, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - unsigned char *fpr, unsigned int card_version) -{ - unsigned int n, nbits; - unsigned char *buffer, *p; - int rc; - - for (; mlen && !*m; mlen--, m++) /* strip leading zeroes */ - ; - for (; elen && !*e; elen--, e++) /* strip leading zeroes */ - ; - - n = 6 + 2 + mlen + 2 + elen; - p = buffer = xtrymalloc (3 + n); - if (!buffer) - return gpg_error (gpg_err_code_from_errno (errno)); - - *p++ = 0x99; /* ctb */ - *p++ = n >> 8; /* 2 byte length header */ - *p++ = n; - *p++ = 4; /* key packet version */ - *p++ = timestamp >> 24; - *p++ = timestamp >> 16; - *p++ = timestamp >> 8; - *p++ = timestamp; - *p++ = 1; /* RSA */ - nbits = count_bits (m, mlen); - *p++ = nbits >> 8; - *p++ = nbits; - memcpy (p, m, mlen); p += mlen; - nbits = count_bits (e, elen); - *p++ = nbits >> 8; - *p++ = nbits; - memcpy (p, e, elen); p += elen; - - log_printhex ("fprbuf:", buffer, n+3); - gcry_md_hash_buffer (GCRY_MD_SHA1, fpr, buffer, n+3); - - xfree (buffer); - - rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6) - + keynumber, fpr, 20); - if (rc) - log_error ("failed to store the fingerprint: %s\n",gpg_strerror (rc)); - - return rc; -} - - -static void -send_fpr_if_not_null (CTRL ctrl, const char *keyword, - int number, const unsigned char *fpr) -{ - int i; - char buf[41]; - char numbuf[25]; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - if (i==20) - return; /* All zero. */ - for (i=0; i< 20; i++) - sprintf (buf+2*i, "%02X", fpr[i]); - if (number == -1) - *numbuf = 0; /* Don't print the key number */ - else - sprintf (numbuf, "%d", number); - send_status_info (ctrl, keyword, - numbuf, (size_t)strlen(numbuf), - buf, (size_t)strlen (buf), NULL, 0); -} - -static void -send_key_data (CTRL ctrl, const char *name, - const unsigned char *a, size_t alen) -{ - char *p, *buf = xmalloc (alen*2+1); - - for (p=buf; alen; a++, alen--, p += 2) - sprintf (p, "%02X", *a); - - send_status_info (ctrl, "KEY-DATA", - name, (size_t)strlen(name), - buf, (size_t)strlen (buf), - NULL, 0); - xfree (buf); -} - -/* Implement the GETATTR command. This is similar to the LEARN - command but returns just one value via the status interface. */ -static int -do_getattr (APP app, CTRL ctrl, const char *name) -{ - static struct { - const char *name; - int tag; - int special; - } table[] = { - { "DISP-NAME", 0x005B }, - { "LOGIN-DATA", 0x005E }, - { "DISP-LANG", 0x5F2D }, - { "DISP-SEX", 0x5F35 }, - { "PUBKEY-URL", 0x5F50 }, - { "KEY-FPR", 0x00C5, 3 }, - { "CA-FPR", 0x00C6, 3 }, - { "CHV-STATUS", 0x00C4, 1 }, - { "SIG-COUNTER", 0x0093, 2 }, - { "SERIALNO", 0x004F, -1 }, - { "AID", 0x004F }, - { NULL, 0 } - }; - int idx, i; - void *relptr; - unsigned char *value; - size_t valuelen; - - for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) - ; - if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); - - if (table[idx].special == -1) - { - /* The serial number is very special. We could have used the - AID DO to retrieve it, but we have it already in the app - context and the stamp argument is required anyway which we - can't by other means. The AID DO is available anyway but not - hex formatted. */ - char *serial; - time_t stamp; - char tmp[50]; - - if (!app_get_serial_and_stamp (app, &serial, &stamp)) - { - sprintf (tmp, "%lu", (unsigned long)stamp); - send_status_info (ctrl, "SERIALNO", - serial, strlen (serial), - tmp, strlen (tmp), - NULL, 0); - xfree (serial); - } - return 0; - } - - relptr = get_one_do (app, table[idx].tag, &value, &valuelen); - if (relptr) - { - if (table[idx].special == 1) - { - char numbuf[7*23]; - - for (i=0,*numbuf=0; i < valuelen && i < 7; i++) - sprintf (numbuf+strlen (numbuf), " %d", value[i]); - send_status_info (ctrl, table[idx].name, - numbuf, strlen (numbuf), NULL, 0); - } - else if (table[idx].special == 2) - { - char numbuf[50]; - - sprintf (numbuf, "%lu", convert_sig_counter_value (value, valuelen)); - send_status_info (ctrl, table[idx].name, - numbuf, strlen (numbuf), NULL, 0); - } - else if (table[idx].special == 3) - { - if (valuelen >= 60) - for (i=0; i < 3; i++) - send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20); - } - else - send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0); - - xfree (relptr); - } - return 0; -} - - -static int -do_learn_status (APP app, CTRL ctrl) -{ - do_getattr (app, ctrl, "DISP-NAME"); - do_getattr (app, ctrl, "DISP-LANG"); - do_getattr (app, ctrl, "DISP-SEX"); - do_getattr (app, ctrl, "PUBKEY-URL"); - do_getattr (app, ctrl, "LOGIN-DATA"); - do_getattr (app, ctrl, "KEY-FPR"); - do_getattr (app, ctrl, "CA-FPR"); - do_getattr (app, ctrl, "CHV-STATUS"); - do_getattr (app, ctrl, "SIG-COUNTER"); - - return 0; -} - - -/* Verify CHV2 if required. Depending on the configuration of the - card CHV1 will also be verified. */ -static int -verify_chv2 (app_t app, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - - if (!app->did_chv2) - { - char *pinvalue; - - rc = pincb (pincb_arg, "PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV2) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify CHV2 failed: %s\n", gpg_strerror (rc)); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv2 = 1; - - if (!app->did_chv1 && !app->force_chv1) - { - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) - rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); - if (rc) - { - log_error ("verify CHV1 failed: %s\n", gpg_strerror (rc)); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv1 = 1; - } - xfree (pinvalue); - } - return rc; -} - -/* Verify CHV3 if required. */ -static int -verify_chv3 (APP app, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - - if (!opt.allow_admin) - { - log_info ("access to admin commands is not configured\n"); - return gpg_error (GPG_ERR_EACCES); - } - - if (!app->did_chv3) - { - char *pinvalue; - - rc = pincb (pincb_arg, "Admin PIN", &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV3) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue)); - xfree (pinvalue); - if (rc) - { - log_error ("verify CHV3 failed: %s\n", gpg_strerror (rc)); - flush_cache_after_error (app); - return rc; - } - app->did_chv3 = 1; - } - return rc; -} - - -/* Handle the SETATTR operation. All arguments are already basically - checked. */ -static int -do_setattr (APP app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen) -{ - gpg_error_t rc; - int idx; - static struct { - const char *name; - int tag; - int special; - } table[] = { - { "DISP-NAME", 0x005B }, - { "LOGIN-DATA", 0x005E }, - { "DISP-LANG", 0x5F2D }, - { "DISP-SEX", 0x5F35 }, - { "PUBKEY-URL", 0x5F50 }, - { "CHV-STATUS-1", 0x00C4, 1 }, - { "CA-FPR-1", 0x00CA }, - { "CA-FPR-2", 0x00CB }, - { "CA-FPR-3", 0x00CC }, - { NULL, 0 } - }; - - - for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) - ; - if (!table[idx].name) - return gpg_error (GPG_ERR_INV_NAME); - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - return rc; - - /* Flush the cache before writing it, so that the next get operation - will reread the data from the card and thus get synced in case of - errors (e.g. data truncated by the card). */ - flush_cache_item (app, table[idx].tag); - rc = iso7816_put_data (app->slot, table[idx].tag, value, valuelen); - if (rc) - log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc)); - - if (table[idx].special == 1) - app->force_chv1 = (valuelen && *value == 0); - - return rc; -} - - -/* Handle the PASSWD command. */ -static int -do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc = 0; - int chvno = atoi (chvnostr); - char *pinvalue; - - if (reset_mode && chvno == 3) - { - rc = gpg_error (GPG_ERR_INV_ID); - goto leave; - } - else if (reset_mode || chvno == 3) - { - /* we always require that the PIN is entered. */ - app->did_chv3 = 0; - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - } - else if (chvno == 1 || chvno == 2) - { - /* CHV1 and CVH2 should always have the same value, thus we - enforce it here. */ - int save_force = app->force_chv1; - - app->force_chv1 = 0; - app->did_chv1 = 0; - app->did_chv2 = 0; - rc = verify_chv2 (app, pincb, pincb_arg); - app->force_chv1 = save_force; - if (rc) - goto leave; - } - else - { - rc = gpg_error (GPG_ERR_INV_ID); - goto leave; - } - - if (chvno == 3) - app->did_chv3 = 0; - else - app->did_chv1 = app->did_chv2 = 0; - - rc = pincb (pincb_arg, chvno == 3? "New Admin PIN" : "New PIN", &pinvalue); - if (rc) - { - log_error ("error getting new PIN: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (reset_mode) - { - rc = iso7816_reset_retry_counter (app->slot, 0x81, - pinvalue, strlen (pinvalue)); - if (!rc) - rc = iso7816_reset_retry_counter (app->slot, 0x82, - pinvalue, strlen (pinvalue)); - } - else - { - if (chvno == 1 || chvno == 2) - { - rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0, - pinvalue, strlen (pinvalue)); - if (!rc) - rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0, - pinvalue, strlen (pinvalue)); - } - else - rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, - pinvalue, strlen (pinvalue)); - } - xfree (pinvalue); - if (rc) - flush_cache_after_error (app); - - leave: - return rc; -} - - - -/* Handle the GENKEY command. */ -static int -do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - int i; - char numbuf[30]; - unsigned char fprbuf[20]; - const unsigned char *fpr; - const unsigned char *keydata, *m, *e; - unsigned char *buffer; - size_t buflen, keydatalen, n, mlen, elen; - time_t created_at; - int keyno = atoi (keynostr); - int force = (flags & 1); - time_t start_at; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - /* We flush the cache to increase the traffic before a key - generation. This _might_ help a card to gather more entropy. */ - flush_cache (app); - - rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen); - if (rc) - { - log_error ("error reading application data\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr = find_tlv (buffer, buflen, 0x00C5, &n); - if (!fpr || n != 60) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("error reading fingerprint DO\n"); - goto leave; - } - fpr += 20*keyno; - for (i=0; i < 20 && !fpr[i]; i++) - ; - if (i!=20 && !force) - { - rc = gpg_error (GPG_ERR_EEXIST); - log_error ("key already exists\n"); - goto leave; - } - else if (i!=20) - log_info ("existing key will be replaced\n"); - else - log_info ("generating new key\n"); - - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - - xfree (buffer); buffer = NULL; - -#if 1 - log_info ("please wait while key is being generated ...\n"); - start_at = time (NULL); - rc = iso7816_generate_keypair -#else -#warning key generation temporary replaced by reading an existing key. - rc = iso7816_read_public_key -#endif - (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); - if (rc) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("generating key failed\n"); - goto leave; - } - log_info ("key generation completed (%d seconds)\n", - (int)(time (NULL) - start_at)); - keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); - if (!keydata) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the public key data\n"); - goto leave; - } - - m = find_tlv (keydata, keydatalen, 0x0081, &mlen); - if (!m) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA modulus\n"); - goto leave; - } -/* log_printhex ("RSA n:", m, mlen); */ - send_key_data (ctrl, "n", m, mlen); - - e = find_tlv (keydata, keydatalen, 0x0082, &elen); - if (!e) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA public exponent\n"); - goto leave; - } -/* log_printhex ("RSA e:", e, elen); */ - send_key_data (ctrl, "e", e, elen); - - created_at = gnupg_get_time (); - sprintf (numbuf, "%lu", (unsigned long)created_at); - send_status_info (ctrl, "KEY-CREATED-AT", - numbuf, (size_t)strlen(numbuf), NULL, 0); - - rc = store_fpr (app->slot, keyno, (u32)created_at, - m, mlen, e, elen, fprbuf, app->card_version); - if (rc) - goto leave; - send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf); - - - leave: - xfree (buffer); - return rc; -} - - -static unsigned long -convert_sig_counter_value (const unsigned char *value, size_t valuelen) -{ - unsigned long ul; - - if (valuelen == 3 ) - ul = (value[0] << 16) | (value[1] << 8) | value[2]; - else - { - log_error ("invalid structure of OpenPGP card (DO 0x93)\n"); - ul = 0; - } - return ul; -} - -static unsigned long -get_sig_counter (APP app) -{ - void *relptr; - unsigned char *value; - size_t valuelen; - unsigned long ul; - - relptr = get_one_do (app, 0x0093, &value, &valuelen); - if (!relptr) - return 0; - ul = convert_sig_counter_value (value, valuelen); - xfree (relptr); - return ul; -} - -static int -compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr) -{ - const unsigned char *fpr; - unsigned char *buffer; - size_t buflen, n; - int rc, i; - - assert (keyno >= 1 && keyno <= 3); - - rc = get_cached_data (app, 0x006E, &buffer, &buflen); - if (rc) - { - log_error ("error reading application data\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr = find_tlv (buffer, buflen, 0x00C5, &n); - if (!fpr || n != 60) - { - xfree (buffer); - log_error ("error reading fingerprint DO\n"); - return gpg_error (GPG_ERR_GENERAL); - } - fpr += (keyno-1)*20; - for (i=0; i < 20; i++) - if (sha1fpr[i] != fpr[i]) - { - xfree (buffer); - return gpg_error (GPG_ERR_WRONG_SECKEY); - } - xfree (buffer); - return 0; -} - - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint we - assume that this is okay. */ -static int -check_against_given_fingerprint (APP app, const char *fpr, int keyno) -{ - unsigned char tmp[20]; - const char *s; - int n; - - for (s=fpr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 40) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* okay */ - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=fpr, n=0; n < 20; s += 2, n++) - tmp[n] = xtoi_2 (s); - return compare_fingerprint (app, keyno, tmp); -} - - - -/* Compute a digital signature on INDATA which is expected to be the - raw message digest. For this application the KEYIDSTR consists of - the serialnumber and the fingerprint delimited by a slash. - - Note that this fucntion may return the error code - GPG_ERR_WRONG_CARD to indicate that the card currently present does - not match the one required for the requested action (e.g. the - serial number does not match). */ -static int -do_sign (APP app, const char *keyidstr, int hashalgo, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - int rc; - unsigned char data[35]; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - unsigned long sigcount; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, gpg - will detect a bogus signature anyway due to the - verify-after-signing feature. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 1) : 0; - if (rc) - return rc; - - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); - else - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); - - sigcount = get_sig_counter (app); - log_info ("signatures created so far: %lu\n", sigcount); - - if (!app->did_chv1 || app->force_chv1 ) - { - char *pinvalue; - - { - char *prompt; - if (asprintf (&prompt, "PIN [sigs done: %lu]", sigcount) < 0) - return gpg_error_from_errno (errno); - rc = pincb (pincb_arg, prompt, &pinvalue); - free (prompt); - } - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - if (strlen (pinvalue) < 6) - { - log_error ("prassphrase (CHV1) is too short; minimum length is 6\n"); - xfree (pinvalue); - return gpg_error (GPG_ERR_BAD_PIN); - } - - rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (rc) - { - log_error ("verify CHV1 failed\n"); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv1 = 1; - if (!app->did_chv2) - { - /* We should also verify CHV2. */ - rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); - if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) - rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); - if (rc) - { - log_error ("verify CHV2 failed\n"); - xfree (pinvalue); - flush_cache_after_error (app); - return rc; - } - app->did_chv2 = 1; - } - xfree (pinvalue); - } - - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); - return rc; -} - -/* Compute a digital signature using the INTERNAL AUTHENTICATE command - on INDATA which is expected to be the raw message digest. For this - application the KEYIDSTR consists of the serialnumber and the - fingerprint delimited by a slash. - - Note that this fucntion may return the error code - GPG_ERR_WRONG_CARD to indicate that the card currently present does - not match the one required for the requested action (e.g. the - serial number does not match). */ -static int -do_auth (APP app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen > 50) /* For a 1024 bit key. */ - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, gpg - will detect a bogus signature anyway due to the - verify-after-signing feature. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 3) : 0; - if (rc) - return rc; - - rc = verify_chv2 (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_internal_authenticate (app->slot, indata, indatalen, - outdata, outdatalen); - return rc; -} - - -static int -do_decipher (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ - const char *s; - int n; - const char *fpr = NULL; - - if (!keyidstr || !*keyidstr || !indatalen) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* no fingerprint given: we allow this for now. */ - else if (*s == '/') - fpr = s + 1; - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - - /* If a fingerprint has been specified check it against the one on - the card. This is allows for a meaningful error message in case - the key on the card has been replaced but the shadow information - known to gpg was not updated. If there is no fingerprint, the - decryption will won't produce the right plaintext anyway. */ - rc = fpr? check_against_given_fingerprint (app, fpr, 2) : 0; - if (rc) - return rc; - - rc = verify_chv2 (app, pincb, pincb_arg); - if (!rc) - rc = iso7816_decipher (app->slot, indata, indatalen, 0, - outdata, outdatalen); - return rc; -} - - -/* Perform a simple verify operation for CHV1 and CHV2, so that - further operations won't ask for CHV2 and it is possible to do a - cheap check on the PIN: If there is something wrong with the PIN - entry system, only the regular CHV will get blocked and not the - dangerous CHV3. KEYIDSTR is the usual card's serial number; an - optional fingerprint part will be ignored. */ -static int -do_check_pin (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg) -{ - unsigned char tmp_sn[20]; - const char *s; - int n; - - if (!keyidstr || !*keyidstr) - return gpg_error (GPG_ERR_INV_VALUE); - - /* Check whether an OpenPGP card of any version has been requested. */ - if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12)) - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; hexdigitp (s); s++, n++) - ; - if (n != 32) - return gpg_error (GPG_ERR_INV_ID); - else if (!*s) - ; /* No fingerprint given: we allow this for now. */ - else if (*s == '/') - ; /* We ignore a fingerprint. */ - else - return gpg_error (GPG_ERR_INV_ID); - - for (s=keyidstr, n=0; n < 16; s += 2, n++) - tmp_sn[n] = xtoi_2 (s); - - if (app->serialnolen != 16) - return gpg_error (GPG_ERR_INV_CARD); - if (memcmp (app->serialno, tmp_sn, 16)) - return gpg_error (GPG_ERR_WRONG_CARD); - /* Yes, there is a race conditions: The user might pull the card - right here and we won't notice that. However this is not a - problem and the check above is merely for a graceful failure - between operations. */ - - return verify_chv2 (app, pincb, pincb_arg); -} - - - - -/* Select the OpenPGP application on the card in SLOT. This function - must be used before any other OpenPGP application functions. */ -int -app_select_openpgp (APP app) -{ - static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; - int slot = app->slot; - int rc; - unsigned char *buffer; - size_t buflen; - void *relptr; - - rc = iso7816_select_application (slot, aid, sizeof aid); - if (!rc) - { - app->apptype = "OPENPGP"; - - app->did_chv1 = 0; - app->did_chv2 = 0; - app->did_chv3 = 0; - - /* The OpenPGP card returns the serial number as part of the - AID; because we prefer to use OpenPGP serial numbers, we - replace a possibly already set one from a EF.GDO with this - one. Note, that for current OpenPGP cards, no EF.GDO exists - and thus it won't matter at all. */ - rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen); - if (rc) - goto leave; - if (opt.verbose) - { - log_info ("got AID: "); - log_printhex ("", buffer, buflen); - } - - app->card_version = buffer[6] << 8; - app->card_version |= buffer[7]; - xfree (app->serialno); - app->serialno = buffer; - app->serialnolen = buflen; - buffer = NULL; - - relptr = get_one_do (app, 0x00C4, &buffer, &buflen); - if (!relptr) - { - log_error ("can't access CHV Status Bytes - invalid OpenPGP card?\n"); - goto leave; - } - app->force_chv1 = (buflen && *buffer == 0); - xfree (relptr); - - if (opt.verbose > 1) - dump_all_do (slot); - - app->fnc.deinit = do_deinit; - app->fnc.learn_status = do_learn_status; - app->fnc.readcert = NULL; - app->fnc.getattr = do_getattr; - app->fnc.setattr = do_setattr; - app->fnc.genkey = do_genkey; - app->fnc.sign = do_sign; - app->fnc.auth = do_auth; - app->fnc.decipher = do_decipher; - app->fnc.change_pin = do_change_pin; - app->fnc.check_pin = do_check_pin; - } - -leave: - return rc; -} - - - -/* This function is a hack to retrieve essential information about the - card to be displayed by simple tools. It mostly resembles what the - LEARN command returns. All parameters return allocated strings or - buffers or NULL if the data object is not available. All returned - values are sanitized. */ -int -app_openpgp_cardinfo (APP app, - char **serialno, - char **disp_name, - char **pubkey_url, - unsigned char **fpr1, - unsigned char **fpr2, - unsigned char **fpr3) -{ - int rc; - void *relptr; - unsigned char *value; - size_t valuelen; - - if (serialno) - { - time_t dummy; - - *serialno = NULL; - rc = app_get_serial_and_stamp (app, serialno, &dummy); - if (rc) - { - log_error ("error getting serial number: %s\n", gpg_strerror (rc)); - return rc; - } - } - - if (disp_name) - { - *disp_name = NULL; - relptr = get_one_do (app, 0x005B, &value, &valuelen); - if (relptr) - { - *disp_name = make_printable_string (value, valuelen, 0); - xfree (relptr); - } - } - - if (pubkey_url) - { - *pubkey_url = NULL; - relptr = get_one_do (app, 0x5F50, &value, &valuelen); - if (relptr) - { - *pubkey_url = make_printable_string (value, valuelen, 0); - xfree (relptr); - } - } - - if (fpr1) - *fpr1 = NULL; - if (fpr2) - *fpr2 = NULL; - if (fpr3) - *fpr3 = NULL; - relptr = get_one_do (app, 0x00C5, &value, &valuelen); - if (relptr && valuelen >= 60) - { - if (fpr1) - { - *fpr1 = xmalloc (20); - memcpy (*fpr1, value + 0, 20); - } - if (fpr2) - { - *fpr2 = xmalloc (20); - memcpy (*fpr2, value + 20, 20); - } - if (fpr3) - { - *fpr3 = xmalloc (20); - memcpy (*fpr3, value + 40, 20); - } - } - xfree (relptr); - - return 0; -} - - - -/* This function is currently only used by the sc-copykeys program to - store a key on the smartcard. APP ist the application handle, - KEYNO is the number of the key and PINCB, PINCB_ARG are used to ask - for the SO PIN. TEMPLATE and TEMPLATE_LEN describe a buffer with - the key template to store. CREATED_AT is the timestamp used to - create the fingerprint. M, MLEN is the RSA modulus and E, ELEN the - RSA public exponent. This function silently overwrites an existing - key.*/ -int -app_openpgp_storekey (APP app, int keyno, - unsigned char *template, size_t template_len, - time_t created_at, - const unsigned char *m, size_t mlen, - const unsigned char *e, size_t elen, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - unsigned char fprbuf[20]; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - rc = verify_chv3 (app, pincb, pincb_arg); - if (rc) - goto leave; - - - rc = iso7816_put_data (app->slot, - (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, - template, template_len); - if (rc) - { - log_error ("failed to store the key: rc=%s\n", gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - -/* log_printhex ("RSA n:", m, mlen); */ -/* log_printhex ("RSA e:", e, elen); */ - - rc = store_fpr (app->slot, keyno, (u32)created_at, - m, mlen, e, elen, fprbuf, app->card_version); - - leave: - return rc; -} - - -/* Utility function for external tools: Read the public RSA key at - KEYNO and return modulus and exponent in (M,MLEN) and (E,ELEN). */ -int -app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen, - unsigned char **e, size_t *elen) -{ - int rc; - const unsigned char *keydata, *a; - unsigned char *buffer; - size_t buflen, keydatalen, alen; - - *m = NULL; - *e = NULL; - - if (keyno < 1 || keyno > 3) - return gpg_error (GPG_ERR_INV_ID); - keyno--; - - rc = iso7816_read_public_key(app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); - if (rc) - { - rc = gpg_error (GPG_ERR_CARD); - log_error ("reading key failed\n"); - goto leave; - } - - keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); - if (!keydata) - { - log_error ("response does not contain the public key data\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - - a = find_tlv (keydata, keydatalen, 0x0081, &alen); - if (!a) - { - log_error ("response does not contain the RSA modulus\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - *mlen = alen; - *m = xmalloc (alen); - memcpy (*m, a, alen); - - a = find_tlv (keydata, keydatalen, 0x0082, &alen); - if (!e) - { - log_error ("response does not contain the RSA public exponent\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - *elen = alen; - *e = xmalloc (alen); - memcpy (*e, a, alen); - - leave: - xfree (buffer); - if (rc) - { - xfree (*m); *m = NULL; - xfree (*e); *e = NULL; - } - return rc; -} diff --git a/scd/app.c b/scd/app.c deleted file mode 100644 index a9a9243eb..000000000 --- a/scd/app.c +++ /dev/null @@ -1,391 +0,0 @@ -/* app.c - Application selection. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#include "scdaemon.h" -#include "app-common.h" -#include "apdu.h" -#include "iso7816.h" -#include "tlv.h" - - -/* If called with NAME as NULL, select the best fitting application - and return a context; otherwise select the application with NAME - and return a context. SLOT identifies the reader device. Returns - NULL if no application was found or no card is present. */ -APP -select_application (ctrl_t ctrl, int slot, const char *name) -{ - int rc; - APP app; - unsigned char *result = NULL; - size_t resultlen; - - app = xtrycalloc (1, sizeof *app); - if (!app) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_info ("error allocating context: %s\n", gpg_strerror (rc)); - return NULL; - } - app->slot = slot; - - /* Fixme: We should now first check whether a card is at all - present. */ - - /* Try to read the GDO file first to get a default serial number. */ - rc = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL); - if (!rc) - rc = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL); - if (!rc) - rc = iso7816_read_binary (slot, 0, 0, &result, &resultlen); - if (!rc) - { - size_t n; - const unsigned char *p; - - p = find_tlv (result, resultlen, 0x5A, &n); - if (p && n && n >= (resultlen - (p - result))) - { - /* The GDO file is pretty short, thus we simply reuse it for - storing the serial number. */ - memmove (result, p, n); - app->serialno = result; - app->serialnolen = n; - } - else - xfree (result); - result = NULL; - } - - - rc = gpg_error (GPG_ERR_NOT_FOUND); - - if (!name || !strcmp (name, "openpgp")) - rc = app_select_openpgp (app); - if (rc && (!name || !strcmp (name, "nks"))) - rc = app_select_nks (app); - if (rc && (!name || !strcmp (name, "dinsig"))) - rc = app_select_dinsig (app); - if (rc && name) - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - - if (rc) - { - if (name) - log_info ("can't select application `%s': %s\n", - name, gpg_strerror (rc)); - else - log_info ("no supported card application found: %s\n", - gpg_strerror (rc)); - xfree (app); - return NULL; - } - - app->initialized = 1; - return app; -} - - -void -release_application (app_t app) -{ - if (!app) - return; - - if (app->fnc.deinit) - { - app->fnc.deinit (app); - app->fnc.deinit = NULL; - } - - xfree (app->serialno); - xfree (app); -} - - - -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. If - no update time is available the returned value is 0. Caller must - free SERIAL unless the function returns an error. If STAMP is not - of interest, NULL may be passed. */ -int -app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp) -{ - unsigned char *buf, *p; - int i; - - if (!app || !serial) - return gpg_error (GPG_ERR_INV_VALUE); - - *serial = NULL; - if (stamp) - *stamp = 0; /* not available */ - - buf = xtrymalloc (app->serialnolen * 2 + 1); - if (!buf) - return gpg_error_from_errno (errno); - for (p=buf, i=0; i < app->serialnolen; p +=2, i++) - sprintf (p, "%02X", app->serialno[i]); - *p = 0; - *serial = buf; - return 0; -} - - -/* Write out the application specifig status lines for the LEARN - command. */ -int -app_write_learn_status (APP app, CTRL ctrl) -{ - if (!app) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.learn_status) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - if (app->apptype) - send_status_info (ctrl, "APPTYPE", - app->apptype, strlen (app->apptype), NULL, 0); - - return app->fnc.learn_status (app, ctrl); -} - - -/* Read the certificate with id CERTID (as returned by learn_status in - the CERTINFO status lines) and return it in the freshly allocated - buffer put into CERT and the length of the certificate put into - CERTLEN. */ -int -app_readcert (app_t app, const char *certid, - unsigned char **cert, size_t *certlen) -{ - if (!app) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.readcert) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - return app->fnc.readcert (app, certid, cert, certlen); -} - - -/* Perform a GETATTR operation. */ -int -app_getattr (APP app, CTRL ctrl, const char *name) -{ - if (!app || !name || !*name) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.getattr) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - return app->fnc.getattr (app, ctrl, name); -} - -/* Perform a SETATTR operation. */ -int -app_setattr (APP app, const char *name, - int (*pincb)(void*, const char *, char **), - void *pincb_arg, - const unsigned char *value, size_t valuelen) -{ - if (!app || !name || !*name || !value) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.setattr) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen); -} - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -app_sign (APP app, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.sign) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.sign (app, keyidstr, hashalgo, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation sign result: %s\n", gpg_strerror (rc)); - return rc; -} - -/* Create the signature using the INTERNAL AUTHENTICATE command and - return the allocated result in OUTDATA. If a PIN is required the - PINCB will be used to ask for the PIN; it should return the PIN in - an allocated buffer and put it into PIN. */ -int -app_auth (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.auth) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.auth (app, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation auth result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Decrypt the data in INDATA and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -app_decipher (APP app, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.decipher) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.decipher (app, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("operation decipher result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a SETATTR operation. */ -int -app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !keynostr || !*keynostr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.genkey) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation genkey result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a GET CHALLENGE operation. This fucntion is special as it - directly accesses the card without any application specific - wrapper. */ -int -app_get_challenge (APP app, size_t nbytes, unsigned char *buffer) -{ - if (!app || !nbytes || !buffer) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - return iso7816_get_challenge (app->slot, nbytes, buffer); -} - - - -/* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */ -int -app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !chvnostr || !*chvnostr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.change_pin) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation change_pin result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Perform a VERIFY operation without doing anything lese. This may - be used to initialze a the PION cache for long lasting other - operations. Its use is highly application dependent. */ -int -app_check_pin (APP app, const char *keyidstr, - int (*pincb)(void*, const char *, char **), - void *pincb_arg) -{ - int rc; - - if (!app || !keyidstr || !*keyidstr || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!app->initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!app->fnc.check_pin) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg); - if (opt.verbose) - log_info ("operation check_pin result: %s\n", gpg_strerror (rc)); - return rc; -} - diff --git a/scd/atr.c b/scd/atr.c deleted file mode 100644 index 6475e83f8..000000000 --- a/scd/atr.c +++ /dev/null @@ -1,287 +0,0 @@ -/* atr.c - ISO 7816 ATR fucntions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "scdaemon.h" -#include "apdu.h" -#include "atr.h" -#include "dynload.h" - -static int const fi_table[16] = { 0, 372, 558, 744, 1116,1488, 1860, -1, - -1, 512, 768, 1024, 1536, 2048, -1, -1 }; -static int const di_table[16] = { -1, 1, 2, 4, 8, 16, -1, -1, - 0, -1, -2, -4, -8, -16, -32, -64}; - - -/* Dump the ATR of the card at SLOT in a human readable format to - stream FP. */ -int -atr_dump (int slot, FILE *fp) -{ - unsigned char *atrbuffer, *atr; - size_t atrlen; - int have_ta, have_tb, have_tc, have_td; - int n_historical; - int idx, val; - unsigned char chksum; - - atr = atrbuffer = apdu_get_atr (slot, &atrlen); - if (!atr) - return gpg_error (GPG_ERR_GENERAL); - - fprintf (fp, "Info on ATR of length %u at slot %d\n", - (unsigned int)atrlen, slot); - if (!atrlen) - { - fprintf (fp, "error: empty ATR\n"); - goto bailout; - } - - - if (*atr == 0x3b) - fputs ("direct convention\n", fp); - else if (*atr == 0x3f) - fputs ("inverse convention\n", fp); - else - fprintf (fp,"error: invalid TS character 0x%02x\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - - chksum = *atr; - for (idx=1; idx < atrlen-1; idx++) - chksum ^= atr[idx]; - - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - n_historical = (*atr & 0x0f); - fprintf (fp, "%d historical characters indicated\n", n_historical); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - if (!--atrlen) - goto bailout; - atr++; - - if (have_ta) - { - fputs ("TA1: F=", fp); - val = fi_table[(*atr >> 4) & 0x0f]; - if (!val) - fputs ("internal clock", fp); - else if (val == -1) - fputs ("RFU", fp); - else - fprintf (fp, "%d", val); - fputs (" D=", fp); - val = di_table[*atr & 0x0f]; - if (!val) - fputs ("[impossible value]\n", fp); - else if (val == -1) - fputs ("RFU\n", fp); - else if (val < 0 ) - fprintf (fp, "1/%d\n", val); - else - fprintf (fp, "%d\n", val); - - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB1: II=%d PI1=%d%s\n", (*atr >> 5) & 3, *atr & 0x1f, - (*atr & 0x80)? " [high bit not cleared]":""); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - if (*atr == 255) - fputs ("TC1: guard time shortened to 1 etu\n", fp); - else - fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr); - - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD1: protocol T%d supported\n", *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - - if (have_ta) - { - fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n", - (*atr & 0x80)? "no-":"", - (*atr & 0x10)? "im": "ex", - (*atr & 0x0f)); - if ((*atr & 0x60)) - fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB2: PI2=%d\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - fprintf (fp, "TC2: PWI=%d\n", *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - - for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++) - { - if (have_ta) - { - fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tb) - { - fprintf (fp, "TB%d: BWI=%d CWI=%d\n", - idx, (*atr >> 4) & 0x0f, *atr & 0x0f); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_tc) - { - fprintf (fp, "TC%d: 0x%02X\n", idx, *atr); - if (!--atrlen) - goto bailout; - atr++; - } - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", - fp); - - if (!--atrlen) - goto bailout; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - } - - if (n_historical + 1 > atrlen) - fputs ("error: ATR shorter than required for historical bytes " - "and checksum\n", fp); - - if (n_historical) - { - fputs ("Historical:", fp); - for (; n_historical && atrlen ; n_historical--, atrlen--, atr++) - fprintf (fp, " %02X", *atr); - putchar ('\n'); - } - - if (!atrlen) - fputs ("error: checksum missing\n", fp); - else if (*atr == chksum) - fprintf (fp, "TCK: %02X (good)\n", *atr); - else - fprintf (fp, "TCK: %02X (bad; calculated %02X)\n", *atr, chksum); - - atrlen--; - if (atrlen) - fprintf (fp, "error: %u bytes garbage at end of ATR\n", - (unsigned int)atrlen ); - - bailout: - xfree (atrbuffer); - - return 0; -} - - - - - - - - - diff --git a/scd/atr.h b/scd/atr.h deleted file mode 100644 index 5fdd57457..000000000 --- a/scd/atr.h +++ /dev/null @@ -1,28 +0,0 @@ -/* atr.h - ISO 7816 ATR functions - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef ATR_H -#define ATR_H - -int atr_dump (int slot, FILE *fp); - - - -#endif /*ATR_H*/ diff --git a/scd/card-common.h b/scd/card-common.h deleted file mode 100644 index cefaf120f..000000000 --- a/scd/card-common.h +++ /dev/null @@ -1,73 +0,0 @@ -/* card-common.h - Common declarations for all card types - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef CARD_COMMON_H -#define CARD_COMMON_H - -/* Declaration of private data structure used by card-p15.c */ -struct p15private_s; - - -struct card_ctx_s { - int reader; /* used reader */ - struct sc_context *ctx; - struct sc_card *scard; - struct sc_pkcs15_card *p15card; /* only if there is a pkcs15 application */ - struct p15private_s *p15priv; /* private data used by card-p15.c */ - - struct { - int initialized; /* the card has been initialied and the function - pointers may be used. However for - unsupported operations the particular - function pointer is set to NULL */ - - int (*enum_keypairs) (CARD card, int idx, - unsigned char *keygrip, char **keyid); - int (*enum_certs) (CARD card, int idx, char **certid, int *certtype); - int (*read_cert) (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - int (*sign) (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); - int (*decipher) (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - } fnc; - -}; - -/*-- card.c --*/ -gpg_error_t map_sc_err (int rc); -int card_help_get_keygrip (ksba_cert_t cert, unsigned char *array); - -/*-- card-15.c --*/ -void p15_release_private_data (CARD card); - -/* constructors */ -void card_p15_bind (CARD card); -void card_dinsig_bind (CARD card); - - -#endif /*CARD_COMMON_H*/ diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c deleted file mode 100644 index df09bfb57..000000000 --- a/scd/card-dinsig.c +++ /dev/null @@ -1,258 +0,0 @@ -/* card-dinsig.c - German signature law (DINSIG) functions - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* The German signature law and its bylaw (SigG and SigV) is currently - used with an interface specification described in DIN V 66291-1. - The AID to be used is: 'D27600006601'. - - The file IDs for certificates utilize the generic format: - Cxyz - C being the hex digit 'C' (12). - x being the service indicator: - '0' := SigG conform digital signature. - '1' := entity authentication. - '2' := key encipherment. - '3' := data encipherment. - '4' := key agreement. - other values are reserved for future use. - y being the security environment number using '0' for cards - not supporting a SE number. - z being the certificate type: - '0' := C.CH (base certificate of ard holder) or C.ICC. - '1' .. '7' := C.CH (business or professional certificate - of card holder. - '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA). - 'E' := C.RCA (self certified certificate of the Root-CA). - 'F' := reserved. - - The file IDs used by default are: - '1F00' EF.SSD (security service descriptor). [o,o] - '2F02' EF.GDO (global data objects) [m,m] - 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte. - Read and update after user authentication. [o,o] - 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size - of keys. [m (unless a 'C00E' is present),m] - 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size - of keys. [o,o] - 'C00n' EF.C.CH.DS (digital signature certificate of card holder) - with n := 0 .. 7. Size is 2k or size of cert. Read and - update allowed after user authentication. [m,m] - 'C00m' EF.C.CA.DS (digital signature certificate of CA) - with m := 8 .. E. Size is 1k or size of cert. Read always - allowed, update after uder authentication. [o,o] - 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m] - 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m] - 'D000' EF.DM (display message) [-,m] - - The letters in brackets indicate optional or mandatory files: The - first for card terminals under full control and the second for - "business" card terminals. - - FIXME: Needs a lot more explanation. - -*/ - - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> -#include "scdaemon.h" -#include <ksba.h> - -#include "card-common.h" - -static int dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - - - -/* See card.c for interface description. Frankly we don't do any real - enumeration but just check whether the well know files are - available. */ -static int -dinsig_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - unsigned char *buf; - size_t buflen; - ksba_cert_t cert; - - /* fixme: We should locate the application via the EF(DIR) and not - assume a Netkey card */ - if (!idx) - rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen); - else if (idx == 1) - rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen); - else - rc = -1; - if (rc) - return rc; - - rc = ksba_cert_new (&cert); - if (rc) - { - xfree (buf); - return rc; - } - - rc = ksba_cert_init_from_mem (cert, buf, buflen); - xfree (buf); - if (rc) - { - log_error ("failed to parse the certificate at idx %d: %s\n", - idx, gpg_strerror (rc)); - ksba_cert_release (cert); - return rc; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip at index %d\n", idx); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - /* return the iD */ - if (keyid) - { - *keyid = xtrymalloc (17); - if (!*keyid) - return gpg_error (gpg_err_code_from_errno (errno)); - if (!idx) - strcpy (*keyid, "DINSIG-DF01.C000"); - else - strcpy (*keyid, "DINSIG-DF01.C200"); - } - - return 0; -} - - - -/* See card.c for interface description */ -static int -dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char *buf; - int buflen; - - if (!strcmp (certidstr, "DINSIG-DF01.C000")) - sc_format_path ("3F00DF01C000", &path); - else if (!strcmp (certidstr, "DINSIG-DF01.C200")) - sc_format_path ("3F00DF01C200", &path); - else - return gpg_error (GPG_ERR_INV_ID); - - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return map_sc_err (rc); - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of certificate EF\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - if (file->size < 20) /* check against a somewhat arbitrary length */ - { - log_error ("certificate EF too short\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - buf = xtrymalloc (file->size); - if (!buf) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - sc_file_free (file); - return tmperr; - } - - rc = sc_read_binary (card->scard, 0, buf, file->size, 0); - if (rc >= 0 && rc != file->size) - { - log_error ("short read on certificate EF\n"); - sc_file_free (file); - xfree (buf); - return gpg_error (GPG_ERR_CARD); - } - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading certificate EF: %s\n", sc_strerror (rc)); - xfree (buf); - return map_sc_err (rc); - } - buflen = rc; - - /* The object is not a plain certificate but wrapped into id-at - userCertificate - fixme: we should check the specs and decided - whether libksba should support it */ - if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3 - && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24) - { - /* We have to strip the padding. Although this is a good idea - anyway, we have to do it due to a KSBA problem; KSBA does not - work correct when the buffer is larger than the ASN.1 - structure and the certificates here are padded with FF. So - as a workaround we look at the outer structure to get the - size of the entire thing and adjust the buflen. We can only - do this when there is a 2 byte length field */ - size_t seqlen; - if (buf[1] == 0x82) - { - seqlen = ((buf[2] << 8) | buf[3]) + 4; - if (seqlen < buflen) - buflen = seqlen; - } - memmove (buf, buf+9, buflen-9); - buflen -= 9; - } - - *cert = buf; - *ncert = buflen; - return 0; -} - - - - -/* Bind our operations to the card */ -void -card_dinsig_bind (CARD card) -{ - card->fnc.enum_keypairs = dinsig_enum_keypairs; - card->fnc.read_cert = dinsig_read_cert; - -} -#endif /*HAVE_OPENSC*/ diff --git a/scd/card-p15.c b/scd/card-p15.c deleted file mode 100644 index ae3ef148f..000000000 --- a/scd/card-p15.c +++ /dev/null @@ -1,500 +0,0 @@ -/* card-p15.c - PKCS-15 based card access - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> - -#include "scdaemon.h" -#include <ksba.h> -#include "card-common.h" - - -struct p15private_s { - int n_prkey_rsa_objs; - struct sc_pkcs15_object *prkey_rsa_objs[32]; - int n_cert_objs; - struct sc_pkcs15_object *cert_objs[32]; -}; - - -/* Allocate private data. */ -static int -init_private_data (CARD card) -{ - struct p15private_s *priv; - int rc; - - if (card->p15priv) - return 0; /* already done. */ - - priv = xtrycalloc (1, sizeof *priv); - if (!priv) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* OpenSC (0.7.0) is a bit strange in that the get_objects functions - tries to be a bit too clever and implicitly does an enumeration - which eventually leads to the fact that every call to this - fucntion returns one more macthing object. The old code in - p15_enum_keypairs assume that it would alwyas return the same - numer of objects and used this to figure out what the last object - enumerated is. We now do an enum_objects just once and keep it - in the private data. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, - priv->prkey_rsa_objs, - DIM (priv->prkey_rsa_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return gpg_error (GPG_ERR_CARD); - } - priv->n_prkey_rsa_objs = rc; - - /* Read all certificate objects. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, - priv->cert_objs, - DIM (priv->cert_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return gpg_error (GPG_ERR_CARD); - } - priv->n_cert_objs = rc; - - card->p15priv = priv; - return 0; -} - - -/* Release private data used in this module. */ -void -p15_release_private_data (CARD card) -{ - if (!card->p15priv) - return; - xfree (card->p15priv); - card->p15priv = NULL; -} - - - -/* See card.c for interface description */ -static int -p15_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - struct p15private_s *priv; - struct sc_pkcs15_object *tmpobj; - int nobjs; - struct sc_pkcs15_prkey_info *pinfo; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - ksba_cert_t cert; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_prkey_rsa_objs; - rc = 0; - if (idx >= nobjs) - return -1; - pinfo = priv->prkey_rsa_objs[idx]->data; - - /* now we need to read the certificate so that we can calculate the - keygrip */ - rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj); - if (rc) - { - log_info ("certificate for private key %d not found: %s\n", - idx, sc_strerror (rc)); - /* note, that we return the ID anyway */ - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto return_keyid; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate for private key %d: %s\n", - idx, sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - - rc = ksba_cert_new (&cert); - if (rc) - { - sc_pkcs15_free_certificate (certder); - return rc; - } - rc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len); - sc_pkcs15_free_certificate (certder); - if (rc) - { - log_error ("failed to parse the certificate for private key %d: %s\n", - idx, gpg_strerror (rc)); - ksba_cert_release (cert); - return rc; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip of private key %d\n", idx); - ksba_cert_release (cert); - return gpg_error (GPG_ERR_CARD); - } - ksba_cert_release (cert); - - rc = 0; - return_keyid: - if (keyid) - { - char *p; - int i; - - *keyid = p = xtrymalloc (9+pinfo->id.len*2+1); - if (!*keyid) - return gpg_error (gpg_err_code_from_errno (errno)); - p = stpcpy (p, "P15-5015."); - for (i=0; i < pinfo->id.len; i++, p += 2) - sprintf (p, "%02X", pinfo->id.value[i]); - *p = 0; - } - - return rc; -} - -/* See card.c for interface description */ -static int -p15_enum_certs (CARD card, int idx, char **certid, int *type) -{ - int rc; - struct p15private_s *priv; - struct sc_pkcs15_object *obj; - struct sc_pkcs15_cert_info *cinfo; - int nobjs; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_cert_objs; - rc = 0; - if (idx >= nobjs) - return -1; - obj = priv->cert_objs[idx]; - cinfo = obj->data; - - if (certid) - { - char *p; - int i; - - *certid = p = xtrymalloc (9+cinfo->id.len*2+1); - if (!*certid) - return gpg_error (gpg_err_code_from_errno (errno)); - p = stpcpy (p, "P15-5015."); - for (i=0; i < cinfo->id.len; i++, p += 2) - sprintf (p, "%02X", cinfo->id.value[i]); - *p = 0; - } - if (type) - { - if (!obj->df) - *type = 0; /* unknown */ - else if (obj->df->type == SC_PKCS15_CDF) - *type = 100; - else if (obj->df->type == SC_PKCS15_CDF_TRUSTED) - *type = 101; - else if (obj->df->type == SC_PKCS15_CDF_USEFUL) - *type = 102; - else - *type = 0; /* error -> unknown */ - } - - return rc; -} - - - -static int -idstr_to_id (const char *idstr, struct sc_pkcs15_id *id) -{ - const char *s; - int n; - - /* For now we only support the standard DF */ - if (strncmp (idstr, "P15-5015.", 9) ) - return gpg_error (GPG_ERR_INV_ID); - for (s=idstr+9, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n&1)) - return gpg_error (GPG_ERR_INV_ID); /*invalid or odd number of digits*/ - n /= 2; - if (!n || n > SC_PKCS15_MAX_ID_SIZE) - return gpg_error (GPG_ERR_INV_ID); /* empty or too large */ - for (s=idstr+9, n=0; *s; s += 2, n++) - id->value[n] = xtoi_2 (s); - id->len = n; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - struct sc_pkcs15_object *tmpobj; - struct sc_pkcs15_id certid; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - int rc; - - if (!card || !certidstr || !cert || !ncert) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->p15card) - return gpg_error (GPG_ERR_NO_PKCS15_APP); - - rc = idstr_to_id (certidstr, &certid); - if (rc) - return rc; - - rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj); - if (rc) - { - log_info ("certificate '%s' not found: %s\n", - certidstr, sc_strerror (rc)); - return -1; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate '%s': %s\n", - certidstr, sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - - *cert = xtrymalloc (certder->data_len); - if (!*cert) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - sc_pkcs15_free_certificate (certder); - return tmperr; - } - memcpy (*cert, certder->data, certder->data_len); - *ncert = certder->data_len; - sc_pkcs15_free_certificate (certder); - return 0; -} - - - - - -static int -p15_prepare_key (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, struct sc_pkcs15_object **r_keyobj) -{ - struct sc_pkcs15_id keyid; - struct sc_pkcs15_pin_info *pin; - struct sc_pkcs15_object *keyobj, *pinobj; - char *pinvalue; - int rc; - - rc = idstr_to_id (keyidstr, &keyid); - if (rc) - return rc; - - rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj); - if (rc < 0) - { - log_error ("private key not found: %s\n", sc_strerror(rc)); - return gpg_error (GPG_ERR_NO_SECKEY); - } - - rc = sc_pkcs15_find_pin_by_auth_id (card->p15card, - &keyobj->auth_id, &pinobj); - if (rc) - { - log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_BAD_PIN_METHOD); - } - pin = pinobj->data; - - /* Fixme: pack this into a verification loop */ - /* Fixme: we might want to pass pin->min_length and - pin->stored_length */ - rc = pincb (pincb_arg, pinobj->label, &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); - return rc; - } - - rc = sc_pkcs15_verify_pin (card->p15card, pin, - pinvalue, strlen (pinvalue)); - xfree (pinvalue); - if (rc) - { - log_info ("PIN verification failed: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_BAD_PIN); - } - - /* fixme: check wheter we need to release KEYOBJ in case of an error */ - *r_keyobj = keyobj; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - unsigned int cryptflags; - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - if (hashalgo != GCRY_MD_SHA1) - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1; - - outbuflen = 1024; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = sc_pkcs15_compute_signature (card->p15card, keyobj, - cryptflags, - indata, indatalen, - outbuf, outbuflen ); - if (rc < 0) - { - log_error ("failed to create signature: %s\n", sc_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - -/* See card.c for description */ -static int -p15_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - if (card && card->scard && card->scard->driver - && !strcasecmp (card->scard->driver->short_name, "tcos")) - { - /* very ugly hack to force the use of a local key. We need this - until we have fixed the initialization code for TCOS cards */ - struct sc_pkcs15_prkey_info *prkey = keyobj->data; - if ( !(prkey->key_reference & 0x80)) - { - prkey->key_reference |= 0x80; - log_debug ("using TCOS hack to force the use of local keys\n"); - } - if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6') - { - prkey->key_reference |= 1; - log_debug ("warning: using even more TCOS hacks\n"); - } - } - - outbuflen = indatalen < 256? 256 : indatalen; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return gpg_error (gpg_err_code_from_errno (errno)); - - rc = sc_pkcs15_decipher (card->p15card, keyobj, - 0, - indata, indatalen, - outbuf, outbuflen); - if (rc < 0) - { - log_error ("failed to decipher the data: %s\n", sc_strerror (rc)); - rc = gpg_error (GPG_ERR_CARD); - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - - -/* Bind our operations to the card */ -void -card_p15_bind (CARD card) -{ - card->fnc.enum_keypairs = p15_enum_keypairs; - card->fnc.enum_certs = p15_enum_certs; - card->fnc.read_cert = p15_read_cert; - card->fnc.sign = p15_sign; - card->fnc.decipher = p15_decipher; -} -#endif /*HAVE_OPENSC*/ diff --git a/scd/card.c b/scd/card.c deleted file mode 100644 index 9ec2a52c5..000000000 --- a/scd/card.c +++ /dev/null @@ -1,570 +0,0 @@ -/* card.c - SCdaemon card functions - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef HAVE_OPENSC -#include <opensc/pkcs15.h> -#endif - -#include "scdaemon.h" -#include <ksba.h> - -#include "card-common.h" - -/* Map the SC error codes to the GNUPG ones */ -gpg_error_t -map_sc_err (int rc) -{ - gpg_err_code_t e; - - switch (rc) - { - case 0: e = 0; break; -#ifdef HAVE_OPENSC - case SC_ERROR_NOT_SUPPORTED: e = GPG_ERR_NOT_SUPPORTED; break; - case SC_ERROR_PKCS15_APP_NOT_FOUND: e = GPG_ERR_NO_PKCS15_APP; break; - case SC_ERROR_OUT_OF_MEMORY: e = GPG_ERR_ENOMEM; break; - case SC_ERROR_CARD_NOT_PRESENT: e = GPG_ERR_CARD_NOT_PRESENT; break; - case SC_ERROR_CARD_REMOVED: e = GPG_ERR_CARD_REMOVED; break; - case SC_ERROR_INVALID_CARD: e = GPG_ERR_INV_CARD; break; -#endif - default: e = GPG_ERR_CARD; break; - } - /* It does not make much sense to further distingusih the error - source between OpenSC and SCD. Thus we use SCD as source - here. */ - return gpg_err_make (GPG_ERR_SOURCE_SCD, e); -} - -/* Get the keygrip from CERT, return 0 on success */ -int -card_help_get_keygrip (ksba_cert_t cert, unsigned char *array) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return -1; /* oops */ - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - return -1; /* libksba did not return a proper S-expression */ - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - return -1; /* can't parse that S-expression */ - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - return -1; /* failed to calculate the keygrip */ - return 0; -} - - - - - - - -/* Create a new context for the card and figures out some basic - information of the card. Detects whether a PKCS_15 application is - stored. - - Common errors: GPG_ERR_CARD_NOT_PRESENT */ -int -card_open (CARD *rcard) -{ -#ifdef HAVE_OPENSC - CARD card; - int rc; - - if (opt.disable_opensc) - return gpg_error (GPG_ERR_NOT_SUPPORTED); - - card = xtrycalloc (1, sizeof *card); - if (!card) - return gpg_error (gpg_err_code_from_errno (errno)); - card->reader = 0; - - rc = sc_establish_context (&card->ctx, "scdaemon"); - if (rc) - { - log_error ("failed to establish SC context: %s\n", sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (card->reader >= card->ctx->reader_count) - { - log_error ("no card reader available\n"); - rc = gpg_error (GPG_ERR_CARD); - goto leave; - } - card->ctx->error_file = log_get_stream (); - card->ctx->debug = opt.debug_sc; - card->ctx->debug_file = log_get_stream (); - - if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1) - { - rc = gpg_error (GPG_ERR_CARD_NOT_PRESENT); - goto leave; - } - - rc = sc_connect_card (card->ctx->reader[card->reader], 0, &card->scard); - if (rc) - { - log_error ("failed to connect card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (opt.verbose) - log_info ("connected to card in reader %d using driver `%s'\n", - card->reader, card->scard->driver->name); - - rc = sc_lock (card->scard); - if (rc) - { - log_error ("can't lock card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - - - leave: - if (rc) - card_close (card); - else - *rcard = card; - - return rc; -#else - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif -} - - -/* Close a card and release all resources */ -void -card_close (CARD card) -{ - if (card) - { -#ifdef HAVE_OPENSC - if (card->p15card) - { - sc_pkcs15_unbind (card->p15card); - card->p15card = NULL; - } - if (card->p15priv) - p15_release_private_data (card); - if (card->scard) - { - sc_unlock (card->scard); - sc_disconnect_card (card->scard, 0); - card->scard = NULL; - } - if (card->ctx) - { - sc_release_context (card->ctx); - card->ctx = NULL; - } -#endif - xfree (card); - } -} - -/* Locate a simple TLV encoded data object in BUFFER of LENGTH and - return a pointer to value as well as its length in NBYTES. Return - NULL if it was not found. Note, that the function does not check - whether the value fits into the provided buffer. */ -#ifdef HAVE_OPENSC -static const char * -find_simple_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes) -{ - const char *s = buffer; - size_t n = length; - size_t len; - - for (;;) - { - buffer = s; - if (n < 2) - return NULL; /* buffer too short for tag and length. */ - len = s[1]; - s += 2; n -= 2; - if (len == 255) - { - if (n < 2) - return NULL; /* we expected 2 more bytes with the length. */ - len = (s[0] << 8) | s[1]; - s += 2; n -= 2; - } - if (*buffer == tag) - { - *nbytes = len; - return s; - } - if (len > n) - return NULL; /* buffer too short to skip to the next tag. */ - s += len; n -= len; - } -} -#endif /*HAVE_OPENSC*/ - -/* Find the ICC Serial Number within the provided BUFFER of LENGTH - (which should contain the GDO file) and return it as a hex encoded - string and allocated string in SERIAL. Return an error code when - the ICCSN was not found. */ -#ifdef HAVE_OPENSC -static int -find_iccsn (const unsigned char *buffer, size_t length, char **serial) -{ - size_t n; - const unsigned char *s; - char *p; - - s = find_simple_tlv (buffer, length, 0x5A, &n); - if (!s) - return gpg_error (GPG_ERR_CARD); - length -= s - buffer; - if (n > length) - { - /* Oops, it does not fit into the buffer. This is an invalid - encoding (or the buffer is too short. However, I have some - test cards with such an invalid encoding and therefore I use - this ugly workaround to return something I can further - experiment with. */ - if (n == 0x0D && length+1 == n) - { - log_debug ("enabling BMI testcard workaround\n"); - n--; - } - else - return gpg_error (GPG_ERR_CARD); /* Bad encoding; does - not fit into buffer. */ - } - if (!n) - return gpg_error (GPG_ERR_CARD); /* Well, that is too short. */ - - *serial = p = xtrymalloc (2*n+1); - if (!*serial) - return gpg_error (gpg_err_code_from_errno (errno)); - for (; n; n--, p += 2, s++) - sprintf (p, "%02X", *s); - *p = 0; - return 0; -} -#endif /*HAVE_OPENSC*/ - -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. - If no update time is available the returned value is 0. The serial - is mandatory for a PKCS_15 application and an error will be - returned if this value is not availbale. For non-PKCS-15 cards a - serial number is constructed by other means. Caller must free - SERIAL unless the function returns an error. */ -int -card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp) -{ -#ifdef HAVE_OPENSC - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char buf[256]; - int buflen; -#endif - - if (!card || !serial || !stamp) - return gpg_error (GPG_ERR_INV_VALUE); - - *serial = NULL; - *stamp = 0; /* not available */ - -#ifdef HAVE_OPENSC - if (!card->fnc.initialized) - { - card->fnc.initialized = 1; - /* The first use of this card tries to figure out the type of the card - and sets up the function pointers. */ - rc = sc_pkcs15_bind (card->scard, &card->p15card); - if (rc) - { - if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND) - log_error ("binding of existing PKCS-15 failed in reader %d: %s\n", - card->reader, sc_strerror (rc)); - card->p15card = NULL; - rc = 0; - } - if (card->p15card) - card_p15_bind (card); - card->fnc.initialized = 1; - } - - - /* We should lookup the iso 7812-1 and 8583-3 - argh ISO - practice is suppressing innovation - IETF rules! So we - always get the serialnumber from the 2F02 GDO file. */ - /* FIXME: in case we can't parse the 2F02 EF and we have a P15 card, - we should get the serial number from the respective P15 file */ - sc_format_path ("3F002F02", &path); - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of GDO file\n"); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - - if (!file->size || file->size >= DIM(buf) ) - { /* FIXME: Use a real parser */ - log_error ("unsupported size of GDO file (%d)\n", file->size); - sc_file_free (file); - return gpg_error (GPG_ERR_CARD); - } - buflen = file->size; - - rc = sc_read_binary (card->scard, 0, buf, buflen, 0); - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading GDO file: %s\n", sc_strerror (rc)); - return gpg_error (GPG_ERR_CARD); - } - if (rc != buflen) - { - log_error ("short read on GDO file\n"); - return gpg_error (GPG_ERR_CARD); - } - - rc = find_iccsn (buf, buflen, serial); - if (gpg_err_code (rc) == GPG_ERR_CARD) - log_error ("invalid structure of GDO file\n"); - if (!rc && card->p15card && !strcmp (*serial, "D27600000000000000000000")) - { /* This is a German card with a silly serial number. Try to get - the serial number from the EF(TokenInfo). We indicate such a - serial number by the using the prefix: "FF0100". */ - const char *efser = card->p15card->serial_number; - char *p; - - if (!efser) - efser = ""; - - xfree (*serial); - *serial = NULL; - p = xtrymalloc (strlen (efser) + 7); - if (!p) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - strcpy (p, "FF0100"); - strcpy (p+6, efser); - *serial = p; - } - } - else if (!rc && **serial == 'F' && (*serial)[1] == 'F') - { /* The serial number starts with our special prefix. This - requires that we put our default prefix "FF0000" in front. */ - char *p = xtrymalloc (strlen (*serial) + 7); - if (!p) - { - xfree (*serial); - *serial = NULL; - rc = gpg_error (gpg_err_code_from_errno (errno)); - } - else - { - strcpy (p, "FF0000"); - strcpy (p+6, *serial); - xfree (*serial); - *serial = p; - } - } - return rc; -#else - return gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif -} - - -/* Enumerate all keypairs on the card and return the Keygrip as well - as the internal identification of the key. KEYGRIP must be a - caller provided buffer with a size of 20 bytes which will receive - the KEYGRIP of the keypair. If KEYID is not NULL, it returns the - ID field of the key in allocated memory; this is a string without - spaces. The function returns -1 when all keys have been - enumerated. Note that the error GPG_ERR_MISSING_CERTIFICATE may be - returned if there is just the private key but no public key (ie.e a - certificate) available. Applications might want to continue - enumerating after this error.*/ -int -card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid) -{ - int rc; - - if (keyid) - *keyid = NULL; - - if (!card || !keygrip) - return gpg_error (GPG_ERR_INV_VALUE); - if (idx < 0) - return gpg_error (GPG_ERR_INV_INDEX); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.enum_keypairs) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.enum_keypairs (card, idx, keygrip, keyid); - if (opt.verbose) - log_info ("card operation enum_keypairs result: %s\n", - gpg_strerror (rc)); - return rc; -} - - -/* Enumerate all trusted certificates available on the card, return - their ID in CERT and the type in CERTTYPE. Types of certificates - are: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - 110 := Root CA cert (DINSIG) - */ -int -card_enum_certs (CARD card, int idx, char **certid, int *certtype) -{ - int rc; - - if (certid) - *certid = NULL; - - if (!card) - return gpg_error (GPG_ERR_INV_VALUE); - if (idx < 0) - return gpg_error (GPG_ERR_INV_INDEX); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.enum_certs) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.enum_certs (card, idx, certid, certtype); - if (opt.verbose) - log_info ("card operation enum_certs result: %s\n", - gpg_strerror (rc)); - return rc; -} - - - -/* Read the certificate identified by CERTIDSTR which is the - hexadecimal encoded ID of the certificate, prefixed with the string - "3F005015.". The certificate is return in DER encoded form in CERT - and NCERT. */ -int -card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - - if (!card || !certidstr || !cert || !ncert) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.read_cert) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.read_cert (card, certidstr, cert, ncert); - if (opt.verbose) - log_info ("card operation read_cert result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.sign) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.sign (card, keyidstr, hashalgo, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation sign result: %s\n", gpg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return gpg_error (GPG_ERR_INV_VALUE); - if (!card->fnc.initialized) - return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - if (!card->fnc.decipher) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - rc = card->fnc.decipher (card, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation decipher result: %s\n", gpg_strerror (rc)); - return rc; -} - diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c deleted file mode 100644 index cd0bee6ef..000000000 --- a/scd/ccid-driver.c +++ /dev/null @@ -1,1277 +0,0 @@ -/* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * Written by Werner Koch. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * ALTERNATIVELY, this file may be distributed under the terms of the - * following license, in which case the provisions of this license are - * required INSTEAD OF the GNU General Public License. If you wish to - * allow use of your version of this file only under the terms of the - * GNU General Public License, and not to allow others to use your - * version of this file under the terms of the following license, - * indicate your decision by deleting this paragraph and the license - * below. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* CCID (ChipCardInterfaceDevices) is a specification for accessing - smartcard via a reader connected to the USB. - - This is a limited driver allowing to use some CCID drivers directly - without any other specila drivers. This is a fallback driver to be - used when nothing else works or the system should be kept minimal - for security reasons. It makes use of the libusb library to gain - portable access to USB. - - This driver has been tested with the SCM SCR335 smartcard reader - and requires that reader implements the TPDU level exchange and - does fully automatic initialization. -*/ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#if defined(HAVE_LIBUSB) || defined(TEST) - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <usb.h> - -#include "ccid-driver.h" - -#define DRVNAME "ccid-driver: " - - -/* Depending on how this source is used we either define our error - output to go to stderr or to the jnlib based logging functions. We - use the latter when GNUPG_MAJOR_VERSION is defines or when both, - GNUPG_SCD_MAIN_HEADER and HAVE_JNLIB_LOGGING are defined. -*/ -#if defined(GNUPG_MAJOR_VERSION) \ - || (defined(GNUPG_SCD_MAIN_HEADER) && defined(HAVE_JNLIB_LOGGING)) - -#if defined(GNUPG_SCD_MAIN_HEADER) -# include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */ -# include "options.h" -# include "util.h" -# include "memory.h" -# include "cardglue.h" -# else /* This is the modularized GnuPG 1.9 or later. */ -# include "scdaemon.h" -#endif - -/* Disable all debugging output for now. */ -#undef DBG_CARD_IO -#define DBG_CARD_IO 0 - -/* Define to print information pertaining the T=1 protocol. */ -#undef DEBUG_T1 - - -# define DEBUGOUT(t) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t); } while (0) -# define DEBUGOUT_1(t,a) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a)); } while (0) -# define DEBUGOUT_2(t,a,b) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a),(b)); } while (0) -# define DEBUGOUT_3(t,a,b,c) do { if (DBG_CARD_IO) \ - log_debug (DRVNAME t,(a),(b),(c));} while (0) -# define DEBUGOUT_CONT(t) do { if (DBG_CARD_IO) \ - log_printf (t); } while (0) -# define DEBUGOUT_CONT_1(t,a) do { if (DBG_CARD_IO) \ - log_printf (t,(a)); } while (0) -# define DEBUGOUT_CONT_2(t,a,b) do { if (DBG_CARD_IO) \ - log_printf (t,(a),(b)); } while (0) -# define DEBUGOUT_CONT_3(t,a,b,c) do { if (DBG_CARD_IO) \ - log_printf (t,(a),(b),(c)); } while (0) -# define DEBUGOUT_LF() do { if (DBG_CARD_IO) \ - log_printf ("\n"); } while (0) - -#else /* Other usage of this source - don't use gnupg specifics. */ - -# define DEBUGOUT(t) fprintf (stderr, DRVNAME t) -# define DEBUGOUT_1(t,a) fprintf (stderr, DRVNAME t, (a)) -# define DEBUGOUT_2(t,a,b) fprintf (stderr, DRVNAME t, (a), (b)) -# define DEBUGOUT_3(t,a,b,c) fprintf (stderr, DRVNAME t, (a), (b), (c)) -# define DEBUGOUT_CONT(t) fprintf (stderr, t) -# define DEBUGOUT_CONT_1(t,a) fprintf (stderr, t, (a)) -# define DEBUGOUT_CONT_2(t,a,b) fprintf (stderr, t, (a), (b)) -# define DEBUGOUT_CONT_3(t,a,b,c) fprintf (stderr, t, (a), (b), (c)) -# define DEBUGOUT_LF() putc ('\n', stderr) - -#endif /* This source not used by scdaemon. */ - - - - - -enum { - RDR_to_PC_NotifySlotChange= 0x50, - RDR_to_PC_HardwareError = 0x51, - - PC_to_RDR_SetParameters = 0x61, - PC_to_RDR_IccPowerOn = 0x62, - PC_to_RDR_IccPowerOff = 0x63, - PC_to_RDR_GetSlotStatus = 0x65, - PC_to_RDR_Secure = 0x69, - PC_to_RDR_T0APDU = 0x6a, - PC_to_RDR_Escape = 0x6b, - PC_to_RDR_GetParameters = 0x6c, - PC_to_RDR_ResetParameters = 0x6d, - PC_to_RDR_IccClock = 0x6e, - PC_to_RDR_XfrBlock = 0x6f, - PC_to_RDR_Mechanical = 0x71, - PC_to_RDR_Abort = 0x72, - PC_to_RDR_SetDataRate = 0x73, - - RDR_to_PC_DataBlock = 0x80, - RDR_to_PC_SlotStatus = 0x81, - RDR_to_PC_Parameters = 0x82, - RDR_to_PC_Escape = 0x83, - RDR_to_PC_DataRate = 0x84 -}; - - -/* Store information on the driver's state. A pointer to such a - structure is used as handle for most functions. */ -struct ccid_driver_s { - usb_dev_handle *idev; - int seqno; - unsigned char t1_ns; - unsigned char t1_nr; - int nonnull_nad; - int auto_ifsd; - int max_ifsd; - int ifsd; -}; - - -static unsigned int compute_edc (const unsigned char *data, size_t datalen, - int use_crc); -static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen); -static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, - size_t *nread, int expected_type, int seqno); - - - -/* Convert a little endian stored 4 byte value into an unsigned - integer. */ -static unsigned int -convert_le_u32 (const unsigned char *buf) -{ - return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); -} - -static void -set_msg_len (unsigned char *msg, unsigned int length) -{ - msg[1] = length; - msg[2] = length >> 8; - msg[3] = length >> 16; - msg[4] = length >> 24; -} - - - - -/* Parse a CCID descriptor, optionally print all available features - and test whether this reader is usable by this driver. Returns 0 - if it is usable. - - Note, that this code is based on the one in lsusb.c of the - usb-utils package, I wrote on 2003-09-01. -wk. */ -static int -parse_ccid_descriptor (ccid_driver_t handle, - const unsigned char *buf, size_t buflen) -{ - unsigned int i; - unsigned int us; - int have_t1 = 0, have_tpdu=0, have_auto_conf = 0; - - - handle->nonnull_nad = 0; - handle->auto_ifsd = 0; - handle->max_ifsd = 32; - handle->ifsd = 0; - if (buflen < 54 || buf[0] < 54) - { - DEBUGOUT ("CCID device descriptor is too short\n"); - return -1; - } - - DEBUGOUT ("ChipCard Interface Descriptor:\n"); - DEBUGOUT_1 (" bLength %5u\n", buf[0]); - DEBUGOUT_1 (" bDescriptorType %5u\n", buf[1]); - DEBUGOUT_2 (" bcdCCID %2x.%02x", buf[3], buf[2]); - if (buf[3] != 1 || buf[2] != 0) - DEBUGOUT_CONT(" (Warning: Only accurate for version 1.0)"); - DEBUGOUT_LF (); - - DEBUGOUT_1 (" nMaxSlotIndex %5u\n", buf[4]); - DEBUGOUT_2 (" bVoltageSupport %5u %s\n", - buf[5], (buf[5] == 1? "5.0V" : buf[5] == 2? "3.0V" - : buf[5] == 3? "1.8V":"?")); - - us = convert_le_u32 (buf+6); - DEBUGOUT_1 (" dwProtocols %5u ", us); - if ((us & 1)) - DEBUGOUT_CONT (" T=0"); - if ((us & 2)) - { - DEBUGOUT_CONT (" T=1"); - have_t1 = 1; - } - if ((us & ~3)) - DEBUGOUT_CONT (" (Invalid values detected)"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+10); - DEBUGOUT_1 (" dwDefaultClock %5u\n", us); - us = convert_le_u32(buf+14); - DEBUGOUT_1 (" dwMaxiumumClock %5u\n", us); - DEBUGOUT_1 (" bNumClockSupported %5u\n", buf[18]); - us = convert_le_u32(buf+19); - DEBUGOUT_1 (" dwDataRate %7u bps\n", us); - us = convert_le_u32(buf+23); - DEBUGOUT_1 (" dwMaxDataRate %7u bps\n", us); - DEBUGOUT_1 (" bNumDataRatesSupp. %5u\n", buf[27]); - - us = convert_le_u32(buf+28); - DEBUGOUT_1 (" dwMaxIFSD %5u\n", us); - handle->max_ifsd = us; - - us = convert_le_u32(buf+32); - DEBUGOUT_1 (" dwSyncProtocols %08X ", us); - if ((us&1)) - DEBUGOUT_CONT ( " 2-wire"); - if ((us&2)) - DEBUGOUT_CONT ( " 3-wire"); - if ((us&4)) - DEBUGOUT_CONT ( " I2C"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+36); - DEBUGOUT_1 (" dwMechanical %08X ", us); - if ((us & 1)) - DEBUGOUT_CONT (" accept"); - if ((us & 2)) - DEBUGOUT_CONT (" eject"); - if ((us & 4)) - DEBUGOUT_CONT (" capture"); - if ((us & 8)) - DEBUGOUT_CONT (" lock"); - DEBUGOUT_LF (); - - us = convert_le_u32(buf+40); - DEBUGOUT_1 (" dwFeatures %08X\n", us); - if ((us & 0x0002)) - { - DEBUGOUT (" Auto configuration based on ATR\n"); - have_auto_conf = 1; - } - if ((us & 0x0004)) - DEBUGOUT (" Auto activation on insert\n"); - if ((us & 0x0008)) - DEBUGOUT (" Auto voltage selection\n"); - if ((us & 0x0010)) - DEBUGOUT (" Auto clock change\n"); - if ((us & 0x0020)) - DEBUGOUT (" Auto baud rate change\n"); - if ((us & 0x0040)) - DEBUGOUT (" Auto parameter negotation made by CCID\n"); - else if ((us & 0x0080)) - DEBUGOUT (" Auto PPS made by CCID\n"); - else if ((us & (0x0040 | 0x0080))) - DEBUGOUT (" WARNING: conflicting negotation features\n"); - - if ((us & 0x0100)) - DEBUGOUT (" CCID can set ICC in clock stop mode\n"); - if ((us & 0x0200)) - { - DEBUGOUT (" NAD value other than 0x00 accepted\n"); - handle->nonnull_nad = 1; - } - if ((us & 0x0400)) - { - DEBUGOUT (" Auto IFSD exchange\n"); - handle->auto_ifsd = 1; - } - - if ((us & 0x00010000)) - { - DEBUGOUT (" TPDU level exchange\n"); - have_tpdu = 1; - } - else if ((us & 0x00020000)) - DEBUGOUT (" Short APDU level exchange\n"); - else if ((us & 0x00040000)) - DEBUGOUT (" Short and extended APDU level exchange\n"); - else if ((us & 0x00070000)) - DEBUGOUT (" WARNING: conflicting exchange levels\n"); - - us = convert_le_u32(buf+44); - DEBUGOUT_1 (" dwMaxCCIDMsgLen %5u\n", us); - - DEBUGOUT ( " bClassGetResponse "); - if (buf[48] == 0xff) - DEBUGOUT_CONT ("echo\n"); - else - DEBUGOUT_CONT_1 (" %02X\n", buf[48]); - - DEBUGOUT ( " bClassEnvelope "); - if (buf[49] == 0xff) - DEBUGOUT_CONT ("echo\n"); - else - DEBUGOUT_1 (" %02X\n", buf[48]); - - DEBUGOUT ( " wlcdLayout "); - if (!buf[50] && !buf[51]) - DEBUGOUT_CONT ("none\n"); - else - DEBUGOUT_CONT_2 ("%u cols %u lines\n", buf[50], buf[51]); - - DEBUGOUT_1 (" bPINSupport %5u ", buf[52]); - if ((buf[52] & 1)) - DEBUGOUT_CONT ( " verification"); - if ((buf[52] & 2)) - DEBUGOUT_CONT ( " modification"); - DEBUGOUT_LF (); - - DEBUGOUT_1 (" bMaxCCIDBusySlots %5u\n", buf[53]); - - if (buf[0] > 54) { - DEBUGOUT (" junk "); - for (i=54; i < buf[0]-54; i++) - DEBUGOUT_CONT_1 (" %02X", buf[i]); - DEBUGOUT_LF (); - } - - if (!have_t1 || !have_tpdu || !have_auto_conf) - { - DEBUGOUT ("this drivers requires that the reader supports T=1, " - "TPDU level exchange and auto configuration - " - "this is not available\n"); - return -1; - } - else - return 0; -} - - -/* Read the device information, return all required data and check - that the device is usable for us. Returns 0 on success or an error - code. */ -static int -read_device_info (ccid_driver_t handle, struct usb_device *dev) -{ - int cfg_no; - - for (cfg_no=0; cfg_no < dev->descriptor->bNumConfigurations; cfg_no++) - { - struct usb_config_descriptor *config = dev->config + cfg_no; - int ifc_no; - - for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) - { - struct usb_interface *interface = config->interface + ifc_no; - int set_no; - - for (set_no=0; set_no < interface->num_altsetting; set_no++) - { - struct usb_interface_descriptor *ifcdesc - = interface->altsetting + set_no; - - if (ifcdesc->bInterfaceClass == 11 - && ifcdesc->bInterfaceSubClass == 0 - && ifcdesc->bInterfaceProtocol == 0) - { - if (ifcdesc->extra) - { - if (!parse_ccid_descriptor (handle, - ifcdesc->extra, - ifcdesc->extralen)) - return 0; /* okay. we can use it. */ - } - } - } - } - } - return -1; /* No suitable device found. */ -} - - -/* Open the reader with the internal number READERNO and return a a - pointer to be used as handle in HANDLE. Returns 0 on success. */ -int -ccid_open_reader (ccid_driver_t *handle, int readerno) -{ - static int initialized; - - int rc; - usb_match_handle *match = NULL; - struct usb_device *dev = NULL; - usb_dev_handle *idev = NULL; - - *handle = NULL; - if (!initialized) - { - usb_init (); - initialized = 1; - } - - rc = usb_create_match (&match, -1, -1, 11, -1, -1); - if (rc) - { - DEBUGOUT_1 ("usb_create_match failed: %d\n", rc); - return -1; - } - - while (usb_find_device(match, dev, &dev) >= 0) - { - DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename, - dev->descriptor->idVendor, dev->descriptor->idProduct); - if (!readerno) - { - *handle = calloc (1, sizeof **handle); - if (!*handle) - { - DEBUGOUT ("out of memory\n"); - rc = -1; - free (*handle); - *handle = NULL; - goto leave; - } - - rc = read_device_info (*handle, dev); - if (rc) - { - DEBUGOUT ("device not supported\n"); - free (*handle); - *handle = NULL; - goto leave; - } - - rc = usb_open (dev, &idev); - if (rc) - { - DEBUGOUT_1 ("usb_open failed: %d\n", rc); - free (*handle); - *handle = NULL; - goto leave; - } - - - /* fixme: Do we need to claim and set the interface as - determined by read_device_info ()? */ - rc = usb_claim_interface (idev, 0); - if (rc) - { - DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); - free (*handle); - *handle = NULL; - goto leave; - } - - (*handle)->idev = idev; - idev = NULL; - /* FIXME: Do we need to get the endpoint addresses from the - structure and store them with the handle? */ - - break; - } - readerno--; - } - - - leave: - if (idev) - usb_close (idev); - /* fixme: Do we need to release dev or is it supposed to be a - shallow copy of the list created internally by usb_init ? */ - usb_free_match (match); - - if (!rc && !*handle) - rc = -1; /* In case we didn't enter the while loop at all. */ - - return rc; -} - - -/* Close the reader HANDLE. */ -int -ccid_close_reader (ccid_driver_t handle) -{ - if (!handle || !handle->idev) - return 0; - - { - int rc; - unsigned char msg[100]; - size_t msglen; - unsigned char seqno; - - msg[0] = PC_to_RDR_IccPowerOff; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - msglen = 10; - - rc = bulk_out (handle, msg, msglen); - if (!rc) - bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno); - } - - usb_release_interface (handle->idev, 0); - usb_close (handle->idev); - handle->idev = NULL; - free (handle); - return 0; -} - - -/* Return False if a card is present and powered. */ -int -ccid_check_card_presence (ccid_driver_t handle) -{ - - return -1; -} - - -/* Write a MSG of length MSGLEN to the designated bulk out endpoint. - Returns 0 on success. */ -static int -bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen) -{ - int rc; - - rc = usb_bulk_write (handle->idev, - 1, /*endpoint */ - msg, msglen, - 1000 /* ms timeout */); - if (rc == msglen) - return 0; - - if (rc == -1) - DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); - else - DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc); - return -1; -} - - -/* Read a maximum of LENGTH bytes from the bulk in endpoint into - BUFFER and return the actual read number if bytes in NREAD. SEQNO - is the sequence number used to send the request and EXPECTED_TYPE - the type of message we expect. Does checks on the ccid - header. Returns 0 on success. */ -static int -bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, - size_t *nread, int expected_type, int seqno) -{ - int i, rc; - size_t msglen; - - retry: - rc = usb_bulk_read (handle->idev, - 0x82, - buffer, length, - 10000 /* ms timeout */ ); - /* Fixme: instead of using a 10 second timeout we should better - handle the timeout here and retry if appropriate. */ - if (rc < 0) - { - DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno)); - return -1; - } - - *nread = msglen = rc; - - if (msglen < 10) - { - DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); - return -1; - } - if (buffer[0] != expected_type) - { - DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); - return -1; - } - if (buffer[5] != 0) - { - DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); - return -1; - } - if (buffer[6] != seqno) - { - DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n", - seqno, buffer[6]); - return -1; - } - - if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80) - { - /* Card present and active, time extension requested. */ - DEBUGOUT_2 ("time extension requested (%02X,%02X)\n", - buffer[7], buffer[8]); - goto retry; - } - - DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n" - " data:", buffer[7], buffer[8], buffer[9] ); - for (i=10; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", buffer[i]); - DEBUGOUT_LF (); - - return 0; -} - - -/* experimental */ -int -ccid_poll (ccid_driver_t handle) -{ - int rc; - unsigned char msg[10]; - size_t msglen; - int i, j; - - rc = usb_bulk_read (handle->idev, - 0x83, - msg, sizeof msg, - 0 /* ms timeout */ ); - if (rc < 0 && errno == ETIMEDOUT) - return 0; - - if (rc < 0) - { - DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno)); - return -1; - } - - msglen = rc; - rc = 0; - - if (msglen < 1) - { - DEBUGOUT ("intr-in msg too short\n"); - return -1; - } - - if (msg[0] == RDR_to_PC_NotifySlotChange) - { - DEBUGOUT ("notify slot change:"); - for (i=1; i < msglen; i++) - for (j=0; j < 4; j++) - DEBUGOUT_CONT_3 (" %d:%c%c", - (i-1)*4+j, - (msg[i] & (1<<(j*2)))? 'p':'-', - (msg[i] & (2<<(j*2)))? '*':' '); - DEBUGOUT_LF (); - } - else if (msg[0] == RDR_to_PC_HardwareError) - { - DEBUGOUT ("hardware error occured\n"); - } - else - { - DEBUGOUT_1 ("unknown intr-in msg of type %02X\n", msg[0]); - } - - return 0; -} - - - -int -ccid_slot_status (ccid_driver_t handle, int *statusbits) -{ - int rc; - unsigned char msg[100]; - size_t msglen; - unsigned char seqno; - - msg[0] = PC_to_RDR_GetSlotStatus; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* RFU */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - - rc = bulk_out (handle, msg, 10); - if (rc) - return rc; - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno); - if (rc) - return rc; - *statusbits = (msg[7] & 3); - - return 0; -} - - -int -ccid_get_atr (ccid_driver_t handle, - unsigned char *atr, size_t maxatrlen, size_t *atrlen) -{ - int rc; - unsigned char msg[100]; - unsigned char *tpdu; - size_t msglen, tpdulen; - unsigned char seqno; - int use_crc = 0; - unsigned int edc; - int i; - - msg[0] = PC_to_RDR_IccPowerOn; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; /* power select (0=auto, 1=5V, 2=3V, 3=1.8V) */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, 0); - msglen = 10; - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - if (atr) - { - size_t n = msglen - 10; - - if (n > maxatrlen) - n = maxatrlen; - memcpy (atr, msg+10, n); - *atrlen = n; - } - - /* Setup parameters to select T=1. */ - msg[0] = PC_to_RDR_SetParameters; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 1; /* Select T=1. */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - - /* FIXME: Get those values from the ATR. */ - msg[10]= 0x01; /* Fi/Di */ - msg[11]= 0x10; /* LRC, direct convention. */ - msg[12]= 0; /* Extra guardtime. */ - msg[13]= 0x41; /* BWI/CWI */ - msg[14]= 0; /* No clock stoppping. */ - msg[15]= 254; /* IFSC */ - msg[16]= 0; /* Does not support non default NAD values. */ - set_msg_len (msg, 7); - msglen = 10 + 7; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - /* Note that we ignore the error code on purpose. */ - bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, seqno); - - - /* Send an S-Block with our maximun IFSD to the CCID. */ - if (!handle->auto_ifsd) - { - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0xc0 | 0 | 1); /* S-block request: change IFSD */ - tpdu[2] = 1; - tpdu[3] = handle->max_ifsd? handle->max_ifsd : 32; - tpdulen = 4; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - - msg[0] = PC_to_RDR_XfrBlock; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 0; - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, tpdulen); - msglen = 10 + tpdulen; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: put %c-block seq=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40))); -#endif - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - - /* Fixme: The next line for the current Valgrid without support - for USB IOCTLs. */ - memset (msg, 0, sizeof msg); - - rc = bulk_in (handle, msg, sizeof msg, &msglen, - RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - tpdu = msg + 10; - tpdulen = msglen - 10; - - if (tpdulen < 4) - { - DEBUGOUT ("cannot yet handle short blocks!\n"); - return -1; - } - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)), - ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0 - ); -#endif - if ((tpdu[1] & 0xe0) != 0xe0 || tpdu[2] != 1) - { - DEBUGOUT ("invalid response for S-block (Change-IFSD)\n"); - return -1; - } - DEBUGOUT_1 ("IFSD has been set to %d\n", tpdu[3]); - } - - return 0; -} - - - - -static unsigned int -compute_edc (const unsigned char *data, size_t datalen, int use_crc) -{ - if (use_crc) - { - return 0x42; /* Not yet implemented. */ - } - else - { - unsigned char crc = 0; - - for (; datalen; datalen--) - crc ^= *data++; - return crc; - } -} - - -/* - Protocol T=1 overview - - Block Structure: - Prologue Field: - 1 byte Node Address (NAD) - 1 byte Protocol Control Byte (PCB) - 1 byte Length (LEN) - Information Field: - 0-254 byte APDU or Control Information (INF) - Epilogue Field: - 1 byte Error Detection Code (EDC) - - NAD: - bit 7 unused - bit 4..6 Destination Node Address (DAD) - bit 3 unused - bit 2..0 Source Node Address (SAD) - - If node adresses are not used, SAD and DAD should be set to 0 on - the first block sent to the card. If they are used they should - have different values (0 for one is okay); that first block sets up - the addresses of the nodes. - - PCB: - Information Block (I-Block): - bit 7 0 - bit 6 Sequence number (yep, that is modulo 2) - bit 5 Chaining flag - bit 4..0 reserved - Received-Ready Block (R-Block): - bit 7 1 - bit 6 0 - bit 5 0 - bit 4 Sequence number - bit 3..0 0 = no error - 1 = EDC or parity error - 2 = other error - other values are reserved - Supervisory Block (S-Block): - bit 7 1 - bit 6 1 - bit 5 clear=request,set=response - bit 4..0 0 = resyncronisation request - 1 = information field size request - 2 = abort request - 3 = extension of BWT request - 4 = VPP error - other values are reserved - -*/ - -int -ccid_transceive (ccid_driver_t handle, - const unsigned char *apdu_buf, size_t apdu_buflen, - unsigned char *resp, size_t maxresplen, size_t *nresp) -{ - int rc; - unsigned char send_buffer[10+259], recv_buffer[10+259]; - const unsigned char *apdu; - size_t apdulen; - unsigned char *msg, *tpdu, *p; - size_t msglen, tpdulen, last_tpdulen, n; - unsigned char seqno; - int i; - unsigned int edc; - int use_crc = 0; - size_t dummy_nresp; - int next_chunk = 1; - int sending = 1; - int retries = 0; - - if (!nresp) - nresp = &dummy_nresp; - *nresp = 0; - - tpdulen = 0; /* Avoid compiler warning about no initialization. */ - msg = send_buffer; - for (;;) - { - if (next_chunk) - { - next_chunk = 0; - - apdu = apdu_buf; - apdulen = apdu_buflen; - assert (apdulen); - - /* Construct an I-Block. */ - if (apdulen > 254) - return -1; /* Invalid length. */ - - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = ((handle->t1_ns & 1) << 6); /* I-block */ - if (apdulen > 128 /* fixme: replace by ifsc */) - { - apdulen = 128; - apdu_buf += 128; - apdu_buflen -= 128; - tpdu[1] |= (1 << 5); /* Set more bit. */ - } - tpdu[2] = apdulen; - memcpy (tpdu+3, apdu, apdulen); - tpdulen = 3 + apdulen; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - } - - msg[0] = PC_to_RDR_XfrBlock; - msg[5] = 0; /* slot */ - msg[6] = seqno = handle->seqno++; - msg[7] = 4; /* bBWI */ - msg[8] = 0; /* RFU */ - msg[9] = 0; /* RFU */ - set_msg_len (msg, tpdulen); - msglen = 10 + tpdulen; - last_tpdulen = tpdulen; - - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: put %c-block seq=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40))); -#endif - - rc = bulk_out (handle, msg, msglen); - if (rc) - return rc; - - /* Fixme: The next line for the current Valgrid without support - for USB IOCTLs. */ - memset (recv_buffer, 0, sizeof recv_buffer); - - msg = recv_buffer; - rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen, - RDR_to_PC_DataBlock, seqno); - if (rc) - return rc; - - tpdu = msg + 10; - tpdulen = msglen - 10; - - if (tpdulen < 4) - { - DEBUGOUT ("cannot yet handle short blocks!\n"); - return -1; - } - -#ifdef DEBUG_T1 - fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", - ((msg[11] & 0xc0) == 0x80)? 'R' : - (msg[11] & 0x80)? 'S' : 'I', - ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)), - ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0 - ); -#endif - - if (!(tpdu[1] & 0x80)) - { /* This is an I-block. */ - retries = 0; - if (sending) - { /* last block sent was successful. */ - handle->t1_ns ^= 1; - sending = 0; - } - - if (!!(tpdu[1] & 0x40) != handle->t1_nr) - { /* Reponse does not match our sequence number. */ - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4 | 2); /* R-block */ - tpdu[2] = 0; - tpdulen = 3; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - - continue; - } - - handle->t1_nr ^= 1; - - p = tpdu + 3; /* Skip the prologue field. */ - n = tpdulen - 3 - 1; /* Strip the epilogue field. */ - /* fixme: verify the checksum. */ - if (resp) - { - if (n > maxresplen) - { - DEBUGOUT_2 ("provided buffer too short for received data " - "(%u/%u)\n", - (unsigned int)n, (unsigned int)maxresplen); - return -1; - } - - memcpy (resp, p, n); - resp += n; - *nresp += n; - maxresplen -= n; - } - - if (!(tpdu[1] & 0x20)) - return 0; /* No chaining requested - ready. */ - - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4); /* R-block */ - tpdu[2] = 0; - tpdulen = 3; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - } - else if ((tpdu[1] & 0xc0) == 0x80) - { /* This is a R-block. */ - if ( (tpdu[1] & 0x0f)) - { /* Error: repeat last block */ - if (++retries > 3) - { - DEBUGOUT ("3 failed retries\n"); - return -1; - } - msg = send_buffer; - tpdulen = last_tpdulen; - } - else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns) - { /* Reponse does not match our sequence number. */ - DEBUGOUT ("R-block with wrong seqno received on more bit\n"); - return -1; - } - else if (sending) - { /* Send next chunk. */ - retries = 0; - msg = send_buffer; - next_chunk = 1; - handle->t1_ns ^= 1; - } - else - { - DEBUGOUT ("unexpected ACK R-block received\n"); - return -1; - } - } - else - { /* This is a S-block. */ - retries = 0; - DEBUGOUT_2 ("T1 S-block %s received cmd=%d\n", - (tpdu[1] & 0x20)? "response": "request", - (tpdu[1] & 0x1f)); - if ( !(tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 3 && tpdu[2]) - { /* Wait time extension request. */ - unsigned char bwi = tpdu[3]; - msg = send_buffer; - tpdu = msg+10; - /* NAD: DAD=1, SAD=0 */ - tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0; - tpdu[1] = (0xc0 | 0x20 | 3); /* S-block response */ - tpdu[2] = 1; - tpdu[3] = bwi; - tpdulen = 4; - edc = compute_edc (tpdu, tpdulen, use_crc); - if (use_crc) - tpdu[tpdulen++] = (edc >> 8); - tpdu[tpdulen++] = edc; - DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi); - } - else - return -1; - } - } /* end T=1 protocol loop. */ - - return 0; -} - - - - -#ifdef TEST -int -main (int argc, char **argv) -{ - int rc; - ccid_driver_t ccid; - unsigned int slotstat; - - rc = ccid_open_reader (&ccid, 0); - if (rc) - return 1; - - ccid_poll (ccid); - fputs ("getting ATR ...\n", stderr); - rc = ccid_get_atr (ccid, NULL, 0, NULL); - if (rc) - return 1; - - ccid_poll (ccid); - fputs ("getting slot status ...\n", stderr); - rc = ccid_slot_status (ccid, &slotstat); - if (rc) - return 1; - - ccid_poll (ccid); - - { - static unsigned char apdu[] = { - 0, 0xA4, 4, 0, 6, 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01}; - rc = ccid_transceive (ccid, - apdu, sizeof apdu, - NULL, 0, NULL); - } - ccid_poll (ccid); - - { - static unsigned char apdu[] = { - 0, 0xCA, 0, 0x65, 254 }; - rc = ccid_transceive (ccid, - apdu, sizeof apdu, - NULL, 0, NULL); - } - ccid_poll (ccid); - - - return 0; -} - -/* - * Local Variables: - * compile-command: "gcc -DTEST -Wall -I/usr/local/include -lusb -g ccid-driver.c" - * End: - */ -#endif /*TEST*/ -#endif /*HAVE_LIBUSB*/ diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h deleted file mode 100644 index 8b86eb1a5..000000000 --- a/scd/ccid-driver.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * ALTERNATIVELY, this file may be distributed under the terms of the - * following license, in which case the provisions of this license are - * required INSTEAD OF the GNU General Public License. If you wish to - * allow use of your version of this file only under the terms of the - * GNU General Public License, and not to allow others to use your - * version of this file under the terms of the following license, - * indicate your decision by deleting this paragraph and the license - * below. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CCID_DRIVER_H -#define CCID_DRIVER_H - - -struct ccid_driver_s; -typedef struct ccid_driver_s *ccid_driver_t; - -int ccid_open_reader (ccid_driver_t *handle, int readerno); -int ccid_close_reader (ccid_driver_t handle); -int ccid_get_atr (ccid_driver_t handle, - unsigned char *atr, size_t maxatrlen, size_t *atrlen); -int ccid_slot_status (ccid_driver_t handle, int *statusbits); -int ccid_transceive (ccid_driver_t handle, - const unsigned char *apdu, size_t apdulen, - unsigned char *resp, size_t maxresplen, size_t *nresp); - - - -#endif /*CCID_DRIVER_H*/ - - - diff --git a/scd/command.c b/scd/command.c deleted file mode 100644 index 6fa100ff9..000000000 --- a/scd/command.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* command.c - SCdaemon command handler - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <signal.h> - -#include <assuan.h> - -#include "scdaemon.h" -#include <ksba.h> -#include "app-common.h" -#include "apdu.h" /* Required for apdu_*_reader (). */ - -/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */ -#define MAXLEN_PIN 100 - - -/* We keep track of the primary client using scdaemon. This one will - for example receive signal on card change. */ -static ctrl_t primary_connection; - - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - -/* Data used to associate an Assuan context with local server data */ -struct server_local_s { - ASSUAN_CONTEXT assuan_ctx; - int event_signal; /* Or 0 if not used. */ -}; - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - -/* Reset the card and free the application context. With DO_CLOSE set - to true, close the reader and don't do just a reset. */ -static void -do_reset (ctrl_t ctrl, int do_close) -{ - if (ctrl->card_ctx) - { - card_close (ctrl->card_ctx); - ctrl->card_ctx = NULL; - xfree (ctrl->in_data.value); - ctrl->in_data.value = NULL; - } - if (ctrl->app_ctx) - { - release_application (ctrl->app_ctx); - ctrl->app_ctx = NULL; - } - if (ctrl->reader_slot != -1) - { - if (do_close || apdu_reset (ctrl->reader_slot)) - { - apdu_close_reader (ctrl->reader_slot); - ctrl->reader_slot = -1; - } - } -} - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - do_reset (ctrl, 0); -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - ctrl_t ctrl = assuan_get_pointer (ctx); - - if (!strcmp (key, "event-signal")) - { - /* A value of 0 is allowed to reset the event signal. */ - int i = *value? atoi (value) : -1; - if (i < 0) - return ASSUAN_Parameter_Error; - ctrl->server_local->event_signal = i; - } - - return 0; -} - - -/* If the card has not yet been opened, do it. Note that this - function returns an Assuan error, so don't map the error a second - time */ -static AssuanError -open_card (ctrl_t ctrl, const char *apptype) -{ - int slot; - - if (ctrl->app_ctx) - return 0; /* Already initialized for one specific application. */ - if (ctrl->card_ctx) - return 0; /* Already initialized using a card context. */ - - if (ctrl->reader_slot != -1) - slot = ctrl->reader_slot; - else - slot = apdu_open_reader (opt.reader_port); - ctrl->reader_slot = slot; - if (slot != -1) - ctrl->app_ctx = select_application (ctrl, slot, apptype); - if (!ctrl->app_ctx) - { /* No application found - fall back to old mode. */ - /* Note that we should rework the old code to use the - application paradigma too. */ - int rc; - - /* If an APPTYPE was requested and it is not pkcs#15, we return - an error here. */ - if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15"))) - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - else - rc = card_open (&ctrl->card_ctx); - if (rc) - return map_to_assuan_status (rc); - } - return 0; -} - - -/* Do the percent and plus/space unescaping in place and return the - length of the valid buffer. */ -static size_t -percent_plus_unescape (unsigned char *string) -{ - unsigned char *p = string; - size_t n = 0; - - while (*string) - { - if (*string == '%' && string[1] && string[2]) - { - string++; - *p++ = xtoi_2 (string); - n++; - string+= 2; - } - else if (*string == '+') - { - *p++ = ' '; - n++; - string++; - } - else - { - *p++ = *string++; - n++; - } - } - - return n; -} - - - -/* SERIALNO [APPTYPE] - - Return the serial number of the card using a status reponse. This - functon should be used to check for the presence of a card. - - If APPTYPE is given, an application of that type is selected and an - error is returned if the application is not supported or available. - The default is to auto-select the application using a hardwired - preference system. Note, that a future extension to this function - may allow to specify a list and order of applications to try. - - This function is special in that it can be used to reset the card. - Most other functions will return an error when a card change has - been detected and the use of this function is therefore required. - - Background: We want to keep the client clear of handling card - changes between operations; i.e. the client can assume that all - operations are done on the same card unless he calls this function. - */ -static int -cmd_serialno (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - char *serial_and_stamp; - char *serial; - time_t stamp; - - if ((rc = open_card (ctrl, *line? line:NULL))) - return rc; - - if (ctrl->app_ctx) - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - else - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - free (serial_and_stamp); - return 0; -} - - - - -/* LEARN [--force] - - Learn all useful information of the currently inserted card. When - used without the force options, the command might do an INQUIRE - like this: - - INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp> - - The client should just send an "END" if the processing should go on - or a "CANCEL" to force the function to terminate with a Cancel - error message. The response of this command is a list of status - lines formatted as this: - - S APPTYPE <apptype> - - This returns the type of the application, currently the strings: - - P15 = PKCS-15 structure used - DINSIG = DIN SIG - OPENPGP = OpenPGP card - - are implemented. These strings are aliases for the AID - - S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id> - - If there is no certificate yet stored on the card a single "X" is - returned as the keygrip. In addition to the keypair info, information - about all certificates stored on the card is also returned: - - S CERTINFO <certtype> <hexstring_with_id> - - Where CERTTYPE is a number indicating the type of certificate: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - 110 := Root CA cert (DINSIG) - - For certain cards, more information will be returned: - - S KEY-FPR <no> <hexstring> - - For OpenPGP cards this returns the stored fingerprints of the - keys. This can be used check whether a key is available on the - card. NO may be 1, 2 or 3. - - S CA-FPR <no> <hexstring> - - Similar to above, these are the fingerprints of keys assumed to be - ultimately trusted. - - S DISP-NAME <name_of_card_holder> - - The name of the card holder as stored on the card; percent - escaping takes place, spaces are encoded as '+' - - S PUBKEY-URL <url> - - The URL to be used for locating the entire public key. - -*/ -static int -cmd_learn (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - int idx; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* Unless the force option is used we try a shortcut by identifying - the card using a serial number and inquiring the client with - that. The client may choose to cancel the operation if he already - knows about this card */ - { - char *serial_and_stamp; - char *serial; - time_t stamp; - - if (ctrl->app_ctx) - rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); - else - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - - if (!has_option (line, "--force")) - { - char *command; - - rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp); - if (rc < 0) - { - free (serial_and_stamp); - return ASSUAN_Out_Of_Core; - } - rc = 0; - rc = assuan_inquire (ctx, command, NULL, NULL, 0); - free (command); /* (must use standard free here) */ - if (rc) - { - if (rc != ASSUAN_Canceled) - log_error ("inquire KNOWNCARDP failed: %s\n", - assuan_strerror (rc)); - free (serial_and_stamp); - return rc; - } - /* not canceled, so we have to proceeed */ - } - free (serial_and_stamp); - } - - /* If we are using the modern application paradigma, let the - application print out its collection of useful status - information. */ - if (!rc && ctrl->app_ctx) - rc = app_write_learn_status (ctrl->app_ctx, ctrl); - - /* Return information about the certificates. FIXME: Move this into - an app-p15.c*/ - for (idx=0; !rc && !ctrl->app_ctx; idx++) - { - char *certid; - int certtype; - - rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype); - if (!rc) - { - char *buf; - - buf = xtrymalloc (40 + 1 + strlen (certid) + 1); - if (!buf) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - sprintf (buf, "%d %s", certtype, certid); - assuan_write_status (ctx, "CERTINFO", buf); - xfree (buf); - } - } - xfree (certid); - } - if (rc == -1) - rc = 0; - - /* Return information about the keys. FIXME: Move this into an - app-p15.c */ - for (idx=0; !rc && !ctrl->app_ctx; idx++) - { - unsigned char keygrip[20]; - char *keyid; - int no_cert = 0; - - rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid); - if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid) - { - /* This does happen with an incomplete personalized - card; i.e. during the time we have stored the key on the - card but not stored the certificate; probably becuase it - has not yet been received back from the CA. Note that we - must release KEYID in this case. */ - rc = 0; - no_cert = 1; - } - if (!rc) - { - char *buf, *p; - - buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1); - if (!buf) - rc = gpg_error (gpg_err_code_from_errno (errno)); - else - { - int i; - - if (no_cert) - *p++ = 'X'; - else - { - for (i=0; i < 20; i++, p += 2) - sprintf (p, "%02X", keygrip[i]); - } - *p++ = ' '; - strcpy (p, keyid); - assuan_write_status (ctx, "KEYPAIRINFO", buf); - xfree (buf); - } - } - xfree (keyid); - } - if (rc == -1) - rc = 0; - - return map_to_assuan_status (rc); -} - - - -/* READCERT <hexified_certid> - - */ -static int -cmd_readcert (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert; - size_t ncert; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - line = xstrdup (line); /* Need a copy of the line. */ - if (ctrl->app_ctx) - { - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); - if (rc) - log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - log_error ("card_read_cert failed: %s\n", gpg_strerror (rc)); - } - xfree (line); - line = NULL; - if (!rc) - { - rc = assuan_send_data (ctx, cert, ncert); - xfree (cert); - if (rc) - return rc; - } - - return map_to_assuan_status (rc); -} - - -/* READKEY <hexified_certid> - - Return the public key for the given cert or key ID as an standard - S-Expression. */ -static int -cmd_readkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert = NULL; - size_t ncert, n; - ksba_cert_t kc = NULL; - ksba_sexp_t p; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - line = xstrdup (line); /* Need a copy of the line. */ - if (ctrl->app_ctx) - { - rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert); - if (rc) - log_error ("app_readcert failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - log_error ("card_read_cert failed: %s\n", gpg_strerror (rc)); - } - xfree (line); - line = NULL; - if (rc) - goto leave; - - rc = ksba_cert_new (&kc); - if (rc) - { - xfree (cert); - goto leave; - } - rc = ksba_cert_init_from_mem (kc, cert, ncert); - if (rc) - { - log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc)); - goto leave; - } - - p = ksba_cert_get_public_key (kc); - if (!p) - { - rc = gpg_error (GPG_ERR_NO_PUBKEY); - goto leave; - } - - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - rc = assuan_send_data (ctx, p, n); - rc = map_assuan_err (rc); - xfree (p); - - - leave: - ksba_cert_release (kc); - xfree (cert); - return map_to_assuan_status (rc); -} - - - - -/* SETDATA <hexstring> - - The client should use this command to tell us the data he want to - sign. */ -static int -cmd_setdata (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int n; - char *p; - unsigned char *buf; - - /* parse the hexstring */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if (!n) - return set_error (Parameter_Error, "no data given"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - buf = xtrymalloc (n); - if (!buf) - return ASSUAN_Out_Of_Core; - - ctrl->in_data.value = buf; - ctrl->in_data.valuelen = n; - for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); - return 0; -} - - - -static int -pin_cb (void *opaque, const char *info, char **retstr) -{ - ASSUAN_CONTEXT ctx = opaque; - char *command; - int rc; - unsigned char *value; - size_t valuelen; - - *retstr = NULL; - log_debug ("asking for PIN '%s'\n", info); - - rc = asprintf (&command, "NEEDPIN %s", info); - if (rc < 0) - return gpg_error (gpg_err_code_from_errno (errno)); - - /* FIXME: Write an inquire function which returns the result in - secure memory */ - rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); - free (command); - if (rc) - return map_assuan_err (rc); - - if (!valuelen || value[valuelen-1]) - { - /* We require that the returned value is an UTF-8 string */ - xfree (value); - return gpg_error (GPG_ERR_INV_RESPONSE); - } - *retstr = value; - return 0; -} - - -/* PKSIGN <hexified_id> - - */ -static int -cmd_pksign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - if (ctrl->app_ctx) - rc = app_sign (ctrl->app_ctx, - keyidstr, GCRY_MD_SHA1, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - else - rc = card_sign (ctrl->card_ctx, - keyidstr, GCRY_MD_SHA1, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("card_sign failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - -/* PKAUTH <hexified_id> - - */ -static int -cmd_pkauth (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - rc = app_auth (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - -/* PKDECRYPT <hexified_id> - - */ -static int -cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - if (ctrl->app_ctx) - rc = app_decipher (ctrl->app_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - else - rc = card_decipher (ctrl->card_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - xfree (keyidstr); - if (rc) - { - log_error ("card_create_signature failed: %s\n", gpg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - - -/* GETATTR <name> - - This command is used to retrieve data from a smartcard. The - allowed names depend on the currently selected smartcard - application. NAME must be percent and '+' escaped. The value is - returned through status message, see the LESRN command for details. - - However, the current implementation assumes that Name is not escaped; - this works as long as noone uses arbitrary escaping. - -*/ -static int -cmd_getattr (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyword; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - keyword = line; - for (; *line && !spacep (line); line++) - ; - if (*line) - *line++ = 0; - - /* (We ignore any garbage for now.) */ - - rc = app_getattr (ctrl->app_ctx, ctrl, keyword); - - return map_to_assuan_status (rc); -} - - -/* SETATTR <name> <value> - - This command is used to store data on a a smartcard. The allowed - names and values are depend on the currently selected smartcard - application. NAME and VALUE must be percent and '+' escaped. - - However, the curent implementation assumes that Name is not escaped; - this works as long as noone uses arbitrary escaping. - - A PIN will be requested for most NAMEs. See the corresponding - setattr function of the actually used application (app-*.c) for - details. */ -static int -cmd_setattr (ASSUAN_CONTEXT ctx, char *orig_line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyword; - int keywordlen; - size_t nbytes; - char *line, *linebuf; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - /* We need to use a copy of LINE, because PIN_CB uses the same - context and thus reuses the Assuan provided LINE. */ - line = linebuf = xtrystrdup (orig_line); - if (!line) - return ASSUAN_Out_Of_Core; - - keyword = line; - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - if (*line) - *line++ = 0; - while (spacep (line)) - line++; - nbytes = percent_plus_unescape (line); - - rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes); - xfree (linebuf); - - return map_to_assuan_status (rc); -} - -/* GENKEY [--force] <no> - - Generate a key on-card identified by NO, which is application - specific. Return values are application specific. For OpenPGP - cards 2 status lines are returned: - - S KEY-FPR <hexstring> - S KEY-CREATED-AT <seconds_since_epoch> - S KEY-DATA [p|n] <hexdata> - - - --force is required to overwriet an already existing key. The - KEY-CREATED-AT is required for further processing because it is - part of the hashed key material for the fingerprint. - - The public part of the key can also later be retrieved using the - READKEY command. - - */ -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyno; - int force = has_option (line, "--force"); - - /* Skip over options. */ - while ( *line == '-' && line[1] == '-' ) - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } - if (!*line) - return set_error (Parameter_Error, "no key number given"); - keyno = line; - while (*line && !spacep (line)) - line++; - *line = 0; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - keyno = xtrystrdup (keyno); - if (!keyno) - return ASSUAN_Out_Of_Core; - rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx); - xfree (keyno); - return map_to_assuan_status (rc); -} - - -/* RANDOM <nbytes> - - Get NBYTES of random from the card and send them back as data. -*/ -static int -cmd_random (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - size_t nbytes; - unsigned char *buffer; - - if (!*line) - return set_error (Parameter_Error, "number of requested bytes missing"); - nbytes = strtoul (line, NULL, 0); - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - buffer = xtrymalloc (nbytes); - if (!buffer) - return ASSUAN_Out_Of_Core; - - rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer); - if (!rc) - { - rc = assuan_send_data (ctx, buffer, nbytes); - xfree (buffer); - return rc; /* that is already an assuan error code */ - } - xfree (buffer); - - return map_to_assuan_status (rc); -} - - -/* PASSWD [--reset] <chvno> - - Change the PIN or reset thye retry counter of the card holder - verfication vector CHVNO. */ -static int -cmd_passwd (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *chvnostr; - int reset_mode = has_option (line, "--reset"); - - /* Skip over options. */ - while (*line == '-' && line[1] == '-') - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } - if (!*line) - return set_error (Parameter_Error, "no CHV number given"); - chvnostr = line; - while (*line && !spacep (line)) - line++; - *line = 0; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - chvnostr = xtrystrdup (chvnostr); - if (!chvnostr) - return ASSUAN_Out_Of_Core; - rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx); - if (rc) - log_error ("command passwd failed: %s\n", gpg_strerror (rc)); - xfree (chvnostr); - return map_to_assuan_status (rc); -} - - -/* CHECKPIN <hexified_id> - - */ -static int -cmd_checkpin (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *keyidstr; - - if ((rc = open_card (ctrl, NULL))) - return rc; - - if (!ctrl->app_ctx) - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid. */ - keyidstr = xtrystrdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - - rc = app_check_pin (ctrl->app_ctx, - keyidstr, - pin_cb, ctx); - xfree (keyidstr); - if (rc) - log_error ("app_check_pin failed: %s\n", gpg_strerror (rc)); - - return map_to_assuan_status (rc); -} - - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "SERIALNO", cmd_serialno }, - { "LEARN", cmd_learn }, - { "READCERT", cmd_readcert }, - { "READKEY", cmd_readkey }, - { "SETDATA", cmd_setdata }, - { "PKSIGN", cmd_pksign }, - { "PKAUTH", cmd_pkauth }, - { "PKDECRYPT", cmd_pkdecrypt }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, - { "GETATTR", cmd_getattr }, - { "SETATTR", cmd_setattr }, - { "GENKEY", cmd_genkey }, - { "RANDOM", cmd_random }, - { "PASSWD", cmd_passwd }, - { "CHECKPIN", cmd_checkpin }, - { NULL } - }; - int i, rc; - - for (i=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, table[i].name, table[i].handler); - if (rc) - return rc; - } - assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready"); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_option_handler (ctx, option_handler); - return 0; -} - - -/* Startup the server. If LISTEN_FD is given as -1, this is simple - piper server, otherwise it is a regular server */ -void -scd_command_handler (int listen_fd) -{ - int rc; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - - memset (&ctrl, 0, sizeof ctrl); - scd_init_default_ctrl (&ctrl); - - if (listen_fd == -1) - { - int filedes[2]; - - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - } - else - { - rc = assuan_init_socket_server (&ctx, listen_fd); - } - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to register commands with Assuan: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - /* Store the primary connection's assuan context. */ - if (!primary_connection) - primary_connection = &ctrl; - - /* We open the reader right at startup so that the ticker is able to - update the status file. */ - if (ctrl.reader_slot == -1) - ctrl.reader_slot = apdu_open_reader (opt.reader_port); - - /* Command processing loop. */ - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - /* The next client will be the primary conenction if this one - terminates. */ - if (primary_connection == &ctrl) - primary_connection = NULL; - - do_reset (&ctrl, 1); /* Cleanup. */ - - assuan_deinit_server (ctx); -} - - -/* Send a line with status information via assuan and escape all given - buffers. The variable elements are pairs of (char *, size_t), - terminated with a (NULL, 0). */ -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - va_list arg_ptr; - const unsigned char *value; - size_t valuelen; - char buf[950], *p; - size_t n; - ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx; - - va_start (arg_ptr, keyword); - - p = buf; - n = 0; - while ( (value = va_arg (arg_ptr, const unsigned char *)) ) - { - valuelen = va_arg (arg_ptr, size_t); - if (!valuelen) - continue; /* empty buffer */ - if (n) - { - *p++ = ' '; - n++; - } - for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++) - { - if (*value < ' ' || *value == '+') - { - sprintf (p, "%%%02X", *value); - p += 3; - } - else if (*value == ' ') - *p++ = '+'; - else - *p++ = *value; - } - } - *p = 0; - assuan_write_status (ctx, keyword, buf); - - va_end (arg_ptr); -} - - - -void -scd_update_reader_status_file (void) -{ - static struct { - int any; - unsigned int status; - unsigned int changed; - } last[10]; - int slot; - int used; - unsigned int status, changed; - - /* Note, that we only try to get the status, becuase it does not - make sense to wait here for a operation to complete. If we are - so busy working with the card, delays in the status file updated - are should be acceptable. */ - for (slot=0; (slot < DIM(last) - &&!apdu_enum_reader (slot, &used)); slot++) - if (used && !apdu_get_status (slot, 0, &status, &changed)) - { - if (!last[slot].any || last[slot].status != status - || last[slot].changed != changed ) - { - char *fname; - char templ[50]; - FILE *fp; - - last[slot].any = 1; - last[slot].status = status; - last[slot].changed = changed; - - log_info ("updating status of slot %d to 0x%04X\n", slot, status); - - sprintf (templ, "reader_%d.status", slot); - fname = make_filename (opt.homedir, templ, NULL ); - fp = fopen (fname, "w"); - if (fp) - { - fprintf (fp, "%s\n", - (status & 1)? "USABLE": - (status & 4)? "ACTIVE": - (status & 2)? "PRESENT": "NOCARD"); - fclose (fp); - } - xfree (fname); - - /* Send a signal to the primary client, if any. */ - if (primary_connection && primary_connection->server_local - && primary_connection->server_local->assuan_ctx) - { - pid_t pid = assuan_get_pid (primary_connection - ->server_local->assuan_ctx); - int signo = primary_connection->server_local->event_signal; - - log_info ("client pid is %d, sending signal %d\n", pid, signo); - if (pid != (pid_t)(-1) && pid && signo > 0) - kill (pid, signo); - } - } - } -} diff --git a/scd/iso7816.c b/scd/iso7816.c deleted file mode 100644 index fd3f0485c..000000000 --- a/scd/iso7816.c +++ /dev/null @@ -1,617 +0,0 @@ -/* iso7816.c - ISO 7816 commands - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if defined(GNUPG_SCD_MAIN_HEADER) -#include GNUPG_SCD_MAIN_HEADER -#elif GNUPG_MAJOR_VERSION == 1 -/* This is used with GnuPG version < 1.9. The code has been source - copied from the current GnuPG >= 1.9 and is maintained over - there. */ -#include "options.h" -#include "errors.h" -#include "memory.h" -#include "util.h" -#include "i18n.h" -#else /* GNUPG_MAJOR_VERSION != 1 */ -#include "scdaemon.h" -#endif /* GNUPG_MAJOR_VERSION != 1 */ - -#include "iso7816.h" -#include "apdu.h" - - -#define CMD_SELECT_FILE 0xA4 -#define CMD_VERIFY 0x20 -#define CMD_CHANGE_REFERENCE_DATA 0x24 -#define CMD_RESET_RETRY_COUNTER 0x2C -#define CMD_GET_DATA 0xCA -#define CMD_PUT_DATA 0xDA -#define CMD_MSE 0x22 -#define CMD_PSO 0x2A -#define CMD_INTERNAL_AUTHENTICATE 0x88 -#define CMD_GENERATE_KEYPAIR 0x47 -#define CMD_GET_CHALLENGE 0x84 -#define CMD_READ_BINARY 0xB0 -#define CMD_READ_RECORD 0xB2 - -static gpg_error_t -map_sw (int sw) -{ - gpg_err_code_t ec; - - switch (sw) - { - case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break; - case SW_WRONG_LENGTH: ec = GPG_ERR_INV_VALUE; break; - case SW_CHV_WRONG: ec = GPG_ERR_BAD_PIN; break; - case SW_CHV_BLOCKED: ec = GPG_ERR_PIN_BLOCKED; break; - case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break; - case SW_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; - case SW_BAD_PARAMETER: ec = GPG_ERR_INV_VALUE; break; - case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break; - case SW_RECORD_NOT_FOUND:ec= GPG_ERR_NOT_FOUND; break; - case SW_REF_NOT_FOUND: ec = GPG_ERR_NO_OBJ; break; - case SW_BAD_P0_P1: ec = GPG_ERR_INV_VALUE; break; - case SW_INS_NOT_SUP: ec = GPG_ERR_CARD; break; - case SW_CLA_NOT_SUP: ec = GPG_ERR_CARD; break; - case SW_SUCCESS: ec = 0; break; - - case SW_HOST_OUT_OF_CORE: ec = GPG_ERR_ENOMEM; break; - case SW_HOST_INV_VALUE: ec = GPG_ERR_INV_VALUE; break; - case SW_HOST_INCOMPLETE_CARD_RESPONSE: ec = GPG_ERR_CARD; break; - case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; - case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break; - case SW_HOST_BUSY: ec = GPG_ERR_EBUSY; break; - default: - if ((sw & 0x010000)) - ec = GPG_ERR_GENERAL; /* Should not happen. */ - else if ((sw & 0xff00) == SW_MORE_DATA) - ec = 0; /* This should actually never been seen here. */ - else - ec = GPG_ERR_CARD; - } - return gpg_error (ec); -} - -/* This function is specialized version of the SELECT FILE command. - SLOT is the card and reader as created for example by - apdu_open_reader (), AID is a buffer of size AIDLEN holding the - requested application ID. The function can't be used to enumerate - AIDs and won't return the AID on success. The return value is 0 - for okay or a GPG error code. Note that ISO error codes are - internally mapped. */ -gpg_error_t -iso7816_select_application (int slot, const char *aid, size_t aidlen) -{ - static char const openpgp_aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 }; - int sw; - int p1 = 0x0C; /* No FCI to be returned. */ - - if (aidlen == sizeof openpgp_aid - && !memcmp (aid, openpgp_aid, sizeof openpgp_aid)) - p1 = 0; /* The current openpgp cards don't allow 0x0c. */ - - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, p1, aidlen, aid); - return map_sw (sw); -} - - -gpg_error_t -iso7816_select_file (int slot, int tag, int is_dir, - unsigned char **result, size_t *resultlen) -{ - int sw, p0, p1; - unsigned char tagbuf[2]; - - tagbuf[0] = (tag >> 8) & 0xff; - tagbuf[1] = tag & 0xff; - - if (result || resultlen) - { - *result = NULL; - *resultlen = 0; - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - } - else - { - p0 = (tag == 0x3F00)? 0: is_dir? 1:2; - p1 = 0x0c; /* No FC return. */ - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, - p0, p1, 2, tagbuf ); - return map_sw (sw); - } - - return 0; -} - - -/* This is a private command currently only working for TCOS cards. */ -gpg_error_t -iso7816_list_directory (int slot, int list_dirs, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - } - return map_sw (sw); -} - - - -/* Perform a VERIFY command on SLOT using the card holder verification - vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */ -gpg_error_t -iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) -{ - int sw; - - sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); - return map_sw (sw); -} - -/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder - verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN - 0), a "change reference data" is done, otherwise an "exchange - reference data". The new reference data is expected in NEWCHV of - length NEWCHVLEN. */ -gpg_error_t -iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen) -{ - int sw; - char *buf; - - if ((!oldchv && oldchvlen) - || (oldchv && !oldchvlen) - || !newchv || !newchvlen ) - return gpg_error (GPG_ERR_INV_VALUE); - - buf = xtrymalloc (oldchvlen + newchvlen); - if (!buf) - return gpg_error (gpg_err_code_from_errno (errno)); - if (oldchvlen) - memcpy (buf, oldchv, oldchvlen); - memcpy (buf+oldchvlen, newchv, newchvlen); - - sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); - xfree (buf); - return map_sw (sw); - -} - -gpg_error_t -iso7816_reset_retry_counter (int slot, int chvno, - const char *newchv, size_t newchvlen) -{ - int sw; - - if (!newchv || !newchvlen ) - return gpg_error (GPG_ERR_INV_VALUE); - - sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER, - 2, chvno, newchvlen, newchv); - return map_sw (sw); -} - - -/* Perform a GET DATA command requesting TAG and storing the result in - a newly allocated buffer at the address passed by RESULT. Return - the length of this data at the address of RESULTLEN. */ -gpg_error_t -iso7816_get_data (int slot, int tag, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_GET_DATA, - ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -/* Perform a PUT DATA command on card in SLOT. Write DATA of length - DATALEN to TAG. */ -gpg_error_t -iso7816_put_data (int slot, int tag, - const unsigned char *data, size_t datalen) -{ - int sw; - - sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA, - ((tag >> 8) & 0xff), (tag & 0xff), - datalen, data); - return map_sw (sw); -} - -/* Manage Security Environment. This is a weird operation and there - is no easy abstraction for it. Furthermore, some card seem to have - a different interpreation of 7816-8 and thus we resort to let the - caller decide what to do. */ -gpg_error_t -iso7816_manage_security_env (int slot, int p1, int p2, - const unsigned char *data, size_t datalen) -{ - int sw; - - if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 || !data || !datalen) - return gpg_error (GPG_ERR_INV_VALUE); - - sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, datalen, data); - return map_sw (sw); -} - - -/* Perform the security operation COMPUTE DIGITAL SIGANTURE. On - success 0 is returned and the data is availavle in a newly - allocated buffer stored at RESULT with its length stored at - RESULTLEN. */ -gpg_error_t -iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, data, - result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -/* Perform the security operation DECIPHER. PADIND is the padding - indicator to be used. It should be 0 if no padding is required, a - value of -1 suppresses the padding byte. On success 0 is returned - and the plaintext is available in a newly allocated buffer stored - at RESULT with its length stored at RESULTLEN. */ -gpg_error_t -iso7816_decipher (int slot, const unsigned char *data, size_t datalen, - int padind, unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buf; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - if (padind >= 0) - { - /* We need to prepend the padding indicator. */ - buf = xtrymalloc (datalen + 1); - if (!buf) - return gpg_error (gpg_err_code_from_errno (errno)); - - *buf = padind; /* Padding indicator. */ - memcpy (buf+1, data, datalen); - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf, - result, resultlen); - xfree (buf); - } - else - { - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen, data, - result, resultlen); - } - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -gpg_error_t -iso7816_internal_authenticate (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, - datalen, data, result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -static gpg_error_t -do_generate_keypair (int slot, int readonly, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - int sw; - - if (!data || !datalen || !result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, - datalen, data, result, resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - - return 0; -} - - -gpg_error_t -iso7816_generate_keypair (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - return do_generate_keypair (slot, 0, data, datalen, result, resultlen); -} - - -gpg_error_t -iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen) -{ - return do_generate_keypair (slot, 1, data, datalen, result, resultlen); -} - - - -gpg_error_t -iso7816_get_challenge (int slot, int length, unsigned char *buffer) -{ - int sw; - unsigned char *result; - size_t resultlen, n; - - if (!buffer || length < 1) - return gpg_error (GPG_ERR_INV_VALUE); - - do - { - result = NULL; - n = length > 254? 254 : length; - sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL, - n, - &result, &resultlen); - if (sw != SW_SUCCESS) - { - /* Make sure that pending buffers are released. */ - xfree (result); - return map_sw (sw); - } - if (resultlen > n) - resultlen = n; - memcpy (buffer, result, resultlen); - buffer += resultlen; - length -= resultlen; - xfree (result); - } - while (length > 0); - - return 0; -} - -/* Perform a READ BINARY command requesting a maximum of NMAX bytes - from OFFSET. With NMAX = 0 the entire file is read. The result is - stored in a newly allocated buffer at the address passed by RESULT. - Returns the length of this data at the address of RESULTLEN. */ -gpg_error_t -iso7816_read_binary (int slot, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buffer; - size_t bufferlen; - int read_all = !nmax; - size_t n; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus - we check for this limit. */ - if (offset > 32767) - return gpg_error (GPG_ERR_INV_VALUE); - - do - { - buffer = NULL; - bufferlen = 0; - /* Fixme: Either the ccid driver or the TCOS cards have problems - with an Le of 0. */ - if (read_all || nmax > 254) - n = 254; - else - n = nmax; - sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY, - ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL, - n, &buffer, &bufferlen); - - if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) - { - /* Make sure that pending buffers are released. */ - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - if (*result) /* Need to extend the buffer. */ - { - unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen); - if (!p) - { - gpg_error_t err = gpg_error_from_errno (errno); - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return err; - } - *result = p; - memcpy (*result + *resultlen, buffer, bufferlen); - *resultlen += bufferlen; - xfree (buffer); - buffer = NULL; - } - else /* Transfer the buffer into our result. */ - { - *result = buffer; - *resultlen = bufferlen; - } - offset += bufferlen; - if (offset > 32767) - break; /* We simply truncate the result for too large - files. */ - if (nmax > bufferlen) - nmax -= bufferlen; - else - nmax = 0; - } - while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax)); - - return 0; -} - -/* Perform a READ RECORD command. RECNO gives the record number to - read with 0 indicating the current record. RECCOUNT must be 1 (not - all cards support reading of more than one record). SHORT_EF - should be 0 to read the current EF or contain a short EF. The - result is stored in a newly allocated buffer at the address passed - by RESULT. Returns the length of this data at the address of - RESULTLEN. */ -gpg_error_t -iso7816_read_record (int slot, int recno, int reccount, int short_ef, - unsigned char **result, size_t *resultlen) -{ - int sw; - unsigned char *buffer; - size_t bufferlen; - - if (!result || !resultlen) - return gpg_error (GPG_ERR_INV_VALUE); - *result = NULL; - *resultlen = 0; - - /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus - we check for this limit. */ - if (recno < 0 || recno > 255 || reccount != 1 - || short_ef < 0 || short_ef > 254 ) - return gpg_error (GPG_ERR_INV_VALUE); - - buffer = NULL; - bufferlen = 0; - /* Fixme: Either the ccid driver of the TCOS cards have problems - with an Le of 0. */ - sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD, - recno, - short_ef? short_ef : 0x04, - -1, NULL, - 254, &buffer, &bufferlen); - - if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) - { - /* Make sure that pending buffers are released. */ - xfree (buffer); - xfree (*result); - *result = NULL; - *resultlen = 0; - return map_sw (sw); - } - *result = buffer; - *resultlen = bufferlen; - - return 0; -} - diff --git a/scd/iso7816.h b/scd/iso7816.h deleted file mode 100644 index 8f2b150e6..000000000 --- a/scd/iso7816.h +++ /dev/null @@ -1,73 +0,0 @@ -/* iso7816.h - ISO 7816 commands - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef ISO7816_H -#define ISO7816_H - -#if GNUPG_MAJOR_VERSION == 1 -#include "cardglue.h" -#endif - -gpg_error_t iso7816_select_application (int slot, - const char *aid, size_t aidlen); -gpg_error_t iso7816_select_file (int slot, int tag, int is_dir, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_list_directory (int slot, int list_dirs, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_verify (int slot, - int chvno, const char *chv, size_t chvlen); -gpg_error_t iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen); -gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, - const char *newchv, size_t newchvlen); -gpg_error_t iso7816_get_data (int slot, int tag, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_put_data (int slot, int tag, - const unsigned char *data, size_t datalen); -gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2, - const unsigned char *data, - size_t datalen); -gpg_error_t iso7816_compute_ds (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_decipher (int slot, - const unsigned char *data, size_t datalen, - int padind, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_internal_authenticate (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_generate_keypair (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_read_public_key (int slot, - const unsigned char *data, size_t datalen, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_get_challenge (int slot, - int length, unsigned char *buffer); - -gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax, - unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_read_record (int slot, int recno, int reccount, - int short_ef, - unsigned char **result, size_t *resultlen); - -#endif /*ISO7816_H*/ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c deleted file mode 100644 index 4f47ee95c..000000000 --- a/scd/pcsc-wrapper.c +++ /dev/null @@ -1,631 +0,0 @@ -/* pcsc-wrapper.c - Wrapper for ccessing the PC/SC service - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* - This wrapper is required to handle problems with the libpscslite - library. That library assumes that pthreads are used and fails - badly if one tries to use it with a procerss using Pth. - - The operation model is pretty simple: It reads requests from stdin - and returns the answer on stdout. There is no direct mapping to the - pcsc interface but to a higher level one which resembles the code - used in scdaemon (apdu.c) when not using Pth or while running under - Windows. - - The interface is binary consisting of a command tag and the length - of the parameter list. The calling process needs to pass the - version number of the interface on the command line to make sure - that both agree on the same interface. For each port a separate - instance of this process needs to be started. - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <dlfcn.h> - - -#define PGM "pcsc-wrapper" - -/* Allow for a standalone build. */ -#ifdef VERSION -#define MYVERSION_LINE PGM " (GnuPG) " VERSION -#define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n" -#else -#define MYVERSION_LINE PGM -#define BUGREPORT_LINE "" -#endif - -#define DEFAULT_PCSC_DRIVER "libpcsclite.so" - - -static int verbose; - - -/* PC/SC constants and function pointer. */ -#define PCSC_SCOPE_USER 0 -#define PCSC_SCOPE_TERMINAL 1 -#define PCSC_SCOPE_SYSTEM 2 -#define PCSC_SCOPE_GLOBAL 3 - -#define PCSC_PROTOCOL_T0 1 -#define PCSC_PROTOCOL_T1 2 -#define PCSC_PROTOCOL_RAW 4 - -#define PCSC_SHARE_EXCLUSIVE 1 -#define PCSC_SHARE_SHARED 2 -#define PCSC_SHARE_DIRECT 3 - -#define PCSC_LEAVE_CARD 0 -#define PCSC_RESET_CARD 1 -#define PCSC_UNPOWER_CARD 2 -#define PCSC_EJECT_CARD 3 - -struct pcsc_io_request_s { - unsigned long protocol; - unsigned long pci_len; -}; - -typedef struct pcsc_io_request_s *pcsc_io_request_t; - - -static int driver_is_open; /* True if the PC/SC driver has been - initialzied and is ready for - operations. The follwoing variables - are then valid. */ -static unsigned long pcsc_context; /* The current PC/CS context. */ -static unsigned long pcsc_card; -static unsigned long pcsc_protocol; -static unsigned char current_atr[33]; -static size_t current_atrlen; - -long (* pcsc_establish_context) (unsigned long scope, - const void *reserved1, - const void *reserved2, - unsigned long *r_context); -long (* pcsc_release_context) (unsigned long context); -long (* pcsc_list_readers) (unsigned long context, - const char *groups, - char *readers, unsigned long*readerslen); -long (* pcsc_connect) (unsigned long context, - const char *reader, - unsigned long share_mode, - unsigned long preferred_protocols, - unsigned long *r_card, - unsigned long *r_active_protocol); -long (* pcsc_disconnect) (unsigned long card, - unsigned long disposition); -long (* pcsc_status) (unsigned long card, - char *reader, unsigned long *readerlen, - unsigned long *r_state, - unsigned long *r_protocol, - unsigned char *atr, unsigned long *atrlen); -long (* pcsc_begin_transaction) (unsigned long card); -long (* pcsc_end_transaction) (unsigned long card); -long (* pcsc_transmit) (unsigned long card, - const pcsc_io_request_t send_pci, - const unsigned char *send_buffer, - unsigned long send_len, - pcsc_io_request_t recv_pci, - unsigned char *recv_buffer, - unsigned long *recv_len); -long (* pcsc_set_timeout) (unsigned long context, - unsigned long timeout); - - - -static void -bad_request (const char *type) -{ - fprintf (stderr, PGM ": bad `%s' request\n", type); - exit (1); -} - -static void -request_failed (int err) -{ - if (!err) - err = -1; - - putchar (0x81); /* Simple error/success response. */ - - putchar (0); - putchar (0); - putchar (0); - putchar (4); - - putchar ((err >> 24) & 0xff); - putchar ((err >> 16) & 0xff); - putchar ((err >> 8) & 0xff); - putchar ((err ) & 0xff); - - fflush (stdout); -} - - -static void -request_succeeded (const void *buffer, size_t buflen) -{ - size_t len; - - putchar (0x81); /* Simple error/success response. */ - - len = 4 + buflen; - putchar ((len >> 24) & 0xff); - putchar ((len >> 16) & 0xff); - putchar ((len >> 8) & 0xff); - putchar ((len ) & 0xff); - - /* Error code. */ - putchar (0); - putchar (0); - putchar (0); - putchar (0); - - /* Optional reponse string. */ - if (buffer) - fwrite (buffer, buflen, 1, stdout); - - fflush (stdout); -} - - - -static unsigned long -read_32 (FILE *fp) -{ - int c1, c2, c3, c4; - - c1 = getc (stdin); - c2 = getc (stdin); - c3 = getc (stdin); - c4 = getc (stdin); - if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF) - { - fprintf (stderr, PGM ": premature EOF while parsing request\n"); - exit (1); - } - return (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; -} - - - -static const char * -pcsc_error_string (long err) -{ - const char *s; - - if (!err) - return "okay"; - if ((err & 0x80100000) != 0x80100000) - return "invalid PC/SC error code"; - err &= 0xffff; - switch (err) - { - case 0x0002: s = "cancelled"; break; - case 0x000e: s = "can't dispose"; break; - case 0x0008: s = "insufficient buffer"; break; - case 0x0015: s = "invalid ATR"; break; - case 0x0003: s = "invalid handle"; break; - case 0x0004: s = "invalid parameter"; break; - case 0x0005: s = "invalid target"; break; - case 0x0011: s = "invalid value"; break; - case 0x0006: s = "no memory"; break; - case 0x0013: s = "comm error"; break; - case 0x0001: s = "internal error"; break; - case 0x0014: s = "unknown error"; break; - case 0x0007: s = "waited too long"; break; - case 0x0009: s = "unknown reader"; break; - case 0x000a: s = "timeout"; break; - case 0x000b: s = "sharing violation"; break; - case 0x000c: s = "no smartcard"; break; - case 0x000d: s = "unknown card"; break; - case 0x000f: s = "proto mismatch"; break; - case 0x0010: s = "not ready"; break; - case 0x0012: s = "system cancelled"; break; - case 0x0016: s = "not transacted"; break; - case 0x0017: s = "reader unavailable"; break; - case 0x0065: s = "unsupported card"; break; - case 0x0066: s = "unresponsive card"; break; - case 0x0067: s = "unpowered card"; break; - case 0x0068: s = "reset card"; break; - case 0x0069: s = "removed card"; break; - case 0x006a: s = "inserted card"; break; - case 0x001f: s = "unsupported feature"; break; - case 0x0019: s = "PCI too small"; break; - case 0x001a: s = "reader unsupported"; break; - case 0x001b: s = "duplicate reader"; break; - case 0x001c: s = "card unsupported"; break; - case 0x001d: s = "no service"; break; - case 0x001e: s = "service stopped"; break; - default: s = "unknown PC/SC error code"; break; - } - return s; -} - -static void -load_pcsc_driver (const char *libname) -{ - void *handle; - - handle = dlopen (libname, RTLD_LAZY); - if (!handle) - { - fprintf (stderr, PGM ": failed to open driver `%s': %s", - libname, dlerror ()); - exit (1); - } - - pcsc_establish_context = dlsym (handle, "SCardEstablishContext"); - pcsc_release_context = dlsym (handle, "SCardReleaseContext"); - pcsc_list_readers = dlsym (handle, "SCardListReaders"); - pcsc_connect = dlsym (handle, "SCardConnect"); - pcsc_disconnect = dlsym (handle, "SCardDisconnect"); - pcsc_status = dlsym (handle, "SCardStatus"); - pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction"); - pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); - pcsc_transmit = dlsym (handle, "SCardTransmit"); - pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); - - if (!pcsc_establish_context - || !pcsc_release_context - || !pcsc_list_readers - || !pcsc_connect - || !pcsc_disconnect - || !pcsc_status - || !pcsc_begin_transaction - || !pcsc_end_transaction - || !pcsc_transmit - /* || !pcsc_set_timeout */) - { - /* Note that set_timeout is currently not used and also not - available under Windows. */ - fprintf (stderr, - "apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d)\n", - !!pcsc_establish_context, - !!pcsc_release_context, - !!pcsc_list_readers, - !!pcsc_connect, - !!pcsc_disconnect, - !!pcsc_status, - !!pcsc_begin_transaction, - !!pcsc_end_transaction, - !!pcsc_transmit, - !!pcsc_set_timeout ); - dlclose (handle); - exit (1); - } -} - - - - -/* Handle a open request. The argument is expected to be a string - with the port indentification. ARGBUF is always guaranteed to be - terminted by a 0 which is not counted in ARGLEN. We may modifiy - ARGBUF. */ -static void -handle_open (unsigned char *argbuf, size_t arglen) -{ - long err; - const char * portstr; - char *list = NULL; - unsigned long nreader, listlen, atrlen; - char *p; - unsigned long card_state, card_protocol; - unsigned char atr[33]; - - /* Make sure there is only the port string */ - if (arglen != strlen (argbuf)) - bad_request ("OPEN"); - portstr = argbuf; - - if (driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has already been opened\n"); - request_failed (-1); - } - - err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &pcsc_context); - if (err) - { - fprintf (stderr, PGM": pcsc_establish_context failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - request_failed (err); - return; - } - - err = pcsc_list_readers (pcsc_context, NULL, NULL, &nreader); - if (!err) - { - list = malloc (nreader+1); /* Better add 1 for safety reasons. */ - if (!list) - { - fprintf (stderr, PGM": error allocating memory for reader list\n"); - exit (1); - } - err = pcsc_list_readers (pcsc_context, NULL, list, &nreader); - } - if (err) - { - fprintf (stderr, PGM": pcsc_list_readers failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - free (list); - request_failed (err); - return; - } - - listlen = nreader; - p = list; - while (nreader) - { - if (!*p && !p[1]) - break; - fprintf (stderr, PGM": detected reader `%s'\n", p); - if (nreader < (strlen (p)+1)) - { - fprintf (stderr, PGM": invalid response from pcsc_list_readers\n"); - break; - } - nreader -= strlen (p)+1; - p += strlen (p) + 1; - } - - err = pcsc_connect (pcsc_context, - portstr && *portstr? portstr : list, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &pcsc_card, - &pcsc_protocol); - if (err) - { - fprintf (stderr, PGM": pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - free (list); - request_failed (err); - return; - } - - atrlen = 32; - /* (We need to pass a dummy buffer. We use LIST because it ought to - be large enough.) */ - err = pcsc_status (pcsc_card, - list, &listlen, - &card_state, &card_protocol, - atr, &atrlen); - free (list); - if (err) - { - fprintf (stderr, PGM": pcsc_status failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (pcsc_context); - request_failed (err); - return; - } - if (atrlen >= sizeof atr || atrlen >= sizeof current_atr) - { - fprintf (stderr, PGM": ATR returned by pcsc_status is too large\n"); - exit (4); - } - memcpy (current_atr, atr, atrlen); - current_atrlen = atrlen; - driver_is_open = 1; - request_succeeded (current_atr, current_atrlen); -} - - - -/* Handle a close request. We expect no arguments. We may modifiy - ARGBUF. */ -static void -handle_close (unsigned char *argbuf, size_t arglen) -{ - if (!driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has not yet been opened\n"); - request_failed (-1); - } - - pcsc_release_context (pcsc_context); - - request_succeeded (NULL, 0); -} - - - -/* Handle a transmit request. The argument is expected to be a bufer - with the APDU. We may modifiy ARGBUF. */ -static void -handle_transmit (unsigned char *argbuf, size_t arglen) -{ - long err; - struct pcsc_io_request_s send_pci; - unsigned long recv_len; - unsigned char buffer[1024]; - - /* The apdu should at least be one byte. */ - if (!arglen) - bad_request ("TRANSMIT"); - - if (!driver_is_open) - { - fprintf (stderr, PGM ": PC/SC has not yet been opened\n"); - request_failed (-1); - } - - if ((pcsc_protocol & PCSC_PROTOCOL_T1)) - send_pci.protocol = PCSC_PROTOCOL_T1; - else - send_pci.protocol = PCSC_PROTOCOL_T0; - send_pci.pci_len = sizeof send_pci; - recv_len = sizeof (buffer); - err = pcsc_transmit (pcsc_card, &send_pci, argbuf, arglen, - NULL, buffer, &recv_len); - if (err) - { - if (verbose) - fprintf (stderr, PGM": pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - request_failed (err); - return; - } - request_succeeded (buffer, recv_len); -} - - - - - - - - - - - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2004 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] API-NUMBER [LIBNAME]\n" - "Helper to connect scdaemon to the PC/SC library\n" - "\n" - " --verbose enable extra informational output\n" - " --version print version of the program and exit\n" - " --help display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - - -int -main (int argc, char **argv) -{ - int last_argc = -1; - int api_number = 0; - int c; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - } - if (argc != 1 && argc != 2) - { - fprintf (stderr, "usage: " PGM " API-NUMBER [LIBNAME]\n"); - exit (1); - } - - api_number = atoi (*argv); - argv++; argc--; - if (api_number != 1) - { - fprintf (stderr, PGM ": api-number %d is not valid\n", api_number); - exit (1); - } - - load_pcsc_driver (argc? *argv : DEFAULT_PCSC_DRIVER); - - while ((c = getc (stdin)) != EOF) - { - size_t arglen; - unsigned char argbuffer[2048]; - - arglen = read_32 (stdin); - if (arglen >= sizeof argbuffer - 1) - { - fprintf (stderr, PGM ": request too long\n"); - exit (1); - } - if (arglen && fread (argbuffer, arglen, 1, stdin) != 1) - { - fprintf (stderr, PGM ": error reading request: %s\n", - strerror (errno)); - exit (1); - } - argbuffer[arglen] = 0; - switch (c) - { - case 1: - handle_open (argbuffer, arglen); - break; - - case 2: - handle_close (argbuffer, arglen); - exit (0); - break; - - case 3: - handle_transmit (argbuffer, arglen); - break; - - default: - fprintf (stderr, PGM ": invalid request 0x%02X\n", c); - exit (1); - } - free (argbuffer); - } - return 0; -} - - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o pcsc-wrapper pcsc-wrapper.c -ldl" -End: -*/ diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c deleted file mode 100644 index 78cb2acc8..000000000 --- a/scd/sc-copykeys.c +++ /dev/null @@ -1,735 +0,0 @@ -/* sc-copykeys.c - A tool to store keys on a smartcard. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <gcrypt.h> - -#include "../common/ttyio.h" -#include "../common/simple-pwquery.h" -#include "apdu.h" /* for open_reader */ -#include "atr.h" -#include "app-common.h" - -#define _(a) (a) - - -enum cmd_and_opt_values -{ oVerbose = 'v', - oReaderPort = 500, - octapiDriver, - oDebug, - oDebugAll, - -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, "@Options:\n " }, - - { oVerbose, "verbose", 0, "verbose" }, - { oReaderPort, "reader-port", 2, "|N|connect to reader at port N"}, - { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"}, - { oDebug, "debug" ,4|16, "set debugging flags"}, - { oDebugAll, "debug-all" ,0, "enable full debugging"}, - {0} -}; - - -static void copykeys (APP app, const char *fname); - - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "sc-copykeys (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: sc-copykeys [options] (-h for help)\n"); - break; - case 41: p = _("Syntax: sc-copykeys [options] " - "file-with-key\n" - "Copy keys to a smartcards\n"); - break; - - default: p = NULL; - } - return p; -} - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int slot, rc; - const char *reader_port = NULL; - struct app_ctx_s appbuf; - - memset (&appbuf, 0, sizeof appbuf); - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("sc-copykeys", 1); - - /* check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* FIXME - we want to use it */ - /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse (&pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: opt.verbose++; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oReaderPort: reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - default : pargs.err = 2; break; - } - } - if (log_get_errorcount(0)) - exit(2); - - if (argc != 1) - usage (1); - - slot = apdu_open_reader (reader_port); - if (slot == -1) - exit (1); - - /* FIXME: Use select_application. */ - appbuf.slot = slot; - rc = app_select_openpgp (&appbuf); - if (rc) - { - log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc)); - exit (1); - } - appbuf.initialized = 1; - log_info ("openpgp application selected\n"); - - copykeys (&appbuf, *argv); - - - return 0; -} - - - -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - /* DUMMY */ -} - - - -static char * -read_file (const char *fname, size_t *r_length) -{ - FILE *fp; - struct stat st; - char *buf; - size_t buflen; - - fp = fname? fopen (fname, "rb") : stdin; - if (!fp) - { - log_error ("can't open `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - return NULL; - } - - if (fstat (fileno(fp), &st)) - { - log_error ("can't stat `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - if (fname) - fclose (fp); - return NULL; - } - - buflen = st.st_size; - buf = xmalloc (buflen+1); - if (fread (buf, buflen, 1, fp) != 1) - { - log_error ("error reading `%s': %s\n", - fname? fname: "[stdin]", strerror (errno)); - if (fname) - fclose (fp); - xfree (buf); - return NULL; - } - if (fname) - fclose (fp); - - *r_length = buflen; - return buf; -} - - -static gcry_sexp_t -read_key (const char *fname) -{ - char *buf; - size_t buflen; - gcry_sexp_t private; - int rc; - - buf = read_file (fname, &buflen); - if (!buf) - return NULL; - - rc = gcry_sexp_new (&private, buf, buflen, 1); - if (rc) - { - log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc)); - return NULL; - } - xfree (buf); - - return private; -} - - - -static gcry_mpi_t * -sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created) -{ - gcry_sexp_t list, l2; - const char *name; - const char *s; - size_t n; - int i, idx; - const char *elems; - gcry_mpi_t *array; - - *created = 0; - list = gcry_sexp_find_token (sexp, "private-key", 0 ); - if(!list) - return NULL; - - /* quick hack to get the creation time. */ - l2 = gcry_sexp_find_token (list, "created", 0); - if (l2 && (name = gcry_sexp_nth_data (l2, 1, &n))) - { - char *tmp = xmalloc (n+1); - memcpy (tmp, name, n); - tmp[n] = 0; - *created = strtoul (tmp, NULL, 10); - xfree (tmp); - } - gcry_sexp_release (l2); - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - name = gcry_sexp_nth_data (list, 0, &n); - if(!name || n != 3 || memcmp (name, "rsa", 3)) - { - gcry_sexp_release (list); - return NULL; - } - - /* Parameter names used with RSA. */ - elems = "nedpqu"; - array = xcalloc (strlen(elems) + 1, sizeof *array); - for (idx=0, s=elems; *s; s++, idx++ ) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - for (i=0; i<idx; i++) - gcry_mpi_release (array[i]); - xfree (array); - gcry_sexp_release (list); - return NULL; /* required parameter not found */ - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - for (i=0; i<idx; i++) - gcry_mpi_release (array[i]); - xfree (array); - gcry_sexp_release (list); - return NULL; /* required parameter is invalid */ - } - } - - gcry_sexp_release (list); - return array; -} - - -/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */ -static int -fpr_is_zero (const char *fpr) -{ - int i; - - for (i=0; i < 20 && !fpr[i]; i++) - ; - return (i == 20); -} - - -static void -show_sha1_fpr (const unsigned char *fpr) -{ - int i; - - if (fpr) - { - for (i=0; i < 20 ; i+=2, fpr += 2 ) - { - if (i == 10 ) - tty_printf (" "); - tty_printf (" %02X%02X", *fpr, fpr[1]); - } - } - else - tty_printf (" [none]"); - tty_printf ("\n"); -} - -/* Query the card, show a list of already stored keys and ask the user - where to store the key. Returns the key number or 0 for cancel - operation. */ -static int -query_card (APP app) -{ - int keyno = 0; - char *serialno, *disp_name, *pubkey_url; - unsigned char *fpr1, *fpr2, *fpr3; - - - if (app_openpgp_cardinfo (app, - &serialno, - &disp_name, - &pubkey_url, - &fpr1, &fpr2, &fpr3)) - return 0; - - - for (;;) - { - char *answer; - - tty_printf ("\n"); - - tty_printf ("Serial number ....: %s\n", - serialno? serialno : "[none]"); - tty_printf ("Name of cardholder: %s\n", - disp_name && *disp_name? disp_name : "[not set]"); - tty_printf ("URL of public key : %s\n", - pubkey_url && *pubkey_url? pubkey_url : "[not set]"); - tty_printf ("Signature key ....:"); - show_sha1_fpr (fpr1); - tty_printf ("Encryption key....:"); - show_sha1_fpr (fpr2); - tty_printf ("Authentication key:"); - show_sha1_fpr (fpr3); - - tty_printf ("\n" - "1 - store as signature key and reset usage counter\n" - "2 - store as encryption key\n" - "3 - store as authentication key\n" - "Q - quit\n" - "\n"); - - answer = tty_get("Your selection? "); - tty_kill_prompt(); - if (strlen (answer) != 1) - ; - else if ( *answer == '1' ) - { - if ( (fpr1 && !fpr_is_zero (fpr1)) ) - { - tty_printf ("\n"); - log_error ("WARNING: signature key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 1; - break; - } - } - else - { - keyno = 1; - break; - } - } - else if ( *answer == '2' ) - { - if ( (fpr2 && !fpr_is_zero (fpr2)) ) - { - tty_printf ("\n"); - log_error ("WARNING: encryption key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 2; - break; - } - } - else - { - keyno = 2; - break; - } - } - else if ( *answer == '3' ) - { - if ( (fpr3 && !fpr_is_zero (fpr3)) ) - { - tty_printf ("\n"); - log_error ("WARNING: authentication key does already exists!\n"); - tty_printf ("\n"); - if ( tty_get_answer_is_yes ("Replace existing key? ") ) - { - keyno = 3; - break; - } - } - else - { - keyno = 3; - break; - } - } - else if ( *answer == 'q' || *answer == 'Q') - { - keyno = 0; - break; - } - } - - xfree (serialno); - xfree (disp_name); - xfree (pubkey_url); - xfree (fpr1); - xfree (fpr2); - xfree (fpr3); - - return keyno; -} - - -/* Callback function to ask for a PIN. */ -static int -pincb (void *arg, const char *prompt, char **pinvalue) -{ - char *pin = xstrdup ("12345678"); - -/* pin = simple_pwquery (NULL, NULL, prompt, */ -/* "We need the admin's PIN to store the key on the card", */ -/* NULL); */ -/* if (!pin) */ -/* return gpg_error (GPG_ERR_CANCELED); */ - - - - *pinvalue = pin; - return 0; -} - - -/* This function expects a file (or NULL for stdin) with the secret - and public key parameters. This file should consist of an - S-expression as used by gpg-agent. Only the unprotected format is - supported. Example: - - (private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#)) - (uri http://foo.bar x-foo:whatever_you_want)) - -*/ -static void -copykeys (APP app, const char *fname) -{ - int rc; - gcry_sexp_t private; - gcry_mpi_t *mpis, rsa_n, rsa_e, rsa_p, rsa_q; - unsigned int nbits; - size_t n; - unsigned char *template, *tp; - unsigned char m[128], e[4]; - size_t mlen, elen; - unsigned long creation_date; - time_t created_at; - int keyno; - - if (!strcmp (fname, "-")) - fname = NULL; - - private = read_key (fname); - if (!private) - exit (1); - - mpis = sexp_to_kparms (private, &creation_date); - if (!creation_date) - { - log_info ("no creation date found - assuming current date\n"); - created_at = time (NULL); - } - else - created_at = creation_date; - gcry_sexp_release (private); - if (!mpis) - { - log_error ("invalid structure of key file or not RSA\n"); - exit (1); - } - /* MPIS is now an array with the key parameters as defined by OpenPGP. */ - rsa_n = mpis[0]; - rsa_e = mpis[1]; - gcry_mpi_release (mpis[2]); - rsa_p = mpis[3]; - rsa_q = mpis[4]; - gcry_mpi_release (mpis[5]); - xfree (mpis); - - nbits = gcry_mpi_get_nbits (rsa_e); - if (nbits < 2 || nbits > 32) - { - log_error ("public exponent too large (more than 32 bits)\n"); - goto failure; - } - nbits = gcry_mpi_get_nbits (rsa_p); - if (nbits != 512) - { - log_error ("length of first RSA prime is not 512\n"); - goto failure; - } - nbits = gcry_mpi_get_nbits (rsa_q); - if (nbits != 512) - { - log_error ("length of second RSA prime is not 512\n"); - goto failure; - } - - nbits = gcry_mpi_get_nbits (rsa_n); - if (nbits != 1024) - { - log_error ("length of RSA modulus is not 1024\n"); - goto failure; - } - - keyno = query_card (app); - if (!keyno) - goto failure; - - /* Build the private key template as described in section 4.3.3.6 of - the specs. - 0xC0 <length> public exponent - 0xC1 <length> prime p - 0xC2 <length> prime q */ - template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64); - *tp++ = 0xC0; - *tp++ = 4; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 4, &n, rsa_e); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n <= 4); - memcpy (e, tp, n); - elen = n; - if (n != 4) - { - memmove (tp+4-n, tp, 4-n); - memset (tp, 0, 4-n); - } - tp += 4; - - *tp++ = 0xC1; - *tp++ = 64; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_p); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 64); - tp += 64; - - *tp++ = 0xC2; - *tp++ = 64; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_q); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 64); - tp += 64; - assert (tp - template == 138); - - /* (we need the modulus to calculate the fingerprint) */ - rc = gcry_mpi_print (GCRYMPI_FMT_USG, m, 128, &n, rsa_n); - if (rc) - { - log_error ("mpi_print failed: %s\n", gpg_strerror (rc)); - goto failure; - } - assert (n == 128); - mlen = 128; - - - rc = app_openpgp_storekey (app, keyno, - template, tp - template, - created_at, - m, mlen, - e, elen, - pincb, NULL); - - if (rc) - { - log_error ("error storing key: %s\n", gpg_strerror (rc)); - goto failure; - } - log_info ("key successfully stored\n"); - { - unsigned char *mm, *ee; - size_t mmlen, eelen; - int i; - - rc = app_openpgp_readkey (app, keyno, &mm, &mmlen, &ee, &eelen); - if (rc) - { - log_error ("error reading key back: %s\n", gpg_strerror (rc)); - goto failure; - } - - /* Strip leading zeroes. */ - for (i=0; i < mmlen && !mm[i]; i++) - ; - mmlen -= i; - memmove (mm, mm+i, mmlen); - for (i=0; i < eelen && !ee[i]; i++) - ; - eelen -= i; - memmove (ee, ee+i, eelen); - - if (eelen != elen || mmlen != mlen) - { - log_error ("key parameter length mismatch (n=%u/%u, e=%u/%u)\n", - (unsigned int)mlen, (unsigned int)mmlen, - (unsigned int)elen, (unsigned int)eelen); - xfree (mm); - xfree (ee); - goto failure; - } - - if (memcmp (m, mm, mlen)) - { - log_error ("key parameter n mismatch\n"); - log_printhex ("original n: ", m, mlen); - log_printhex (" copied n: ", mm, mlen); - xfree (mm); - xfree (ee); - goto failure; - } - if (memcmp (e, ee, elen)) - { - log_error ("key parameter e mismatch\n"); - log_printhex ("original e: ", e, elen); - log_printhex (" copied e: ", ee, elen); - xfree (mm); - xfree (ee); - goto failure; - } - xfree (mm); - xfree (ee); - } - - - gcry_mpi_release (rsa_e); - gcry_mpi_release (rsa_p); - gcry_mpi_release (rsa_q); - gcry_mpi_release (rsa_n); - return; - - failure: - gcry_mpi_release (rsa_e); - gcry_mpi_release (rsa_p); - gcry_mpi_release (rsa_q); - gcry_mpi_release (rsa_n); - exit (1); -} - - diff --git a/scd/sc-investigate.c b/scd/sc-investigate.c deleted file mode 100644 index 3882e1dfd..000000000 --- a/scd/sc-investigate.c +++ /dev/null @@ -1,770 +0,0 @@ -/* sc-investigate.c - A tool to look around on smartcards. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <unistd.h> - -#ifdef HAVE_READLINE_READLINE_H -#include <readline/readline.h> -#include <readline/history.h> -#endif - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <gcrypt.h> - -#include "apdu.h" /* for open_reader */ -#include "atr.h" -#include "app-common.h" -#include "iso7816.h" - -#define _(a) (a) - -#define CONTROL_D ('D' - 'A' + 1) - - -enum cmd_and_opt_values -{ - oInteractive = 'i', - oVerbose = 'v', - oQuiet = 'q', - oReaderPort = 500, - octapiDriver, - - oDebug, - oDebugAll, - - oDisableCCID, - - - oGenRandom, - -aTest }; - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, "@Options:\n " }, - - { oInteractive, "interactive", 0, "start in interactive explorer mode"}, - { oQuiet, "quiet", 0, "quiet" }, - { oVerbose, "verbose", 0, "verbose" }, - { oReaderPort, "reader-port", 2, "|N|connect to reader at port N"}, - { octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"}, - { oDisableCCID, "disable-ccid", 0, -#ifdef HAVE_LIBUSB - "do not use the internal CCID driver" -#else - "@" -#endif - }, - { oDebug, "debug" ,4|16, "set debugging flags"}, - { oDebugAll, "debug-all" ,0, "enable full debugging"}, - { oGenRandom, "gen-random", 4, "|N|generate N bytes of random"}, - {0} -}; - - -static void interactive_shell (int slot); -static void dump_other_cards (int slot); - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "sc-investigate (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: sc-investigate [options] (-h for help)\n"); - break; - case 41: p = _("Syntax: sc-investigate [options] [args]]\n" - "Have a look at smartcards\n"); - break; - - default: p = NULL; - } - return p; -} - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int slot, rc; - const char *reader_port = NULL; - unsigned long gen_random = 0; - int interactive = 0; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - log_set_prefix ("sc-investigate", 1); - - /* Try to auto set the character set. */ - set_native_charset (NULL); - - /* check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - - gcry_set_log_handler (my_gcry_logger, NULL); - /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/ - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse (&pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: opt.verbose++; break; - case oQuiet: opt.quiet++; break; - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oReaderPort: reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - case oDisableCCID: opt.disable_ccid = 1; break; - case oGenRandom: gen_random = pargs.r.ret_ulong; break; - case oInteractive: interactive = 1; break; - default : pargs.err = 2; break; - } - } - if (log_get_errorcount(0)) - exit(2); - - if (opt.verbose < 2) - opt.verbose = 2; /* Hack to let select_openpgp print some info. */ - - if (argc) - usage (1); - - slot = apdu_open_reader (reader_port); - if (slot == -1) - exit (1); - - if (!gen_random && !opt.quiet) - { - rc = atr_dump (slot, stdout); - if (rc) - log_error ("can't dump ATR: %s\n", gpg_strerror (rc)); - } - - if (interactive) - interactive_shell (slot); - else - { - struct app_ctx_s appbuf; - - /* Fixme: We better use app.c directly. */ - memset (&appbuf, 0, sizeof appbuf); - appbuf.slot = slot; - rc = app_select_openpgp (&appbuf); - if (rc) - { - if (!opt.quiet) - log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc)); - memset (&appbuf, 0, sizeof appbuf); - appbuf.slot = slot; - rc = app_select_dinsig (&appbuf); - if (rc) - { - if (!opt.quiet) - log_info ("selecting dinsig failed: %s\n", gpg_strerror (rc)); - dump_other_cards (slot); - } - else - { - appbuf.initialized = 1; - log_info ("dinsig application selected\n"); - } - } - else - { - appbuf.initialized = 1; - log_info ("openpgp application selected\n"); - - if (gen_random) - { - size_t nbytes; - unsigned char *buffer; - - buffer = xmalloc (4096); - do - { - nbytes = gen_random > 4096? 4096 : gen_random; - rc = app_get_challenge (&appbuf, nbytes, buffer); - if (rc) - log_error ("app_get_challenge failed: %s\n",gpg_strerror (rc)); - else - { - if (fwrite (buffer, nbytes, 1, stdout) != 1) - log_error ("writing to stdout failed: %s\n", - strerror (errno)); - gen_random -= nbytes; - } - } - while (gen_random && !log_get_errorcount (0)); - xfree (buffer); - } - } - } - - return log_get_errorcount (0)? 2:0; -} - - - -void -send_status_info (CTRL ctrl, const char *keyword, ...) -{ - /* DUMMY */ -} - - - -/* Dump BUFFER of length NBYTES in a nicely human readable format. */ -static void -dump_buffer (const unsigned char *buffer, size_t nbytes) -{ - int i; - - while (nbytes) - { - for (i=0; i < 16 && i < nbytes; i++) - printf ("%02X%s ", buffer[i], i==8? " ":""); - for (; i < 16; i++) - printf (" %s ", i==8? " ":""); - putchar (' '); - putchar (' '); - for (i=0; i < 16 && i < nbytes; i++) - if (isprint (buffer[i])) - putchar (buffer[i]); - else - putchar ('.'); - nbytes -= i; - buffer += i; - for (; i < 16; i++) - putchar (' '); - putchar ('\n'); - } -} - - -static void -dump_or_store_buffer (const char *arg, - const unsigned char *buffer, size_t nbytes) -{ - const char *s = strchr (arg, '>'); - int append; - FILE *fp; - - if (!s) - { - dump_buffer (buffer, nbytes); - return; - } - if ((append = (*++s == '>'))) - s++; - fp = fopen (s, append? "ab":"wb"); - if (!fp) - { - log_error ("failed to create `%s': %s\n", s, strerror (errno)); - return; - } - if (nbytes && fwrite (buffer, nbytes, 1, fp) != 1) - log_error ("failed to write to `%s': %s\n", s, strerror (errno)); - if (fclose (fp)) - log_error ("failed to close `%s': %s\n", s, strerror (errno)); -} - - -/* Convert STRING into a a newly allocated buffer and return the - length of the buffer in R_LENGTH. Detect xx:xx:xx... sequence and - unhexify that one. */ -static unsigned char * -pin_to_buffer (const char *string, size_t *r_length) -{ - unsigned char *buffer = xmalloc (strlen (string)+1); - const char *s; - size_t n; - - for (s=string, n=0; *s; s += 3) - { - if (hexdigitp (s) && hexdigitp (s+1) && (s[2]==':'||!s[2])) - { - buffer[n++] = xtoi_2 (s); - if (!s[2]) - break; - } - else - { - memcpy (buffer, string, strlen (string)); - *r_length = strlen (string); - return buffer; - } - } - *r_length = n; - return buffer; -} - - -static char * -read_line (int use_readline, char *prompt) -{ - static char buf[256]; - -#ifdef HAVE_READLINE - if (use_readline) - { - char *line = readline (prompt); - if (line) - trim_spaces (line); - if (line && strlen (line) > 2 ) - add_history (line); - return line; - } -#endif - /* Either we don't have readline or we are not running - interactively */ -#ifndef HAVE_READLINE - printf ("%s", prompt ); -#endif - fflush(stdout); - if (!fgets(buf, sizeof(buf), stdin)) - return NULL; - if (!strlen(buf)) - return NULL; - if (buf[strlen (buf)-1] == '\n') - buf[strlen (buf)-1] = 0; - trim_spaces (buf); - return buf; -} - -/* Run a shell for interactive exploration of the card. */ -static void -interactive_shell (int slot) -{ - enum cmdids - { - cmdNOP = 0, - cmdQUIT, cmdHELP, - cmdSELECT, - cmdCHDIR, - cmdLS, - cmdAPP, - cmdREAD, - cmdREADREC, - cmdREADSHORTREC, - cmdDEBUG, - cmdVERIFY, - cmdCHANGEREF, - - cmdINVCMD - }; - static struct - { - const char *name; - enum cmdids id; - const char *desc; - } cmds[] = { - { "quit" , cmdQUIT , "quit this menu" }, - { "q" , cmdQUIT , NULL }, - { "help" , cmdHELP , "show this help" }, - { "?" , cmdHELP , NULL }, - { "debug" , cmdDEBUG, "set debugging flags" }, - { "select" , cmdSELECT, "select file (EF)" }, - { "s" , cmdSELECT, NULL }, - { "chdir" , cmdCHDIR, "change directory (select DF)"}, - { "cd" , cmdCHDIR, NULL }, - { "ls" , cmdLS, "list directory (some cards only)"}, - { "app" , cmdAPP, "select application"}, - { "read" , cmdREAD, "read binary" }, - { "rb" , cmdREAD, NULL }, - { "readrec", cmdREADREC, "read record(s)" }, - { "rr" , cmdREADREC, NULL }, - { "rsr" , cmdREADSHORTREC, "readshortrec RECNO SHORT_EF" }, - { "verify" , cmdVERIFY, "verify CHVNO PIN" }, - { "ver" , cmdVERIFY, NULL }, - { "changeref", cmdCHANGEREF, "change reference data" }, - { NULL, cmdINVCMD } - }; - enum cmdids cmd = cmdNOP; - int use_readline = isatty (fileno(stdin)); - char *line; - gpg_error_t err = 0; - unsigned char *result = NULL; - size_t resultlen; - -#ifdef HAVE_READLINE - if (use_readline) - using_history (); -#endif - - for (;;) - { - int arg_number; - const char *arg_string = ""; - const char *arg_next = ""; - char *p; - int i; - - if (err) - printf ("command failed: %s\n", gpg_strerror (err)); - err = 0; - xfree (result); - result = NULL; - - printf ("\n"); - do - { - line = read_line (use_readline, "cmd> "); - } - while ( line && *line == '#' ); - - arg_number = 0; - if (!line || *line == CONTROL_D) - cmd = cmdQUIT; - else if (!*line) - cmd = cmdNOP; - else { - if ((p=strchr (line,' '))) - { - char *endp; - - *p++ = 0; - trim_spaces (line); - trim_spaces (p); - arg_number = strtol (p, &endp, 0); - arg_string = p; - if (endp != p) - { - arg_next = endp; - while ( spacep (arg_next) ) - arg_next++; - } - } - - for (i=0; cmds[i].name; i++ ) - if (!ascii_strcasecmp (line, cmds[i].name )) - break; - - cmd = cmds[i].id; - } - - switch (cmd) - { - case cmdHELP: - for (i=0; cmds[i].name; i++ ) - if (cmds[i].desc) - printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); - break; - - case cmdQUIT: - goto leave; - - case cmdNOP: - break; - - case cmdDEBUG: - if (!*arg_string) - opt.debug = opt.debug? 0 : 2048; - else - opt.debug = arg_number; - break; - - case cmdSELECT: - err = iso7816_select_file (slot, arg_number, 0, NULL, NULL); - break; - - case cmdCHDIR: - err = iso7816_select_file (slot, arg_number, 1, NULL, NULL); - break; - - case cmdLS: - err = iso7816_list_directory (slot, 1, &result, &resultlen); - if (!err || gpg_err_code (err) == GPG_ERR_ENOENT) - err = iso7816_list_directory (slot, 0, &result, &resultlen); - /* FIXME: Do something with RESULT. */ - break; - - case cmdAPP: - { - app_t app; - - app = select_application (NULL, slot, *arg_string? arg_string:NULL); - if (app) - { - char *sn; - - app_get_serial_and_stamp (app, &sn, NULL); - log_info ("application `%s' ready; sn=%s\n", - app->apptype?app->apptype:"?", sn? sn:"[none]"); - release_application (app); - } - } - break; - - case cmdREAD: - err = iso7816_read_binary (slot, 0, 0, &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - break; - - case cmdREADREC: - if (*arg_string == '*' && (!arg_string[1] || arg_string[1] == ' ')) - { - /* Fixme: Can't write to a file yet. */ - for (i=1, err=0; !err; i++) - { - xfree (result); result = NULL; - err = iso7816_read_record (slot, i, 1, 0, - &result, &resultlen); - if (!err) - dump_buffer (result, resultlen); - } - if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) - err = 0; - } - else - { - err = iso7816_read_record (slot, arg_number, 1, 0, - &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - } - break; - - case cmdREADSHORTREC: - { - int short_ef; - - short_ef = strtol (arg_next, NULL, 0); - - if (short_ef < 1 || short_ef > 254) - printf ("error: short EF must be between 1 and 254\n"); - else - { - err = iso7816_read_record (slot, arg_number, 1, short_ef, - &result, &resultlen); - if (!err) - dump_or_store_buffer (arg_string, result, resultlen); - } - } - break; - - case cmdVERIFY: - if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31) - printf ("error: invalid CHVNO\n"); - else - { - unsigned char *pin; - size_t pinlen; - - pin = pin_to_buffer (arg_next, &pinlen); - err = iso7816_verify (slot, arg_number, pin, pinlen); - xfree (pin); - } - break; - - case cmdCHANGEREF: - { - const char *newpin = arg_next; - - while ( *newpin && !spacep (newpin) ) - newpin++; - while ( spacep (newpin) ) - newpin++; - - if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31) - printf ("error: invalid CHVNO\n"); - else if (!*arg_next || !*newpin || newpin == arg_next) - printf ("usage: changeref CHVNO OLDPIN NEWPIN\n"); - else - { - char *oldpin = xstrdup (arg_next); - unsigned char *oldpin_buf, *newpin_buf; - size_t oldpin_len, newpin_len; - - for (p=oldpin; *p && !spacep (p); p++ ) - ; - *p = 0; - oldpin_buf = pin_to_buffer (oldpin, &oldpin_len); - newpin_buf = pin_to_buffer (newpin, &newpin_len); - - err = iso7816_change_reference_data (slot, arg_number, - oldpin_buf, oldpin_len, - newpin_buf, newpin_len); - - xfree (newpin_buf); - xfree (oldpin_buf); - xfree (oldpin); - } - } - break; - - case cmdINVCMD: - default: - printf ("\n"); - printf ("Invalid command (try \"help\")\n"); - break; - } /* End command switch. */ - } /* End of main menu loop. */ - - leave: - ; -} - - - -/* Figure out whether the current card is a German Geldkarte and print - what we know about it. */ -static int -dump_geldkarte (int slot) -{ - unsigned char *r = NULL; - size_t rlen; - const char *t; - - if (iso7816_read_record (slot, 1, 1, 0xbc, &r, &rlen)) - return -1; - /* We require that the record is at least 24 bytes, the first byte - is 0x67 and the filler byte is correct. */ - if (rlen < 24 || *r != 0x67 || r[22]) - return -1; - - /* The short Bankleitzahl consists of 3 bytes at offset 1. */ - switch (r[1]) - { - case 0x21: t = "Oeffentlich-rechtliche oder private Bank"; break; - case 0x22: t = "Privat- oder Geschäftsbank"; break; - case 0x25: t = "Sparkasse"; break; - case 0x26: - case 0x29: t = "Genossenschaftsbank"; break; - default: - xfree (r); - return -1; /* Probably not a Geldkarte. */ - } - - printf ("KBLZ .....: %02X-%02X%02X (%s)\n", r[1], r[2], r[3], t); - printf ("Card-No ..: %02X%02X%02X%02X%02X\n", r[4], r[5], r[6], r[7], r[8]); - -/* Byte 10 enthält im linken Halbbyte eine Prüfziffer, die nach dem */ -/* Verfahren 'Luhn formula for computing modulus 10' über die Ziffern der */ -/* ersten 9 Byte berechnet ist. */ - -/* Das rechte Halbbyte wird zu 'D' gesetzt. */ - -/* Für die Berechnung der Luhn-Prüfziffer sind die folgenden Schritte */ -/* durchzuführen: */ - -/* Schritt 1: Mit der rechtesten Ziffer beginnend ist einschließlich dieser */ -/* Ziffer jede übernächste Ziffer zu verdoppeln (mit 2 multiplizieren). */ - -/* Schritt 2: Die einzelnen Ziffern der Produkte aus Schritt 1 und die bei */ -/* diesen Multiplikationen unberührt gebliebenen Ziffern sind zu addieren. */ - -/* Schritt 3: Das Ergebnis der Addition aus Schritt 2 ist von dem auf die */ -/* nächst höhere Zahl mit der Einerstelle 0 aufgerundeten Ergebnis der */ -/* Addition aus Schritt 2 abzuziehen. Wenn das Ergebnis der Addition aus */ -/* Schritt 2 bereits eine Zahl mit der Einerstelle 0 ergibt (z.B. 30, 40, */ -/* usw.), ist die Prüfziffer 0. */ - -/* Beispiel: Kartennummer ohne Prüfziffer: 992 839 871 */ - -/* 9 9 2 8 3 9 8 7 1 */ - -/* x 2 x 2 x 2 x 2 x 2 Schritt 1 */ - -/* 18 4 6 16 2 */ - -/* 1+8 +9 +4 +8 +6 +9 +1+6 +7 +2 = 61 Schritt 2 */ - -/* 70-61 = 9 Schritt 3 */ - -/* Prüfziffer zu 992 839 871 = 9 */ - - - printf ("Expires at: %02X/%02X\n", r[11], r[10] ); - printf ("Valid from: %02X.%02X.%02X\n", r[14], r[13], r[12]); - printf ("Country ..: %02X%02X\n", r[15], r[16]); - printf ("Currency .: %c%c%c\n", isascii (r[17])? r[17]:' ', - isascii (r[18])? r[18]:' ', isascii (r[19])? r[19]:' '); - printf ("Cur.-Mult : %s\n", - r[20] == 0x01? "0.01": - r[20] == 0x02? "0.1": - r[20] == 0x04? "1": - r[20] == 0x08? "10": - r[20] == 0x10? "100": - r[20] == 0x20? "1000": "?"); - printf ("ZKA ChipID: %02X\n", r[21]); - printf ("OS version: %02X\n", r[23]); - - xfree (r); - return 0; -} - - - -/* Try to figure out the type of teh card and dump its contents. */ -static void -dump_other_cards (int slot) -{ - - if (!dump_geldkarte (slot)) - return; - -} - diff --git a/scd/scdaemon.c b/scd/scdaemon.c deleted file mode 100644 index 5e9737ae4..000000000 --- a/scd/scdaemon.c +++ /dev/null @@ -1,933 +0,0 @@ -/* scdaemon.c - The GnuPG Smartcard Daemon - * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <time.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#include <signal.h> -#ifdef USE_GNU_PTH -# include <pth.h> -#endif - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include <ksba.h> -#include <gcrypt.h> - -#include <assuan.h> /* malloc hooks */ - -#include "i18n.h" -#include "sysutils.h" -#include "app-common.h" - - -enum cmd_and_opt_values -{ aNull = 0, - oCsh = 'c', - oQuiet = 'q', - oSh = 's', - oVerbose = 'v', - - oNoVerbose = 500, - aGPGConfList, - oOptions, - oDebug, - oDebugAll, - oDebugLevel, - oDebugWait, - oDebugSC, - oNoGreeting, - oNoOptions, - oHomedir, - oNoDetach, - oNoGrab, - oLogFile, - oServer, - oDaemon, - oBatch, - oReaderPort, - octapiDriver, - opcscDriver, - oDisableCCID, - oDisableOpenSC, - oAllowAdmin, - oDenyAdmin, - -aTest }; - - - -static ARGPARSE_OPTS opts[] = { - - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { 301, NULL, 0, N_("@Options:\n ") }, - - { oServer, "server", 0, N_("run in server mode (foreground)") }, - { oDaemon, "daemon", 0, N_("run in daemon mode (background)") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oSh, "sh", 0, N_("sh-style command output") }, - { oCsh, "csh", 0, N_("csh-style command output") }, - { oOptions, "options" , 2, N_("read options from file")}, - { oDebug, "debug" ,4|16, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugWait,"debug-wait",1, "@"}, - { oDebugSC, "debug-sc", 1, N_("|N|set OpenSC debug level to N")}, - { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - { oReaderPort, "reader-port", 2, N_("|N|connect to reader at port N")}, - { octapiDriver, "ctapi-driver", 2, N_("|NAME|use NAME as ct-API driver")}, - { opcscDriver, "pcsc-driver", 2, N_("|NAME|use NAME as PC/SC driver")}, - { oDisableCCID, "disable-ccid", 0, -#ifdef HAVE_LIBUSB - N_("do not use the internal CCID driver") -#else - "@" -#endif - /* end --disable-ccid */}, - { oDisableOpenSC, "disable-opensc", 0, -#ifdef HAVE_OPENSC - N_("do not use the OpenSC layer") -#else - "@" -#endif - /* end --disable-opensc */}, - { oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")}, - { oDenyAdmin, "deny-admin", 0, "@" }, - - {0} -}; - - -#define DEFAULT_PCSC_DRIVER "libpcsclite.so" - - -static volatile int caught_fatal_sig = 0; - -/* Flag to indicate that a shutdown was requested. */ -static int shutdown_pending; - -/* It is possible that we are currently running under setuid permissions */ -static int maybe_setuid = 1; - -/* Name of the communication socket */ -static char socket_name[128]; - - -#ifdef USE_GNU_PTH -/* Pth wrapper function definitions. */ -GCRY_THREAD_OPTION_PTH_IMPL; - -static void *ticker_thread (void *arg); -#endif /*USE_GNU_PTH*/ - - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "scdaemon (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: scdaemon [options] (-h for help)"); - break; - case 41: p = _("Syntax: scdaemon [options] [command [args]]\n" - "Smartcard daemon for GnuPG\n"); - break; - - default: p = NULL; - } - return p; -} - - - -static void -i18n_init (void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE_GT ); -#else -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -#endif -#endif -} - - - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_ASSUAN_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE - |DBG_CACHE_VALUE|DBG_CARD_IO_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - scd_exit(2); - } - - - if (opt.debug && !opt.verbose) - opt.verbose = 1; - if (opt.debug && opt.quiet) - opt.quiet = 0; - - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CRYPTO_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); -} - - - -static void -cleanup (void) -{ - if (*socket_name) - { - char *p; - - remove (socket_name); - p = strrchr (socket_name, '/'); - if (p) - { - *p = 0; - rmdir (socket_name); - *p = '/'; - } - *socket_name = 0; - } -} - - -static RETSIGTYPE -cleanup_sh (int sig) -{ - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - /* gcry_control( GCRYCTL_TERM_SECMEM );*/ - cleanup (); - -#ifndef HAVE_DOSISH_SYSTEM - { /* reset action to default action and raise signal again */ - struct sigaction nact; - nact.sa_handler = SIG_DFL; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - sigaction( sig, &nact, NULL); - } -#endif - raise( sig ); -} - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - gpg_error_t err; - int may_coredump; - char **orig_argv; - FILE *configfp = NULL; - char *configname = NULL; - const char *shell; - unsigned configlineno; - int parse_debug = 0; - const char *debug_level = NULL; - int default_config =1; - int greeting = 0; - int nogreeting = 0; - int pipe_server = 0; - int is_daemon = 0; - int nodetach = 0; - int csh_style = 0; - char *logfile = NULL; - int debug_wait = 0; - int gpgconf_list = 0; - const char *config_filename = NULL; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to INIT_SECMEM() - somewhere after the option parsing */ - log_set_prefix ("scdaemon", 1|4); - /* Try to auto set the character set. */ - set_native_charset (NULL); - - i18n_init (); - - /* Libgcrypt requires us to register the threading model first. - Note that this will also do the pth_init. */ -#ifdef USE_GNU_PTH - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); - if (err) - { - log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", - gpg_strerror (err)); - } -#endif /*USE_GNU_PTH*/ - - /* Check that the libraries are suitable. Do it here because - the option parsing may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - assuan_set_assuan_log_stream (log_get_stream ()); - assuan_set_assuan_log_prefix (log_get_prefix (NULL)); - - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - /* Set default options. */ - opt.pcsc_driver = DEFAULT_PCSC_DRIVER; - - - shell = getenv ("SHELL"); - if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) - csh_style = 1; - - /* FIXME: Using this homedir option does only make sense when not - running as a system service. We might want to check for this by - looking at the uid or ebtter use an explict option for this */ - opt.homedir = getenv("GNUPGHOME"); - if (!opt.homedir || !*opt.homedir) - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - - /* check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while (arg_parse( &pargs, opts)) - { - if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) - parse_debug++; - else if (pargs.r_opt == oOptions) - { /* yes there is one, so we do not try the default one, but - read the option file when it is encountered at the - commandline */ - default_config = 0; - } - else if (pargs.r_opt == oNoOptions) - default_config = 0; /* --no-options */ - else if (pargs.r_opt == oHomedir) - opt.homedir = pargs.r.ret_str; - } - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are working under our real uid - */ - - - if (default_config) - configname = make_filename (opt.homedir, "scdaemon.conf", NULL ); - - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - next_pass: - if (configname) - { - configlineno = 0; - configfp = fopen (configname, "r"); - if (!configfp) - { - if (default_config) - { - if( parse_debug ) - log_info (_("NOTE: no default option file `%s'\n"), - configname ); - } - else - { - log_error (_("option file `%s': %s\n"), - configname, strerror(errno) ); - exit(2); - } - xfree (configname); - configname = NULL; - } - if (parse_debug && configname ) - log_info (_("reading options from `%s'\n"), configname ); - default_config = 0; - } - - while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) - { - switch (pargs.r_opt) - { - case aGPGConfList: gpgconf_list = 1; break; - case oQuiet: opt.quiet = 1; break; - case oVerbose: opt.verbose++; break; - case oBatch: opt.batch=1; break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugSC: opt.debug_sc = pargs.r.ret_int; break; - - case oOptions: - /* config files may not be nested (silently ignore them) */ - if (!configfp) - { - xfree(configname); - configname = xstrdup(pargs.r.ret_str); - goto next_pass; - } - break; - case oNoGreeting: nogreeting = 1; break; - case oNoVerbose: opt.verbose = 0; break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oNoDetach: nodetach = 1; break; - case oLogFile: logfile = pargs.r.ret_str; break; - case oCsh: csh_style = 1; break; - case oSh: csh_style = 0; break; - case oServer: pipe_server = 1; break; - case oDaemon: is_daemon = 1; break; - - case oReaderPort: opt.reader_port = pargs.r.ret_str; break; - case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; - case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break; - case oDisableCCID: opt.disable_ccid = 1; break; - case oDisableOpenSC: opt.disable_opensc = 1; break; - - case oAllowAdmin: opt.allow_admin = 1; break; - case oDenyAdmin: opt.allow_admin = 0; break; - - default : pargs.err = configfp? 1:2; break; - } - } - if (configfp) - { - fclose( configfp ); - configfp = NULL; - /* Keep a copy of the config name for use by --gpgconf-list. */ - config_filename = configname; - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - if (log_get_errorcount(0)) - exit(2); - if (nogreeting ) - greeting = 0; - - if (greeting) - { - fprintf (stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf (stderr, "%s\n", strusage(15) ); - } -#ifdef IS_DEVELOPMENT_VERSION - log_info ("NOTE: this is a development version!\n"); -#endif - - - if (atexit (cleanup)) - { - log_error ("atexit failed\n"); - cleanup (); - exit (1); - } - - set_debug (debug_level); - - if (debug_wait && pipe_server) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - - if (gpgconf_list) - { - /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - if (!config_filename) - config_filename = make_filename (opt.homedir, "scdaemon.conf", NULL ); - - printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - - printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("pcsc-driver:%lu:\"%s:\n", - GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER ); -#ifdef HAVE_LIBUSB - printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); -#endif -#ifdef HAVE_LIBUSB - printf ("disable-opensc:%lu:\n", GC_OPT_FLAG_NONE ); -#endif - printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE ); - - - scd_exit (0); - } - - /* now start with logging to a file if this is desired */ - if (logfile) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - - if (pipe_server) - { /* This is the simple pipe based server */ -#ifdef USE_GNU_PTH - pth_attr_t tattr; - - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "ticker"); - - if (!pth_spawn (tattr, ticker_thread, NULL)) - { - log_error ("error spawning ticker thread: %s\n", strerror (errno)); - scd_exit (2); - } -#endif /*USE_GNU_PTH*/ - scd_command_handler (-1); - } - else if (!is_daemon) - { - log_info (_("please use the option `--daemon'" - " to run the program in the background\n")); - } - else - { /* regular server mode */ - int fd; - pid_t pid; - int i; - int len; - struct sockaddr_un serv_addr; - char *p; - - /* fixme: if there is already a running gpg-agent we should - share the same directory - and vice versa */ - *socket_name = 0; - snprintf (socket_name, DIM(socket_name)-1, - "/tmp/gpg-XXXXXX/S.scdaemon"); - socket_name[DIM(socket_name)-1] = 0; - p = strrchr (socket_name, '/'); - if (!p) - BUG (); - *p = 0;; - if (!mkdtemp(socket_name)) - { - log_error ("can't create directory `%s': %s\n", - socket_name, strerror(errno) ); - exit (1); - } - *p = '/'; - - if (strchr (socket_name, ':') ) - { - log_error ("colons are not allowed in the socket name\n"); - exit (1); - } - if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) - { - log_error ("name of socket to long\n"); - exit (1); - } - - - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - log_error ("can't create socket: %s\n", strerror(errno) ); - exit (1); - } - - memset (&serv_addr, 0, sizeof serv_addr); - serv_addr.sun_family = AF_UNIX; - strcpy (serv_addr.sun_path, socket_name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(serv_addr.sun_path) + 1); - - if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1) - { - log_error ("error binding socket to `%s': %s\n", - serv_addr.sun_path, strerror (errno) ); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - log_error ("listen() failed: %s\n", strerror (errno)); - close (fd); - exit (1); - } - - if (opt.verbose) - log_info ("listening on socket `%s'\n", socket_name ); - - - fflush (NULL); - pid = fork (); - if (pid == (pid_t)-1) - { - log_fatal ("fork failed: %s\n", strerror (errno) ); - exit (1); - } - else if (pid) - { /* we are the parent */ - char *infostr; - - close (fd); - - /* create the info string: <name>:<pid>:<protocol_version> */ - if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1", - socket_name, (ulong)pid ) < 0) - { - log_error ("out of core\n"); - kill (pid, SIGTERM); - exit (1); - } - *socket_name = 0; /* don't let cleanup() remove the socket - - the child should do this from now on */ - if (argc) - { /* run the program given on the commandline */ - if (putenv (infostr)) - { - log_error ("failed to set environment: %s\n", - strerror (errno) ); - kill (pid, SIGTERM ); - exit (1); - } - execvp (argv[0], argv); - log_error ("failed to run the command: %s\n", strerror (errno)); - kill (pid, SIGTERM); - exit (1); - } - else - { - /* print the environment string, so that the caller can use - shell's eval to set it */ - if (csh_style) - { - *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); - } - else - { - printf ( "%s; export SCDAEMON_INFO;\n", infostr); - } - free (infostr); - exit (0); - } - /* NOTREACHED */ - } /* end parent */ - - /* this is the child */ - - /* detach from tty and put process into a new session */ - if (!nodetach ) - { /* close stdin, stdout and stderr unless it is the log stream */ - for (i=0; i <= 2; i++) - { - if ( log_get_fd () != i) - close (i); - } - if (setsid() == -1) - { - log_error ("setsid() failed: %s\n", strerror(errno) ); - cleanup (); - exit (1); - } - } - - /* setup signals */ - { - struct sigaction oact, nact; - - nact.sa_handler = cleanup_sh; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - - sigaction (SIGHUP, NULL, &oact); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGHUP, &nact, NULL); - sigaction( SIGTERM, NULL, &oact ); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGTERM, &nact, NULL); - nact.sa_handler = SIG_IGN; - sigaction (SIGPIPE, &nact, NULL); - sigaction (SIGINT, &nact, NULL); - } - - if (chdir("/")) - { - log_error ("chdir to / failed: %s\n", strerror (errno)); - exit (1); - } - - scd_command_handler (fd); - - close (fd); - } - - return 0; -} - -void -scd_exit (int rc) -{ -#if 0 -#warning no update_random_seed_file - update_random_seed_file(); -#endif -#if 0 - /* at this time a bit annoying */ - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); -#endif - gcry_control (GCRYCTL_TERM_SECMEM ); - rc = rc? rc : log_get_errorcount(0)? 2 : 0; - exit (rc); -} - - -void -scd_init_default_ctrl (CTRL ctrl) -{ - ctrl->reader_slot = -1; -} - - -#ifdef USE_GNU_PTH - -static void -handle_signal (int signo) -{ - switch (signo) - { - case SIGHUP: - log_info ("SIGHUP received - " - "re-reading configuration and resetting cards\n"); -/* reread_configuration (); */ - break; - - case SIGUSR1: - log_info ("SIGUSR1 received - no action defined\n"); - break; - - case SIGUSR2: - log_info ("SIGUSR2 received - no action defined\n"); - break; - - case SIGTERM: - if (!shutdown_pending) - log_info ("SIGTERM received - shutting down ...\n"); - else - log_info ("SIGTERM received - still %ld running threads\n", - pth_ctrl( PTH_CTRL_GETTHREADS )); - shutdown_pending++; - if (shutdown_pending > 2) - { - log_info ("shutdown forced\n"); - log_info ("%s %s stopped\n", strusage(11), strusage(13) ); - cleanup (); - scd_exit (0); - } - break; - - case SIGINT: - log_info ("SIGINT received - immediate shutdown\n"); - log_info( "%s %s stopped\n", strusage(11), strusage(13)); - cleanup (); - scd_exit (0); - break; - - default: - log_info ("signal %d received - no action defined\n", signo); - } -} - -static void -handle_tick (void) -{ - scd_update_reader_status_file (); -} - -static void * -ticker_thread (void *dummy_arg) -{ - pth_event_t sigs_ev, time_ev = NULL; - sigset_t sigs; - int signo; - - sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - sigs_ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); - - for (;;) - { - if (!time_ev) - { - time_ev = pth_event (PTH_EVENT_TIME, pth_timeout (2, 0)); - if (time_ev) - pth_event_concat (sigs_ev, time_ev, NULL); - } - - if (pth_wait (sigs_ev) < 1) - continue; - - if ( -#ifdef PTH_STATUS_OCCURRED /* This is Pth 2 */ - pth_event_status (sigs_ev) == PTH_STATUS_OCCURRED -#else - pth_event_occurred (sigs_ev) -#endif - ) - handle_signal (signo); - - /* Always run the ticker. */ - if (!shutdown_pending) - { - pth_event_isolate (sigs_ev); - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } - } - - pth_event_free (sigs_ev, PTH_FREE_ALL); -} -#endif /*USE_GNU_PTH*/ diff --git a/scd/scdaemon.h b/scd/scdaemon.h deleted file mode 100644 index 1dd32ae90..000000000 --- a/scd/scdaemon.h +++ /dev/null @@ -1,130 +0,0 @@ -/* scdaemon.h - Global definitions for the SCdaemon - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SCDAEMON_H -#define SCDAEMON_H - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_SCD -#include <gpg-error.h> -#include <errno.h> - -#include <time.h> -#include <gcrypt.h> -#include "../common/util.h" -#include "../common/errors.h" - - -#define MAX_DIGEST_LEN 24 - -/* A large struct name "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int debug_sc; /* OpenSC debug level */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ - const char *ctapi_driver; /* Library to access the ctAPI. */ - const char *pcsc_driver; /* Library to access the PC/SC system. */ - const char *reader_port; /* NULL or reder port to use. */ - int disable_opensc; /* Disable the use of the OpenSC framework. */ - int disable_ccid; /* Disable the use of the internal CCID driver. */ - int allow_admin; /* Allow the use of admin commands for certain - cards. */ -} opt; - - -#define DBG_COMMAND_VALUE 1 /* debug commands i/o */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 -#define DBG_CARD_IO_VALUE 2048 - -#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) -#define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE) - -struct server_local_s; -struct card_ctx_s; -struct app_ctx_s; - -struct server_control_s { - struct server_local_s *server_local; - int reader_slot; /* Slot of the open reader or -1 if not open. */ - struct card_ctx_s *card_ctx; - struct app_ctx_s *app_ctx; - struct { - unsigned char *value; - int valuelen; - } in_data; /* helper to store the value we are going to sign */ - -}; - -typedef struct server_control_s *CTRL; -typedef struct server_control_s *ctrl_t; -typedef struct card_ctx_s *CARD; -typedef struct app_ctx_s *APP; -typedef struct app_ctx_s *app_t; - -/*-- scdaemon.c --*/ -void scd_exit (int rc); -void scd_init_default_ctrl (CTRL ctrl); - -/*-- command.c --*/ -void scd_command_handler (int); -void send_status_info (CTRL ctrl, const char *keyword, ...); -void scd_update_reader_status_file (void); - -/*-- card.c --*/ -int card_open (CARD *rcard); -void card_close (CARD card); -int card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp); -int card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid); -int card_enum_certs (CARD card, int idx, char **certid, int *certtype); -int card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); -int card_sign (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen ); -int card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - unsigned char **outdata, size_t *outdatalen); - - -#endif /*SCDAEMON_H*/ diff --git a/scd/tlv.c b/scd/tlv.c deleted file mode 100644 index 5b9d0d6b9..000000000 --- a/scd/tlv.c +++ /dev/null @@ -1,208 +0,0 @@ -/* tlv.c - Tag-Length-Value Utilities - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <gpg-error.h> - -#include "tlv.h" - -static const unsigned char * -do_find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes, int nestlevel) -{ - const unsigned char *s = buffer; - size_t n = length; - size_t len; - int this_tag; - int composite; - - for (;;) - { - buffer = s; - if (n < 2) - return NULL; /* Buffer definitely too short for tag and length. */ - if (!*s || *s == 0xff) - { /* Skip optional filler between TLV objects. */ - s++; - n--; - continue; - } - composite = !!(*s & 0x20); - if ((*s & 0x1f) == 0x1f) - { /* more tag bytes to follow */ - s++; - n--; - if (n < 2) - return NULL; /* buffer definitely too short for tag and length. */ - if ((*s & 0x1f) == 0x1f) - return NULL; /* We support only up to 2 bytes. */ - this_tag = (s[-1] << 8) | (s[0] & 0x7f); - } - else - this_tag = s[0]; - len = s[1]; - s += 2; n -= 2; - if (len < 0x80) - ; - else if (len == 0x81) - { /* One byte length follows. */ - if (!n) - return NULL; /* we expected 1 more bytes with the length. */ - len = s[0]; - s++; n--; - } - else if (len == 0x82) - { /* Two byte length follows. */ - if (n < 2) - return NULL; /* We expected 2 more bytes with the length. */ - len = (s[0] << 8) | s[1]; - s += 2; n -= 2; - } - else - return NULL; /* APDU limit is 65535, thus it does not make - sense to assume longer length fields. */ - - if (composite && nestlevel < 100) - { /* Dive into this composite DO after checking for a too deep - nesting. */ - const unsigned char *tmp_s; - size_t tmp_len; - - tmp_s = do_find_tlv (s, len, tag, &tmp_len, nestlevel+1); - if (tmp_s) - { - *nbytes = tmp_len; - return tmp_s; - } - } - - if (this_tag == tag) - { - *nbytes = len; - return s; - } - if (len > n) - return NULL; /* Buffer too short to skip to the next tag. */ - s += len; n -= len; - } -} - - -/* Locate a TLV encoded data object in BUFFER of LENGTH and - return a pointer to value as well as its length in NBYTES. Return - NULL if it was not found. Note, that the function does not check - whether the value fits into the provided buffer. */ -const unsigned char * -find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes) -{ - return do_find_tlv (buffer, length, tag, nbytes, 0); -} - - - - -/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag - and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ -gpg_error_t -parse_ber_header (unsigned char const **buffer, size_t *size, - int *r_class, int *r_tag, - int *r_constructed, int *r_ndef, - size_t *r_length, size_t *r_nhdr) -{ - int c; - unsigned long tag; - const unsigned char *buf = *buffer; - size_t length = *size; - - *r_ndef = 0; - *r_length = 0; - *r_nhdr = 0; - - /* Get the tag. */ - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - - *r_class = (c & 0xc0) >> 6; - *r_constructed = !!(c & 0x20); - tag = c & 0x1f; - - if (tag == 0x1f) - { - tag = 0; - do - { - tag <<= 7; - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - tag |= c & 0x7f; - - } - while (c & 0x80); - } - *r_tag = tag; - - /* Get the length. */ - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - - if ( !(c & 0x80) ) - *r_length = c; - else if (c == 0x80) - *r_ndef = 1; - else if (c == 0xff) - return gpg_error (GPG_ERR_BAD_BER); - else - { - unsigned long len = 0; - int count = c & 0x7f; - - if (count > sizeof (len) || count > sizeof (size_t)) - return gpg_error (GPG_ERR_BAD_BER); - - for (; count; count--) - { - len <<= 8; - if (!length) - return gpg_error (GPG_ERR_EOF); - c = *buf++; length--; ++*r_nhdr; - len |= c & 0xff; - } - *r_length = len; - } - - /* Without this kludge some example certs can't be parsed. */ - if (*r_class == CLASS_UNIVERSAL && !*r_tag) - *r_length = 0; - - *buffer = buf; - *size = length; - return 0; -} diff --git a/scd/tlv.h b/scd/tlv.h deleted file mode 100644 index 26a9905f7..000000000 --- a/scd/tlv.h +++ /dev/null @@ -1,84 +0,0 @@ -/* tlv.h - Tag-Length-Value Utilities - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef SCD_TLV_H -#define SCD_TLV_H 1 - - -enum tlv_tag_class { - CLASS_UNIVERSAL = 0, - CLASS_APPLICATION = 1, - CLASS_CONTEXT = 2, - CLASS_PRIVATE =3 -}; - -enum tlv_tag_type { - TAG_NONE = 0, - TAG_BOOLEAN = 1, - TAG_INTEGER = 2, - TAG_BIT_STRING = 3, - TAG_OCTET_STRING = 4, - TAG_NULL = 5, - TAG_OBJECT_ID = 6, - TAG_OBJECT_DESCRIPTOR = 7, - TAG_EXTERNAL = 8, - TAG_REAL = 9, - TAG_ENUMERATED = 10, - TAG_EMBEDDED_PDV = 11, - TAG_UTF8_STRING = 12, - TAG_REALTIVE_OID = 13, - TAG_SEQUENCE = 16, - TAG_SET = 17, - TAG_NUMERIC_STRING = 18, - TAG_PRINTABLE_STRING = 19, - TAG_TELETEX_STRING = 20, - TAG_VIDEOTEX_STRING = 21, - TAG_IA5_STRING = 22, - TAG_UTC_TIME = 23, - TAG_GENERALIZED_TIME = 24, - TAG_GRAPHIC_STRING = 25, - TAG_VISIBLE_STRING = 26, - TAG_GENERAL_STRING = 27, - TAG_UNIVERSAL_STRING = 28, - TAG_CHARACTER_STRING = 29, - TAG_BMP_STRING = 30 -}; - - - -/* Locate a TLV encoded data object in BUFFER of LENGTH and return a - pointer to value as well as its length in NBYTES. Return NULL if - it was not found. Note, that the function does not check whether - the value fits into the provided buffer.*/ -const unsigned char *find_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes); - - -/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag - and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ -gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size, - int *r_class, int *r_tag, - int *r_constructed, - int *r_ndef, size_t *r_length, size_t *r_nhdr); - - - -#endif /* SCD_TLV_H */ diff --git a/scripts/compile b/scripts/compile deleted file mode 100755 index ac07cc541..000000000 --- a/scripts/compile +++ /dev/null @@ -1,107 +0,0 @@ -#! /bin/sh - -# Wrapper for compilers which do not understand `-c -o'. - -# Copyright 1999, 2000 Free Software Foundation, Inc. -# Written by Tom Tromey <tromey@cygnus.com>. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Usage: -# compile PROGRAM [ARGS]... -# `-o FOO.o' is removed from the args passed to the actual compile. - -# Usage statement added by Billy Biggs <vektor@dumbterm.net>. -if [ -z $1 ]; then - echo "Wrapper for compilers which do not understand '-c -o'." - echo "usage: compile PROGRAM [ARGS]..." - echo "'-o FOO.o' is removed from the args passed to the actual compile." - exit 1 -fi - -prog=$1 -shift - -ofile= -cfile= -args= -while test $# -gt 0; do - case "$1" in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we do something ugly here. - ofile=$2 - shift - case "$ofile" in - *.o | *.obj) - ;; - *) - args="$args -o $ofile" - ofile= - ;; - esac - ;; - *.c) - cfile=$1 - args="$args $1" - ;; - *) - args="$args $1" - ;; - esac - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also - # ok. - exec "$prog" $args -fi - -# Name of file we expect compiler to create. -cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` - -# Create the lock directory. -# Note: use `[/.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d -while true; do - if mkdir $lockdir > /dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir $lockdir; exit 1" 1 2 15 - -# Run the compile. -"$prog" $args -status=$? - -if test -f "$cofile"; then - mv "$cofile" "$ofile" -fi - -rmdir $lockdir -exit $status diff --git a/scripts/config.guess b/scripts/config.guess deleted file mode 100755 index ed2e03b7f..000000000 --- a/scripts/config.guess +++ /dev/null @@ -1,1321 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-20' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; - for c in cc gcc c89 c99 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $dummy.c $dummy.o $dummy.rel ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <<EOF >$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - ftp://ftp.gnu.org/pub/gnu/config/ - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/scripts/config.rpath b/scripts/config.rpath deleted file mode 100755 index fa24bfc2d..000000000 --- a/scripts/config.rpath +++ /dev/null @@ -1,548 +0,0 @@ -#! /bin/sh -# Output a system dependent set of variables, describing how to set the -# run time search path of shared libraries in an executable. -# -# Copyright 1996-2003 Free Software Foundation, Inc. -# Taken from GNU libtool, 2001 -# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. - -# Known limitations: -# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer -# than 256 bytes, otherwise the compiler driver will dump core. The only -# known workaround is to choose shorter directory names for the build -# directory and/or the installation directory. - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -shrext=.so - -host="$1" -host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. - -wl= -if test "$GCC" = yes; then - wl='-Wl,' -else - case "$host_os" in - aix*) - wl='-Wl,' - ;; - mingw* | pw32* | os2*) - ;; - hpux9* | hpux10* | hpux11*) - wl='-Wl,' - ;; - irix5* | irix6* | nonstopux*) - wl='-Wl,' - ;; - newsos6) - ;; - linux*) - case $CC in - icc|ecc) - wl='-Wl,' - ;; - ccc) - wl='-Wl,' - ;; - esac - ;; - osf3* | osf4* | osf5*) - wl='-Wl,' - ;; - sco3.2v5*) - ;; - solaris*) - wl='-Wl,' - ;; - sunos4*) - wl='-Qoption ld ' - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - wl='-Wl,' - ;; - sysv4*MP*) - ;; - uts4*) - ;; - esac -fi - -# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. - -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no - -case "$host_os" in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - case "$host_os" in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - fi - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - netbsd*) - ;; - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - sunos4*) - hardcode_direct=yes - ;; - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - esac - if test "$ld_shlibs" = yes; then - # Unlike libtool, we use -rpath here, not --rpath, since the documented - # option of GNU ld is called -rpath, not --rpath. - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - fi -else - case "$host_os" in - aix3*) - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - else - aix_use_runtimelinking=no - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - fi - hardcode_direct=yes - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - fi - # Begin _LT_AC_SYS_LIBPATH_AIX. - echo 'int main () { return 0; }' > conftest.c - ${CC} ${LDFLAGS} conftest.c -o conftest - aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - fi - if test -z "$aix_libpath"; then - aix_libpath="/usr/lib:/lib" - fi - rm -f conftest.c conftest - # End _LT_AC_SYS_LIBPATH_AIX. - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - else - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - fi - fi - ;; - amigaos*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - bsdi4*) - ;; - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - libext=lib - ;; - darwin* | rhapsody*) - if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then - hardcode_direct=no - fi - ;; - dgux*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - freebsd1*) - ld_shlibs=no - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) - hardcode_direct=yes - hardcode_minus_L=yes - ;; - freebsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - hpux9*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - hpux10* | hpux11*) - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - irix5* | irix6* | nonstopux*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - netbsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - newsos6) - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - openbsd*) - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - osf3*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - osf4* | osf5*) - if test "$GCC" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - # Both cc and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - sco3.2v5*) - ;; - solaris*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - sunos4*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - ;; - sysv4) - case $host_vendor in - sni) - hardcode_direct=yes # is this really true??? - ;; - siemens) - hardcode_direct=no - ;; - motorola) - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - ;; - sysv4.3*) - ;; - sysv4*MP*) - if test -d /usr/nec; then - ld_shlibs=yes - fi - ;; - sysv4.2uw2*) - hardcode_direct=yes - hardcode_minus_L=no - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - ;; - sysv5*) - hardcode_libdir_flag_spec= - ;; - uts4*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - *) - ld_shlibs=no - ;; - esac -fi - -# Check dynamic linker characteristics -# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. -libname_spec='lib$name' -case "$host_os" in - aix3*) - ;; - aix4* | aix5*) - ;; - amigaos*) - ;; - beos*) - ;; - bsdi4*) - ;; - cygwin* | mingw* | pw32*) - shrext=.dll - ;; - darwin* | rhapsody*) - shrext=.dylib - ;; - dgux*) - ;; - freebsd1*) - ;; - freebsd*) - ;; - gnu*) - ;; - hpux9* | hpux10* | hpux11*) - case "$host_cpu" in - ia64*) - shrext=.so - ;; - hppa*64*) - shrext=.sl - ;; - *) - shrext=.sl - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case "$host_os" in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; - *) libsuff= shlibsuff= ;; - esac - ;; - esac - ;; - linux*oldld* | linux*aout* | linux*coff*) - ;; - linux*) - ;; - netbsd*) - ;; - newsos6) - ;; - nto-qnx) - ;; - openbsd*) - ;; - os2*) - libname_spec='$name' - shrext=.dll - ;; - osf3* | osf4* | osf5*) - ;; - sco3.2v5*) - ;; - solaris*) - ;; - sunos4*) - ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - ;; - sysv4*MP*) - ;; - uts4*) - ;; -esac - -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` -shlibext=`echo "$shrext" | sed -e 's,^\.,,'` -escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` - -sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF - -# How to pass a linker flag through the compiler. -wl="$escaped_wl" - -# Static library suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally "so"). -shlibext="$shlibext" - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="$hardcode_libdir_separator" - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct="$hardcode_direct" - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L="$hardcode_minus_L" - -EOF diff --git a/scripts/config.sub b/scripts/config.sub deleted file mode 100755 index f3657978c..000000000 --- a/scripts/config.sub +++ /dev/null @@ -1,1443 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-03-07' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ - | mipsisa32 | mipsisa64 \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ - | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh3eb | sh4eb) - basic_machine=sh-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/scripts/depcomp b/scripts/depcomp deleted file mode 100755 index aea3d0078..000000000 --- a/scripts/depcomp +++ /dev/null @@ -1,472 +0,0 @@ -#! /bin/sh - -# depcomp - compile a program generating dependencies as side-effects -# Copyright 1999, 2000 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi -# `libtool' can also be set to `yes' or `no'. - -if test -z "$depfile"; then - base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` - dir=`echo "$object" | sed 's,/.*$,/,'` - if test "$dir" = "$object"; then - dir= - fi - # FIXME: should be _deps on DOS. - depfile="$dir.deps/$base" -fi - -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. - "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. This file always lives in the current directory. - # Also, the AIX compiler puts `$object:' at the start of each line; - # $object doesn't have directory information. - stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" - outname="$stripped.o" - if test "$libtool" = yes; then - "$@" -Wc,-M - else - "$@" -M - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - tmpdepfile1="$dir.libs/$base.lo.d" - tmpdepfile2="$dir.libs/$base.d" - "$@" -Wc,-MD - else - tmpdepfile1="$dir$base.o.d" - tmpdepfile2="$dir$base.d" - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - if test -f "$tmpdepfile1"; then - tmpdepfile="$tmpdepfile1" - else - tmpdepfile="$tmpdepfile2" - fi - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a space and a tab in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the proprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/install-sh b/scripts/install-sh deleted file mode 100755 index 6ce63b9f7..000000000 --- a/scripts/install-sh +++ /dev/null @@ -1,294 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd=$cpprog - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd=$stripprog - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "$0: no input file specified" >&2 - exit 1 -else - : -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d "$dst" ]; then - instcmd=: - chmodcmd="" - else - instcmd=$mkdirprog - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f "$src" ] || [ -d "$src" ] - then - : - else - echo "$0: $src does not exist" >&2 - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "$0: no destination specified" >&2 - exit 1 - else - : - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d "$dst" ] - then - dst=$dst/`basename "$src"` - else - : - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' - ' -IFS="${IFS-$defaultIFS}" - -oIFS=$IFS -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS=$oIFS - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp=$pathcomp$1 - shift - - if [ ! -d "$pathcomp" ] ; - then - $mkdirprog "$pathcomp" - else - : - fi - - pathcomp=$pathcomp/ -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd "$dst" && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename "$dst"` - else - dstfile=`basename "$dst" $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename "$dst"` - else - : - fi - -# Make a couple of temp file names in the proper directory. - - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - -# Trap to clean up temp files at exit. - - trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 - trap '(exit $?); exit' 1 2 13 15 - -# Move or copy the file name to the temp name - - $doit $instcmd "$src" "$dsttmp" && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && - -# Now remove or move aside any old file at destination location. We try this -# two ways since rm can't unlink itself on some systems and the destination -# file might be busy for other reasons. In this case, the final cleanup -# might fail but the new file should still install successfully. - -{ - if [ -f "$dstdir/$dstfile" ] - then - $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || - $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || - { - echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 - (exit 1); exit - } - else - : - fi -} && - -# Now rename the file to the real destination. - - $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" - -fi && - -# The final little trick to "correctly" pass the exit status to the exit trap. - -{ - (exit 0); exit -} diff --git a/scripts/mdate-sh b/scripts/mdate-sh deleted file mode 100755 index b610b47a6..000000000 --- a/scripts/mdate-sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/sh -# Get modification time of a file or directory and pretty-print it. -# Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc. -# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Prevent date giving response in another language. -LANG=C -export LANG -LC_ALL=C -export LC_ALL -LC_TIME=C -export LC_TIME - -save_arg1="$1" - -# Find out how to get the extended ls output of a file or directory. -if ls -L /dev/null 1>/dev/null 2>&1; then - ls_command='ls -L -l -d' -else - ls_command='ls -l -d' -fi - -# A `ls -l' line looks as follows on OS/2. -# drwxrwx--- 0 Aug 11 2001 foo -# This differs from Unix, which adds ownership information. -# drwxrwx--- 2 root root 4096 Aug 11 2001 foo -# -# To find the date, we split the line on spaces and iterate on words -# until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' -# will be owned by a user whose name is a month. So we first look at -# the extended ls output of the root directory to decide how many -# words should be skipped to get the date. - -# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set - x`$ls_command /` - -# Find which argument is the month. -month= -command= -until test $month -do - shift - # Add another shift to the command. - command="$command shift;" - case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; - esac -done - -# Get the extended ls output of the file or directory. -set - x`eval "$ls_command \"\$save_arg1\""` - -# Remove all preceding arguments -eval $command - -# Get the month. Next argument is day, followed by the year or time. -case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; -esac - -day=$2 - -# Here we have to deal with the problem that the ls output gives either -# the time of day or the year. -case $3 in - *:*) set `date`; eval year=\$$# - case $2 in - Jan) nummonthtod=1;; - Feb) nummonthtod=2;; - Mar) nummonthtod=3;; - Apr) nummonthtod=4;; - May) nummonthtod=5;; - Jun) nummonthtod=6;; - Jul) nummonthtod=7;; - Aug) nummonthtod=8;; - Sep) nummonthtod=9;; - Oct) nummonthtod=10;; - Nov) nummonthtod=11;; - Dec) nummonthtod=12;; - esac - # For the first six month of the year the time notation can also - # be used for files modified in the last year. - if (expr $nummonth \> $nummonthtod) > /dev/null; - then - year=`expr $year - 1` - fi;; - *) year=$3;; -esac - -# The result. -echo $day $month $year diff --git a/scripts/missing b/scripts/missing deleted file mode 100755 index 6a37006e8..000000000 --- a/scripts/missing +++ /dev/null @@ -1,336 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing 0.4 - GNU automake" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. - You can get \`$1Help2man' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` - test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` - fi - if [ -f "$file" ]; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then - # We have makeinfo, but it failed. - exit 1 - fi - - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - tar) - shift - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - fi - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case "$firstarg" in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case "$firstarg" in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs deleted file mode 100755 index d2d5f21b6..000000000 --- a/scripts/mkinstalldirs +++ /dev/null @@ -1,111 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman <friedman@prep.ai.mit.edu> -# Created: 1993-05-16 -# Public domain - -errstatus=0 -dirmode="" - -usage="\ -Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" 1>&2 - exit 0 - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -case $dirmode in - '') - if mkdir -p -- . 2>/dev/null; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - fi - ;; - *) - if mkdir -m "$dirmode" -p -- . 2>/dev/null; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - fi - ;; -esac - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr="" - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# End: -# mkinstalldirs ends here diff --git a/scripts/texinfo.tex b/scripts/texinfo.tex deleted file mode 100644 index e9293f3b9..000000000 --- a/scripts/texinfo.tex +++ /dev/null @@ -1,6773 +0,0 @@ -% texinfo.tex -- TeX macros to handle Texinfo files. -% -% Load plain if necessary, i.e., if running under initex. -\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi -% -\def\texinfoversion{2003-05-04.08} -% -% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, -% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -% -% This texinfo.tex file is free software; you can redistribute it and/or -% modify it under the terms of the GNU General Public License as -% published by the Free Software Foundation; either version 2, or (at -% your option) any later version. -% -% This texinfo.tex file is distributed in the hope that it will be -% useful, but WITHOUT ANY WARRANTY; without even the implied warranty -% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -% General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this texinfo.tex file; see the file COPYING. If not, write -% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -% Boston, MA 02111-1307, USA. -% -% In other words, you are welcome to use, share and improve this program. -% You are forbidden to forbid anyone else to use, share and improve -% what you give them. Help stamp out software-hoarding! -% -% Please try the latest version of texinfo.tex before submitting bug -% reports; you can get the latest version from: -% ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex -% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html) -% ftp://tug.org/tex/texinfo.tex -% (and all CTAN mirrors, see http://www.ctan.org), -% and /home/gd/gnu/doc/texinfo.tex on the GNU machines. -% -% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. -% -% The texinfo.tex in any given Texinfo distribution could well be out -% of date, so if that's what you're using, please check. -% -% Send bug reports to bug-texinfo@gnu.org. Please include including a -% complete document in each bug report with which we can reproduce the -% problem. Patches are, of course, greatly appreciated. -% -% To process a Texinfo manual with TeX, it's most reliable to use the -% texi2dvi shell script that comes with the distribution. For a simple -% manual foo.texi, however, you can get away with this: -% tex foo.texi -% texindex foo.?? -% tex foo.texi -% tex foo.texi -% dvips foo.dvi -o # or whatever; this makes foo.ps. -% The extra TeX runs get the cross-reference information correct. -% Sometimes one run after texindex suffices, and sometimes you need more -% than two; texi2dvi does it as many times as necessary. -% -% It is possible to adapt texinfo.tex for other languages, to some -% extent. You can get the existing language-specific files from the -% full Texinfo distribution. - -\message{Loading texinfo [version \texinfoversion]:} - -% If in a .fmt file, print the version number -% and turn on active characters that we couldn't do earlier because -% they might have appeared in the input file name. -\everyjob{\message{[Texinfo version \texinfoversion]}% - \catcode`+=\active \catcode`\_=\active} - -\message{Basics,} -\chardef\other=12 - -% We never want plain's \outer definition of \+ in Texinfo. -% For @tex, we can use \tabalign. -\let\+ = \relax - -% Save some plain tex macros whose names we will redefine. -\let\ptexb=\b -\let\ptexbullet=\bullet -\let\ptexc=\c -\let\ptexcomma=\, -\let\ptexdot=\. -\let\ptexdots=\dots -\let\ptexend=\end -\let\ptexequiv=\equiv -\let\ptexexclam=\! -\let\ptexgtr=> -\let\ptexhat=^ -\let\ptexi=\i -\let\ptexindent=\indent -\let\ptexlbrace=\{ -\let\ptexless=< -\let\ptexplus=+ -\let\ptexrbrace=\} -\let\ptexslash=\/ -\let\ptexstar=\* -\let\ptext=\t - -% If this character appears in an error message or help string, it -% starts a new line in the output. -\newlinechar = `^^J - -% Set up fixed words for English if not already set. -\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi -\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi -\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi -\ifx\putwordin\undefined \gdef\putwordin{in}\fi -\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi -\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi -\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi -\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi -\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi -\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi -\ifx\putwordof\undefined \gdef\putwordof{of}\fi -\ifx\putwordon\undefined \gdef\putwordon{on}\fi -\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi -\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi -\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi -\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi -\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi -\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi -\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi -% -\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi -\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi -\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi -\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi -\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi -\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi -\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi -\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi -\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi -\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi -\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi -\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi -% -\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi -\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi -\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi -\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi -\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi -\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi - -% In some macros, we cannot use the `\? notation---the left quote is -% in some cases the escape char. -\chardef\colonChar = `\: -\chardef\commaChar = `\, -\chardef\dotChar = `\. -\chardef\equalChar = `\= -\chardef\exclamChar= `\! -\chardef\questChar = `\? -\chardef\semiChar = `\; -\chardef\spaceChar = `\ % -\chardef\underChar = `\_ - -% Ignore a token. -% -\def\gobble#1{} - -% True if #1 is the empty string, i.e., called like `\ifempty{}'. -% -\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}% -\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}% - -% Hyphenation fixes. -\hyphenation{ap-pen-dix} -\hyphenation{eshell} -\hyphenation{mini-buf-fer mini-buf-fers} -\hyphenation{time-stamp} -\hyphenation{white-space} - -% Margin to add to right of even pages, to left of odd pages. -\newdimen\bindingoffset -\newdimen\normaloffset -\newdimen\pagewidth \newdimen\pageheight - -% Sometimes it is convenient to have everything in the transcript file -% and nothing on the terminal. We don't just call \tracingall here, -% since that produces some useless output on the terminal. We also make -% some effort to order the tracing commands to reduce output in the log -% file; cf. trace.sty in LaTeX. -% -\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% -\def\loggingall{% - \tracingstats2 - \tracingpages1 - \tracinglostchars2 % 2 gives us more in etex - \tracingparagraphs1 - \tracingoutput1 - \tracingmacros2 - \tracingrestores1 - \showboxbreadth\maxdimen \showboxdepth\maxdimen - \ifx\eTeXversion\undefined\else % etex gives us more logging - \tracingscantokens1 - \tracingifs1 - \tracinggroups1 - \tracingnesting2 - \tracingassigns1 - \fi - \tracingcommands3 % 3 gives us more in etex - \errorcontextlines\maxdimen -}% - -% add check for \lastpenalty to plain's definitions. If the last thing -% we did was a \nobreak, we don't want to insert more space. -% -\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount - \removelastskip\penalty-50\smallskip\fi\fi} -\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount - \removelastskip\penalty-100\medskip\fi\fi} -\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount - \removelastskip\penalty-200\bigskip\fi\fi} - -% For @cropmarks command. -% Do @cropmarks to get crop marks. -% -\newif\ifcropmarks -\let\cropmarks = \cropmarkstrue -% -% Dimensions to add cropmarks at corners. -% Added by P. A. MacKay, 12 Nov. 1986 -% -\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines -\newdimen\cornerlong \cornerlong=1pc -\newdimen\cornerthick \cornerthick=.3pt -\newdimen\topandbottommargin \topandbottommargin=.75in - -% Main output routine. -\chardef\PAGE = 255 -\output = {\onepageout{\pagecontents\PAGE}} - -\newbox\headlinebox -\newbox\footlinebox - -% \onepageout takes a vbox as an argument. Note that \pagecontents -% does insertions, but you have to call it yourself. -\def\onepageout#1{% - \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi - % - \ifodd\pageno \advance\hoffset by \bindingoffset - \else \advance\hoffset by -\bindingoffset\fi - % - % Do this outside of the \shipout so @code etc. will be expanded in - % the headline as they should be, not taken literally (outputting ''code). - \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% - \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% - % - {% - % Have to do this stuff outside the \shipout because we want it to - % take effect in \write's, yet the group defined by the \vbox ends - % before the \shipout runs. - % - \escapechar = `\\ % use backslash in output files. - \indexdummies % don't expand commands in the output. - \normalturnoffactive % \ in index entries must not stay \, e.g., if - % the page break happens to be in the middle of an example. - \shipout\vbox{% - % Do this early so pdf references go to the beginning of the page. - \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi - % - \ifcropmarks \vbox to \outervsize\bgroup - \hsize = \outerhsize - \vskip-\topandbottommargin - \vtop to0pt{% - \line{\ewtop\hfil\ewtop}% - \nointerlineskip - \line{% - \vbox{\moveleft\cornerthick\nstop}% - \hfill - \vbox{\moveright\cornerthick\nstop}% - }% - \vss}% - \vskip\topandbottommargin - \line\bgroup - \hfil % center the page within the outer (page) hsize. - \ifodd\pageno\hskip\bindingoffset\fi - \vbox\bgroup - \fi - % - \unvbox\headlinebox - \pagebody{#1}% - \ifdim\ht\footlinebox > 0pt - % Only leave this space if the footline is nonempty. - % (We lessened \vsize for it in \oddfootingxxx.) - % The \baselineskip=24pt in plain's \makefootline has no effect. - \vskip 2\baselineskip - \unvbox\footlinebox - \fi - % - \ifcropmarks - \egroup % end of \vbox\bgroup - \hfil\egroup % end of (centering) \line\bgroup - \vskip\topandbottommargin plus1fill minus1fill - \boxmaxdepth = \cornerthick - \vbox to0pt{\vss - \line{% - \vbox{\moveleft\cornerthick\nsbot}% - \hfill - \vbox{\moveright\cornerthick\nsbot}% - }% - \nointerlineskip - \line{\ewbot\hfil\ewbot}% - }% - \egroup % \vbox from first cropmarks clause - \fi - }% end of \shipout\vbox - }% end of group with \normalturnoffactive - \advancepageno - \ifnum\outputpenalty>-20000 \else\dosupereject\fi -} - -\newinsert\margin \dimen\margin=\maxdimen - -\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} -{\catcode`\@ =11 -\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi -% marginal hacks, juha@viisa.uucp (Juha Takala) -\ifvoid\margin\else % marginal info is present - \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi -\dimen@=\dp#1 \unvbox#1 -\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi -\ifr@ggedbottom \kern-\dimen@ \vfil \fi} -} - -% Here are the rules for the cropmarks. Note that they are -% offset so that the space between them is truly \outerhsize or \outervsize -% (P. A. MacKay, 12 November, 1986) -% -\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} -\def\nstop{\vbox - {\hrule height\cornerthick depth\cornerlong width\cornerthick}} -\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} -\def\nsbot{\vbox - {\hrule height\cornerlong depth\cornerthick width\cornerthick}} - -% Parse an argument, then pass it to #1. The argument is the rest of -% the input line (except we remove a trailing comment). #1 should be a -% macro which expects an ordinary undelimited TeX argument. -% -\def\parsearg#1{% - \let\next = #1% - \begingroup - \obeylines - \futurelet\temp\parseargx -} - -% If the next token is an obeyed space (from an @example environment or -% the like), remove it and recurse. Otherwise, we're done. -\def\parseargx{% - % \obeyedspace is defined far below, after the definition of \sepspaces. - \ifx\obeyedspace\temp - \expandafter\parseargdiscardspace - \else - \expandafter\parseargline - \fi -} - -% Remove a single space (as the delimiter token to the macro call). -{\obeyspaces % - \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} - -{\obeylines % - \gdef\parseargline#1^^M{% - \endgroup % End of the group started in \parsearg. - % - % First remove any @c comment, then any @comment. - % Result of each macro is put in \toks0. - \argremovec #1\c\relax % - \expandafter\argremovecomment \the\toks0 \comment\relax % - % - % Call the caller's macro, saved as \next in \parsearg. - \expandafter\next\expandafter{\the\toks0}% - }% -} - -% Since all \c{,omment} does is throw away the argument, we can let TeX -% do that for us. The \relax here is matched by the \relax in the call -% in \parseargline; it could be more or less anything, its purpose is -% just to delimit the argument to the \c. -\def\argremovec#1\c#2\relax{\toks0 = {#1}} -\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} - -% \argremovec{,omment} might leave us with trailing spaces, though; e.g., -% @end itemize @c foo -% will have two active spaces as part of the argument with the -% `itemize'. Here we remove all active spaces from #1, and assign the -% result to \toks0. -% -% This loses if there are any *other* active characters besides spaces -% in the argument -- _ ^ +, for example -- since they get expanded. -% Fortunately, Texinfo does not define any such commands. (If it ever -% does, the catcode of the characters in questionwill have to be changed -% here.) But this means we cannot call \removeactivespaces as part of -% \argremovec{,omment}, since @c uses \parsearg, and thus the argument -% that \parsearg gets might well have any character at all in it. -% -\def\removeactivespaces#1{% - \begingroup - \ignoreactivespaces - \edef\temp{#1}% - \global\toks0 = \expandafter{\temp}% - \endgroup -} - -% Change the active space to expand to nothing. -% -\begingroup - \obeyspaces - \gdef\ignoreactivespaces{\obeyspaces\let =\empty} -\endgroup - - -\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} - -%% These are used to keep @begin/@end levels from running away -%% Call \inENV within environments (after a \begingroup) -\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} -\def\ENVcheck{% -\ifENV\errmessage{Still within an environment; press RETURN to continue} -\endgroup\fi} % This is not perfect, but it should reduce lossage - -% @begin foo is the same as @foo, for now. -\newhelp\EMsimple{Press RETURN to continue.} - -\outer\def\begin{\parsearg\beginxxx} - -\def\beginxxx #1{% -\expandafter\ifx\csname #1\endcsname\relax -{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else -\csname #1\endcsname\fi} - -% @end foo executes the definition of \Efoo. -% -\def\end{\parsearg\endxxx} -\def\endxxx #1{% - \removeactivespaces{#1}% - \edef\endthing{\the\toks0}% - % - \expandafter\ifx\csname E\endthing\endcsname\relax - \expandafter\ifx\csname \endthing\endcsname\relax - % There's no \foo, i.e., no ``environment'' foo. - \errhelp = \EMsimple - \errmessage{Undefined command `@end \endthing'}% - \else - \unmatchedenderror\endthing - \fi - \else - % Everything's ok; the right environment has been started. - \csname E\endthing\endcsname - \fi -} - -% There is an environment #1, but it hasn't been started. Give an error. -% -\def\unmatchedenderror#1{% - \errhelp = \EMsimple - \errmessage{This `@end #1' doesn't have a matching `@#1'}% -} - -% Define the control sequence \E#1 to give an unmatched @end error. -% -\def\defineunmatchedend#1{% - \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% -} - - -%% Simple single-character @ commands - -% @@ prints an @ -% Kludge this until the fonts are right (grr). -\def\@{{\tt\char64}} - -% This is turned off because it was never documented -% and you can use @w{...} around a quote to suppress ligatures. -%% Define @` and @' to be the same as ` and ' -%% but suppressing ligatures. -%\def\`{{`}} -%\def\'{{'}} - -% Used to generate quoted braces. -\def\mylbrace {{\tt\char123}} -\def\myrbrace {{\tt\char125}} -\let\{=\mylbrace -\let\}=\myrbrace -\begingroup - % Definitions to produce \{ and \} commands for indices, - % and @{ and @} for the aux file. - \catcode`\{ = \other \catcode`\} = \other - \catcode`\[ = 1 \catcode`\] = 2 - \catcode`\! = 0 \catcode`\\ = \other - !gdef!lbracecmd[\{]% - !gdef!rbracecmd[\}]% - !gdef!lbraceatcmd[@{]% - !gdef!rbraceatcmd[@}]% -!endgroup - -% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent -% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. -\let\, = \c -\let\dotaccent = \. -\def\ringaccent#1{{\accent23 #1}} -\let\tieaccent = \t -\let\ubaraccent = \b -\let\udotaccent = \d - -% Other special characters: @questiondown @exclamdown -% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. -\def\questiondown{?`} -\def\exclamdown{!`} - -% Dotless i and dotless j, used for accents. -\def\imacro{i} -\def\jmacro{j} -\def\dotless#1{% - \def\temp{#1}% - \ifx\temp\imacro \ptexi - \else\ifx\temp\jmacro \j - \else \errmessage{@dotless can be used only with i or j}% - \fi\fi -} - -% Be sure we're in horizontal mode when doing a tie, since we make space -% equivalent to this in @example-like environments. Otherwise, a space -% at the beginning of a line will start with \penalty -- and -% since \penalty is valid in vertical mode, we'd end up putting the -% penalty on the vertical list instead of in the new paragraph. -{\catcode`@ = 11 - % Avoid using \@M directly, because that causes trouble - % if the definition is written into an index file. - \global\let\tiepenalty = \@M - \gdef\tie{\leavevmode\penalty\tiepenalty\ } -} - -% @: forces normal size whitespace following. -\def\:{\spacefactor=1000 } - -% @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} - -% @/ allows a line break. -\let\/=\allowbreak - -% @. is an end-of-sentence period. -\def\.{.\spacefactor=3000 } - -% @! is an end-of-sentence bang. -\def\!{!\spacefactor=3000 } - -% @? is an end-of-sentence query. -\def\?{?\spacefactor=3000 } - -% @w prevents a word break. Without the \leavevmode, @w at the -% beginning of a paragraph, when TeX is still in vertical mode, would -% produce a whole line of output instead of starting the paragraph. -\def\w#1{\leavevmode\hbox{#1}} - -% @group ... @end group forces ... to be all on one page, by enclosing -% it in a TeX vbox. We use \vtop instead of \vbox to construct the box -% to keep its height that of a normal line. According to the rules for -% \topskip (p.114 of the TeXbook), the glue inserted is -% max (\topskip - \ht (first item), 0). If that height is large, -% therefore, no glue is inserted, and the space between the headline and -% the text is small, which looks bad. -% -% Another complication is that the group might be very large. This can -% cause the glue on the previous page to be unduly stretched, because it -% does not have much material. In this case, it's better to add an -% explicit \vfill so that the extra space is at the bottom. The -% threshold for doing this is if the group is more than \vfilllimit -% percent of a page (\vfilllimit can be changed inside of @tex). -% -\newbox\groupbox -\def\vfilllimit{0.7} -% -\def\group{\begingroup - \ifnum\catcode13=\active \else - \errhelp = \groupinvalidhelp - \errmessage{@group invalid in context where filling is enabled}% - \fi - % - % The \vtop we start below produces a box with normal height and large - % depth; thus, TeX puts \baselineskip glue before it, and (when the - % next line of text is done) \lineskip glue after it. (See p.82 of - % the TeXbook.) Thus, space below is not quite equal to space - % above. But it's pretty close. - \def\Egroup{% - \egroup % End the \vtop. - % \dimen0 is the vertical size of the group's box. - \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox - % \dimen2 is how much space is left on the page (more or less). - \dimen2 = \pageheight \advance\dimen2 by -\pagetotal - % if the group doesn't fit on the current page, and it's a big big - % group, force a page break. - \ifdim \dimen0 > \dimen2 - \ifdim \pagetotal < \vfilllimit\pageheight - \page - \fi - \fi - \copy\groupbox - \endgroup % End the \group. - }% - % - \setbox\groupbox = \vtop\bgroup - % We have to put a strut on the last line in case the @group is in - % the midst of an example, rather than completely enclosing it. - % Otherwise, the interline space between the last line of the group - % and the first line afterwards is too small. But we can't put the - % strut in \Egroup, since there it would be on a line by itself. - % Hence this just inserts a strut at the beginning of each line. - \everypar = {\strut}% - % - % Since we have a strut on every line, we don't need any of TeX's - % normal interline spacing. - \offinterlineskip - % - % OK, but now we have to do something about blank - % lines in the input in @example-like environments, which normally - % just turn into \lisppar, which will insert no space now that we've - % turned off the interline space. Simplest is to make them be an - % empty paragraph. - \ifx\par\lisppar - \edef\par{\leavevmode \par}% - % - % Reset ^^M's definition to new definition of \par. - \obeylines - \fi - % - % Do @comment since we are called inside an environment such as - % @example, where each end-of-line in the input causes an - % end-of-line in the output. We don't want the end-of-line after - % the `@group' to put extra space in the output. Since @group - % should appear on a line by itself (according to the Texinfo - % manual), we don't worry about eating any user text. - \comment -} -% -% TeX puts in an \escapechar (i.e., `@') at the beginning of the help -% message, so this ends up printing `@group can only ...'. -% -\newhelp\groupinvalidhelp{% -group can only be used in environments such as @example,^^J% -where each line of input produces a line of output.} - -% @need space-in-mils -% forces a page break if there is not space-in-mils remaining. - -\newdimen\mil \mil=0.001in - -\def\need{\parsearg\needx} - -% Old definition--didn't work. -%\def\needx #1{\par % -%% This method tries to make TeX break the page naturally -%% if the depth of the box does not fit. -%{\baselineskip=0pt% -%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak -%\prevdepth=-1000pt -%}} - -\def\needx#1{% - % Ensure vertical mode, so we don't make a big box in the middle of a - % paragraph. - \par - % - % If the @need value is less than one line space, it's useless. - \dimen0 = #1\mil - \dimen2 = \ht\strutbox - \advance\dimen2 by \dp\strutbox - \ifdim\dimen0 > \dimen2 - % - % Do a \strut just to make the height of this box be normal, so the - % normal leading is inserted relative to the preceding line. - % And a page break here is fine. - \vtop to #1\mil{\strut\vfil}% - % - % TeX does not even consider page breaks if a penalty added to the - % main vertical list is 10000 or more. But in order to see if the - % empty box we just added fits on the page, we must make it consider - % page breaks. On the other hand, we don't want to actually break the - % page after the empty box. So we use a penalty of 9999. - % - % There is an extremely small chance that TeX will actually break the - % page at this \penalty, if there are no other feasible breakpoints in - % sight. (If the user is using lots of big @group commands, which - % almost-but-not-quite fill up a page, TeX will have a hard time doing - % good page breaking, for example.) However, I could not construct an - % example where a page broke at this \penalty; if it happens in a real - % document, then we can reconsider our strategy. - \penalty9999 - % - % Back up by the size of the box, whether we did a page break or not. - \kern -#1\mil - % - % Do not allow a page break right after this kern. - \nobreak - \fi -} - -% @br forces paragraph break - -\let\br = \par - -% @dots{} output an ellipsis using the current font. -% We do .5em per period so that it has the same spacing in a typewriter -% font as three actual period characters. -% -\def\dots{% - \leavevmode - \hbox to 1.5em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% -} - -% @enddots{} is an end-of-sentence ellipsis. -% -\def\enddots{% - \leavevmode - \hbox to 2em{% - \hskip 0pt plus 0.25fil minus 0.25fil - .\hss.\hss.\hss.% - \hskip 0pt plus 0.5fil minus 0.5fil - }% - \spacefactor=3000 -} - -% @page forces the start of a new page. -% -\def\page{\par\vfill\supereject} - -% @exdent text.... -% outputs text on separate line in roman font, starting at standard page margin - -% This records the amount of indent in the innermost environment. -% That's how much \exdent should take out. -\newskip\exdentamount - -% This defn is used inside fill environments such as @defun. -\def\exdent{\parsearg\exdentyyy} -\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} - -% This defn is used inside nofill environments such as @example. -\def\nofillexdent{\parsearg\nofillexdentyyy} -\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount -\leftline{\hskip\leftskip{\rm#1}}}} - -% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current -% paragraph. For more general purposes, use the \margin insertion -% class. WHICH is `l' or `r'. -% -\newskip\inmarginspacing \inmarginspacing=1cm -\def\strutdepth{\dp\strutbox} -% -\def\doinmargin#1#2{\strut\vadjust{% - \nobreak - \kern-\strutdepth - \vtop to \strutdepth{% - \baselineskip=\strutdepth - \vss - % if you have multiple lines of stuff to put here, you'll need to - % make the vbox yourself of the appropriate size. - \ifx#1l% - \llap{\ignorespaces #2\hskip\inmarginspacing}% - \else - \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% - \fi - \null - }% -}} -\def\inleftmargin{\doinmargin l} -\def\inrightmargin{\doinmargin r} -% -% @inmargin{TEXT [, RIGHT-TEXT]} -% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; -% else use TEXT for both). -% -\def\inmargin#1{\parseinmargin #1,,\finish} -\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \def\lefttext{#1}% have both texts - \def\righttext{#2}% - \else - \def\lefttext{#1}% have only one text - \def\righttext{#1}% - \fi - % - \ifodd\pageno - \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin - \else - \def\temp{\inleftmargin\lefttext}% - \fi - \temp -} - -% @include file insert text of that file as input. -% Allow normal characters that we make active in the argument (a file name). -\def\include{\begingroup - \catcode`\\=\other - \catcode`~=\other - \catcode`^=\other - \catcode`_=\other - \catcode`|=\other - \catcode`<=\other - \catcode`>=\other - \catcode`+=\other - \parsearg\includezzz} -% Restore active chars for included file. -\def\includezzz#1{\endgroup\begingroup - % Read the included file in a group so nested @include's work. - \def\thisfile{#1}% - \let\value=\expandablevalue - \input\thisfile -\endgroup} - -\def\thisfile{} - -% @center line -% outputs that line, centered. -% -\def\center{\parsearg\docenter} -\def\docenter#1{{% - \ifhmode \hfil\break \fi - \advance\hsize by -\leftskip - \advance\hsize by -\rightskip - \line{\hfil \ignorespaces#1\unskip \hfil}% - \ifhmode \break \fi -}} - -% @sp n outputs n lines of vertical space - -\def\sp{\parsearg\spxxx} -\def\spxxx #1{\vskip #1\baselineskip} - -% @comment ...line which is ignored... -% @c is the same as @comment -% @ignore ... @end ignore is another way to write a comment - -\def\comment{\begingroup \catcode`\^^M=\other% -\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% -\commentxxx} -{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} - -\let\c=\comment - -% @paragraphindent NCHARS -% We'll use ems for NCHARS, close enough. -% NCHARS can also be the word `asis' or `none'. -% We cannot feasibly implement @paragraphindent asis, though. -% -\def\asisword{asis} % no translation, these are keywords -\def\noneword{none} -% -\def\paragraphindent{\parsearg\doparagraphindent} -\def\doparagraphindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \defaultparindent = 0pt - \else - \defaultparindent = #1em - \fi - \fi - \parindent = \defaultparindent -} - -% @exampleindent NCHARS -% We'll use ems for NCHARS like @paragraphindent. -% It seems @exampleindent asis isn't necessary, but -% I preserve it to make it similar to @paragraphindent. -\def\exampleindent{\parsearg\doexampleindent} -\def\doexampleindent#1{% - \def\temp{#1}% - \ifx\temp\asisword - \else - \ifx\temp\noneword - \lispnarrowing = 0pt - \else - \lispnarrowing = #1em - \fi - \fi -} - -% @firstparagraphindent WORD -% If WORD is `none', then suppress indentation of the first paragraph -% after a section heading. If WORD is `insert', then do indentat such -% paragraphs. -% -% The paragraph indentation is suppressed or not by calling -% \suppressfirstparagraphindent, which the sectioning commands do. We -% switch the definition of this back and forth according to WORD. By -% default, we suppress indentation. -% -\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} -\newdimen\currentparindent -% -\def\insertword{insert} -% -\def\firstparagraphindent{\parsearg\dofirstparagraphindent} -\def\dofirstparagraphindent#1{% - \def\temp{#1}% - \ifx\temp\noneword - \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent - \else\ifx\temp\insertword - \let\suppressfirstparagraphindent = \relax - \else - \errhelp = \EMsimple - \errmessage{Unknown @firstparagraphindent option `\temp'}% - \fi\fi -} - -% Here is how we actually suppress indentation. Redefine \everypar to -% \kern backwards by \parindent, and then reset itself to empty. -% -% We also make \indent itself not actually do anything until the next -% paragraph. -% -\gdef\dosuppressfirstparagraphindent{% - \gdef\indent{% - \global\let\indent=\ptexindent - \global\everypar = {}% - }% - \global\everypar = {% - \kern-\parindent - \global\let\indent=\ptexindent - \global\everypar = {}% - }% -}% - - -% @asis just yields its argument. Used with @table, for example. -% -\def\asis#1{#1} - -% @math outputs its argument in math mode. -% We don't use $'s directly in the definition of \math because we need -% to set catcodes according to plain TeX first, to allow for subscripts, -% superscripts, special math chars, etc. -% -\let\implicitmath = $%$ font-lock fix -% -% One complication: _ usually means subscripts, but it could also mean -% an actual _ character, as in @math{@var{some_variable} + 1}. So make -% _ within @math be active (mathcode "8000), and distinguish by seeing -% if the current family is \slfam, which is what @var uses. -% -{\catcode\underChar = \active -\gdef\mathunderscore{% - \catcode\underChar=\active - \def_{\ifnum\fam=\slfam \_\else\sb\fi}% -}} -% -% Another complication: we want \\ (and @\) to output a \ character. -% FYI, plain.tex uses \\ as a temporary control sequence (why?), but -% this is not advertised and we don't care. Texinfo does not -% otherwise define @\. -% -% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. -\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} -% -\def\math{% - \tex - \mathcode`\_="8000 \mathunderscore - \let\\ = \mathbackslash - \mathactive - \implicitmath\finishmath} -\def\finishmath#1{#1\implicitmath\Etex} - -% Some active characters (such as <) are spaced differently in math. -% We have to reset their definitions in case the @math was an -% argument to a command which set the catcodes (such as @item or @section). -% -{ - \catcode`^ = \active - \catcode`< = \active - \catcode`> = \active - \catcode`+ = \active - \gdef\mathactive{% - \let^ = \ptexhat - \let< = \ptexless - \let> = \ptexgtr - \let+ = \ptexplus - } -} - -% @bullet and @minus need the same treatment as @math, just above. -\def\bullet{\implicitmath\ptexbullet\implicitmath} -\def\minus{\implicitmath-\implicitmath} - -% @refill is a no-op. -\let\refill=\relax - -% If working on a large document in chapters, it is convenient to -% be able to disable indexing, cross-referencing, and contents, for test runs. -% This is done with @novalidate (before @setfilename). -% -\newif\iflinks \linkstrue % by default we want the aux files. -\let\novalidate = \linksfalse - -% @setfilename is done at the beginning of every texinfo file. -% So open here the files we need to have open while reading the input. -% This makes it possible to make a .fmt file for texinfo. -\def\setfilename{% - \iflinks - \readauxfile - \fi % \openindices needs to do some work in any case. - \openindices - \fixbackslash % Turn off hack to swallow `\input texinfo'. - \global\let\setfilename=\comment % Ignore extra @setfilename cmds. - % - % If texinfo.cnf is present on the system, read it. - % Useful for site-wide @afourpaper, etc. - % Just to be on the safe side, close the input stream before the \input. - \openin 1 texinfo.cnf - \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi - \closein1 - \temp - % - \comment % Ignore the actual filename. -} - -% Called from \setfilename. -% -\def\openindices{% - \newindex{cp}% - \newcodeindex{fn}% - \newcodeindex{vr}% - \newcodeindex{tp}% - \newcodeindex{ky}% - \newcodeindex{pg}% -} - -% @bye. -\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} - - -\message{pdf,} -% adobe `portable' document format -\newcount\tempnum -\newcount\lnkcount -\newtoks\filename -\newcount\filenamelength -\newcount\pgn -\newtoks\toksA -\newtoks\toksB -\newtoks\toksC -\newtoks\toksD -\newbox\boxA -\newcount\countA -\newif\ifpdf -\newif\ifpdfmakepagedest - -\ifx\pdfoutput\undefined - \pdffalse - \let\pdfmkdest = \gobble - \let\pdfurl = \gobble - \let\endlink = \relax - \let\linkcolor = \relax - \let\pdfmakeoutlines = \relax -\else - \pdftrue - \pdfoutput = 1 - \input pdfcolor - \def\dopdfimage#1#2#3{% - \def\imagewidth{#2}% - \def\imageheight{#3}% - % without \immediate, pdftex seg faults when the same image is - % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) - \ifnum\pdftexversion < 14 - \immediate\pdfimage - \else - \immediate\pdfximage - \fi - \ifx\empty\imagewidth\else width \imagewidth \fi - \ifx\empty\imageheight\else height \imageheight \fi - \ifnum\pdftexversion<13 - #1.pdf% - \else - {#1.pdf}% - \fi - \ifnum\pdftexversion < 14 \else - \pdfrefximage \pdflastximage - \fi} - \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}} - \def\pdfmkpgn#1{#1} - \let\linkcolor = \Blue % was Cyan, but that seems light? - \def\endlink{\Black\pdfendlink} - % Adding outlines to PDF; macros for calculating structure of outlines - % come from Petr Olsak - \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% - \else \csname#1\endcsname \fi} - \def\advancenumber#1{\tempnum=\expnumber{#1}\relax - \advance\tempnum by1 - \expandafter\xdef\csname#1\endcsname{\the\tempnum}} - \def\pdfmakeoutlines{{% - \openin 1 \jobname.toc - \ifeof 1\else\begingroup - \closein 1 - % Thanh's hack / proper braces in bookmarks - \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace - \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace - % - \def\chapentry ##1##2##3{} - \def\secentry ##1##2##3##4{\advancenumber{chap##2}} - \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}} - \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}} - \let\appendixentry = \chapentry - \let\unnumbchapentry = \chapentry - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - \input \jobname.toc - \def\chapentry ##1##2##3{% - \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}} - \def\secentry ##1##2##3##4{% - \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}} - \def\subsecentry ##1##2##3##4##5{% - \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}} - \def\subsubsecentry ##1##2##3##4##5##6{% - \pdfoutline goto name{\pdfmkpgn{##6}}{##1}} - \let\appendixentry = \chapentry - \let\unnumbchapentry = \chapentry - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - % - % Make special characters normal for writing to the pdf file. - % - \indexnofonts - \let\tt=\relax - \turnoffactive - \input \jobname.toc - \endgroup\fi - }} - \def\makelinks #1,{% - \def\params{#1}\def\E{END}% - \ifx\params\E - \let\nextmakelinks=\relax - \else - \let\nextmakelinks=\makelinks - \ifnum\lnkcount>0,\fi - \picknum{#1}% - \startlink attr{/Border [0 0 0]} - goto name{\pdfmkpgn{\the\pgn}}% - \linkcolor #1% - \advance\lnkcount by 1% - \endlink - \fi - \nextmakelinks - } - \def\picknum#1{\expandafter\pn#1} - \def\pn#1{% - \def\p{#1}% - \ifx\p\lbrace - \let\nextpn=\ppn - \else - \let\nextpn=\ppnn - \def\first{#1} - \fi - \nextpn - } - \def\ppn#1{\pgn=#1\gobble} - \def\ppnn{\pgn=\first} - \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\skipspaces#1{\def\PP{#1}\def\D{|}% - \ifx\PP\D\let\nextsp\relax - \else\let\nextsp\skipspaces - \ifx\p\space\else\addtokens{\filename}{\PP}% - \advance\filenamelength by 1 - \fi - \fi - \nextsp} - \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} - \ifnum\pdftexversion < 14 - \let \startlink \pdfannotlink - \else - \let \startlink \pdfstartlink - \fi - \def\pdfurl#1{% - \begingroup - \normalturnoffactive\def\@{@}% - \let\value=\expandablevalue - \leavevmode\Red - \startlink attr{/Border [0 0 0]}% - user{/Subtype /Link /A << /S /URI /URI (#1) >>}% - % #1 - \endgroup} - \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} - \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} - \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} - \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} - \def\maketoks{% - \expandafter\poptoks\the\toksA|ENDTOKS| - \ifx\first0\adn0 - \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 - \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 - \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 - \else - \ifnum0=\countA\else\makelink\fi - \ifx\first.\let\next=\done\else - \let\next=\maketoks - \addtokens{\toksB}{\the\toksD} - \ifx\first,\addtokens{\toksB}{\space}\fi - \fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \next} - \def\makelink{\addtokens{\toksB}% - {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} - \def\pdflink#1{% - \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} - \linkcolor #1\endlink} - \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} -\fi % \ifx\pdfoutput - - -\message{fonts,} -% Font-change commands. - -% Texinfo sort of supports the sans serif font style, which plain TeX does not. -% So we set up a \sf analogous to plain's \rm, etc. -\newfam\sffam -\def\sf{\fam=\sffam \tensf} -\let\li = \sf % Sometimes we call it \li, not \sf. - -% We don't need math for this one. -\def\ttsl{\tenttsl} - -% Default leading. -\newdimen\textleading \textleading = 13.2pt - -% Set the baselineskip to #1, and the lineskip and strut size -% correspondingly. There is no deep meaning behind these magic numbers -% used as factors; they just match (closely enough) what Knuth defined. -% -\def\lineskipfactor{.08333} -\def\strutheightpercent{.70833} -\def\strutdepthpercent {.29167} -% -\def\setleading#1{% - \normalbaselineskip = #1\relax - \normallineskip = \lineskipfactor\normalbaselineskip - \normalbaselines - \setbox\strutbox =\hbox{% - \vrule width0pt height\strutheightpercent\baselineskip - depth \strutdepthpercent \baselineskip - }% -} - -% Set the font macro #1 to the font named #2, adding on the -% specified font prefix (normally `cm'). -% #3 is the font's design size, #4 is a scale factor -\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} - -% Use cm as the default font prefix. -% To specify the font prefix, you must define \fontprefix -% before you read in texinfo.tex. -\ifx\fontprefix\undefined -\def\fontprefix{cm} -\fi -% Support font families that don't use the same naming scheme as CM. -\def\rmshape{r} -\def\rmbshape{bx} %where the normal face is bold -\def\bfshape{b} -\def\bxshape{bx} -\def\ttshape{tt} -\def\ttbshape{tt} -\def\ttslshape{sltt} -\def\itshape{ti} -\def\itbshape{bxti} -\def\slshape{sl} -\def\slbshape{bxsl} -\def\sfshape{ss} -\def\sfbshape{ss} -\def\scshape{csc} -\def\scbshape{csc} - -\newcount\mainmagstep -\ifx\bigger\relax - % not really supported. - \mainmagstep=\magstep1 - \setfont\textrm\rmshape{12}{1000} - \setfont\texttt\ttshape{12}{1000} -\else - \mainmagstep=\magstephalf - \setfont\textrm\rmshape{10}{\mainmagstep} - \setfont\texttt\ttshape{10}{\mainmagstep} -\fi -% Instead of cmb10, you may want to use cmbx10. -% cmbx10 is a prettier font on its own, but cmb10 -% looks better when embedded in a line with cmr10 -% (in Bob's opinion). -\setfont\textbf\bfshape{10}{\mainmagstep} -\setfont\textit\itshape{10}{\mainmagstep} -\setfont\textsl\slshape{10}{\mainmagstep} -\setfont\textsf\sfshape{10}{\mainmagstep} -\setfont\textsc\scshape{10}{\mainmagstep} -\setfont\textttsl\ttslshape{10}{\mainmagstep} -\font\texti=cmmi10 scaled \mainmagstep -\font\textsy=cmsy10 scaled \mainmagstep - -% A few fonts for @defun, etc. -\setfont\defbf\bxshape{10}{\magstep1} %was 1314 -\setfont\deftt\ttshape{10}{\magstep1} -\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} - -% Fonts for indices, footnotes, small examples (9pt). -\setfont\smallrm\rmshape{9}{1000} -\setfont\smalltt\ttshape{9}{1000} -\setfont\smallbf\bfshape{10}{900} -\setfont\smallit\itshape{9}{1000} -\setfont\smallsl\slshape{9}{1000} -\setfont\smallsf\sfshape{9}{1000} -\setfont\smallsc\scshape{10}{900} -\setfont\smallttsl\ttslshape{10}{900} -\font\smalli=cmmi9 -\font\smallsy=cmsy9 - -% Fonts for small examples (8pt). -\setfont\smallerrm\rmshape{8}{1000} -\setfont\smallertt\ttshape{8}{1000} -\setfont\smallerbf\bfshape{10}{800} -\setfont\smallerit\itshape{8}{1000} -\setfont\smallersl\slshape{8}{1000} -\setfont\smallersf\sfshape{8}{1000} -\setfont\smallersc\scshape{10}{800} -\setfont\smallerttsl\ttslshape{10}{800} -\font\smalleri=cmmi8 -\font\smallersy=cmsy8 - -% Fonts for title page: -\setfont\titlerm\rmbshape{12}{\magstep3} -\setfont\titleit\itbshape{10}{\magstep4} -\setfont\titlesl\slbshape{10}{\magstep4} -\setfont\titlett\ttbshape{12}{\magstep3} -\setfont\titlettsl\ttslshape{10}{\magstep4} -\setfont\titlesf\sfbshape{17}{\magstep1} -\let\titlebf=\titlerm -\setfont\titlesc\scbshape{10}{\magstep4} -\font\titlei=cmmi12 scaled \magstep3 -\font\titlesy=cmsy10 scaled \magstep4 -\def\authorrm{\secrm} -\def\authortt{\sectt} - -% Chapter (and unnumbered) fonts (17.28pt). -\setfont\chaprm\rmbshape{12}{\magstep2} -\setfont\chapit\itbshape{10}{\magstep3} -\setfont\chapsl\slbshape{10}{\magstep3} -\setfont\chaptt\ttbshape{12}{\magstep2} -\setfont\chapttsl\ttslshape{10}{\magstep3} -\setfont\chapsf\sfbshape{17}{1000} -\let\chapbf=\chaprm -\setfont\chapsc\scbshape{10}{\magstep3} -\font\chapi=cmmi12 scaled \magstep2 -\font\chapsy=cmsy10 scaled \magstep3 - -% Section fonts (14.4pt). -\setfont\secrm\rmbshape{12}{\magstep1} -\setfont\secit\itbshape{10}{\magstep2} -\setfont\secsl\slbshape{10}{\magstep2} -\setfont\sectt\ttbshape{12}{\magstep1} -\setfont\secttsl\ttslshape{10}{\magstep2} -\setfont\secsf\sfbshape{12}{\magstep1} -\let\secbf\secrm -\setfont\secsc\scbshape{10}{\magstep2} -\font\seci=cmmi12 scaled \magstep1 -\font\secsy=cmsy10 scaled \magstep2 - -% Subsection fonts (13.15pt). -\setfont\ssecrm\rmbshape{12}{\magstephalf} -\setfont\ssecit\itbshape{10}{1315} -\setfont\ssecsl\slbshape{10}{1315} -\setfont\ssectt\ttbshape{12}{\magstephalf} -\setfont\ssecttsl\ttslshape{10}{1315} -\setfont\ssecsf\sfbshape{12}{\magstephalf} -\let\ssecbf\ssecrm -\setfont\ssecsc\scbshape{10}{\magstep1} -\font\sseci=cmmi12 scaled \magstephalf -\font\ssecsy=cmsy10 scaled 1315 -% The smallcaps and symbol fonts should actually be scaled \magstep1.5, -% but that is not a standard magnification. - -% In order for the font changes to affect most math symbols and letters, -% we have to define the \textfont of the standard families. Since -% texinfo doesn't allow for producing subscripts and superscripts except -% in the main text, we don't bother to reset \scriptfont and -% \scriptscriptfont (which would also require loading a lot more fonts). -% -\def\resetmathfonts{% - \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy - \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf - \textfont\ttfam=\tentt \textfont\sffam=\tensf -} - -% The font-changing commands redefine the meanings of \tenSTYLE, instead -% of just \STYLE. We do this so that font changes will continue to work -% in math mode, where it is the current \fam that is relevant in most -% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam -% \tenbf}, for example. By redefining \tenbf, we obviate the need to -% redefine \bf itself. -\def\textfonts{% - \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl - \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl - \resetmathfonts \setleading{\textleading}} -\def\titlefonts{% - \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl - \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc - \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy - \let\tenttsl=\titlettsl - \resetmathfonts \setleading{25pt}} -\def\titlefont#1{{\titlefonts\rm #1}} -\def\chapfonts{% - \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl - \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl - \resetmathfonts \setleading{19pt}} -\def\secfonts{% - \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl - \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl - \resetmathfonts \setleading{16pt}} -\def\subsecfonts{% - \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl - \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl - \resetmathfonts \setleading{15pt}} -\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? -\def\smallfonts{% - \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl - \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc - \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy - \let\tenttsl=\smallttsl - \resetmathfonts \setleading{10.5pt}} -\def\smallerfonts{% - \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl - \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc - \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy - \let\tenttsl=\smallerttsl - \resetmathfonts \setleading{9.5pt}} - -% Set the fonts to use with the @small... environments. -\let\smallexamplefonts = \smallfonts - -% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample -% can fit this many characters: -% 8.5x11=86 smallbook=72 a4=90 a5=69 -% If we use \smallerfonts (8pt), then we can fit this many characters: -% 8.5x11=90+ smallbook=80 a4=90+ a5=77 -% For me, subjectively, the few extra characters that fit aren't worth -% the additional smallness of 8pt. So I'm making the default 9pt. -% -% By the way, for comparison, here's what fits with @example (10pt): -% 8.5x11=71 smallbook=60 a4=75 a5=58 -% -% I wish we used A4 paper on this side of the Atlantic. -% -% --karl, 24jan03. - - -% Set up the default fonts, so we can use them for creating boxes. -% -\textfonts - -% Define these so they can be easily changed for other fonts. -\def\angleleft{$\langle$} -\def\angleright{$\rangle$} - -% Count depth in font-changes, for error checks -\newcount\fontdepth \fontdepth=0 - -% Fonts for short table of contents. -\setfont\shortcontrm\rmshape{12}{1000} -\setfont\shortcontbf\bxshape{12}{1000} -\setfont\shortcontsl\slshape{12}{1000} -\setfont\shortconttt\ttshape{12}{1000} - -%% Add scribe-like font environments, plus @l for inline lisp (usually sans -%% serif) and @ii for TeX italic - -% \smartitalic{ARG} outputs arg in italics, followed by an italic correction -% unless the following character is such as not to need one. -\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else - \ptexslash\fi\fi\fi} -\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} -\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} - -\let\i=\smartitalic -\let\var=\smartslanted -\let\dfn=\smartslanted -\let\emph=\smartitalic -\let\cite=\smartslanted - -\def\b#1{{\bf #1}} -\let\strong=\b - -% We can't just use \exhyphenpenalty, because that only has effect at -% the end of a paragraph. Restore normal hyphenation at the end of the -% group within which \nohyphenation is presumably called. -% -\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} -\def\restorehyphenation{\hyphenchar\font = `- } - -% Set sfcode to normal for the chars that usually have another value. -% Can't use plain's \frenchspacing because it uses the `\x notation, and -% sometimes \x has an active definition that messes things up. -% -\catcode`@=11 - \def\frenchspacing{% - \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m - \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m - } -\catcode`@=\other - -\def\t#1{% - {\tt \rawbackslash \frenchspacing #1}% - \null -} -\let\ttfont=\t -\def\samp#1{`\tclose{#1}'\null} -\setfont\keyrm\rmshape{8}{1000} -\font\keysy=cmsy9 -\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% - \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% - \vbox{\hrule\kern-0.4pt - \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% - \kern-0.4pt\hrule}% - \kern-.06em\raise0.4pt\hbox{\angleright}}}} -% The old definition, with no lozenge: -%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp - -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. -\def\tclose#1{% - {% - % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % - % Switch to typewriter. - \tt - % - % But `\ ' produces the large typewriter interword space. - \def\ {{\spaceskip = 0pt{} }}% - % - % Turn off hyphenation. - \nohyphenation - % - \rawbackslash - \frenchspacing - #1% - }% - \null -} - -% We *must* turn on hyphenation at `-' and `_' in \code. -% Otherwise, it is too hard to avoid overfull hboxes -% in the Emacs manual, the Library manual, etc. - -% Unfortunately, TeX uses one parameter (\hyphenchar) to control -% both hyphenation at - and hyphenation within words. -% We must therefore turn them both off (\tclose does that) -% and arrange explicitly to hyphenate at a dash. -% -- rms. -{ - \catcode`\-=\active - \catcode`\_=\active - % - \global\def\code{\begingroup - \catcode`\-=\active \let-\codedash - \catcode`\_=\active \let_\codeunder - \codex - } - % - % If we end up with any active - characters when handling the index, - % just treat them as a normal -. - \global\def\indexbreaks{\catcode`\-=\active \let-\realdash} -} - -\def\realdash{-} -\def\codedash{-\discretionary{}{}{}} -\def\codeunder{% - % this is all so @math{@code{var_name}+1} can work. In math mode, _ - % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) - % will therefore expand the active definition of _, which is us - % (inside @code that is), therefore an endless loop. - \ifusingtt{\ifmmode - \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. - \else\normalunderscore \fi - \discretionary{}{}{}}% - {\_}% -} -\def\codex #1{\tclose{#1}\endgroup} - -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. - -% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), -% `example' (@kbd uses ttsl only inside of @example and friends), -% or `code' (@kbd uses normal tty font always). -\def\kbdinputstyle{\parsearg\kbdinputstylexxx} -\def\kbdinputstylexxx#1{% - \def\arg{#1}% - \ifx\arg\worddistinct - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% - \else\ifx\arg\wordexample - \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% - \else\ifx\arg\wordcode - \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% - \else - \errhelp = \EMsimple - \errmessage{Unknown @kbdinputstyle option `\arg'}% - \fi\fi\fi -} -\def\worddistinct{distinct} -\def\wordexample{example} -\def\wordcode{code} - -% Default is `distinct.' -\kbdinputstyle distinct - -\def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\look}}\fi -\else{\tclose{\kbdfont\look}}\fi} - -% For @url, @env, @command quotes seem unnecessary, so use \code. -\let\url=\code -\let\env=\code -\let\command=\code - -% @uref (abbreviation for `urlref') takes an optional (comma-separated) -% second argument specifying the text to display and an optional third -% arg as text to display instead of (rather than in addition to) the url -% itself. First (mandatory) arg is the url. Perhaps eventually put in -% a hypertex \special here. -% -\def\uref#1{\douref #1,,,\finish} -\def\douref#1,#2,#3,#4\finish{\begingroup - \unsepspaces - \pdfurl{#1}% - \setbox0 = \hbox{\ignorespaces #3}% - \ifdim\wd0 > 0pt - \unhbox0 % third arg given, show only that - \else - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0 > 0pt - \ifpdf - \unhbox0 % PDF: 2nd arg given, show only it - \else - \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url - \fi - \else - \code{#1}% only url given, so show it - \fi - \fi - \endlink -\endgroup} - -% rms does not like angle brackets --karl, 17may97. -% So now @email is just like @uref, unless we are pdf. -% -%\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdf - \def\email#1{\doemail#1,,\finish} - \def\doemail#1,#2,#3\finish{\begingroup - \unsepspaces - \pdfurl{mailto:#1}% - \setbox0 = \hbox{\ignorespaces #2}% - \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi - \endlink - \endgroup} -\else - \let\email=\uref -\fi - -% Check if we are currently using a typewriter font. Since all the -% Computer Modern typewriter fonts have zero interword stretch (and -% shrink), and it is reasonable to expect all typewriter fonts to have -% this property, we can check that font parameter. -% -\def\ifmonospace{\ifdim\fontdimen3\font=0pt } - -% Typeset a dimension, e.g., `in' or `pt'. The only reason for the -% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. -% -\def\dmn#1{\thinspace #1} - -\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} - -% @l was never documented to mean ``switch to the Lisp font'', -% and it is not used as such in any manual I can find. We need it for -% Polish suppressed-l. --karl, 22sep96. -%\def\l#1{{\li #1}\null} - -% Explicit font changes: @r, @sc, undocumented @ii. -\def\r#1{{\rm #1}} % roman font -\def\sc#1{{\smallcaps#1}} % smallcaps font -\def\ii#1{{\it #1}} % italic font - -% @acronym downcases the argument and prints in smallcaps. -\def\acronym#1{{\smallcaps \lowercase{#1}}} - -% @pounds{} is a sterling sign. -\def\pounds{{\it\$}} - -% @registeredsymbol - R in a circle. For now, only works in text size; -% we'd have to redo the font mechanism to change the \scriptstyle and -% \scriptscriptstyle font sizes to make it look right in headings. -% Adapted from the plain.tex definition of \copyright. -% -\def\registeredsymbol{% - $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}% - }$% -} - - -\message{page headings,} - -\newskip\titlepagetopglue \titlepagetopglue = 1.5in -\newskip\titlepagebottomglue \titlepagebottomglue = 2pc - -% First the title page. Must do @settitle before @titlepage. -\newif\ifseenauthor -\newif\iffinishedtitlepage - -% Do an implicit @contents or @shortcontents after @end titlepage if the -% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. -% -\newif\ifsetcontentsaftertitlepage - \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue -\newif\ifsetshortcontentsaftertitlepage - \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue - -\def\shorttitlepage{\parsearg\shorttitlepagezzz} -\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% - \endgroup\page\hbox{}\page} - -\def\titlepage{\begingroup \parindent=0pt \textfonts - \let\subtitlerm=\tenrm - \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% - % - \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines - \let\tt=\authortt}% - % - % Leave some space at the very top of the page. - \vglue\titlepagetopglue - % - % Now you can print the title using @title. - \def\title{\parsearg\titlezzz}% - \def\titlezzz##1{\leftline{\titlefonts\rm ##1} - % print a rule at the page bottom also. - \finishedtitlepagefalse - \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% - % No rule at page bottom unless we print one at the top with @title. - \finishedtitlepagetrue - % - % Now you can put text using @subtitle. - \def\subtitle{\parsearg\subtitlezzz}% - \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% - % - % @author should come last, but may come many times. - \def\author{\parsearg\authorzzz}% - \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi - {\authorfont \leftline{##1}}}% - % - % Most title ``pages'' are actually two pages long, with space - % at the top of the second. We don't want the ragged left on the second. - \let\oldpage = \page - \def\page{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - \oldpage - \let\page = \oldpage - \hbox{}}% -% \def\page{\oldpage \hbox{}} -} - -\def\Etitlepage{% - \iffinishedtitlepage\else - \finishtitlepage - \fi - % It is important to do the page break before ending the group, - % because the headline and footline are only empty inside the group. - % If we use the new definition of \page, we always get a blank page - % after the title page, which we certainly don't want. - \oldpage - \endgroup - % - % Need this before the \...aftertitlepage checks so that if they are - % in effect the toc pages will come out with page numbers. - \HEADINGSon - % - % If they want short, they certainly want long too. - \ifsetshortcontentsaftertitlepage - \shortcontents - \contents - \global\let\shortcontents = \relax - \global\let\contents = \relax - \fi - % - \ifsetcontentsaftertitlepage - \contents - \global\let\contents = \relax - \global\let\shortcontents = \relax - \fi -} - -\def\finishtitlepage{% - \vskip4pt \hrule height 2pt width \hsize - \vskip\titlepagebottomglue - \finishedtitlepagetrue -} - -%%% Set up page headings and footings. - -\let\thispage=\folio - -\newtoks\evenheadline % headline on even pages -\newtoks\oddheadline % headline on odd pages -\newtoks\evenfootline % footline on even pages -\newtoks\oddfootline % footline on odd pages - -% Now make Tex use those variables -\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline - \else \the\evenheadline \fi}} -\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline - \else \the\evenfootline \fi}\HEADINGShook} -\let\HEADINGShook=\relax - -% Commands to set those variables. -% For example, this is what @headings on does -% @evenheading @thistitle|@thispage|@thischapter -% @oddheading @thischapter|@thispage|@thistitle -% @evenfooting @thisfile|| -% @oddfooting ||@thisfile - -\def\evenheading{\parsearg\evenheadingxxx} -\def\oddheading{\parsearg\oddheadingxxx} -\def\everyheading{\parsearg\everyheadingxxx} - -\def\evenfooting{\parsearg\evenfootingxxx} -\def\oddfooting{\parsearg\oddfootingxxx} -\def\everyfooting{\parsearg\everyfootingxxx} - -{\catcode`\@=0 % - -\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} -\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% -\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} -\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% -\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% - -\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} -\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% -\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} - -\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} -\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% - \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% - % - % Leave some space for the footline. Hopefully ok to assume - % @evenfooting will not be used by itself. - \global\advance\pageheight by -\baselineskip - \global\advance\vsize by -\baselineskip -} - -\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} -% -}% unbind the catcode of @. - -% @headings double turns headings on for double-sided printing. -% @headings single turns headings on for single-sided printing. -% @headings off turns them off. -% @headings on same as @headings double, retained for compatibility. -% @headings after turns on double-sided headings after this page. -% @headings doubleafter turns on double-sided headings after this page. -% @headings singleafter turns on single-sided headings after this page. -% By default, they are off at the start of a document, -% and turned `on' after @end titlepage. - -\def\headings #1 {\csname HEADINGS#1\endcsname} - -\def\HEADINGSoff{ -\global\evenheadline={\hfil} \global\evenfootline={\hfil} -\global\oddheadline={\hfil} \global\oddfootline={\hfil}} -\HEADINGSoff -% When we turn headings on, set the page number to 1. -% For double-sided printing, put current file name in lower left corner, -% chapter name on inside top of right hand pages, document -% title on inside top of left hand pages, and page numbers on outside top -% edge of all pages. -\def\HEADINGSdouble{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} -\let\contentsalignmacro = \chappager - -% For single-sided printing, chapter title goes across top left of page, -% page number on top right. -\def\HEADINGSsingle{ -\global\pageno=1 -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} -\def\HEADINGSon{\HEADINGSdouble} - -\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} -\let\HEADINGSdoubleafter=\HEADINGSafter -\def\HEADINGSdoublex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chapoddpage -} - -\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} -\def\HEADINGSsinglex{% -\global\evenfootline={\hfil} -\global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} -\global\let\contentsalignmacro = \chappager -} - -% Subroutines used in generating headings -% This produces Day Month Year style of output. -% Only define if not already defined, in case a txi-??.tex file has set -% up a different format (e.g., txi-cs.tex does this). -\ifx\today\undefined -\def\today{% - \number\day\space - \ifcase\month - \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr - \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug - \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec - \fi - \space\number\year} -\fi - -% @settitle line... specifies the title of the document, for headings. -% It generates no output of its own. -\def\thistitle{\putwordNoTitle} -\def\settitle{\parsearg\settitlezzz} -\def\settitlezzz #1{\gdef\thistitle{#1}} - - -\message{tables,} -% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). - -% default indentation of table text -\newdimen\tableindent \tableindent=.8in -% default indentation of @itemize and @enumerate text -\newdimen\itemindent \itemindent=.3in -% margin between end of table item and start of table text. -\newdimen\itemmargin \itemmargin=.1in - -% used internally for \itemindent minus \itemmargin -\newdimen\itemmax - -% Note @table, @vtable, and @vtable define @item, @itemx, etc., with -% these defs. -% They also define \itemindex -% to index the item name in whatever manner is desired (perhaps none). - -\newif\ifitemxneedsnegativevskip - -\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} - -\def\internalBitem{\smallbreak \parsearg\itemzzz} -\def\internalBitemx{\itemxpar \parsearg\itemzzz} - -\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} -\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} - -\def\internalBkitem{\smallbreak \parsearg\kitemzzz} -\def\internalBkitemx{\itemxpar \parsearg\kitemzzz} - -\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% - \itemzzz {#1}} - -\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% - \itemzzz {#1}} - -\def\itemzzz #1{\begingroup % - \advance\hsize by -\rightskip - \advance\hsize by -\tableindent - \setbox0=\hbox{\itemfont{#1}}% - \itemindex{#1}% - \nobreak % This prevents a break before @itemx. - % - % If the item text does not fit in the space we have, put it on a line - % by itself, and do not allow a page break either before or after that - % line. We do not start a paragraph here because then if the next - % command is, e.g., @kindex, the whatsit would get put into the - % horizontal list on a line by itself, resulting in extra blank space. - \ifdim \wd0>\itemmax - % - % Make this a paragraph so we get the \parskip glue and wrapping, - % but leave it ragged-right. - \begingroup - \advance\leftskip by-\tableindent - \advance\hsize by\tableindent - \advance\rightskip by0pt plus1fil - \leavevmode\unhbox0\par - \endgroup - % - % We're going to be starting a paragraph, but we don't want the - % \parskip glue -- logically it's part of the @item we just started. - \nobreak \vskip-\parskip - % - % Stop a page break at the \parskip glue coming up. (Unfortunately - % we can't prevent a possible page break at the following - % \baselineskip glue.) However, if what follows is an environment - % such as @example, there will be no \parskip glue; then - % the negative vskip we just would cause the example and the item to - % crash together. So we use this bizarre value of 10001 as a signal - % to \aboveenvbreak to insert \parskip glue after all. - % (Possibly there are other commands that could be followed by - % @example which need the same treatment, but not section titles; or - % maybe section titles are the only special case and they should be - % penalty 10001...) - \penalty 10001 - \endgroup - \itemxneedsnegativevskipfalse - \else - % The item text fits into the space. Start a paragraph, so that the - % following text (if any) will end up on the same line. - \noindent - % Do this with kerns and \unhbox so that if there is a footnote in - % the item text, it can migrate to the main vertical list and - % eventually be printed. - \nobreak\kern-\tableindent - \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 - \unhbox0 - \nobreak\kern\dimen0 - \endgroup - \itemxneedsnegativevskiptrue - \fi -} - -\def\item{\errmessage{@item while not in a table}} -\def\itemx{\errmessage{@itemx while not in a table}} -\def\kitem{\errmessage{@kitem while not in a table}} -\def\kitemx{\errmessage{@kitemx while not in a table}} -\def\xitem{\errmessage{@xitem while not in a table}} -\def\xitemx{\errmessage{@xitemx while not in a table}} - -% Contains a kludge to get @end[description] to work. -\def\description{\tablez{\dontindex}{1}{}{}{}{}} - -% @table, @ftable, @vtable. -\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} -{\obeylines\obeyspaces% -\gdef\tablex #1^^M{% -\tabley\dontindex#1 \endtabley}} - -\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} -{\obeylines\obeyspaces% -\gdef\ftablex #1^^M{% -\tabley\fnitemindex#1 \endtabley -\def\Eftable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} -{\obeylines\obeyspaces% -\gdef\vtablex #1^^M{% -\tabley\vritemindex#1 \endtabley -\def\Evtable{\endgraf\afterenvbreak\endgroup}% -\let\Etable=\relax}} - -\def\dontindex #1{} -\def\fnitemindex #1{\doind {fn}{\code{#1}}}% -\def\vritemindex #1{\doind {vr}{\code{#1}}}% - -{\obeyspaces % -\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% -\tablez{#1}{#2}{#3}{#4}{#5}{#6}}} - -\def\tablez #1#2#3#4#5#6{% -\aboveenvbreak % -\begingroup % -\def\Edescription{\Etable}% Necessary kludge. -\let\itemindex=#1% -\ifnum 0#3>0 \advance \leftskip by #3\mil \fi % -\ifnum 0#4>0 \tableindent=#4\mil \fi % -\ifnum 0#5>0 \advance \rightskip by #5\mil \fi % -\def\itemfont{#2}% -\itemmax=\tableindent % -\advance \itemmax by -\itemmargin % -\advance \leftskip by \tableindent % -\exdentamount=\tableindent -\parindent = 0pt -\parskip = \smallskipamount -\ifdim \parskip=0pt \parskip=2pt \fi% -\def\Etable{\endgraf\afterenvbreak\endgroup}% -\let\item = \internalBitem % -\let\itemx = \internalBitemx % -\let\kitem = \internalBkitem % -\let\kitemx = \internalBkitemx % -\let\xitem = \internalBxitem % -\let\xitemx = \internalBxitemx % -} - -% This is the counter used by @enumerate, which is really @itemize - -\newcount \itemno - -\def\itemize{\parsearg\itemizezzz} - -\def\itemizezzz #1{% - \begingroup % ended by the @end itemize - \itemizey {#1}{\Eitemize} -} - -\def\itemizey#1#2{% - \aboveenvbreak - \itemmax=\itemindent - \advance\itemmax by -\itemmargin - \advance\leftskip by \itemindent - \exdentamount=\itemindent - \parindent=0pt - \parskip=\smallskipamount - \ifdim\parskip=0pt \parskip=2pt \fi - \def#2{\endgraf\afterenvbreak\endgroup}% - \def\itemcontents{#1}% - % @itemize with no arg is equivalent to @itemize @bullet. - \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi - \let\item=\itemizeitem -} - -% \splitoff TOKENS\endmark defines \first to be the first token in -% TOKENS, and \rest to be the remainder. -% -\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% - -% Allow an optional argument of an uppercase letter, lowercase letter, -% or number, to specify the first label in the enumerated list. No -% argument is the same as `1'. -% -\def\enumerate{\parsearg\enumeratezzz} -\def\enumeratezzz #1{\enumeratey #1 \endenumeratey} -\def\enumeratey #1 #2\endenumeratey{% - \begingroup % ended by the @end enumerate - % - % If we were given no argument, pretend we were given `1'. - \def\thearg{#1}% - \ifx\thearg\empty \def\thearg{1}\fi - % - % Detect if the argument is a single token. If so, it might be a - % letter. Otherwise, the only valid thing it can be is a number. - % (We will always have one token, because of the test we just made. - % This is a good thing, since \splitoff doesn't work given nothing at - % all -- the first parameter is undelimited.) - \expandafter\splitoff\thearg\endmark - \ifx\rest\empty - % Only one token in the argument. It could still be anything. - % A ``lowercase letter'' is one whose \lccode is nonzero. - % An ``uppercase letter'' is one whose \lccode is both nonzero, and - % not equal to itself. - % Otherwise, we assume it's a number. - % - % We need the \relax at the end of the \ifnum lines to stop TeX from - % continuing to look for a <number>. - % - \ifnum\lccode\expandafter`\thearg=0\relax - \numericenumerate % a number (we hope) - \else - % It's a letter. - \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax - \lowercaseenumerate % lowercase letter - \else - \uppercaseenumerate % uppercase letter - \fi - \fi - \else - % Multiple tokens in the argument. We hope it's a number. - \numericenumerate - \fi -} - -% An @enumerate whose labels are integers. The starting integer is -% given in \thearg. -% -\def\numericenumerate{% - \itemno = \thearg - \startenumeration{\the\itemno}% -} - -% The starting (lowercase) letter is in \thearg. -\def\lowercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more lowercase letters in @enumerate; get a bigger - alphabet}% - \fi - \char\lccode\itemno - }% -} - -% The starting (uppercase) letter is in \thearg. -\def\uppercaseenumerate{% - \itemno = \expandafter`\thearg - \startenumeration{% - % Be sure we're not beyond the end of the alphabet. - \ifnum\itemno=0 - \errmessage{No more uppercase letters in @enumerate; get a bigger - alphabet} - \fi - \char\uccode\itemno - }% -} - -% Call itemizey, adding a period to the first argument and supplying the -% common last two arguments. Also subtract one from the initial value in -% \itemno, since @item increments \itemno. -% -\def\startenumeration#1{% - \advance\itemno by -1 - \itemizey{#1.}\Eenumerate\flushcr -} - -% @alphaenumerate and @capsenumerate are abbreviations for giving an arg -% to @enumerate. -% -\def\alphaenumerate{\enumerate{a}} -\def\capsenumerate{\enumerate{A}} -\def\Ealphaenumerate{\Eenumerate} -\def\Ecapsenumerate{\Eenumerate} - -% Definition of @item while inside @itemize. - -\def\itemizeitem{% -\advance\itemno by 1 -{\let\par=\endgraf \smallbreak}% -\ifhmode \errmessage{In hmode at itemizeitem}\fi -{\parskip=0in \hskip 0pt -\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% -\vadjust{\penalty 1200}}% -\flushcr} - -% @multitable macros -% Amy Hendrickson, 8/18/94, 3/6/96 -% -% @multitable ... @end multitable will make as many columns as desired. -% Contents of each column will wrap at width given in preamble. Width -% can be specified either with sample text given in a template line, -% or in percent of \hsize, the current width of text on page. - -% Table can continue over pages but will only break between lines. - -% To make preamble: -% -% Either define widths of columns in terms of percent of \hsize: -% @multitable @columnfractions .25 .3 .45 -% @item ... -% -% Numbers following @columnfractions are the percent of the total -% current hsize to be used for each column. You may use as many -% columns as desired. - - -% Or use a template: -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item ... -% using the widest term desired in each column. -% -% For those who want to use more than one line's worth of words in -% the preamble, break the line within one argument and it -% will parse correctly, i.e., -% -% @multitable {Column 1 template} {Column 2 template} {Column 3 -% template} -% Not: -% @multitable {Column 1 template} {Column 2 template} -% {Column 3 template} - -% Each new table line starts with @item, each subsequent new column -% starts with @tab. Empty columns may be produced by supplying @tab's -% with nothing between them for as many times as empty columns are needed, -% ie, @tab@tab@tab will produce two empty columns. - -% @item, @tab, @multitable or @end multitable do not need to be on their -% own lines, but it will not hurt if they are. - -% Sample multitable: - -% @multitable {Column 1 template} {Column 2 template} {Column 3 template} -% @item first col stuff @tab second col stuff @tab third col -% @item -% first col stuff -% @tab -% second col stuff -% @tab -% third col -% @item first col stuff @tab second col stuff -% @tab Many paragraphs of text may be used in any column. -% -% They will wrap at the width determined by the template. -% @item@tab@tab This will be in third column. -% @end multitable - -% Default dimensions may be reset by user. -% @multitableparskip is vertical space between paragraphs in table. -% @multitableparindent is paragraph indent in table. -% @multitablecolmargin is horizontal space to be left between columns. -% @multitablelinespace is space to leave between table items, baseline -% to baseline. -% 0pt means it depends on current normal line spacing. -% -\newskip\multitableparskip -\newskip\multitableparindent -\newdimen\multitablecolspace -\newskip\multitablelinespace -\multitableparskip=0pt -\multitableparindent=6pt -\multitablecolspace=12pt -\multitablelinespace=0pt - -% Macros used to set up halign preamble: -% -\let\endsetuptable\relax -\def\xendsetuptable{\endsetuptable} -\let\columnfractions\relax -\def\xcolumnfractions{\columnfractions} -\newif\ifsetpercent - -% #1 is the part of the @columnfraction before the decimal point, which -% is presumably either 0 or the empty string (but we don't check, we -% just throw it away). #2 is the decimal part, which we use as the -% percent of \hsize for this column. -\def\pickupwholefraction#1.#2 {% - \global\advance\colcount by 1 - \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}% - \setuptable -} - -\newcount\colcount -\def\setuptable#1{% - \def\firstarg{#1}% - \ifx\firstarg\xendsetuptable - \let\go = \relax - \else - \ifx\firstarg\xcolumnfractions - \global\setpercenttrue - \else - \ifsetpercent - \let\go\pickupwholefraction - \else - \global\advance\colcount by 1 - \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a - % separator; typically that is always in the input, anyway. - \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% - \fi - \fi - \ifx\go\pickupwholefraction - % Put the argument back for the \pickupwholefraction call, so - % we'll always have a period there to be parsed. - \def\go{\pickupwholefraction#1}% - \else - \let\go = \setuptable - \fi% - \fi - \go -} - -% @multitable ... @end multitable definitions: -% -\def\multitable{\parsearg\dotable} -\def\dotable#1{\bgroup - \vskip\parskip - \let\item=\crcrwithfootnotes - % A \tab used to include \hskip1sp. But then the space in a template - % line is not enough. That is bad. So let's go back to just & until - % we encounter the problem it was intended to solve again. --karl, - % nathan@acm.org, 20apr99. - \let\tab=&% - \let\startfootins=\startsavedfootnote - \tolerance=9500 - \hbadness=9500 - \setmultitablespacing - \parskip=\multitableparskip - \parindent=\multitableparindent - \overfullrule=0pt - \global\colcount=0 - \def\Emultitable{% - \global\setpercentfalse - \crcrwithfootnotes\crcr - \egroup\egroup - }% - % - % To parse everything between @multitable and @item: - \setuptable#1 \endsetuptable - % - % \everycr will reset column counter, \colcount, at the end of - % each line. Every column entry will cause \colcount to advance by one. - % The table preamble - % looks at the current \colcount to find the correct column width. - \everycr{\noalign{% - % - % \filbreak%% keeps underfull box messages off when table breaks over pages. - % Maybe so, but it also creates really weird page breaks when the table - % breaks over pages. Wouldn't \vfil be better? Wait until the problem - % manifests itself, so it can be fixed for real --karl. - \global\colcount=0\relax}}% - % - % This preamble sets up a generic column definition, which will - % be used as many times as user calls for columns. - % \vtop will set a single line and will also let text wrap and - % continue for many paragraphs if desired. - \halign\bgroup&\global\advance\colcount by 1\relax - \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname - % - % In order to keep entries from bumping into each other - % we will add a \leftskip of \multitablecolspace to all columns after - % the first one. - % - % If a template has been used, we will add \multitablecolspace - % to the width of each template entry. - % - % If the user has set preamble in terms of percent of \hsize we will - % use that dimension as the width of the column, and the \leftskip - % will keep entries from bumping into each other. Table will start at - % left margin and final column will justify at right margin. - % - % Make sure we don't inherit \rightskip from the outer environment. - \rightskip=0pt - \ifnum\colcount=1 - % The first column will be indented with the surrounding text. - \advance\hsize by\leftskip - \else - \ifsetpercent \else - % If user has not set preamble in terms of percent of \hsize - % we will advance \hsize by \multitablecolspace. - \advance\hsize by \multitablecolspace - \fi - % In either case we will make \leftskip=\multitablecolspace: - \leftskip=\multitablecolspace - \fi - % Ignoring space at the beginning and end avoids an occasional spurious - % blank line, when TeX decides to break the line at the space before the - % box from the multistrut, so the strut ends up on a line by itself. - % For example: - % @multitable @columnfractions .11 .89 - % @item @code{#} - % @tab Legal holiday which is valid in major parts of the whole country. - % Is automatically provided with highlighting sequences respectively marking - % characters. - \noindent\ignorespaces##\unskip\multistrut}\cr -} - -\def\setmultitablespacing{% test to see if user has set \multitablelinespace. -% If so, do nothing. If not, give it an appropriate dimension based on -% current baselineskip. -\ifdim\multitablelinespace=0pt -\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip -\global\advance\multitablelinespace by-\ht0 -%% strut to put in table in case some entry doesn't have descenders, -%% to keep lines equally spaced -\let\multistrut = \strut -\else -%% FIXME: what is \box0 supposed to be? -\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 -width0pt\relax} \fi -%% Test to see if parskip is larger than space between lines of -%% table. If not, do nothing. -%% If so, set to same dimension as multitablelinespace. -\ifdim\multitableparskip>\multitablelinespace -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi% -\ifdim\multitableparskip=0pt -\global\multitableparskip=\multitablelinespace -\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller - %% than skip between lines in the table. -\fi} - -% In case a @footnote appears inside an alignment, save the footnote -% text to a box and make the \insert when a row of the table is -% finished. Otherwise, the insertion is lost, it never migrates to the -% main vertical list. --kasal, 22jan03. -% -\newbox\savedfootnotes -% -% \dotable \let's \startfootins to this, so that \dofootnote will call -% it instead of starting the insertion right away. -\def\startsavedfootnote{% - \global\setbox\savedfootnotes = \vbox\bgroup - \unvbox\savedfootnotes -} -\def\crcrwithfootnotes{% - \crcr - \ifvoid\savedfootnotes \else - \noalign{\insert\footins{\box\savedfootnotes}}% - \fi -} - -\message{conditionals,} -% Prevent errors for section commands. -% Used in @ignore and in failing conditionals. -\def\ignoresections{% - \let\chapter=\relax - \let\unnumbered=\relax - \let\top=\relax - \let\unnumberedsec=\relax - \let\unnumberedsection=\relax - \let\unnumberedsubsec=\relax - \let\unnumberedsubsection=\relax - \let\unnumberedsubsubsec=\relax - \let\unnumberedsubsubsection=\relax - \let\section=\relax - \let\subsec=\relax - \let\subsubsec=\relax - \let\subsection=\relax - \let\subsubsection=\relax - \let\appendix=\relax - \let\appendixsec=\relax - \let\appendixsection=\relax - \let\appendixsubsec=\relax - \let\appendixsubsection=\relax - \let\appendixsubsubsec=\relax - \let\appendixsubsubsection=\relax - \let\contents=\relax - \let\smallbook=\relax - \let\titlepage=\relax -} - -% Used in nested conditionals, where we have to parse the Texinfo source -% and so want to turn off most commands, in case they are used -% incorrectly. -% -% We use \empty instead of \relax for the @def... commands, so that \end -% doesn't throw an error. For instance: -% @ignore -% @deffn ... -% @end deffn -% @end ignore -% -% The @end deffn is going to get expanded, because we're trying to allow -% nested conditionals. But we don't want to expand the actual @deffn, -% since it might be syntactically correct and intended to be ignored. -% Since \end checks for \relax, using \empty does not cause an error. -% -\def\ignoremorecommands{% - \let\defcodeindex = \relax - \let\defcv = \empty - \let\defcvx = \empty - \let\Edefcv = \empty - \let\deffn = \empty - \let\deffnx = \empty - \let\Edeffn = \empty - \let\defindex = \relax - \let\defivar = \empty - \let\defivarx = \empty - \let\Edefivar = \empty - \let\defmac = \empty - \let\defmacx = \empty - \let\Edefmac = \empty - \let\defmethod = \empty - \let\defmethodx = \empty - \let\Edefmethod = \empty - \let\defop = \empty - \let\defopx = \empty - \let\Edefop = \empty - \let\defopt = \empty - \let\defoptx = \empty - \let\Edefopt = \empty - \let\defspec = \empty - \let\defspecx = \empty - \let\Edefspec = \empty - \let\deftp = \empty - \let\deftpx = \empty - \let\Edeftp = \empty - \let\deftypefn = \empty - \let\deftypefnx = \empty - \let\Edeftypefn = \empty - \let\deftypefun = \empty - \let\deftypefunx = \empty - \let\Edeftypefun = \empty - \let\deftypeivar = \empty - \let\deftypeivarx = \empty - \let\Edeftypeivar = \empty - \let\deftypemethod = \empty - \let\deftypemethodx = \empty - \let\Edeftypemethod = \empty - \let\deftypeop = \empty - \let\deftypeopx = \empty - \let\Edeftypeop = \empty - \let\deftypevar = \empty - \let\deftypevarx = \empty - \let\Edeftypevar = \empty - \let\deftypevr = \empty - \let\deftypevrx = \empty - \let\Edeftypevr = \empty - \let\defun = \empty - \let\defunx = \empty - \let\Edefun = \empty - \let\defvar = \empty - \let\defvarx = \empty - \let\Edefvar = \empty - \let\defvr = \empty - \let\defvrx = \empty - \let\Edefvr = \empty - \let\clear = \relax - \let\down = \relax - \let\evenfooting = \relax - \let\evenheading = \relax - \let\everyfooting = \relax - \let\everyheading = \relax - \let\headings = \relax - \let\include = \relax - \let\item = \relax - \let\lowersections = \relax - \let\oddfooting = \relax - \let\oddheading = \relax - \let\printindex = \relax - \let\pxref = \relax - \let\raisesections = \relax - \let\ref = \relax - \let\set = \relax - \let\setchapternewpage = \relax - \let\setchapterstyle = \relax - \let\settitle = \relax - \let\up = \relax - \let\verbatiminclude = \relax - \let\xref = \relax -} - -% Ignore @ignore, @ifhtml, @ifinfo, and the like. -% -\def\direntry{\doignore{direntry}} -\def\documentdescriptionword{documentdescription} -\def\documentdescription{\doignore{documentdescription}} -\def\html{\doignore{html}} -\def\ifhtml{\doignore{ifhtml}} -\def\ifinfo{\doignore{ifinfo}} -\def\ifnottex{\doignore{ifnottex}} -\def\ifplaintext{\doignore{ifplaintext}} -\def\ifxml{\doignore{ifxml}} -\def\ignore{\doignore{ignore}} -\def\menu{\doignore{menu}} -\def\xml{\doignore{xml}} - -% @dircategory CATEGORY -- specify a category of the dir file -% which this file should belong to. Ignore this in TeX. -\let\dircategory = \comment - -% Ignore text until a line `@end #1'. -% -\def\doignore#1{\begingroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define a command to swallow text until we reach `@end #1'. - % This @ is a catcode 12 token (that is the normal catcode of @ in - % this texinfo.tex file). We change the catcode of @ below to match. - \long\def\doignoretext##1@end #1{\enddoignore}% - % - % Make sure that spaces turn into tokens that match what \doignoretext wants. - \catcode\spaceChar = 10 - % - % Ignore braces, too, so mismatched braces don't cause trouble. - \catcode`\{ = 9 - \catcode`\} = 9 - % - % We must not have @c interpreted as a control sequence. - \catcode`\@ = 12 - % - \def\ignoreword{#1}% - \ifx\ignoreword\documentdescriptionword - % The c kludge breaks documentdescription, since - % `documentdescription' contains a `c'. Means not everything will - % be ignored inside @documentdescription, but oh well... - \else - % Make the letter c a comment character so that the rest of the line - % will be ignored. This way, the document can have (for example) - % @c @end ifinfo - % and the @end ifinfo will be properly ignored. - % (We've just changed @ to catcode 12.) - \catcode`\c = 14 - \fi - % - % And now expand the command defined above. - \doignoretext -} - -% What we do to finish off ignored text. -% -\def\enddoignore{\endgroup\ignorespaces}% - -\newif\ifwarnedobs\warnedobsfalse -\def\obstexwarn{% - \ifwarnedobs\relax\else - % We need to warn folks that they may have trouble with TeX 3.0. - % This uses \immediate\write16 rather than \message to get newlines. - \immediate\write16{} - \immediate\write16{WARNING: for users of Unix TeX 3.0!} - \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} - \immediate\write16{If you are running another version of TeX, relax.} - \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} - \immediate\write16{ Then upgrade your TeX installation if you can.} - \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)} - \immediate\write16{If you are stuck with version 3.0, run the} - \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} - \immediate\write16{ to use a workaround.} - \immediate\write16{} - \global\warnedobstrue - \fi -} - -% **In TeX 3.0, setting text in \nullfont hangs tex. For a -% workaround (which requires the file ``dummy.tfm'' to be installed), -% uncomment the following line: -%%%%%\font\nullfont=dummy\let\obstexwarn=\relax - -% Ignore text, except that we keep track of conditional commands for -% purposes of nesting, up to an `@end #1' command. -% -\def\nestedignore#1{% - \obstexwarn - % We must actually expand the ignored text to look for the @end - % command, so that nested ignore constructs work. Thus, we put the - % text into a \vbox and then do nothing with the result. To minimize - % the chance of memory overflow, we follow the approach outlined on - % page 401 of the TeXbook. - % - \setbox0 = \vbox\bgroup - % Don't complain about control sequences we have declared \outer. - \ignoresections - % - % Define `@end #1' to end the box, which will in turn undefine the - % @end command again. - \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% - % - % We are going to be parsing Texinfo commands. Most cause no - % trouble when they are used incorrectly, but some commands do - % complicated argument parsing or otherwise get confused, so we - % undefine them. - % - % We can't do anything about stray @-signs, unfortunately; - % they'll produce `undefined control sequence' errors. - \ignoremorecommands - % - % Set the current font to be \nullfont, a TeX primitive, and define - % all the font commands to also use \nullfont. We don't use - % dummy.tfm, as suggested in the TeXbook, because some sites - % might not have that installed. Therefore, math mode will still - % produce output, but that should be an extremely small amount of - % stuff compared to the main input. - % - \nullfont - \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont - \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont - \let\tensf=\nullfont - % Similarly for index fonts. - \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont - \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont - \let\smallsf=\nullfont - % Similarly for smallexample fonts. - \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont - \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont - \let\smallersf=\nullfont - % - % Don't complain when characters are missing from the fonts. - \tracinglostchars = 0 - % - % Don't bother to do space factor calculations. - \frenchspacing - % - % Don't report underfull hboxes. - \hbadness = 10000 - % - % Do minimal line-breaking. - \pretolerance = 10000 - % - % Do not execute instructions in @tex. - \def\tex{\doignore{tex}}% - % Do not execute macro definitions. - % `c' is a comment character, so the word `macro' will get cut off. - \def\macro{\doignore{ma}}% -} - -% @set VAR sets the variable VAR to an empty value. -% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. -% -% Since we want to separate VAR from REST-OF-LINE (which might be -% empty), we can't just use \parsearg; we have to insert a space of our -% own to delimit the rest of the line, and then take it out again if we -% didn't need it. Make sure the catcode of space is correct to avoid -% losing inside @example, for instance. -% -\def\set{\begingroup\catcode` =10 - \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. - \parsearg\setxxx} -\def\setxxx#1{\setyyy#1 \endsetyyy} -\def\setyyy#1 #2\endsetyyy{% - \def\temp{#2}% - \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty - \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. - \fi - \endgroup -} -% Can't use \xdef to pre-expand #2 and save some time, since \temp or -% \next or other control sequences that we've defined might get us into -% an infinite loop. Consider `@set foo @cite{bar}'. -\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} - -% @clear VAR clears (i.e., unsets) the variable VAR. -% -\def\clear{\parsearg\clearxxx} -\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} - -% @value{foo} gets the text saved in variable foo. -{ - \catcode`\_ = \active - % - % We might end up with active _ or - characters in the argument if - % we're called from @code, as @code{@value{foo-bar_}}. So \let any - % such active characters to their normal equivalents. - \gdef\value{\begingroup - \catcode`\-=\other \catcode`\_=\other - \indexbreaks \let_\normalunderscore - \valuexxx} -} -\def\valuexxx#1{\expandablevalue{#1}\endgroup} - -% We have this subroutine so that we can handle at least some @value's -% properly in indexes (we \let\value to this in \indexdummies). Ones -% whose names contain - or _ still won't work, but we can't do anything -% about that. The command has to be fully expandable (if the variable -% is set), since the result winds up in the index file. This means that -% if the variable's value contains other Texinfo commands, it's almost -% certain it will fail (although perhaps we could fix that with -% sufficient work to do a one-level expansion on the result, instead of -% complete). -% -\def\expandablevalue#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - {[No value for ``#1'']}% - \message{Variable `#1', used in @value, is not set.}% - \else - \csname SET#1\endcsname - \fi -} - -% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined -% with @set. -% -\def\ifset{\parsearg\doifset} -\def\doifset#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \let\next=\ifsetfail - \else - \let\next=\ifsetsucceed - \fi - \next -} -\def\ifsetsucceed{\conditionalsucceed{ifset}} -\def\ifsetfail{\nestedignore{ifset}} -\defineunmatchedend{ifset} - -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been -% defined with @set, or has been undefined with @clear. -% -\def\ifclear{\parsearg\doifclear} -\def\doifclear#1{% - \expandafter\ifx\csname SET#1\endcsname\relax - \let\next=\ifclearsucceed - \else - \let\next=\ifclearfail - \fi - \next -} -\def\ifclearsucceed{\conditionalsucceed{ifclear}} -\def\ifclearfail{\nestedignore{ifclear}} -\defineunmatchedend{ifclear} - -% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we -% read the text following, through the first @end iftex (etc.). Make -% `@end iftex' (etc.) valid only after an @iftex. -% -\def\iftex{\conditionalsucceed{iftex}} -\def\ifnothtml{\conditionalsucceed{ifnothtml}} -\def\ifnotinfo{\conditionalsucceed{ifnotinfo}} -\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}} -\defineunmatchedend{iftex} -\defineunmatchedend{ifnothtml} -\defineunmatchedend{ifnotinfo} -\defineunmatchedend{ifnotplaintext} - -% True conditional. Since \set globally defines its variables, we can -% just start and end a group (to keep the @end definition undefined at -% the outer level). -% -\def\conditionalsucceed#1{\begingroup - \expandafter\def\csname E#1\endcsname{\endgroup}% -} - -% @defininfoenclose. -\let\definfoenclose=\comment - - -\message{indexing,} -% Index generation facilities - -% Define \newwrite to be identical to plain tex's \newwrite -% except not \outer, so it can be used within \newindex. -{\catcode`\@=11 -\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} - -% \newindex {foo} defines an index named foo. -% It automatically defines \fooindex such that -% \fooindex ...rest of line... puts an entry in the index foo. -% It also defines \fooindfile to be the number of the output channel for -% the file that accumulates this index. The file's extension is foo. -% The name of an index should be no more than 2 characters long -% for the sake of vms. -% -\def\newindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 % Open the file - \fi - \expandafter\xdef\csname#1index\endcsname{% % Define @#1index - \noexpand\doindex{#1}} -} - -% @defindex foo == \newindex{foo} -% -\def\defindex{\parsearg\newindex} - -% Define @defcodeindex, like @defindex except put all entries in @code. -% -\def\defcodeindex{\parsearg\newcodeindex} -% -\def\newcodeindex#1{% - \iflinks - \expandafter\newwrite \csname#1indfile\endcsname - \openout \csname#1indfile\endcsname \jobname.#1 - \fi - \expandafter\xdef\csname#1index\endcsname{% - \noexpand\docodeindex{#1}}% -} - - -% @synindex foo bar makes index foo feed into index bar. -% Do this instead of @defindex foo if you don't want it as a separate index. -% -% @syncodeindex foo bar similar, but put all entries made for index foo -% inside @code. -% -\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} -\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} - -% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), -% #3 the target index (bar). -\def\dosynindex#1#2#3{% - % Only do \closeout if we haven't already done it, else we'll end up - % closing the target index. - \expandafter \ifx\csname donesynindex#2\endcsname \undefined - % The \closeout helps reduce unnecessary open files; the limit on the - % Acorn RISC OS is a mere 16 files. - \expandafter\closeout\csname#2indfile\endcsname - \expandafter\let\csname\donesynindex#2\endcsname = 1 - \fi - % redefine \fooindfile: - \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname - \expandafter\let\csname#2indfile\endcsname=\temp - % redefine \fooindex: - \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% -} - -% Define \doindex, the driver for all \fooindex macros. -% Argument #1 is generated by the calling \fooindex macro, -% and it is "foo", the name of the index. - -% \doindex just uses \parsearg; it calls \doind for the actual work. -% This is because \doind is more useful to call from other macros. - -% There is also \dosubind {index}{topic}{subtopic} -% which makes an entry in a two-level index such as the operation index. - -\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} -\def\singleindexer #1{\doind{\indexname}{#1}} - -% like the previous two, but they put @code around the argument. -\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} -\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} - -% Take care of Texinfo commands that can appear in an index entry. -% Since there are some commands we want to expand, and others we don't, -% we have to laboriously prevent expansion for those that we don't. -% -\def\indexdummies{% - \def\@{@}% change to @@ when we switch to @ as escape char in index files. - \def\ {\realbackslash\space }% - % Need these in case \tex is in effect and \{ is a \delimiter again. - % But can't use \lbracecmd and \rbracecmd because texindex assumes - % braces and backslashes are used only as delimiters. - \let\{ = \mylbrace - \let\} = \myrbrace - % - % \definedummyword defines \#1 as \realbackslash #1\space, thus - % effectively preventing its expansion. This is used only for control - % words, not control letters, because the \space would be incorrect - % for control characters, but is needed to separate the control word - % from whatever follows. - % - % For control letters, we have \definedummyletter, which omits the - % space. - % - % These can be used both for control words that take an argument and - % those that do not. If it is followed by {arg} in the input, then - % that will dutifully get written to the index (or wherever). - % - \def\definedummyword##1{% - \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}% - }% - \def\definedummyletter##1{% - \expandafter\def\csname ##1\endcsname{\realbackslash ##1}% - }% - % - % Do the redefinitions. - \commondummies -} - -% For the aux file, @ is the escape character. So we want to redefine -% everything using @ instead of \realbackslash. When everything uses -% @, this will be simpler. -% -\def\atdummies{% - \def\@{@@}% - \def\ {@ }% - \let\{ = \lbraceatcmd - \let\} = \rbraceatcmd - % - % (See comments in \indexdummies.) - \def\definedummyword##1{% - \expandafter\def\csname ##1\endcsname{@##1\space}% - }% - \def\definedummyletter##1{% - \expandafter\def\csname ##1\endcsname{@##1}% - }% - % - % Do the redefinitions. - \commondummies -} - -% Called from \indexdummies and \atdummies. \definedummyword and -% \definedummyletter must be defined first. -% -\def\commondummies{% - % - \normalturnoffactive - % - % Control letters and accents. - \definedummyletter{_}% - \definedummyletter{,}% - \definedummyletter{"}% - \definedummyletter{`}% - \definedummyletter{'}% - \definedummyletter{^}% - \definedummyletter{~}% - \definedummyletter{=}% - \definedummyword{u}% - \definedummyword{v}% - \definedummyword{H}% - \definedummyword{dotaccent}% - \definedummyword{ringaccent}% - \definedummyword{tieaccent}% - \definedummyword{ubaraccent}% - \definedummyword{udotaccent}% - \definedummyword{dotless}% - % - % Other non-English letters. - \definedummyword{AA}% - \definedummyword{AE}% - \definedummyword{L}% - \definedummyword{OE}% - \definedummyword{O}% - \definedummyword{aa}% - \definedummyword{ae}% - \definedummyword{l}% - \definedummyword{oe}% - \definedummyword{o}% - \definedummyword{ss}% - % - % Although these internal commands shouldn't show up, sometimes they do. - \definedummyword{bf}% - \definedummyword{gtr}% - \definedummyword{hat}% - \definedummyword{less}% - \definedummyword{sf}% - \definedummyword{sl}% - \definedummyword{tclose}% - \definedummyword{tt}% - % - % Texinfo font commands. - \definedummyword{b}% - \definedummyword{i}% - \definedummyword{r}% - \definedummyword{sc}% - \definedummyword{t}% - % - \definedummyword{TeX}% - \definedummyword{acronym}% - \definedummyword{cite}% - \definedummyword{code}% - \definedummyword{command}% - \definedummyword{dfn}% - \definedummyword{dots}% - \definedummyword{emph}% - \definedummyword{env}% - \definedummyword{file}% - \definedummyword{kbd}% - \definedummyword{key}% - \definedummyword{math}% - \definedummyword{option}% - \definedummyword{samp}% - \definedummyword{strong}% - \definedummyword{uref}% - \definedummyword{url}% - \definedummyword{var}% - \definedummyword{w}% - % - % Assorted special characters. - \definedummyword{bullet}% - \definedummyword{copyright}% - \definedummyword{dots}% - \definedummyword{enddots}% - \definedummyword{equiv}% - \definedummyword{error}% - \definedummyword{expansion}% - \definedummyword{minus}% - \definedummyword{pounds}% - \definedummyword{point}% - \definedummyword{print}% - \definedummyword{result}% - % - % Handle some cases of @value -- where the variable name does not - % contain - or _, and the value does not contain any - % (non-fully-expandable) commands. - \let\value = \expandablevalue - % - % Normal spaces, not active ones. - \unsepspaces - % - % No macro expansion. - \turnoffmacros -} - -% If an index command is used in an @example environment, any spaces -% therein should become regular spaces in the raw index file, not the -% expansion of \tie (\leavevmode \penalty \@M \ ). -{\obeyspaces - \gdef\unsepspaces{\obeyspaces\let =\space}} - - -% \indexnofonts is used when outputting the strings to sort the index -% by, and when constructing control sequence names. It eliminates all -% control sequences and just writes whatever the best ASCII sort string -% would be for a given command (usually its argument). -% -\def\indexdummytex{TeX} -\def\indexdummydots{...} -% -\def\indexnofonts{% - \def\ { }% - \def\@{@}% - % how to handle braces? - \def\_{\normalunderscore}% - % - \let\,=\asis - \let\"=\asis - \let\`=\asis - \let\'=\asis - \let\^=\asis - \let\~=\asis - \let\==\asis - \let\u=\asis - \let\v=\asis - \let\H=\asis - \let\dotaccent=\asis - \let\ringaccent=\asis - \let\tieaccent=\asis - \let\ubaraccent=\asis - \let\udotaccent=\asis - \let\dotless=\asis - % - % Other non-English letters. - \def\AA{AA}% - \def\AE{AE}% - \def\L{L}% - \def\OE{OE}% - \def\O{O}% - \def\aa{aa}% - \def\ae{ae}% - \def\l{l}% - \def\oe{oe}% - \def\o{o}% - \def\ss{ss}% - \def\exclamdown{!}% - \def\questiondown{?}% - % - % Don't no-op \tt, since it isn't a user-level command - % and is used in the definitions of the active chars like <, >, |, etc. - % Likewise with the other plain tex font commands. - %\let\tt=\asis - % - % Texinfo font commands. - \let\b=\asis - \let\i=\asis - \let\r=\asis - \let\sc=\asis - \let\t=\asis - % - \let\TeX=\indexdummytex - \let\acronym=\asis - \let\cite=\asis - \let\code=\asis - \let\command=\asis - \let\dfn=\asis - \let\dots=\indexdummydots - \let\emph=\asis - \let\env=\asis - \let\file=\asis - \let\kbd=\asis - \let\key=\asis - \let\math=\asis - \let\option=\asis - \let\samp=\asis - \let\strong=\asis - \let\uref=\asis - \let\url=\asis - \let\var=\asis - \let\w=\asis -} - -\let\indexbackslash=0 %overridden during \printindex. -\let\SETmarginindex=\relax % put index entries in margin (undocumented)? - -% For \ifx comparisons. -\def\emptymacro{\empty} - -% Most index entries go through here, but \dosubind is the general case. -% -\def\doind#1#2{\dosubind{#1}{#2}\empty} - -% Workhorse for all \fooindexes. -% #1 is name of index, #2 is stuff to put there, #3 is subentry -- -% \empty if called from \doind, as we usually are. The main exception -% is with defuns, which call us directly. -% -\def\dosubind#1#2#3{% - % Put the index entry in the margin if desired. - \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% - \fi - {% - \count255=\lastpenalty - {% - \indexdummies % Must do this here, since \bf, etc expand at this stage - \escapechar=`\\ - {% - \let\folio = 0% We will expand all macros now EXCEPT \folio. - \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now - % so it will be output as is; and it will print as backslash. - % - % The main index entry text. - \toks0 = {#2}% - % - % If third arg is present, precede it with space in sort key. - \def\thirdarg{#3}% - \ifx\thirdarg\emptymacro \else - % If the third (subentry) arg is present, add it to the index - % line to write. - \toks0 = \expandafter{\the\toks0 \space #3}% - \fi - % - % Process the index entry with all font commands turned off, to - % get the string to sort by. - {\indexnofonts - \edef\temp{\the\toks0}% need full expansion - \xdef\indexsorttmp{\temp}% - }% - % - % Set up the complete index entry, with both the sort key and - % the original text, including any font commands. We write - % three arguments to \entry to the .?? file (four in the - % subentry case), texindex reduces to two when writing the .??s - % sorted result. - \edef\temp{% - \write\csname#1indfile\endcsname{% - \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% - }% - % - % If a skip is the last thing on the list now, preserve it - % by backing up by \lastskip, doing the \write, then inserting - % the skip again. Otherwise, the whatsit generated by the - % \write will make \lastskip zero. The result is that sequences - % like this: - % @end defun - % @tindex whatever - % @defun ... - % will have extra space inserted, because the \medbreak in the - % start of the @defun won't see the skip inserted by the @end of - % the previous defun. - % - % But don't do any of this if we're not in vertical mode. We - % don't want to do a \vskip and prematurely end a paragraph. - % - % Avoid page breaks due to these extra skips, too. - % - \iflinks - \ifvmode - \skip0 = \lastskip - \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi - \fi - % - \temp % do the write - % - \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi - \fi - }% - }% - \penalty\count255 - }% -} - -% The index entry written in the file actually looks like -% \entry {sortstring}{page}{topic} -% or -% \entry {sortstring}{page}{topic}{subtopic} -% The texindex program reads in these files and writes files -% containing these kinds of lines: -% \initial {c} -% before the first topic whose initial is c -% \entry {topic}{pagelist} -% for a topic that is used without subtopics -% \primary {topic} -% for the beginning of a topic that is used with subtopics -% \secondary {subtopic}{pagelist} -% for each subtopic. - -% Define the user-accessible indexing commands -% @findex, @vindex, @kindex, @cindex. - -\def\findex {\fnindex} -\def\kindex {\kyindex} -\def\cindex {\cpindex} -\def\vindex {\vrindex} -\def\tindex {\tpindex} -\def\pindex {\pgindex} - -\def\cindexsub {\begingroup\obeylines\cindexsub} -{\obeylines % -\gdef\cindexsub "#1" #2^^M{\endgroup % -\dosubind{cp}{#2}{#1}}} - -% Define the macros used in formatting output of the sorted index material. - -% @printindex causes a particular index (the ??s file) to get printed. -% It does not print any chapter heading (usually an @unnumbered). -% -\def\printindex{\parsearg\doprintindex} -\def\doprintindex#1{\begingroup - \dobreak \chapheadingskip{10000}% - % - \smallfonts \rm - \tolerance = 9500 - \everypar = {}% don't want the \kern\-parindent from indentation suppression. - \indexbreaks - % - % See if the index file exists and is nonempty. - % Change catcode of @ here so that if the index file contains - % \initial {@} - % as its first line, TeX doesn't complain about mismatched braces - % (because it thinks @} is a control sequence). - \catcode`\@ = 11 - \openin 1 \jobname.#1s - \ifeof 1 - % \enddoublecolumns gets confused if there is no text in the index, - % and it loses the chapter title and the aux file entries for the - % index. The easiest way to prevent this problem is to make sure - % there is some text. - \putwordIndexNonexistent - \else - % - % If the index file exists but is empty, then \openin leaves \ifeof - % false. We have to make TeX try to read something from the file, so - % it can discover if there is anything in it. - \read 1 to \temp - \ifeof 1 - \putwordIndexIsEmpty - \else - % Index files are almost Texinfo source, but we use \ as the escape - % character. It would be better to use @, but that's too big a change - % to make right now. - \def\indexbackslash{\rawbackslashxx}% - \catcode`\\ = 0 - \escapechar = `\\ - \begindoublecolumns - \input \jobname.#1s - \enddoublecolumns - \fi - \fi - \closein 1 -\endgroup} - -% These macros are used by the sorted index file itself. -% Change them to control the appearance of the index. - -\def\initial#1{{% - % Some minor font changes for the special characters. - \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt - % - % Remove any glue we may have, we'll be inserting our own. - \removelastskip - % - % We like breaks before the index initials, so insert a bonus. - \penalty -300 - % - % Typeset the initial. Making this add up to a whole number of - % baselineskips increases the chance of the dots lining up from column - % to column. It still won't often be perfect, because of the stretch - % we need before each entry, but it's better. - % - % No shrink because it confuses \balancecolumns. - \vskip 1.67\baselineskip plus .5\baselineskip - \leftline{\secbf #1}% - \vskip .33\baselineskip plus .1\baselineskip - % - % Do our best not to break after the initial. - \nobreak -}} - -% This typesets a paragraph consisting of #1, dot leaders, and then #2 -% flush to the right margin. It is used for index and table of contents -% entries. The paragraph is indented by \leftskip. -% -\def\entry#1#2{\begingroup - % - % Start a new paragraph if necessary, so our assignments below can't - % affect previous text. - \par - % - % Do not fill out the last line with white space. - \parfillskip = 0in - % - % No extra space above this paragraph. - \parskip = 0in - % - % Do not prefer a separate line ending with a hyphen to fewer lines. - \finalhyphendemerits = 0 - % - % \hangindent is only relevant when the entry text and page number - % don't both fit on one line. In that case, bob suggests starting the - % dots pretty far over on the line. Unfortunately, a large - % indentation looks wrong when the entry text itself is broken across - % lines. So we use a small indentation and put up with long leaders. - % - % \hangafter is reset to 1 (which is the value we want) at the start - % of each paragraph, so we need not do anything with that. - \hangindent = 2em - % - % When the entry text needs to be broken, just fill out the first line - % with blank space. - \rightskip = 0pt plus1fil - % - % A bit of stretch before each entry for the benefit of balancing columns. - \vskip 0pt plus1pt - % - % Start a ``paragraph'' for the index entry so the line breaking - % parameters we've set above will have an effect. - \noindent - % - % Insert the text of the index entry. TeX will do line-breaking on it. - #1% - % The following is kludged to not output a line of dots in the index if - % there are no page numbers. The next person who breaks this will be - % cursed by a Unix daemon. - \def\tempa{{\rm }}% - \def\tempb{#2}% - \edef\tempc{\tempa}% - \edef\tempd{\tempb}% - \ifx\tempc\tempd\ \else% - % - % If we must, put the page number on a line of its own, and fill out - % this line with blank space. (The \hfil is overwhelmed with the - % fill leaders glue in \indexdotfill if the page number does fit.) - \hfil\penalty50 - \null\nobreak\indexdotfill % Have leaders before the page number. - % - % The `\ ' here is removed by the implicit \unskip that TeX does as - % part of (the primitive) \par. Without it, a spurious underfull - % \hbox ensues. - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - \ #2% The page number ends the paragraph. - \fi - \fi% - \par -\endgroup} - -% Like \dotfill except takes at least 1 em. -\def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} - -\def\primary #1{\line{#1\hfil}} - -\newskip\secondaryindent \secondaryindent=0.5cm -\def\secondary#1#2{{% - \parfillskip=0in - \parskip=0in - \hangindent=1in - \hangafter=1 - \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill - \ifpdf - \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. - \else - #2 - \fi - \par -}} - -% Define two-column mode, which we use to typeset indexes. -% Adapted from the TeXbook, page 416, which is to say, -% the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 - -\newbox\partialpage -\newdimen\doublecolumnhsize - -\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns - % Grab any single-column material above us. - \output = {% - % - % Here is a possibility not foreseen in manmac: if we accumulate a - % whole lot of material, we might end up calling this \output - % routine twice in a row (see the doublecol-lose test, which is - % essentially a couple of indexes with @setchapternewpage off). In - % that case we just ship out what is in \partialpage with the normal - % output routine. Generally, \partialpage will be empty when this - % runs and this will be a no-op. See the indexspread.tex test case. - \ifvoid\partialpage \else - \onepageout{\pagecontents\partialpage}% - \fi - % - \global\setbox\partialpage = \vbox{% - % Unvbox the main output page. - \unvbox\PAGE - \kern-\topskip \kern\baselineskip - }% - }% - \eject % run that output routine to set \partialpage - % - % Use the double-column output routine for subsequent pages. - \output = {\doublecolumnout}% - % - % Change the page size parameters. We could do this once outside this - % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 - % format, but then we repeat the same computation. Repeating a couple - % of assignments once per index is clearly meaningless for the - % execution time, so we may as well do it in one place. - % - % First we halve the line length, less a little for the gutter between - % the columns. We compute the gutter based on the line length, so it - % changes automatically with the paper format. The magic constant - % below is chosen so that the gutter has the same value (well, +-<1pt) - % as it did when we hard-coded it. - % - % We put the result in a separate register, \doublecolumhsize, so we - % can restore it in \pagesofar, after \hsize itself has (potentially) - % been clobbered. - % - \doublecolumnhsize = \hsize - \advance\doublecolumnhsize by -.04154\hsize - \divide\doublecolumnhsize by 2 - \hsize = \doublecolumnhsize - % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) - \vsize = 2\vsize -} - -% The double-column output routine for all double-column pages except -% the last. -% -\def\doublecolumnout{% - \splittopskip=\topskip \splitmaxdepth=\maxdepth - % Get the available space for the double columns -- the normal - % (undoubled) page height minus any material left over from the - % previous page. - \dimen@ = \vsize - \divide\dimen@ by 2 - \advance\dimen@ by -\ht\partialpage - % - % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ - \onepageout\pagesofar - \unvbox255 - \penalty\outputpenalty -} -% -% Re-output the contents of the output page -- any previous material, -% followed by the two boxes we just split, in box0 and box2. -\def\pagesofar{% - \unvbox\partialpage - % - \hsize = \doublecolumnhsize - \wd0=\hsize \wd2=\hsize - \hbox to\pagewidth{\box0\hfil\box2}% -} -% -% All done with double columns. -\def\enddoublecolumns{% - \output = {% - % Split the last of the double-column material. Leave it on the - % current page, no automatic page break. - \balancecolumns - % - % If we end up splitting too much material for the current page, - % though, there will be another page break right after this \output - % invocation ends. Having called \balancecolumns once, we do not - % want to call it again. Therefore, reset \output to its normal - % definition right away. (We hope \balancecolumns will never be - % called on to balance too much material, but if it is, this makes - % the output somewhat more palatable.) - \global\output = {\onepageout{\pagecontents\PAGE}}% - }% - \eject - \endgroup % started in \begindoublecolumns - % - % \pagegoal was set to the doubled \vsize above, since we restarted - % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize -} -% -% Called at the end of the double column material. -\def\balancecolumns{% - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. - \dimen@ = \ht0 - \advance\dimen@ by \topskip - \advance\dimen@ by-\baselineskip - \divide\dimen@ by 2 % target to split to - %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% - \splittopskip = \topskip - % Loop until we get a decent breakpoint. - {% - \vbadness = 10000 - \loop - \global\setbox3 = \copy0 - \global\setbox1 = \vsplit3 to \dimen@ - \ifdim\ht3>\dimen@ - \global\advance\dimen@ by 1pt - \repeat - }% - %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% - \setbox0=\vbox to\dimen@{\unvbox1}% - \setbox2=\vbox to\dimen@{\unvbox3}% - % - \pagesofar -} -\catcode`\@ = \other - - -\message{sectioning,} -% Chapters, sections, etc. - -\newcount\chapno -\newcount\secno \secno=0 -\newcount\subsecno \subsecno=0 -\newcount\subsubsecno \subsubsecno=0 - -% This counter is funny since it counts through charcodes of letters A, B, ... -\newcount\appendixno \appendixno = `\@ -% \def\appendixletter{\char\the\appendixno} -% We do the following for the sake of pdftex, which needs the actual -% letter in the expansion, not just typeset. -\def\appendixletter{% - \ifnum\appendixno=`A A% - \else\ifnum\appendixno=`B B% - \else\ifnum\appendixno=`C C% - \else\ifnum\appendixno=`D D% - \else\ifnum\appendixno=`E E% - \else\ifnum\appendixno=`F F% - \else\ifnum\appendixno=`G G% - \else\ifnum\appendixno=`H H% - \else\ifnum\appendixno=`I I% - \else\ifnum\appendixno=`J J% - \else\ifnum\appendixno=`K K% - \else\ifnum\appendixno=`L L% - \else\ifnum\appendixno=`M M% - \else\ifnum\appendixno=`N N% - \else\ifnum\appendixno=`O O% - \else\ifnum\appendixno=`P P% - \else\ifnum\appendixno=`Q Q% - \else\ifnum\appendixno=`R R% - \else\ifnum\appendixno=`S S% - \else\ifnum\appendixno=`T T% - \else\ifnum\appendixno=`U U% - \else\ifnum\appendixno=`V V% - \else\ifnum\appendixno=`W W% - \else\ifnum\appendixno=`X X% - \else\ifnum\appendixno=`Y Y% - \else\ifnum\appendixno=`Z Z% - % The \the is necessary, despite appearances, because \appendixletter is - % expanded while writing the .toc file. \char\appendixno is not - % expandable, thus it is written literally, thus all appendixes come out - % with the same letter (or @) in the toc without it. - \else\char\the\appendixno - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi - \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} - -% Each @chapter defines this as the name of the chapter. -% page headings and footings can use it. @section does likewise. -\def\thischapter{} -\def\thissection{} - -\newcount\absseclevel % used to calculate proper heading level -\newcount\secbase\secbase=0 % @raise/lowersections modify this count - -% @raisesections: treat @section as chapter, @subsection as section, etc. -\def\raisesections{\global\advance\secbase by -1} -\let\up=\raisesections % original BFox name - -% @lowersections: treat @chapter as section, @section as subsection, etc. -\def\lowersections{\global\advance\secbase by 1} -\let\down=\lowersections % original BFox name - -% Choose a numbered-heading macro -% #1 is heading level if unmodified by @raisesections or @lowersections -% #2 is text for heading -\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \chapterzzz{#2} -\or - \seczzz{#2} -\or - \numberedsubseczzz{#2} -\or - \numberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \chapterzzz{#2} - \else - \numberedsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% like \numhead, but chooses appendix heading levels -\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \appendixzzz{#2} -\or - \appendixsectionzzz{#2} -\or - \appendixsubseczzz{#2} -\or - \appendixsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \appendixzzz{#2} - \else - \appendixsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% like \numhead, but chooses numberless heading levels -\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 -\ifcase\absseclevel - \unnumberedzzz{#2} -\or - \unnumberedseczzz{#2} -\or - \unnumberedsubseczzz{#2} -\or - \unnumberedsubsubseczzz{#2} -\else - \ifnum \absseclevel<0 - \unnumberedzzz{#2} - \else - \unnumberedsubsubseczzz{#2} - \fi -\fi -\suppressfirstparagraphindent -} - -% @chapter, @appendix, @unnumbered. -\def\thischaptername{No Chapter Title} -\outer\def\chapter{\parsearg\chapteryyy} -\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz -\def\chapterzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}% - \chapmacro {#1}{\the\chapno}% - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - % We don't substitute the actual chapter name into \thischapter - % because we don't want its macros evaluated now. - \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% - \writetocentry{chap}{#1}{{\the\chapno}} - \donoderef - \global\let\section = \numberedsec - \global\let\subsection = \numberedsubsec - \global\let\subsubsection = \numberedsubsubsec -} - -% we use \chapno to avoid indenting back -\def\appendixbox#1{% - \setbox0 = \hbox{\putwordAppendix{} \the\chapno}% - \hbox to \wd0{#1\hss}} - -\outer\def\appendix{\parsearg\appendixyyy} -\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz -\def\appendixzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - \global\advance \appendixno by 1 - \message{\putwordAppendix\space \appendixletter}% - \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}% - \gdef\thissection{#1}% - \gdef\thischaptername{#1}% - \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% - \writetocentry{appendix}{#1}{{\appendixletter}} - \appendixnoderef - \global\let\section = \appendixsec - \global\let\subsection = \appendixsubsec - \global\let\subsubsection = \appendixsubsubsec -} - -% @centerchap is like @unnumbered, but the heading is centered. -\outer\def\centerchap{\parsearg\centerchapyyy} -\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} - -% @top is like @unnumbered. -\outer\def\top{\parsearg\unnumberedyyy} - -\outer\def\unnumbered{\parsearg\unnumberedyyy} -\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz -\def\unnumberedzzz #1{% - \secno=0 \subsecno=0 \subsubsecno=0 - % - % This used to be simply \message{#1}, but TeX fully expands the - % argument to \message. Therefore, if #1 contained @-commands, TeX - % expanded them. For example, in `@unnumbered The @cite{Book}', TeX - % expanded @cite (which turns out to cause errors because \cite is meant - % to be executed, not expanded). - % - % Anyway, we don't want the fully-expanded definition of @cite to appear - % as a result of the \message, we just want `@cite' itself. We use - % \the<toks register> to achieve this: TeX expands \the<toks> only once, - % simply yielding the contents of <toks register>. (We also do this for - % the toc entries.) - \toks0 = {#1}\message{(\the\toks0)}% - % - \unnumbchapmacro {#1}% - \gdef\thischapter{#1}\gdef\thissection{#1}% - \writetocentry{unnumbchap}{#1}{{\the\chapno}} - \unnumbnoderef - \global\let\section = \unnumberedsec - \global\let\subsection = \unnumberedsubsec - \global\let\subsubsection = \unnumberedsubsubsec -} - -% Sections. -\outer\def\numberedsec{\parsearg\secyyy} -\def\secyyy #1{\numhead1{#1}} % normally calls seczzz -\def\seczzz #1{% - \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % - \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% - \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}} - \donoderef - \nobreak -} - -\outer\def\appendixsection{\parsearg\appendixsecyyy} -\outer\def\appendixsec{\parsearg\appendixsecyyy} -\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz -\def\appendixsectionzzz #1{% - \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % - \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% - \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} -\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz -\def\unnumberedseczzz #1{% - \plainsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}} - \unnumbnoderef - \nobreak -} - -% Subsections. -\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} -\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz -\def\numberedsubseczzz #1{% - \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % - \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% - \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} - \donoderef - \nobreak -} - -\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} -\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz -\def\appendixsubseczzz #1{% - \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % - \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% - \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} -\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz -\def\unnumberedsubseczzz #1{% - \plainsubsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}} - \unnumbnoderef - \nobreak -} - -% Subsubsections. -\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} -\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz -\def\numberedsubsubseczzz #1{% - \gdef\thissection{#1}\global\advance \subsubsecno by 1 % - \subsubsecheading {#1} - {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% - \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \donoderef - \nobreak -} - -\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} -\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz -\def\appendixsubsubseczzz #1{% - \gdef\thissection{#1}\global\advance \subsubsecno by 1 % - \subsubsecheading {#1} - {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% - \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \appendixnoderef - \nobreak -} - -\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} -\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz -\def\unnumberedsubsubseczzz #1{% - \plainsubsubsecheading {#1}\gdef\thissection{#1}% - \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}} - \unnumbnoderef - \nobreak -} - -% These are variants which are not "outer", so they can appear in @ifinfo. -% Actually, they should now be obsolete; ordinary section commands should work. -\def\infotop{\parsearg\unnumberedzzz} -\def\infounnumbered{\parsearg\unnumberedzzz} -\def\infounnumberedsec{\parsearg\unnumberedseczzz} -\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} -\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} - -\def\infoappendix{\parsearg\appendixzzz} -\def\infoappendixsec{\parsearg\appendixseczzz} -\def\infoappendixsubsec{\parsearg\appendixsubseczzz} -\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} - -\def\infochapter{\parsearg\chapterzzz} -\def\infosection{\parsearg\sectionzzz} -\def\infosubsection{\parsearg\subsectionzzz} -\def\infosubsubsection{\parsearg\subsubsectionzzz} - -% These macros control what the section commands do, according -% to what kind of chapter we are in (ordinary, appendix, or unnumbered). -% Define them by default for a numbered chapter. -\global\let\section = \numberedsec -\global\let\subsection = \numberedsubsec -\global\let\subsubsection = \numberedsubsubsec - -% Define @majorheading, @heading and @subheading - -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - - -\def\majorheading{\parsearg\majorheadingzzz} -\def\majorheadingzzz #1{% - {\advance\chapheadingskip by 10pt \chapbreak }% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -\def\chapheading{\parsearg\chapheadingzzz} -\def\chapheadingzzz #1{\chapbreak % - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\penalty 200} - -% @heading, @subheading, @subsubheading. -\def\heading{\parsearg\plainsecheading} -\def\subheading{\parsearg\plainsubsecheading} -\def\subsubheading{\parsearg\plainsubsubsecheading} - -% These macros generate a chapter, section, etc. heading only -% (including whitespace, linebreaking, etc. around it), -% given all the information in convenient, parsed form. - -%%% Args are the skip and penalty (usually negative) -\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} - -\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} - -%%% Define plain chapter starts, and page on/off switching for it -% Parameter controlling skip before chapter headings (if needed) - -\newskip\chapheadingskip - -\def\chapbreak{\dobreak \chapheadingskip {-4000}} -\def\chappager{\par\vfill\supereject} -\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} - -\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} - -\def\CHAPPAGoff{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chapbreak -\global\let\pagealignmacro=\chappager} - -\def\CHAPPAGon{% -\global\let\contentsalignmacro = \chappager -\global\let\pchapsepmacro=\chappager -\global\let\pagealignmacro=\chappager -\global\def\HEADINGSon{\HEADINGSsingle}} - -\def\CHAPPAGodd{ -\global\let\contentsalignmacro = \chapoddpage -\global\let\pchapsepmacro=\chapoddpage -\global\let\pagealignmacro=\chapoddpage -\global\def\HEADINGSon{\HEADINGSdouble}} - -\CHAPPAGon - -\def\CHAPFplain{ -\global\let\chapmacro=\chfplain -\global\let\unnumbchapmacro=\unnchfplain -\global\let\centerchapmacro=\centerchfplain} - -% Plain chapter opening. -% #1 is the text, #2 the chapter number or empty if unnumbered. -\def\chfplain#1#2{% - \pchapsepmacro - {% - \chapfonts \rm - \def\chapnum{#2}% - \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 \centerparametersmaybe - \unhbox0 #1\par}% - }% - \nobreak\bigskip % no page break after a chapter title - \nobreak -} - -% Plain opening for unnumbered. -\def\unnchfplain#1{\chfplain{#1}{}} - -% @centerchap -- centered and unnumbered. -\let\centerparametersmaybe = \relax -\def\centerchfplain#1{{% - \def\centerparametersmaybe{% - \advance\rightskip by 3\rightskip - \leftskip = \rightskip - \parfillskip = 0pt - }% - \chfplain{#1}{}% -}} - -\CHAPFplain % The default - -\def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\raggedright - \rm #1\hfill}}\bigskip \par\nobreak -} - -\def\chfopen #1#2{\chapoddpage {\chapfonts -\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% -\par\penalty 5000 % -} - -\def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rm #1}\hfill}}\bigskip \par\nobreak -} - -\def\CHAPFopen{ -\global\let\chapmacro=\chfopen -\global\let\unnumbchapmacro=\unnchfopen -\global\let\centerchapmacro=\centerchfopen} - - -% Section titles. -\newskip\secheadingskip -\def\secheadingbreak{\dobreak \secheadingskip {-1000}} -\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} -\def\plainsecheading#1{\sectionheading{sec}{}{#1}} - -% Subsection titles. -\newskip \subsecheadingskip -\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} -\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} -\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} - -% Subsubsection titles. -\let\subsubsecheadingskip = \subsecheadingskip -\let\subsubsecheadingbreak = \subsecheadingbreak -\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} -\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} - - -% Print any size section title. -% -% #1 is the section type (sec/subsec/subsubsec), #2 is the section -% number (maybe empty), #3 the text. -\def\sectionheading#1#2#3{% - {% - \expandafter\advance\csname #1headingskip\endcsname by \parskip - \csname #1headingbreak\endcsname - }% - {% - % Switch to the right set of fonts. - \csname #1fonts\endcsname \rm - % - % Only insert the separating space if we have a section number. - \def\secnum{#2}% - \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% - % - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright - \hangindent = \wd0 % zero if no section number - \unhbox0 #3}% - }% - % Add extra space after the heading -- either a line space or a - % paragraph space, whichever is more. (Some people like to set - % \parskip to large values for some reason.) Don't allow stretch, though. - \nobreak - \ifdim\parskip>\normalbaselineskip - \kern\parskip - \else - \kern\normalbaselineskip - \fi - \nobreak -} - - -\message{toc,} -% Table of contents. -\newwrite\tocfile - -% Write an entry to the toc file, opening it if necessary. -% Called from @chapter, etc. We supply {\folio} at the end of the -% argument, which will end up as the last argument to the \...entry macro. -% -% Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}} -% We open the .toc file for writing here instead of at @setfilename (or -% any other fixed time) so that @contents can be anywhere in the document. -% -\newif\iftocfileopened -\def\writetocentry#1#2#3{% - \iftocfileopened\else - \immediate\openout\tocfile = \jobname.toc - \global\tocfileopenedtrue - \fi - % - \iflinks - \toks0 = {#2}% - \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}% - \temp - \fi - % - % Tell \shipout to create a page destination if we're doing pdf, which - % will be the target of the links in the table of contents. We can't - % just do it on every page because the title pages are numbered 1 and - % 2 (the page numbers aren't printed), and so are the first two pages - % of the document. Thus, we'd have two destinations named `1', and - % two named `2'. - \ifpdf \pdfmakepagedesttrue \fi -} - -\newskip\contentsrightmargin \contentsrightmargin=1in -\newcount\savepageno -\newcount\lastnegativepageno \lastnegativepageno = -1 - -% Finish up the main text and prepare to read what we've written -% to \tocfile. -% -\def\startcontents#1{% - % If @setchapternewpage on, and @headings double, the contents should - % start on an odd page, unlike chapters. Thus, we maintain - % \contentsalignmacro in parallel with \pagealignmacro. - % From: Torbjorn Granlund <tege@matematik.su.se> - \contentsalignmacro - \immediate\closeout\tocfile - % - % Don't need to put `Contents' or `Short Contents' in the headline. - % It is abundantly clear what they are. - \unnumbchapmacro{#1}\def\thischapter{}% - \savepageno = \pageno - \begingroup % Set up to handle contents files properly. - \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 - % We can't do this, because then an actual ^ in a section - % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. - %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi - \raggedbottom % Worry more about breakpoints than the bottom. - \advance\hsize by -\contentsrightmargin % Don't use the full line length. - % - % Roman numerals for page numbers. - \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi -} - - -% Normal (long) toc. -\def\contents{% - \startcontents{\putwordTOC}% - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \pdfmakeoutlines - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} - -% And just the chapters. -\def\summarycontents{% - \startcontents{\putwordShortTOC}% - % - \let\chapentry = \shortchapentry - \let\appendixentry = \shortappendixentry - \let\unnumbchapentry = \shortunnumberedentry - % We want a true roman here for the page numbers. - \secfonts - \let\rm=\shortcontrm \let\bf=\shortcontbf - \let\sl=\shortcontsl \let\tt=\shortconttt - \rm - \hyphenpenalty = 10000 - \advance\baselineskip by 1pt % Open it up a little. - \def\secentry ##1##2##3##4{} - \def\subsecentry ##1##2##3##4##5{} - \def\subsubsecentry ##1##2##3##4##5##6{} - \let\unnumbsecentry = \secentry - \let\unnumbsubsecentry = \subsecentry - \let\unnumbsubsubsecentry = \subsubsecentry - \openin 1 \jobname.toc - \ifeof 1 \else - \closein 1 - \input \jobname.toc - \fi - \vfill \eject - \contentsalignmacro % in case @setchapternewpage odd is in effect - \endgroup - \lastnegativepageno = \pageno - \global\pageno = \savepageno -} -\let\shortcontents = \summarycontents - -\ifpdf - \pdfcatalog{/PageMode /UseOutlines}% -\fi - -% These macros generate individual entries in the table of contents. -% The first argument is the chapter or section name. -% The last argument is the page number. -% The arguments in between are the chapter number, section number, ... - -% Chapters, in the main contents. -\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} -% -% Chapters, in the short toc. -% See comments in \dochapentry re vbox and related settings. -\def\shortchapentry#1#2#3{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}% -} - -% Appendices, in the main contents. -\def\appendixentry#1#2#3{% - \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}} -% -% Appendices, in the short toc. -\let\shortappendixentry = \shortchapentry - -% Typeset the label for a chapter or appendix for the short contents. -% The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter. -% We could simplify the code here by writing out an \appendixentry -% command in the toc file for appendices, instead of using \chapentry -% for both, but it doesn't seem worth it. -% -\newdimen\shortappendixwidth -% -\def\shortchaplabel#1{% - % This space should be enough, since a single number is .5em, and the - % widest letter (M) is 1em, at least in the Computer Modern fonts. - % But use \hss just in case. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) - \dimen0 = 1em - \hbox to \dimen0{#1\hss}% -} - -% Unnumbered chapters. -\def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}} -\def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}} - -% Sections. -\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} -\def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}} - -% Subsections. -\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} -\def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}} - -% And subsubsections. -\def\subsubsecentry#1#2#3#4#5#6{% - \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} -\def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}} - -% This parameter controls the indentation of the various levels. -\newdimen\tocindent \tocindent = 3pc - -% Now for the actual typesetting. In all these, #1 is the text and #2 is the -% page number. -% -% If the toc has to be broken over pages, we want it to be at chapters -% if at all possible; hence the \penalty. -\def\dochapentry#1#2{% - \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip - \begingroup - \chapentryfonts - \tocentry{#1}{\dopageno\bgroup#2\egroup}% - \endgroup - \nobreak\vskip .25\baselineskip plus.1\baselineskip -} - -\def\dosecentry#1#2{\begingroup - \secentryfonts \leftskip=\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsecentry#1#2{\begingroup - \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -\def\dosubsubsecentry#1#2{\begingroup - \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{\dopageno\bgroup#2\egroup}% -\endgroup} - -% Final typesetting of a toc entry; we use the same \entry macro as for -% the index entries, but we want to suppress hyphenation here. (We -% can't do that in the \entry macro, since index entries might consist -% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) -\def\tocentry#1#2{\begingroup - \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks - % Do not use \turnoffactive in these arguments. Since the toc is - % typeset in cmr, characters such as _ would come out wrong; we - % have to do the usual translation tricks. - \entry{#1}{#2}% -\endgroup} - -% Space between chapter (or whatever) number and the title. -\def\labelspace{\hskip1em \relax} - -\def\dopageno#1{{\rm #1}} -\def\doshortpageno#1{{\rm #1}} - -\def\chapentryfonts{\secfonts \rm} -\def\secentryfonts{\textfonts} -\let\subsecentryfonts = \textfonts -\let\subsubsecentryfonts = \textfonts - - -\message{environments,} -% @foo ... @end foo. - -% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. -% -% Since these characters are used in examples, it should be an even number of -% \tt widths. Each \tt character is 1en, so two makes it 1em. -% -\def\point{$\star$} -\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} -\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} -\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} -\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} - -% The @error{} command. -% Adapted from the TeXbook's \boxit. -% -\newbox\errorbox -% -{\tentt \global\dimen0 = 3em}% Width of the box. -\dimen2 = .55pt % Thickness of rules -% The text. (`r' is open on the right, `e' somewhat less so on the left.) -\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} -% -\global\setbox\errorbox=\hbox to \dimen0{\hfil - \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. - \advance\hsize by -2\dimen2 % Rules. - \vbox{ - \hrule height\dimen2 - \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. - \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. - \kern3pt\vrule width\dimen2}% Space to right. - \hrule height\dimen2} - \hfil} -% -\def\error{\leavevmode\lower.7ex\copy\errorbox} - -% @tex ... @end tex escapes into raw Tex temporarily. -% One exception: @ is still an escape character, so that @end tex works. -% But \@ or @@ will get a plain tex @ character. - -\def\tex{\begingroup - \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 - \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 - \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie - \catcode `\%=14 - \catcode `\+=\other - \catcode `\"=\other - \catcode `\==\other - \catcode `\|=\other - \catcode `\<=\other - \catcode `\>=\other - \escapechar=`\\ - % - \let\b=\ptexb - \let\bullet=\ptexbullet - \let\c=\ptexc - \let\,=\ptexcomma - \let\.=\ptexdot - \let\dots=\ptexdots - \let\equiv=\ptexequiv - \let\!=\ptexexclam - \let\i=\ptexi - \let\indent=\ptexindent - \let\{=\ptexlbrace - \let\+=\tabalign - \let\}=\ptexrbrace - \let\/=\ptexslash - \let\*=\ptexstar - \let\t=\ptext - % - \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% - \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% - \def\@{@}% -\let\Etex=\endgroup} - -% Define @lisp ... @end lisp. -% @lisp does a \begingroup so it can rebind things, -% including the definition of @end lisp (which normally is erroneous). - -% Amount to narrow the margins by for @lisp. -\newskip\lispnarrowing \lispnarrowing=0.4in - -% This is the definition that ^^M gets inside @lisp, @example, and other -% such environments. \null is better than a space, since it doesn't -% have any width. -\def\lisppar{\null\endgraf} - -% Make each space character in the input produce a normal interword -% space in the output. Don't allow a line break at this space, as this -% is used only in environments like @example, where each line of input -% should produce a line of output anyway. -% -{\obeyspaces % -\gdef\sepspaces{\obeyspaces\let =\tie}} - -% Define \obeyedspace to be our active space, whatever it is. This is -% for use in \parsearg. -{\sepspaces% -\global\let\obeyedspace= } - -% This space is always present above and below environments. -\newskip\envskipamount \envskipamount = 0pt - -% Make spacing and below environment symmetrical. We use \parskip here -% to help in doing that, since in @example-like environments \parskip -% is reset to zero; thus the \afterenvbreak inserts no space -- but the -% start of the next paragraph will insert \parskip. -% -\def\aboveenvbreak{{% - % =10000 instead of <10000 because of a special case in \itemzzz, q.v. - \ifnum \lastpenalty=10000 \else - \advance\envskipamount by \parskip - \endgraf - \ifdim\lastskip<\envskipamount - \removelastskip - % it's not a good place to break if the last penalty was \nobreak - % or better ... - \ifnum\lastpenalty>10000 \else \penalty-50 \fi - \vskip\envskipamount - \fi - \fi -}} - -\let\afterenvbreak = \aboveenvbreak - -% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. -\let\nonarrowing=\relax - -% @cartouche ... @end cartouche: draw rectangle w/rounded corners around -% environment contents. -\font\circle=lcircle10 -\newdimen\circthick -\newdimen\cartouter\newdimen\cartinner -\newskip\normbskip\newskip\normpskip\newskip\normlskip -\circthick=\fontdimen8\circle -% -\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth -\def\ctr{{\hskip 6pt\circle\char'010}} -\def\cbl{{\circle\char'012\hskip -6pt}} -\def\cbr{{\hskip 6pt\circle\char'011}} -\def\carttop{\hbox to \cartouter{\hskip\lskip - \ctl\leaders\hrule height\circthick\hfil\ctr - \hskip\rskip}} -\def\cartbot{\hbox to \cartouter{\hskip\lskip - \cbl\leaders\hrule height\circthick\hfil\cbr - \hskip\rskip}} -% -\newskip\lskip\newskip\rskip - -\def\cartouche{% -\par % can't be in the midst of a paragraph. -\begingroup - \lskip=\leftskip \rskip=\rightskip - \leftskip=0pt\rightskip=0pt %we want these *outside*. - \cartinner=\hsize \advance\cartinner by-\lskip - \advance\cartinner by-\rskip - \cartouter=\hsize - \advance\cartouter by 18.4pt % allow for 3pt kerns on either -% side, and for 6pt waste from -% each corner char, and rule thickness - \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip - % Flag to tell @lisp, etc., not to narrow margin. - \let\nonarrowing=\comment - \vbox\bgroup - \baselineskip=0pt\parskip=0pt\lineskip=0pt - \carttop - \hbox\bgroup - \hskip\lskip - \vrule\kern3pt - \vbox\bgroup - \hsize=\cartinner - \kern3pt - \begingroup - \baselineskip=\normbskip - \lineskip=\normlskip - \parskip=\normpskip - \vskip -\parskip -\def\Ecartouche{% - \endgroup - \kern3pt - \egroup - \kern3pt\vrule - \hskip\rskip - \egroup - \cartbot - \egroup -\endgroup -}} - - -% This macro is called at the beginning of all the @example variants, -% inside a group. -\def\nonfillstart{% - \aboveenvbreak - \inENV % This group ends at the end of the body - \hfuzz = 12pt % Don't be fussy - \sepspaces % Make spaces be word-separators rather than space tokens. - \let\par = \lisppar % don't ignore blank lines - \obeylines % each line of input is a line of output - \parskip = 0pt - \parindent = 0pt - \emergencystretch = 0pt % don't try to avoid overfull boxes - % @cartouche defines \nonarrowing to inhibit narrowing - % at next level down. - \ifx\nonarrowing\relax - \advance \leftskip by \lispnarrowing - \exdentamount=\lispnarrowing - \let\exdent=\nofillexdent - \let\nonarrowing=\relax - \fi -} - -% Define the \E... control sequence only if we are inside the particular -% environment, so the error checking in \end will work. -% -% To end an @example-like environment, we first end the paragraph (via -% \afterenvbreak's vertical glue), and then the group. That way we keep -% the zero \parskip that the environments set -- \parskip glue will be -% inserted at the beginning of the next paragraph in the document, after -% the environment. -% -\def\nonfillfinish{\afterenvbreak\endgroup} - -% @lisp: indented, narrowed, typewriter font. -\def\lisp{\begingroup - \nonfillstart - \let\Elisp = \nonfillfinish - \tt - \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. - \gobble % eat return -} - -% @example: Same as @lisp. -\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} - -% @smallexample and @smalllisp: use smaller fonts. -% Originally contributed by Pavel@xerox. -\def\smalllisp{\begingroup - \def\Esmalllisp{\nonfillfinish\endgroup}% - \def\Esmallexample{\nonfillfinish\endgroup}% - \smallexamplefonts - \lisp -} -\let\smallexample = \smalllisp - - -% @display: same as @lisp except keep current font. -% -\def\display{\begingroup - \nonfillstart - \let\Edisplay = \nonfillfinish - \gobble -} -% -% @smalldisplay: @display plus smaller fonts. -% -\def\smalldisplay{\begingroup - \def\Esmalldisplay{\nonfillfinish\endgroup}% - \smallexamplefonts \rm - \display -} - -% @format: same as @display except don't narrow margins. -% -\def\format{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eformat = \nonfillfinish - \gobble -} -% -% @smallformat: @format plus smaller fonts. -% -\def\smallformat{\begingroup - \def\Esmallformat{\nonfillfinish\endgroup}% - \smallexamplefonts \rm - \format -} - -% @flushleft (same as @format). -% -\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format} - -% @flushright. -% -\def\flushright{\begingroup - \let\nonarrowing = t - \nonfillstart - \let\Eflushright = \nonfillfinish - \advance\leftskip by 0pt plus 1fill - \gobble -} - - -% @quotation does normal linebreaking (hence we can't use \nonfillstart) -% and narrows the margins. -% -\def\quotation{% - \begingroup\inENV %This group ends at the end of the @quotation body - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % We have retained a nonzero parskip for the environment, since we're - % doing normal filling. So to avoid extra space below the environment... - \def\Equotation{\parskip = 0pt \nonfillfinish}% - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. - \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing - \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \let\nonarrowing = \relax - \fi -} - - -% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>} -% If we want to allow any <char> as delimiter, -% we need the curly braces so that makeinfo sees the @verb command, eg: -% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org -% -% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. -% -% [Knuth] p.344; only we need to do the other characters Texinfo sets -% active too. Otherwise, they get lost as the first character on a -% verbatim line. -\def\dospecials{% - \do\ \do\\\do\{\do\}\do\$\do\&% - \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% - \do\<\do\>\do\|\do\@\do+\do\"% -} -% -% [Knuth] p. 380 -\def\uncatcodespecials{% - \def\do##1{\catcode`##1=12}\dospecials} -% -% [Knuth] pp. 380,381,391 -% Disable Spanish ligatures ?` and !` of \tt font -\begingroup - \catcode`\`=\active\gdef`{\relax\lq} -\endgroup -% -% Setup for the @verb command. -% -% Eight spaces for a tab -\begingroup - \catcode`\^^I=\active - \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} -\endgroup -% -\def\setupverb{% - \tt % easiest (and conventionally used) font for verbatim - \def\par{\leavevmode\endgraf}% - \catcode`\`=\active - \tabeightspaces - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces -} - -% Setup for the @verbatim environment -% -% Real tab expansion -\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount -% -\def\starttabbox{\setbox0=\hbox\bgroup} -\begingroup - \catcode`\^^I=\active - \gdef\tabexpand{% - \catcode`\^^I=\active - \def^^I{\leavevmode\egroup - \dimen0=\wd0 % the width so far, or since the previous tab - \divide\dimen0 by\tabw - \multiply\dimen0 by\tabw % compute previous multiple of \tabw - \advance\dimen0 by\tabw % advance to next multiple of \tabw - \wd0=\dimen0 \box0 \starttabbox - }% - } -\endgroup -\def\setupverbatim{% - % Easiest (and conventionally used) font for verbatim - \tt - \def\par{\leavevmode\egroup\box0\endgraf}% - \catcode`\`=\active - \tabexpand - % Respect line breaks, - % print special symbols as themselves, and - % make each space count - % must do in this order: - \obeylines \uncatcodespecials \sepspaces - \everypar{\starttabbox}% -} - -% Do the @verb magic: verbatim text is quoted by unique -% delimiter characters. Before first delimiter expect a -% right brace, after last delimiter expect closing brace: -% -% \def\doverb'{'<char>#1<char>'}'{#1} -% -% [Knuth] p. 382; only eat outer {} -\begingroup - \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12 - \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] -\endgroup -% -\def\verb{\begingroup\setupverb\doverb} -% -% -% Do the @verbatim magic: define the macro \doverbatim so that -% the (first) argument ends when '@end verbatim' is reached, ie: -% -% \def\doverbatim#1@end verbatim{#1} -% -% For Texinfo it's a lot easier than for LaTeX, -% because texinfo's \verbatim doesn't stop at '\end{verbatim}': -% we need not redefine '\', '{' and '}'. -% -% Inspired by LaTeX's verbatim command set [latex.ltx] -%% Include LaTeX hack for completeness -- never know -%% \begingroup -%% \catcode`|=0 \catcode`[=1 -%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active -%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[ -%% #1|endgroup|def|Everbatim[]|end[verbatim]] -%% |endgroup -% -\begingroup - \catcode`\ =\active - \obeylines % - % ignore everything up to the first ^^M, that's the newline at the end - % of the @verbatim input line itself. Otherwise we get an extra blank - % line in the output. - \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}% -\endgroup -% -\def\verbatim{% - \def\Everbatim{\nonfillfinish\endgroup}% - \begingroup - \nonfillstart - \advance\leftskip by -\defbodyindent - \begingroup\setupverbatim\doverbatim -} - -% @verbatiminclude FILE - insert text of file in verbatim environment. -% -% Allow normal characters that we make active in the argument (a file name). -\def\verbatiminclude{% - \begingroup - \catcode`\\=\other - \catcode`~=\other - \catcode`^=\other - \catcode`_=\other - \catcode`|=\other - \catcode`<=\other - \catcode`>=\other - \catcode`+=\other - \parsearg\doverbatiminclude -} -\def\setupverbatiminclude{% - \begingroup - \nonfillstart - \advance\leftskip by -\defbodyindent - \begingroup\setupverbatim -} -% -\def\doverbatiminclude#1{% - % Restore active chars for included file. - \endgroup - \begingroup - \let\value=\expandablevalue - \def\thisfile{#1}% - \expandafter\expandafter\setupverbatiminclude\input\thisfile - \endgroup - \nonfillfinish - \endgroup -} - -% @copying ... @end copying. -% Save the text away for @insertcopying later. Many commands won't be -% allowed in this context, but that's ok. -% -% We save the uninterpreted tokens, rather than creating a box. -% Saving the text in a box would be much easier, but then all the -% typesetting commands (@smallbook, font changes, etc.) have to be done -% beforehand -- and a) we want @copying to be done first in the source -% file; b) letting users define the frontmatter in as flexible order as -% possible is very desirable. -% -\def\copying{\begingroup - % Define a command to swallow text until we reach `@end copying'. - % \ is the escape char in this texinfo.tex file, so it is the - % delimiter for the command; @ will be the escape char when we read - % it, but that doesn't matter. - \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}% - % - % We must preserve ^^M's in the input file; see \insertcopying below. - \catcode`\^^M = \active - \docopying -} - -% What we do to finish off the copying text. -% -\def\enddocopying{\endgroup\ignorespaces} - -% @insertcopying. Here we must play games with ^^M's. On the one hand, -% we need them to delimit commands such as `@end quotation', so they -% must be active. On the other hand, we certainly don't want every -% end-of-line to be a \par, as would happen with the normal active -% definition of ^^M. On the third hand, two ^^M's in a row should still -% generate a \par. -% -% Our approach is to make ^^M insert a space and a penalty1 normally; -% then it can also check if \lastpenalty=1. If it does, then manually -% do \par. -% -% This messes up the normal definitions of @c[omment], so we redefine -% it. Similarly for @ignore. (These commands are used in the gcc -% manual for man page generation.) -% -% Seems pretty fragile, most line-oriented commands will presumably -% fail, but for the limited use of getting the copying text (which -% should be quite simple) inserted, we can hope it's ok. -% -{\catcode`\^^M=\active % -\gdef\insertcopying{\begingroup % - \parindent = 0pt % looks wrong on title page - \def^^M{% - \ifnum \lastpenalty=1 % - \par % - \else % - \space \penalty 1 % - \fi % - }% - % - % Fix @c[omment] for catcode 13 ^^M's. - \def\c##1^^M{\ignorespaces}% - \let\comment = \c % - % - % Don't bother jumping through all the hoops that \doignore does, it - % would be very hard since the catcodes are already set. - \long\def\ignore##1\end ignore{\ignorespaces}% - % - \copyingtext % -\endgroup}% -} - -\message{defuns,} -% @defun etc. - -% Allow user to change definition object font (\df) internally -\def\setdeffont#1 {\csname DEF#1\endcsname} - -\newskip\defbodyindent \defbodyindent=.4in -\newskip\defargsindent \defargsindent=50pt -\newskip\deflastargmargin \deflastargmargin=18pt - -\newcount\parencount - -% We want ()&[] to print specially on the defun line. -% -\def\activeparens{% - \catcode`\(=\active \catcode`\)=\active - \catcode`\&=\active - \catcode`\[=\active \catcode`\]=\active -} - -% Make control sequences which act like normal parenthesis chars. -\let\lparen = ( \let\rparen = ) - -{\activeparens % Now, smart parens don't turn on until &foo (see \amprm) - -% Be sure that we always have a definition for `(', etc. For example, -% if the fn name has parens in it, \boldbrax will not be in effect yet, -% so TeX would otherwise complain about undefined control sequence. -\global\let(=\lparen \global\let)=\rparen -\global\let[=\lbrack \global\let]=\rbrack - -\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } -\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} -% This is used to turn on special parens -% but make & act ordinary (given that it's active). -\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} - -% Definitions of (, ) and & used in args for functions. -% This is the definition of ( outside of all parentheses. -\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested - \global\advance\parencount by 1 -} -% -% This is the definition of ( when already inside a level of parens. -\gdef\opnested{\char`\(\global\advance\parencount by 1 } -% -\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. - % also in that case restore the outer-level definition of (. - \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi - \global\advance \parencount by -1 } -% If we encounter &foo, then turn on ()-hacking afterwards -\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ } -% -\gdef\normalparens{\boldbrax\let&=\ampnr} -} % End of definition inside \activeparens -%% These parens (in \boldbrax) actually are a little bolder than the -%% contained text. This is especially needed for [ and ] -\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } -\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } -\let\ampnr = \& -\def\lbrb{{\bf\char`\[}} -\def\rbrb{{\bf\char`\]}} - -% Active &'s sneak into the index arguments, so make sure it's defined. -{ - \catcode`& = \active - \global\let& = \ampnr -} - -% \defname, which formats the name of the @def (not the args). -% #1 is the function name. -% #2 is the type of definition, such as "Function". -% -\def\defname#1#2{% - % How we'll output the type name. Putting it in brackets helps - % distinguish it from the body text that may end up on the next line - % just below it. - \ifempty{#2}% - \def\defnametype{}% - \else - \def\defnametype{[\rm #2]}% - \fi - % - % Get the values of \leftskip and \rightskip as they were outside the @def... - \dimen2=\leftskip - \advance\dimen2 by -\defbodyindent - % - % Figure out values for the paragraph shape. - \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}% - \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line - \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations - \parshape 2 0in \dimen0 \defargsindent \dimen1 - % - % Output arg 2 ("Function" or some such) but stuck inside a box of - % width 0 so it does not interfere with linebreaking. - \noindent - % - {% Adjust \hsize to exclude the ambient margins, - % so that \rightline will obey them. - \advance \hsize by -\dimen2 - \dimen3 = 0pt % was -1.25pc - \rlap{\rightline{\defnametype\kern\dimen3}}% - }% - % - % Allow all lines to be underfull without complaint: - \tolerance=10000 \hbadness=10000 - \advance\leftskip by -\defbodyindent - \exdentamount=\defbodyindent - {\df #1}\enskip % output function name - % \defunargs will be called next to output the arguments, if any. -} - -% Common pieces to start any @def... -% #1 is the \E... control sequence to end the definition (which we define). -% #2 is the \...x control sequence (which our caller defines). -% #3 is the control sequence to process the header, such as \defunheader. -% -\def\parsebodycommon#1#2#3{% - \begingroup\inENV - % If there are two @def commands in a row, we'll have a \nobreak, - % which is there to keep the function description together with its - % header. But if there's nothing but headers, we want to allow a - % break after all. Check for penalty 10002 (inserted by - % \defargscommonending) instead of 10000, since the sectioning - % commands insert a \penalty10000, and we don't want to allow a break - % between a section heading and a defun. - \ifnum\lastpenalty=10002 \penalty0 \fi - \medbreak - % - % Define the \E... end token that this defining construct specifies - % so that it will exit this group. - \def#1{\endgraf\endgroup\medbreak}% - % - \parindent=0in - \advance\leftskip by \defbodyindent - \exdentamount=\defbodyindent -} - -% Common part of the \...x definitions. -% -\def\defxbodycommon{% - % As with \parsebodycommon above, allow line break if we have multiple - % x headers in a row. It's not a great place, though. - \ifnum\lastpenalty=10000 \penalty1000 \fi - % - \begingroup\obeylines -} - -% Process body of @defun, @deffn, @defmac, etc. -% -\def\defparsebody#1#2#3{% - \parsebodycommon{#1}{#2}{#3}% - \def#2{\defxbodycommon \activeparens \spacesplit#3}% - \catcode\equalChar=\active - \begingroup\obeylines\activeparens - \spacesplit#3% -} - -% #1, #2, #3 are the common arguments (see \parsebodycommon above). -% #4, delimited by the space, is the class name. -% -\def\defmethparsebody#1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}% - \begingroup\obeylines\activeparens - % The \empty here prevents misinterpretation of a construct such as - % @deffn {whatever} {Enharmonic comma} - % See comments at \deftpparsebody, although in our case we don't have - % to remove the \empty afterwards, since it is empty. - \spacesplit{#3{#4}}\empty -} - -% Used for @deftypemethod and @deftypeivar. -% #1, #2, #3 are the common arguments (see \defparsebody). -% #4, delimited by a space, is the class name. -% #5 is the method's return type. -% -\def\deftypemethparsebody#1#2#3#4 #5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#4}{#5}}% -} - -% Used for @deftypeop. The change from \deftypemethparsebody is an -% extra argument at the beginning which is the `category', instead of it -% being the hardwired string `Method' or `Instance Variable'. We have -% to account for this both in the \...x definition and in parsing the -% input at hand. Thus also need a control sequence (passed as #5) for -% the \E... definition to assign the category name to. -% -\def\deftypeopparsebody#1#2#3#4#5 #6 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 ##3 {\def#4{##1}% - \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#5}{#6}}% -} - -% For @defop. -\def\defopparsebody #1#2#3#4#5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\def#4{##1}% - \defxbodycommon \activeparens \spacesplit{#3{##2}}}% - \begingroup\obeylines\activeparens - \spacesplit{#3{#5}}% -} - -% These parsing functions are similar to the preceding ones -% except that they do not make parens into active characters. -% These are used for "variables" since they have no arguments. -% -\def\defvarparsebody #1#2#3{% - \parsebodycommon{#1}{#2}{#3}% - \def#2{\defxbodycommon \spacesplit#3}% - \catcode\equalChar=\active - \begingroup\obeylines - \spacesplit#3% -} - -% @defopvar. -\def\defopvarparsebody #1#2#3#4#5 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 ##2 {\def#4{##1}% - \defxbodycommon \spacesplit{#3{##2}}}% - \begingroup\obeylines - \spacesplit{#3{#5}}% -} - -\def\defvrparsebody#1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% - \begingroup\obeylines - \spacesplit{#3{#4}}% -} - -% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the -% type is just `struct', because we lose the braces in `{struct -% termios}' when \spacesplit reads its undelimited argument. Sigh. -% \let\deftpparsebody=\defvrparsebody -% -% So, to get around this, we put \empty in with the type name. That -% way, TeX won't find exactly `{...}' as an undelimited argument, and -% won't strip off the braces. -% -\def\deftpparsebody #1#2#3#4 {% - \parsebodycommon{#1}{#2}{#3}% - \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}% - \begingroup\obeylines - \spacesplit{\parsetpheaderline{#3{#4}}}\empty -} - -% Fine, but then we have to eventually remove the \empty *and* the -% braces (if any). That's what this does. -% -\def\removeemptybraces\empty#1\relax{#1} - -% After \spacesplit has done its work, this is called -- #1 is the final -% thing to call, #2 the type name (which starts with \empty), and #3 -% (which might be empty) the arguments. -% -\def\parsetpheaderline#1#2#3{% - #1{\removeemptybraces#2\relax}{#3}% -}% - -% Split up #2 (the rest of the input line) at the first space token. -% call #1 with two arguments: -% the first is all of #2 before the space token, -% the second is all of #2 after that space token. -% If #2 contains no space token, all of it is passed as the first arg -% and the second is passed as empty. -% -{\obeylines % - \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}% - \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{% - \ifx\relax #3% - #1{#2}{}% - \else % - #1{#2}{#3#4}% - \fi}% -} - -% Define @defun. - -% This is called to end the arguments processing for all the @def... commands. -% -\def\defargscommonending{% - \interlinepenalty = 10000 - \advance\rightskip by 0pt plus 1fil - \endgraf - \nobreak\vskip -\parskip - \penalty 10002 % signal to \parsebodycommon. -} - -% This expands the args and terminates the paragraph they comprise. -% -\def\defunargs#1{\functionparens \sl -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Set the font temporarily and use \font in case \setfont made \tensl a macro. -{\tensl\hyphenchar\font=0}% -#1% -{\tensl\hyphenchar\font=45}% -\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% - \defargscommonending -} - -\def\deftypefunargs #1{% -% Expand, preventing hyphenation at `-' chars. -% Note that groups don't affect changes in \hyphenchar. -% Use \boldbraxnoamp, not \functionparens, so that & is not special. -\boldbraxnoamp -\tclose{#1}% avoid \code because of side effects on active chars - \defargscommonending -} - -% Do complete processing of one @defun or @defunx line already parsed. - -% @deffn Command forward-char nchars - -\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} - -\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% -\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defun == @deffn Function - -\def\defun{\defparsebody\Edefun\defunx\defunheader} - -\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDeffunc}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @deftypefun int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} - -% #1 is the data type. #2 is the name and args. -\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} -% #1 is the data type, #2 the name, #3 the args. -\def\deftypefunheaderx #1#2 #3\relax{% -\doind {fn}{\code{#2}}% Make entry in function index -\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}% -\deftypefunargs {#3}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) - -\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} - -% \defheaderxcond#1\relax$.$ -% puts #1 in @code, followed by a space, but does nothing if #1 is null. -\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi} - -% #1 is the classification. #2 is the data type. #3 is the name and args. -\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} -% #1 is the classification, #2 the data type, #3 the name, #4 the args. -\def\deftypefnheaderx #1#2#3 #4\relax{% -\doind {fn}{\code{#3}}% Make entry in function index -\begingroup -\normalparens % notably, turn off `&' magic, which prevents -% at least some C++ text from working -\defname {\defheaderxcond#2\relax$.$#3}{#1}% -\deftypefunargs {#4}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defmac == @deffn Macro - -\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} - -\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefmac}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defspec == @deffn Special Form - -\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} - -\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index -\begingroup\defname {#1}{\putwordDefspec}% -\defunargs {#2}\endgroup % -\catcode\equalChar=\other % Turn off change made in \defparsebody -} - -% @defop CATEGORY CLASS OPERATION ARG... -% -\def\defop #1 {\def\defoptype{#1}% -\defopparsebody\Edefop\defopx\defopheader\defoptype} -% -\def\defopheader#1#2#3{% - \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry - \begingroup - \defname{#2}{\defoptype\ \putwordon\ #1}% - \defunargs{#3}% - \endgroup -} - -% @deftypeop CATEGORY CLASS TYPE OPERATION ARG... -% -\def\deftypeop #1 {\def\deftypeopcategory{#1}% - \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader - \deftypeopcategory} -% -% #1 is the class name, #2 the data type, #3 the operation name, #4 the args. -\def\deftypeopheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3} - {\deftypeopcategory\ \putwordon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypemethod CLASS TYPE METHOD ARG... -% -\def\deftypemethod{% - \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} -% -% #1 is the class name, #2 the data type, #3 the method name, #4 the args. -\def\deftypemethodheader#1#2#3#4{% - \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}% - \deftypefunargs{#4}% - \endgroup -} - -% @deftypeivar CLASS TYPE VARNAME -% -\def\deftypeivar{% - \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader} -% -% #1 is the class name, #2 the data type, #3 the variable name. -\def\deftypeivarheader#1#2#3{% - \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index - \begingroup - \defname{\defheaderxcond#2\relax$.$#3} - {\putwordInstanceVariableof\ \code{#1}}% - \defvarargs{#3}% - \endgroup -} - -% @defmethod == @defop Method -% -\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} -% -% #1 is the class name, #2 the method name, #3 the args. -\def\defmethodheader#1#2#3{% - \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index - \begingroup - \defname{#2}{\putwordMethodon\ \code{#1}}% - \defunargs{#3}% - \endgroup -} - -% @defcv {Class Option} foo-class foo-flag - -\def\defcv #1 {\def\defcvtype{#1}% -\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} - -\def\defcvarheader #1#2#3{% - \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry - \begingroup - \defname{#2}{\defcvtype\ \putwordof\ #1}% - \defvarargs{#3}% - \endgroup -} - -% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME -% -\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} -% -\def\defivarheader#1#2#3{% - \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index - \begingroup - \defname{#2}{\putwordInstanceVariableof\ #1}% - \defvarargs{#3}% - \endgroup -} - -% @defvar -% First, define the processing that is wanted for arguments of @defvar. -% This is actually simple: just print them in roman. -% This must expand the args and terminate the paragraph they make up -\def\defvarargs #1{\normalparens #1% - \defargscommonending -} - -% @defvr Counter foo-count - -\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} - -\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% -\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} - -% @defvar == @defvr Variable - -\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} - -\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefvar}% -\defvarargs {#2}\endgroup % -} - -% @defopt == @defvr {User Option} - -\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} - -\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index -\begingroup\defname {#1}{\putwordDefopt}% -\defvarargs {#2}\endgroup % -} - -% @deftypevar int foobar - -\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} - -% #1 is the data type. #2 is the name, perhaps followed by text that -% is actually part of the data type, which should not be put into the index. -\def\deftypevarheader #1#2{% -\dovarind#2 \relax% Make entry in variables index -\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}% - \defargscommonending -\endgroup} -\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} - -% @deftypevr {Global Flag} int enable - -\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} - -\def\deftypevrheader #1#2#3{\dovarind#3 \relax% -\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1} - \defargscommonending -\endgroup} - -% Now define @deftp -% Args are printed in bold, a slight difference from @defvar. - -\def\deftpargs #1{\bf \defvarargs{#1}} - -% @deftp Class window height width ... - -\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} - -\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% -\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} - -% These definitions are used if you use @defunx (etc.) -% anywhere other than immediately after a @defun or @defunx. -% -\def\defcvx#1 {\errmessage{@defcvx in invalid context}} -\def\deffnx#1 {\errmessage{@deffnx in invalid context}} -\def\defivarx#1 {\errmessage{@defivarx in invalid context}} -\def\defmacx#1 {\errmessage{@defmacx in invalid context}} -\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}} -\def\defoptx #1 {\errmessage{@defoptx in invalid context}} -\def\defopx#1 {\errmessage{@defopx in invalid context}} -\def\defspecx#1 {\errmessage{@defspecx in invalid context}} -\def\deftpx#1 {\errmessage{@deftpx in invalid context}} -\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}} -\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}} -\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}} -\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}} -\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}} -\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}} -\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}} -\def\defunx#1 {\errmessage{@defunx in invalid context}} -\def\defvarx#1 {\errmessage{@defvarx in invalid context}} -\def\defvrx#1 {\errmessage{@defvrx in invalid context}} - - -\message{macros,} -% @macro. - -% To do this right we need a feature of e-TeX, \scantokens, -% which we arrange to emulate with a temporary file in ordinary TeX. -\ifx\eTeXversion\undefined - \newwrite\macscribble - \def\scanmacro#1{% - \begingroup \newlinechar`\^^M - % Undo catcode changes of \startcontents and \doprintindex - \catcode`\@=0 \catcode`\\=\other \escapechar=`\@ - % Append \endinput to make sure that TeX does not see the ending newline. - \toks0={#1\endinput}% - \immediate\openout\macscribble=\jobname.tmp - \immediate\write\macscribble{\the\toks0}% - \immediate\closeout\macscribble - \let\xeatspaces\eatspaces - \input \jobname.tmp - \endgroup -} -\else -\def\scanmacro#1{% -\begingroup \newlinechar`\^^M -% Undo catcode changes of \startcontents and \doprintindex -\catcode`\@=0 \catcode`\\=\other \escapechar=`\@ -\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup} -\fi - -\newcount\paramno % Count of parameters -\newtoks\macname % Macro name -\newif\ifrecursive % Is it recursive? -\def\macrolist{} % List of all defined macros in the form - % \do\macro1\do\macro2... - -% Utility routines. -% Thisdoes \let #1 = #2, except with \csnames. -\def\cslet#1#2{% -\expandafter\expandafter -\expandafter\let -\expandafter\expandafter -\csname#1\endcsname -\csname#2\endcsname} - -% Trim leading and trailing spaces off a string. -% Concepts from aro-bend problem 15 (see CTAN). -{\catcode`\@=11 -\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} -\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} -\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} -\def\unbrace#1{#1} -\unbrace{\gdef\trim@@@ #1 } #2@{#1} -} - -% Trim a single trailing ^^M off a string. -{\catcode`\^^M=\other \catcode`\Q=3% -\gdef\eatcr #1{\eatcra #1Q^^MQ}% -\gdef\eatcra#1^^MQ{\eatcrb#1Q}% -\gdef\eatcrb#1Q#2Q{#1}% -} - -% Macro bodies are absorbed as an argument in a context where -% all characters are catcode 10, 11 or 12, except \ which is active -% (as in normal texinfo). It is necessary to change the definition of \. - -% It's necessary to have hard CRs when the macro is executed. This is -% done by making ^^M (\endlinechar) catcode 12 when reading the macro -% body, and then making it the \newlinechar in \scanmacro. - -\def\macrobodyctxt{% - \catcode`\~=\other - \catcode`\^=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\+=\other - \catcode`\{=\other - \catcode`\}=\other - \catcode`\@=\other - \catcode`\^^M=\other - \usembodybackslash} - -\def\macroargctxt{% - \catcode`\~=\other - \catcode`\^=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\+=\other - \catcode`\@=\other - \catcode`\\=\other} - -% \mbodybackslash is the definition of \ in @macro bodies. -% It maps \foo\ => \csname macarg.foo\endcsname => #N -% where N is the macro parameter number. -% We define \csname macarg.\endcsname to be \realbackslash, so -% \\ in macro replacement text gets you a backslash. - -{\catcode`@=0 @catcode`@\=@active - @gdef@usembodybackslash{@let\=@mbodybackslash} - @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} -} -\expandafter\def\csname macarg.\endcsname{\realbackslash} - -\def\macro{\recursivefalse\parsearg\macroxxx} -\def\rmacro{\recursivetrue\parsearg\macroxxx} - -\def\macroxxx#1{% - \getargs{#1}% now \macname is the macname and \argl the arglist - \ifx\argl\empty % no arguments - \paramno=0% - \else - \expandafter\parsemargdef \argl;% - \fi - \if1\csname ismacro.\the\macname\endcsname - \message{Warning: redefining \the\macname}% - \else - \expandafter\ifx\csname \the\macname\endcsname \relax - \else \errmessage{Macro name \the\macname\space already defined}\fi - \global\cslet{macsave.\the\macname}{\the\macname}% - \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% - % Add the macroname to \macrolist - \toks0 = \expandafter{\macrolist\do}% - \xdef\macrolist{\the\toks0 - \expandafter\noexpand\csname\the\macname\endcsname}% - \fi - \begingroup \macrobodyctxt - \ifrecursive \expandafter\parsermacbody - \else \expandafter\parsemacbody - \fi} - -\def\unmacro{\parsearg\dounmacro} -\def\dounmacro#1{% - \if1\csname ismacro.#1\endcsname - \global\cslet{#1}{macsave.#1}% - \global\expandafter\let \csname ismacro.#1\endcsname=0% - % Remove the macro name from \macrolist: - \begingroup - \expandafter\let\csname#1\endcsname \relax - \let\do\unmacrodo - \xdef\macrolist{\macrolist}% - \endgroup - \else - \errmessage{Macro #1 not defined}% - \fi -} - -% Called by \do from \dounmacro on each macro. The idea is to omit any -% macro definitions that have been changed to \relax. -% -\def\unmacrodo#1{% - \ifx#1\relax - % remove this - \else - \noexpand\do \noexpand #1% - \fi -} - -% This makes use of the obscure feature that if the last token of a -% <parameter list> is #, then the preceding argument is delimited by -% an opening brace, and that opening brace is not consumed. -\def\getargs#1{\getargsxxx#1{}} -\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} -\def\getmacname #1 #2\relax{\macname={#1}} -\def\getmacargs#1{\def\argl{#1}} - -% Parse the optional {params} list. Set up \paramno and \paramlist -% so \defmacro knows what to do. Define \macarg.blah for each blah -% in the params list, to be ##N where N is the position in that list. -% That gets used by \mbodybackslash (above). - -% We need to get `macro parameter char #' into several definitions. -% The technique used is stolen from LaTeX: let \hash be something -% unexpandable, insert that wherever you need a #, and then redefine -% it to # just before using the token list produced. -% -% The same technique is used to protect \eatspaces till just before -% the macro is used. - -\def\parsemargdef#1;{\paramno=0\def\paramlist{}% - \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} -\def\parsemargdefxxx#1,{% - \if#1;\let\next=\relax - \else \let\next=\parsemargdefxxx - \advance\paramno by 1% - \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno}}% - \edef\paramlist{\paramlist\hash\the\paramno,}% - \fi\next} - -% These two commands read recursive and nonrecursive macro bodies. -% (They're different since rec and nonrec macros end differently.) - -\long\def\parsemacbody#1@end macro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% -\long\def\parsermacbody#1@end rmacro% -{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% - -% This defines the macro itself. There are six cases: recursive and -% nonrecursive macros of zero, one, and many arguments. -% Much magic with \expandafter here. -% \xdef is used so that macro definitions will survive the file -% they're defined in; @include reads the file inside a group. -\def\defmacro{% - \let\hash=##% convert placeholders to macro parameter chars - \ifrecursive - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\scanmacro{\temp}}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup\noexpand\scanmacro{\temp}}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{\egroup\noexpand\scanmacro{\temp}}% - \fi - \else - \ifcase\paramno - % 0 - \expandafter\xdef\csname\the\macname\endcsname{% - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \or % 1 - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\braceorline - \expandafter\noexpand\csname\the\macname xxx\endcsname}% - \expandafter\xdef\csname\the\macname xxx\endcsname##1{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \else % many - \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname xx\endcsname}% - \expandafter\xdef\csname\the\macname xx\endcsname##1{% - \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname xxx\endcsname - \paramlist{% - \egroup - \noexpand\norecurse{\the\macname}% - \noexpand\scanmacro{\temp}\egroup}% - \fi - \fi} - -\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} - -% \braceorline decides whether the next nonwhitespace character is a -% {. If so it reads up to the closing }, if not, it reads the whole -% line. Whatever was read is then fed to the next control sequence -% as an argument (by \parsebrace or \parsearg) -\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx} -\def\braceorlinexxx{% - \ifx\nchar\bgroup\else - \expandafter\parsearg - \fi \next} - -% We mant to disable all macros during \shipout so that they are not -% expanded by \write. -\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}% - \edef\next{\macrolist}\expandafter\endgroup\next} - - -% @alias. -% We need some trickery to remove the optional spaces around the equal -% sign. Just make them active and then expand them all to nothing. -\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx} -\def\aliasxxx #1{\aliasyyy#1\relax} -\def\aliasyyy #1=#2\relax{\ignoreactivespaces -\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=% - \expandafter\noexpand\csname#2\endcsname}% -\expandafter\endgroup\next} - - -\message{cross references,} -% @xref etc. - -\newwrite\auxfile - -\newif\ifhavexrefs % True if xref values are known. -\newif\ifwarnedxrefs % True if we warned once that they aren't known. - -% @inforef is relatively simple. -\def\inforef #1{\inforefzzz #1,,,,**} -\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, - node \samp{\ignorespaces#1{}}} - -% @node's job is to define \lastnode. -\def\node{\ENVcheck\parsearg\nodezzz} -\def\nodezzz#1{\nodexxx #1,\finishnodeparse} -\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}} -\let\nwnode=\node -\let\lastnode=\relax - -% The sectioning commands (@chapter, etc.) call these. -\def\donoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Ysectionnumberandtype}% - \global\let\lastnode=\relax - \fi -} -\def\unnumbnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}% - \global\let\lastnode=\relax - \fi -} -\def\appendixnoderef{% - \ifx\lastnode\relax\else - \expandafter\expandafter\expandafter\setref{\lastnode}% - {Yappendixletterandtype}% - \global\let\lastnode=\relax - \fi -} - - -% @anchor{NAME} -- define xref target at arbitrary point. -% -\newcount\savesfregister -\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} -\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} - -% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), namely NAME-title (the corresponding @chapter/etc. name), -% NAME-pg (the page number), and NAME-snt (section number and type). -% Called from \foonoderef. -% -% We have to set \indexdummies so commands such as @code in a section -% title aren't expanded. It would be nicer not to expand the titles in -% the first place, but there's so many layers that that is hard to do. -% -% Likewise, use \turnoffactive so that punctuation chars such as underscore -% and backslash work in node names. -% -\def\setref#1#2{{% - \atdummies - \pdfmkdest{#1}% - % - \turnoffactive - \dosetq{#1-title}{Ytitle}% - \dosetq{#1-pg}{Ypagenumber}% - \dosetq{#1-snt}{#2}% -}} - -% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is -% the node name, #2 the name of the Info cross-reference, #3 the printed -% node name, #4 the name of the Info file, #5 the name of the printed -% manual. All but the node name can be omitted. -% -\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} -\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} -\def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup - \unsepspaces - \def\printedmanual{\ignorespaces #5}% - \def\printednodename{\ignorespaces #3}% - \setbox1=\hbox{\printedmanual}% - \setbox0=\hbox{\printednodename}% - \ifdim \wd0 = 0pt - % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax - % Use the node name inside the square brackets. - \def\printednodename{\ignorespaces #1}% - \else - % Use the actual chapter/section title appear inside - % the square brackets. Use the real section title if we have it. - \ifdim \wd1 > 0pt - % It is in another manual, so we don't have it. - \def\printednodename{\ignorespaces #1}% - \else - \ifhavexrefs - % We know the real title if we have the xref values. - \def\printednodename{\refx{#1-title}{}}% - \else - % Otherwise just copy the Info node name. - \def\printednodename{\ignorespaces #1}% - \fi% - \fi - \fi - \fi - % - % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not - % insert empty discretionaries after hyphens, which means that it will - % not find a line break at a hyphen in a node names. Since some manuals - % are best written with fairly long node names, containing hyphens, this - % is a loss. Therefore, we give the text of the node name again, so it - % is as if TeX is seeing it for the first time. - \ifpdf - \leavevmode - \getfilename{#4}% - {\turnoffactive \otherbackslash - \ifnum\filenamelength>0 - \startlink attr{/Border [0 0 0]}% - goto file{\the\filename.pdf} name{#1}% - \else - \startlink attr{/Border [0 0 0]}% - goto name{#1}% - \fi - }% - \linkcolor - \fi - % - \ifdim \wd1 > 0pt - \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}% - \else - % _ (for example) has to be the character _ for the purposes of the - % control sequence corresponding to the node, but it has to expand - % into the usual \leavevmode...\vrule stuff for purposes of - % printing. So we \turnoffactive for the \refx-snt, back on for the - % printing, back off for the \refx-pg. - {\turnoffactive \otherbackslash - % Only output a following space if the -snt ref is nonempty; for - % @unnumbered and @anchor, it won't be. - \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% - \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi - }% - % output the `[mynode]' via a macro. - \xrefprintnodename\printednodename - % - % But we always want a comma and a space: - ,\space - % - % output the `page 3'. - \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}% - \fi - \endlink -\endgroup} - -% This macro is called from \xrefX for the `[nodename]' part of xref -% output. It's a separate macro only so it can be changed more easily, -% since not square brackets don't work in some documents. Particularly -% one that Bob is working on :). -% -\def\xrefprintnodename#1{[#1]} - -% \dosetq is called from \setref to do the actual \write (\iflinks). -% -\def\dosetq#1#2{% - {\let\folio=0% - \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}% - \iflinks \next \fi - }% -} - -% \internalsetq{foo}{page} expands into -% CHARACTERS @xrdef{foo}{...expansion of \page...} -\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}} - -% Things to be expanded by \internalsetq. -% -\def\Ypagenumber{\folio} -\def\Ytitle{\thissection} -\def\Ynothing{} -\def\Ysectionnumberandtype{% - \ifnum\secno=0 - \putwordChapter@tie \the\chapno - \else \ifnum\subsecno=0 - \putwordSection@tie \the\chapno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection@tie \the\chapno.\the\secno.\the\subsecno - \else - \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} - -\def\Yappendixletterandtype{% - \ifnum\secno=0 - \putwordAppendix@tie @char\the\appendixno{}% - \else \ifnum\subsecno=0 - \putwordSection@tie @char\the\appendixno.\the\secno - \else \ifnum\subsubsecno=0 - \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno - \else - \putwordSection@tie - @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno - \fi\fi\fi -} - -% Use TeX 3.0's \inputlineno to get the line number, for better error -% messages, but if we're using an old version of TeX, don't do anything. -% -\ifx\inputlineno\thisisundefined - \let\linenumber = \empty % Pre-3.0. -\else - \def\linenumber{\the\inputlineno:\space} -\fi - -% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. -% If its value is nonempty, SUFFIX is output afterward. -% -\def\refx#1#2{% - {% - \indexnofonts - \otherbackslash - \expandafter\global\expandafter\let\expandafter\thisrefX - \csname X#1\endcsname - }% - \ifx\thisrefX\relax - % If not defined, say something at least. - \angleleft un\-de\-fined\angleright - \iflinks - \ifhavexrefs - \message{\linenumber Undefined cross reference `#1'.}% - \else - \ifwarnedxrefs\else - \global\warnedxrefstrue - \message{Cross reference values unknown; you must run TeX again.}% - \fi - \fi - \fi - \else - % It's defined, so just use it. - \thisrefX - \fi - #2% Output the suffix in any case. -} - -% This is the macro invoked by entries in the aux file. -% -\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname} - -% Read the last existing aux file, if any. No error if none exists. -\def\readauxfile{\begingroup - \catcode`\^^@=\other - \catcode`\^^A=\other - \catcode`\^^B=\other - \catcode`\^^C=\other - \catcode`\^^D=\other - \catcode`\^^E=\other - \catcode`\^^F=\other - \catcode`\^^G=\other - \catcode`\^^H=\other - \catcode`\^^K=\other - \catcode`\^^L=\other - \catcode`\^^N=\other - \catcode`\^^P=\other - \catcode`\^^Q=\other - \catcode`\^^R=\other - \catcode`\^^S=\other - \catcode`\^^T=\other - \catcode`\^^U=\other - \catcode`\^^V=\other - \catcode`\^^W=\other - \catcode`\^^X=\other - \catcode`\^^Z=\other - \catcode`\^^[=\other - \catcode`\^^\=\other - \catcode`\^^]=\other - \catcode`\^^^=\other - \catcode`\^^_=\other - % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. - % in xref tags, i.e., node names. But since ^^e4 notation isn't - % supported in the main text, it doesn't seem desirable. Furthermore, - % that is not enough: for node names that actually contain a ^ - % character, we would end up writing a line like this: 'xrdef {'hat - % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first - % argument, and \hat is not an expandable control sequence. It could - % all be worked out, but why? Either we support ^^ or we don't. - % - % The other change necessary for this was to define \auxhat: - % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter - % and then to call \auxhat in \setq. - % - \catcode`\^=\other - % - % Special characters. Should be turned off anyway, but... - \catcode`\~=\other - \catcode`\[=\other - \catcode`\]=\other - \catcode`\"=\other - \catcode`\_=\other - \catcode`\|=\other - \catcode`\<=\other - \catcode`\>=\other - \catcode`\$=\other - \catcode`\#=\other - \catcode`\&=\other - \catcode`\%=\other - \catcode`+=\other % avoid \+ for paranoia even though we've turned it off - % - % Make the characters 128-255 be printing characters - {% - \count 1=128 - \def\loop{% - \catcode\count 1=\other - \advance\count 1 by 1 - \ifnum \count 1<256 \loop \fi - }% - }% - % - % Turn off \ as an escape so we do not lose on - % entries which were dumped with control sequences in their names. - % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^ - % Reference to such entries still does not work the way one would wish, - % but at least they do not bomb out when the aux file is read in. - \catcode`\\=\other - % - % @ is our escape character in .aux files. - \catcode`\{=1 - \catcode`\}=2 - \catcode`\@=0 - % - \openin 1 \jobname.aux - \ifeof 1 \else - \closein 1 - \input \jobname.aux - \global\havexrefstrue - \global\warnedobstrue - \fi - % Open the new aux file. TeX will close it automatically at exit. - \openout\auxfile=\jobname.aux -\endgroup} - - -% Footnotes. - -\newcount \footnoteno - -% The trailing space in the following definition for supereject is -% vital for proper filling; pages come out unaligned when you do a -% pagealignmacro call if that space before the closing brace is -% removed. (Generally, numeric constants should always be followed by a -% space to prevent strange expansion errors.) -\def\supereject{\par\penalty -20000\footnoteno =0 } - -% @footnotestyle is meaningful for info output only. -\let\footnotestyle=\comment - -\let\ptexfootnote=\footnote - -{\catcode `\@=11 -% -% Auto-number footnotes. Otherwise like plain. -\gdef\footnote{% - \let\indent=\ptexindent - \global\advance\footnoteno by \@ne - \edef\thisfootno{$^{\the\footnoteno}$}% - % - % In case the footnote comes at the end of a sentence, preserve the - % extra spacing after we do the footnote number. - \let\@sf\empty - \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi - % - % Remove inadvertent blank space before typesetting the footnote number. - \unskip - \thisfootno\@sf - \dofootnote -}% - -% Don't bother with the trickery in plain.tex to not require the -% footnote text as a parameter. Our footnotes don't need to be so general. -% -% Oh yes, they do; otherwise, @ifset and anything else that uses -% \parseargline fail inside footnotes because the tokens are fixed when -% the footnote is read. --karl, 16nov96. -% -% The start of the footnote looks usually like this: -\gdef\startfootins{\insert\footins\bgroup} -% -% ... but this macro is redefined inside @multitable. -% -\gdef\dofootnote{% - \startfootins - % We want to typeset this text as a normal paragraph, even if the - % footnote reference occurs in (for example) a display environment. - % So reset some parameters. - \hsize=\pagewidth - \interlinepenalty\interfootnotelinepenalty - \splittopskip\ht\strutbox % top baseline for broken footnotes - \splitmaxdepth\dp\strutbox - \floatingpenalty\@MM - \leftskip\z@skip - \rightskip\z@skip - \spaceskip\z@skip - \xspaceskip\z@skip - \parindent\defaultparindent - % - \smallfonts \rm - % - % Because we use hanging indentation in footnotes, a @noindent appears - % to exdent this text, so make it be a no-op. makeinfo does not use - % hanging indentation so @noindent can still be needed within footnote - % text after an @example or the like (not that this is good style). - \let\noindent = \relax - % - % Hang the footnote text off the number. Use \everypar in case the - % footnote extends for more than one paragraph. - \everypar = {\hang}% - \textindent{\thisfootno}% - % - % Don't crash into the line above the footnote text. Since this - % expands into a box, it must come within the paragraph, lest it - % provide a place where TeX can split the footnote. - \footstrut - \futurelet\next\fo@t -} -}%end \catcode `\@=11 - -% @| inserts a changebar to the left of the current line. It should -% surround any changed text. This approach does *not* work if the -% change spans more than two lines of output. To handle that, we would -% have adopt a much more difficult approach (putting marks into the main -% vertical list for the beginning and end of each change). -% -\def\|{% - % \vadjust can only be used in horizontal mode. - \leavevmode - % - % Append this vertical mode material after the current line in the output. - \vadjust{% - % We want to insert a rule with the height and depth of the current - % leading; that is exactly what \strutbox is supposed to record. - \vskip-\baselineskip - % - % \vadjust-items are inserted at the left edge of the type. So - % the \llap here moves out into the left-hand margin. - \llap{% - % - % For a thicker or thinner bar, change the `1pt'. - \vrule height\baselineskip width1pt - % - % This is the space between the bar and the text. - \hskip 12pt - }% - }% -} - -% For a final copy, take out the rectangles -% that mark overfull boxes (in case you have decided -% that the text looks ok even though it passes the margin). -% -\def\finalout{\overfullrule=0pt} - -% @image. We use the macros from epsf.tex to support this. -% If epsf.tex is not installed and @image is used, we complain. -% -% Check for and read epsf.tex up front. If we read it only at @image -% time, we might be inside a group, and then its definitions would get -% undone and the next image would fail. -\openin 1 = epsf.tex -\ifeof 1 \else - \closein 1 - % Do not bother showing banner with epsf.tex v2.7k (available in - % doc/epsf.tex and on ctan). - \def\epsfannounce{\toks0 = }% - \input epsf.tex -\fi -% -% We will only complain once about lack of epsf.tex. -\newif\ifwarnednoepsf -\newhelp\noepsfhelp{epsf.tex must be installed for images to - work. It is also included in the Texinfo distribution, or you can get - it from ftp://tug.org/tex/epsf.tex.} -% -\def\image#1{% - \ifx\epsfbox\undefined - \ifwarnednoepsf \else - \errhelp = \noepsfhelp - \errmessage{epsf.tex not found, images will be ignored}% - \global\warnednoepsftrue - \fi - \else - \imagexxx #1,,,,,\finish - \fi -} -% -% Arguments to @image: -% #1 is (mandatory) image filename; we tack on .eps extension. -% #2 is (optional) width, #3 is (optional) height. -% #4 is (ignored optional) html alt text. -% #5 is (ignored optional) extension. -% #6 is just the usual extra ignored arg for parsing this stuff. -\newif\ifimagevmode -\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup - \catcode`\^^M = 5 % in case we're inside an example - \normalturnoffactive % allow _ et al. in names - % If the image is by itself, center it. - \ifvmode - \imagevmodetrue - \nobreak\bigskip - % Usually we'll have text after the image which will insert - % \parskip glue, so insert it here too to equalize the space - % above and below. - \nobreak\vskip\parskip - \nobreak - \line\bgroup\hss - \fi - % - % Output the image. - \ifpdf - \dopdfimage{#1}{#2}{#3}% - \else - % \epsfbox itself resets \epsf?size at each figure. - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi - \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi - \epsfbox{#1.eps}% - \fi - % - \ifimagevmode \hss \egroup \bigbreak \fi % space after the image -\endgroup} - - -\message{localization,} -% and i18n. - -% @documentlanguage is usually given very early, just after -% @setfilename. If done too late, it may not override everything -% properly. Single argument is the language abbreviation. -% It would be nice if we could set up a hyphenation file here. -% -\def\documentlanguage{\parsearg\dodocumentlanguage} -\def\dodocumentlanguage#1{% - \tex % read txi-??.tex file in plain TeX. - % Read the file if it exists. - \openin 1 txi-#1.tex - \ifeof1 - \errhelp = \nolanghelp - \errmessage{Cannot read language file txi-#1.tex}% - \let\temp = \relax - \else - \def\temp{\input txi-#1.tex }% - \fi - \temp - \endgroup -} -\newhelp\nolanghelp{The given language definition file cannot be found or -is empty. Maybe you need to install it? In the current directory -should work if nowhere else does.} - - -% @documentencoding should change something in TeX eventually, most -% likely, but for now just recognize it. -\let\documentencoding = \comment - - -% Page size parameters. -% -\newdimen\defaultparindent \defaultparindent = 15pt - -\chapheadingskip = 15pt plus 4pt minus 2pt -\secheadingskip = 12pt plus 3pt minus 2pt -\subsecheadingskip = 9pt plus 2pt minus 2pt - -% Prevent underfull vbox error messages. -\vbadness = 10000 - -% Don't be so finicky about underfull hboxes, either. -\hbadness = 2000 - -% Following George Bush, just get rid of widows and orphans. -\widowpenalty=10000 -\clubpenalty=10000 - -% Use TeX 3.0's \emergencystretch to help line breaking, but if we're -% using an old version of TeX, don't do anything. We want the amount of -% stretch added to depend on the line length, hence the dependence on -% \hsize. We call this whenever the paper size is set. -% -\def\setemergencystretch{% - \ifx\emergencystretch\thisisundefined - % Allow us to assign to \emergencystretch anyway. - \def\emergencystretch{\dimen0}% - \else - \emergencystretch = .15\hsize - \fi -} - -% Parameters in order: 1) textheight; 2) textwidth; 3) voffset; -% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8) -% physical page width. -% -% We also call \setleading{\textleading}, so the caller should define -% \textleading. The caller should also set \parskip. -% -\def\internalpagesizes#1#2#3#4#5#6#7#8{% - \voffset = #3\relax - \topskip = #6\relax - \splittopskip = \topskip - % - \vsize = #1\relax - \advance\vsize by \topskip - \outervsize = \vsize - \advance\outervsize by 2\topandbottommargin - \pageheight = \vsize - % - \hsize = #2\relax - \outerhsize = \hsize - \advance\outerhsize by 0.5in - \pagewidth = \hsize - % - \normaloffset = #4\relax - \bindingoffset = #5\relax - % - \ifpdf - \pdfpageheight #7\relax - \pdfpagewidth #8\relax - \fi - % - \setleading{\textleading} - % - \parindent = \defaultparindent - \setemergencystretch -} - -% @letterpaper (the default). -\def\letterpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % If page is nothing but text, make it come out even. - \internalpagesizes{46\baselineskip}{6in}% - {\voffset}{.25in}% - {\bindingoffset}{36pt}% - {11in}{8.5in}% -}} - -% Use @smallbook to reset parameters for 7x9.5 (or so) format. -\def\smallbook{{\globaldefs = 1 - \parskip = 2pt plus 1pt - \textleading = 12pt - % - \internalpagesizes{7.5in}{5in}% - {\voffset}{.25in}% - {\bindingoffset}{16pt}% - {9.25in}{7in}% - % - \lispnarrowing = 0.3in - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = .5cm -}} - -% Use @afourpaper to print on European A4 paper. -\def\afourpaper{{\globaldefs = 1 - \parskip = 3pt plus 2pt minus 1pt - \textleading = 13.2pt - % - % Double-side printing via postscript on Laserjet 4050 - % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. - % To change the settings for a different printer or situation, adjust - % \normaloffset until the front-side and back-side texts align. Then - % do the same for \bindingoffset. You can set these for testing in - % your texinfo source file like this: - % @tex - % \global\normaloffset = -6mm - % \global\bindingoffset = 10mm - % @end tex - \internalpagesizes{51\baselineskip}{160mm} - {\voffset}{\hoffset}% - {\bindingoffset}{44pt}% - {297mm}{210mm}% - % - \tolerance = 700 - \hfuzz = 1pt - \contentsrightmargin = 0pt - \defbodyindent = 5mm -}} - -% Use @afivepaper to print on European A5 paper. -% From romildo@urano.iceb.ufop.br, 2 July 2000. -% He also recommends making @example and @lisp be small. -\def\afivepaper{{\globaldefs = 1 - \parskip = 2pt plus 1pt minus 0.1pt - \textleading = 12.5pt - % - \internalpagesizes{160mm}{120mm}% - {\voffset}{\hoffset}% - {\bindingoffset}{8pt}% - {210mm}{148mm}% - % - \lispnarrowing = 0.2in - \tolerance = 800 - \hfuzz = 1.2pt - \contentsrightmargin = 0pt - \defbodyindent = 2mm - \tableindent = 12mm -}} - -% A specific text layout, 24x15cm overall, intended for A4 paper. -\def\afourlatex{{\globaldefs = 1 - \afourpaper - \internalpagesizes{237mm}{150mm}% - {\voffset}{4.6mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - % - % Must explicitly reset to 0 because we call \afourpaper. - \globaldefs = 0 -}} - -% Use @afourwide to print on A4 paper in landscape format. -\def\afourwide{{\globaldefs = 1 - \afourpaper - \internalpagesizes{241mm}{165mm}% - {\voffset}{-2.95mm}% - {\bindingoffset}{7mm}% - {297mm}{210mm}% - \globaldefs = 0 -}} - -% @pagesizes TEXTHEIGHT[,TEXTWIDTH] -% Perhaps we should allow setting the margins, \topskip, \parskip, -% and/or leading, also. Or perhaps we should compute them somehow. -% -\def\pagesizes{\parsearg\pagesizesxxx} -\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish} -\def\pagesizesyyy#1,#2,#3\finish{{% - \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi - \globaldefs = 1 - % - \parskip = 3pt plus 2pt minus 1pt - \setleading{\textleading}% - % - \dimen0 = #1 - \advance\dimen0 by \voffset - % - \dimen2 = \hsize - \advance\dimen2 by \normaloffset - % - \internalpagesizes{#1}{\hsize}% - {\voffset}{\normaloffset}% - {\bindingoffset}{44pt}% - {\dimen0}{\dimen2}% -}} - -% Set default to letter. -% -\letterpaper - - -\message{and turning on texinfo input format.} - -% Define macros to output various characters with catcode for normal text. -\catcode`\"=\other -\catcode`\~=\other -\catcode`\^=\other -\catcode`\_=\other -\catcode`\|=\other -\catcode`\<=\other -\catcode`\>=\other -\catcode`\+=\other -\catcode`\$=\other -\def\normaldoublequote{"} -\def\normaltilde{~} -\def\normalcaret{^} -\def\normalunderscore{_} -\def\normalverticalbar{|} -\def\normalless{<} -\def\normalgreater{>} -\def\normalplus{+} -\def\normaldollar{$}%$ font-lock fix - -% This macro is used to make a character print one way in ttfont -% where it can probably just be output, and another way in other fonts, -% where something hairier probably needs to be done. -% -% #1 is what to print if we are indeed using \tt; #2 is what to print -% otherwise. Since all the Computer Modern typewriter fonts have zero -% interword stretch (and shrink), and it is reasonable to expect all -% typewriter fonts to have this, we can check that font parameter. -% -\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} - -% Same as above, but check for italic font. Actually this also catches -% non-italic slanted fonts since it is impossible to distinguish them from -% italic fonts. But since this is only used by $ and it uses \sl anyway -% this is not a problem. -\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} - -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). -% Most of these we simply print from the \tt font, but for some, we can -% use math or other variants that look better in normal text. - -\catcode`\"=\active -\def\activedoublequote{{\tt\char34}} -\let"=\activedoublequote -\catcode`\~=\active -\def~{{\tt\char126}} -\chardef\hat=`\^ -\catcode`\^=\active -\def^{{\tt \hat}} - -\catcode`\_=\active -\def_{\ifusingtt\normalunderscore\_} -% Subroutine for the previous macro. -\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } - -\catcode`\|=\active -\def|{{\tt\char124}} -\chardef \less=`\< -\catcode`\<=\active -\def<{{\tt \less}} -\chardef \gtr=`\> -\catcode`\>=\active -\def>{{\tt \gtr}} -\catcode`\+=\active -\def+{{\tt \char 43}} -\catcode`\$=\active -\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix - -% Set up an active definition for =, but don't enable it most of the time. -{\catcode`\==\active -\global\def={{\tt \char 61}}} - -\catcode`+=\active -\catcode`\_=\active - -% If a .fmt file is being used, characters that might appear in a file -% name cannot be active until we have parsed the command line. -% So turn them off again, and have \everyjob (or @setfilename) turn them on. -% \otherifyactive is called near the end of this file. -\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} - -\catcode`\@=0 - -% \rawbackslashxx outputs one backslash character in current font, -% as in \char`\\. -\global\chardef\rawbackslashxx=`\\ - -% \rawbackslash defines an active \ to do \rawbackslashxx. -% \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. -{\catcode`\\=\active - @gdef@rawbackslash{@let\=@rawbackslashxx} - @gdef@otherbackslash{@let\=@realbackslash} -} - -% \realbackslash is an actual character `\' with catcode other. -{\catcode`\\=\other @gdef@realbackslash{\}} - -% \normalbackslash outputs one backslash in fixed width font. -\def\normalbackslash{{\tt\rawbackslashxx}} - -\catcode`\\=\active - -% Used sometimes to turn off (effectively) the active characters -% even after parsing them. -@def@turnoffactive{% - @let"=@normaldoublequote - @let\=@realbackslash - @let~=@normaltilde - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let<=@normalless - @let>=@normalgreater - @let+=@normalplus - @let$=@normaldollar %$ font-lock fix -} - -% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. (Thus, \ is not expandable when this is in -% effect.) -% -@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash} - -% Make _ and + \other characters, temporarily. -% This is canceled by @fixbackslash. -@otherifyactive - -% If a .fmt file is being used, we don't want the `\input texinfo' to show up. -% That is what \eatinput is for; after that, the `\' should revert to printing -% a backslash. -% -@gdef@eatinput input texinfo{@fixbackslash} -@global@let\ = @eatinput - -% On the other hand, perhaps the file did not have a `\input texinfo'. Then -% the first `\{ in the file would cause an error. This macro tries to fix -% that, assuming it is called before the first `\' could plausibly occur. -% Also back turn on active characters that might appear in the input -% file name, in case not using a pre-dumped format. -% -@gdef@fixbackslash{% - @ifx\@eatinput @let\ = @normalbackslash @fi - @catcode`+=@active - @catcode`@_=@active -} - -% Say @foo, not \foo, in error messages. -@escapechar = `@@ - -% These look ok in all fonts, so just make them not special. -@catcode`@& = @other -@catcode`@# = @other -@catcode`@% = @other - -@c Set initial fonts. -@textfonts -@rm - - -@c Local variables: -@c eval: (add-hook 'write-file-hooks 'time-stamp) -@c page-delimiter: "^\\\\message" -@c time-stamp-start: "def\\\\texinfoversion{" -@c time-stamp-format: "%:y-%02m-%02d.%02H" -@c time-stamp-end: "}" -@c End: diff --git a/sm/ChangeLog b/sm/ChangeLog deleted file mode 100644 index c1a8f6411..000000000 --- a/sm/ChangeLog +++ /dev/null @@ -1,1220 +0,0 @@ -2004-06-06 Werner Koch <wk@gnupg.org> - - * certreqgen.c (get_parameter_uint, create_request): Create - an extension for key usage when requested. - -2004-05-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Install emergency_cleanup also as an atexit - handler. - - * verify.c (gpgsm_verify): Removed the separate error code - handling for KSBA. We use shared error codes anyway. - - * export.c (export_p12): Removed debugging code. - - * encrypt.c (gpgsm_encrypt): Put the session key in to secure memory. - -2004-05-11 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Include the error source in the final error - message. - * decrypt.c (gpgsm_decrypt): Ditto. - - * fingerprint.c (gpgsm_get_key_algo_info): New. - * sign.c (gpgsm_sign): Don't assume RSA in the status line. - * keylist.c (list_cert_colon): Really print the algorithm and key - length. - (list_cert_raw, list_cert_std): Ditto. - (list_cert_colon): Reorganized to be able to tell whether a root - certificate is trusted. - - * gpgsm.c: New option --debug-allow-core-dump. - - * gpgsm.h (opt): Add member CONFIG_FILENAME. - * gpgsm.c (main): Use it here instead of the local var. - - * server.c (gpgsm_server): Print some additional information with - the hello in verbose mode. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * import.c (check_and_store): Do not update the stats for hidden - imports of issuer certs. - (popen_protect_tool): Request statusmessages from the protect-tool. - (parse_p12): Detect status messages. Add new arg STATS and update them. - (print_imported_summary): Include secret key stats. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New command --keydb-clear-some-cert-flags. - * keydb.c (keydb_clear_some_cert_flags): New. - (keydb_update_keyblock, keydb_set_flags): Change error code - CONFLICT to NOT_LOCKED. - -2004-04-26 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main) <gpgconf>: Do not use /dev/null as default config - filename. - - * call-agent.c (gpgsm_agent_pksign, gpgsm_agent_pkdecrypt) - (gpgsm_agent_genkey, gpgsm_agent_istrusted) - (gpgsm_agent_marktrusted, gpgsm_agent_havekey) - (gpgsm_agent_passwd): Add new arg CTRL and changed all callers. - (start_agent): New arg CTRL. Send progress item when starting a - new agent. - * sign.c (gpgsm_get_default_cert, get_default_signer): New arg - CTRL to be passed down to the agent function. - * decrypt.c (prepare_decryption): Ditto. - * certreqgen.c (proc_parameters, read_parameters): Ditto. - * certcheck.c (gpgsm_create_cms_signature): Ditto. - -2004-04-23 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Try to compress the file on init. - - * keylist.c (oidtranstbl): New. OIDs collected from several sources. - (print_name_raw, print_names_raw, list_cert_raw): New. - (gpgsm_list_keys): Check the dump mode and pass it down as - necessary. - -2004-04-22 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New commands --dump-keys, --dump-external-keys, - --dump-secret-keys. - -2004-04-13 Werner Koch <wk@gnupg.org> - - * misc.c (setup_pinentry_env): New. - * import.c (popen_protect_tool): Call it. - * export.c (popen_protect_tool): Call it. - -2004-04-08 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Return GPG_ERR_NO_DATA if it is not a - encrypted message. - -2004-04-07 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --force-crl-refresh. - * call-dirmngr.c (gpgsm_dirmngr_isvalid): Pass option to dirmngr. - -2004-04-05 Werner Koch <wk@gnupg.org> - - * server.c (get_status_string): Add STATUS_NEWSIG. - * verify.c (gpgsm_verify): Print STATUS_NEWSIG for each signature. - - * certchain.c (gpgsm_validate_chain) <gpgsm_cert_use_cer_p>: Do - not just warn if a cert is not suitable; bail out immediately. - -2004-04-01 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (isvalid_status_cb): New. - (unhexify_fpr): New. Taken from ../g10/call-agent.c - (gpgsm_dirmngr_isvalid): Add new arg CTRL, changed caller to pass - it thru. Detect need to check the respondert cert and do that. - * certchain.c (gpgsm_validate_chain): Add new arg FLAGS. Changed - all callers. - -2004-03-24 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Include a short list of capabilities. - -2004-03-17 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main) <gpgconf>: Fixed default value quoting. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Implemented --gpgconf-list. - -2004-03-15 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Hack to set the expired flag. - -2004-03-09 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Correctly intitialze USE_OCSP flag. - - * keydb.c (keydb_delete): s/GPG_ERR_CONFLICT/GPG_ERR_NOT_LOCKED/ - -2004-03-04 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (gpgsm_dirmngr_isvalid): New arg ISSUER_CERT. - - * certchain.c (is_cert_still_valid): New. Code moved from ... - (gpgsm_validate_chain): ... here because we now need to check at - two places and at a later stage, so that we can pass the issuer - cert down to the dirmngr. - -2004-03-03 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Replaced pinentry setup code by a - call to a new common function. - - * certdump.c (gpgsm_format_keydesc): Make sure the string is - returned as utf-8. - - * export.c (gpgsm_export): Make sure that we don't export more - than one certificate. - -2004-03-02 Werner Koch <wk@gnupg.org> - - * export.c (create_duptable, destroy_duptable) - (insert_duptable): New. - (gpgsm_export): Avoid duplicates. - -2004-02-26 Werner Koch <wk@gnupg.org> - - * certchain.c (compare_certs): New. - (gpgsm_validate_chain): Fixed infinite certificate checks after - bad signatures. - -2004-02-24 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Print the fingerprint as the - cert-id for root certificates. - -2004-02-21 Werner Koch <wk@gnupg.org> - - * keylist.c (list_internal_keys): Return error codes. - (list_external_keys, gpgsm_list_keys): Ditto. - * server.c (do_listkeys): Ditto. - - * gpgsm.c (main): Display a key description for --passwd. - * call-agent.c (gpgsm_agent_passwd): New arg DESC. - -2004-02-20 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New option --debug-ignore-expiration. - * certchain.c (gpgsm_validate_chain): Use it here. - - * certlist.c (cert_usage_p): Apply extKeyUsage. - -2004-02-19 Werner Koch <wk@gnupg.org> - - * export.c (export_p12, popen_protect_tool) - (gpgsm_p12_export): New. - * gpgsm.c (main): New command --export-secret-key-p12. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpgsm.c (set_debug): Set the new --debug-level flags. - (main): New option --gpgconf-list. - (main): Do not setup -u and -r keys when not required. - (main): Setup the used character set. - - * keydb.c (keydb_add_resource): Print a hint to start the - gpg-agent. - -2004-02-17 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Fixed value parsing for --with-validation. - * call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO. - * call-dirmngr.c (start_dirmngr): Likewise for DIRMNGR_INFO. - - * gpgsm.c: New option --with-md5-fingerprint. - * keylist.c (list_cert_std): Print MD5 fpr. - - * gpgsm.c: New options --with-validation. - * server.c (option_handler): New option "with-validation". - * keylist.c (list_cert_std, list_internal_keys): New args CTRL and - WITH_VALIDATION. Changed callers to set it. - (list_external_cb, list_external_keys): Pass CTRL to the callback. - (list_cert_colon): Add arg CTRL. Check validation if requested. - * certchain.c (unknown_criticals, allowed_ca, check_cert_policy) - (gpgsm_validate_chain): New args LISTMODE and FP. - (do_list): New helper for info output. - (find_up): New arg FIND_NEXT. - (gpgsm_validate_chain): After a bad signature try again with other - CA certificates. - - * import.c (print_imported_status): New arg NEW_CERT. Print - additional STATUS_IMPORT_OK becuase that is what gpgme expects. - (check_and_store): Always call above function after import. - * server.c (get_status_string): Added STATUS_IMPORT_OK. - -2004-02-13 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_create_cms_signature): Format a description - for use by the pinentry. - * decrypt.c (gpgsm_decrypt): Ditto. Free HEXKEYGRIP. - * certdump.c (format_name_cookie, format_name_writer) - (gpgsm_format_name): New. - (gpgsm_format_serial): New. - (gpgsm_format_keydesc): New. - * call-agent.c (gpgsm_agent_pksign): New arg DESC. - (gpgsm_agent_pkdecrypt): Ditto. - - * encrypt.c (init_dek): Check for too weak algorithms. - - * import.c (parse_p12, popen_protect_tool): New. - - * base64.c (gpgsm_create_reader): New arg ALLOW_MULTI_PEM. - Changed all callers. - (base64_reader_cb): Handle it here. - (gpgsm_reader_eof_seen): New. - (base64_reader_cb): Set a flag for EOF. - (simple_reader_cb): Ditto. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * gpgsm.h, gpgsm.c: New option --protect-tool-program. - * gpgsm.c (run_protect_tool): Use it. - -2004-02-11 Werner Koch <wk@gnupg.org> - - * Makefile.am (AM_CPPFLAGS): Pass directory constants via -D; this - will allow to override directory names at make time. - -2004-02-02 Werner Koch <wk@gnupg.org> - - * import.c (check_and_store): Import certificates even with - missing issuer's cert. Fixed an "depending on the verbose - setting" bug. - - * certchain.c (gpgsm_validate_chain): Mark revoked certs in the - keybox. - - * keylist.c (list_cert_colon): New arg VALIDITY; use it to print a - revoked flag. - (list_internal_keys): Retrieve validity flag. - (list_external_cb): Pass 0 as validity flag. - * keydb.c (keydb_get_flags, keydb_set_flags): New. - (keydb_set_cert_flags): New. - (lock_all): Return a proper error code. - (keydb_lock): New. - (keydb_delete): Don't lock but check that it has been locked. - (keydb_update_keyblock): Ditto. - * delete.c (delete_one): Take a lock. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * certchain.c (check_cert_policy): Fixed read error checking. - (check_cert_policy): With no critical policies issue only a - warning if the policy file does not exists. - - * sign.c (add_certificate_list): Decrement N for the first cert. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * certdump.c (parse_dn_part): Map common OIDs to human readable - labels. Make sure that a value won't get truncated if it includes - a Nul. - -2004-01-28 Werner Koch <wk@gnupg.org> - - * certchain.c (gpgsm_validate_chain): Changed the message printed - for an untrusted root certificate. - -2004-01-27 Werner Koch <wk@gnupg.org> - - * certdump.c (parse_dn_part): Pretty print the nameDistinguisher OID. - (print_dn_part): Do not delimit multiple RDN by " + ". Handle - multi-valued RDNs in a special way, i.e. in the order specified by - the certificate. - (print_dn_parts): Simplified. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * sign.c (gpgsm_sign): Print an error message on all failures. - * decrypt.c (gpgsm_decrypt): Ditto. - -2003-12-17 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_server): Add arg DEFAULT_RECPLIST. - (cmd_encrypt): Add all enrypt-to marked certs to the list. - * encrypt.c (gpgsm_encrypt): Check that real recipients are - available. - * gpgsm.c (main): Make the --encrypt-to and --no-encrypt-to - options work. Pass the list of recients to gpgsm_server. - * gpgsm.h (certlist_s): Add field IS_ENCRYPT_TO. - (opt): Add NO_ENCRYPT_TO. - * certlist.c (gpgsm_add_to_certlist): New arg IS_ENCRYPT_TO. - Changed all callers and ignore duplicate entries. - (is_cert_in_certlist): New. - (gpgsm_add_cert_to_certlist): New. - - * certdump.c (gpgsm_print_serial): Cleaned up cast use in strtoul. - (gpgsm_dump_serial): Ditto. - - * decrypt.c (gpgsm_decrypt): Replaced ERR by RC. - -2003-12-16 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Set the prefixes for assuan logging. - - * sign.c (gpgsm_sign): Add validation checks for the default - certificate. - - * gpgsm.c: Add -k as alias for --list-keys and -K for - --list-secret-keys. - -2003-12-15 Werner Koch <wk@gnupg.org> - - * encrypt.c (init_dek): Use gry_create_nonce for the IV; there is - not need for real strong random here and it even better protect - the random bits used for the key. - -2003-12-01 Werner Koch <wk@gnupg.org> - - * gpgsm.c, gpgsm.h: New options --{enable,disable}-ocsp. - (gpgsm_init_default_ctrl): Set USE_OCSP to the default value. - * certchain.c (gpgsm_validate_chain): Handle USE_OCSP. - * call-dirmngr.c (gpgsm_dirmngr_isvalid): Add arg USE_OCSP and - proceed accordingly. - -2003-11-19 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Use "0" instead of an empty string for - the VALIDSIG status. - -2003-11-18 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Fixed for changes API of gcry_md_info. - - * certchain.c (unknown_criticals): Fixed an error code test. - -2003-11-12 Werner Koch <wk@gnupg.org> - - Adjusted for API changes in Libksba. - -2003-10-31 Werner Koch <wk@gnupg.org> - - * certchain.c (gpgsm_validate_chain): Changed to use ksba_isotime_t. - * verify.c (strtimestamp_r, gpgsm_verify): Ditto. - * sign.c (gpgsm_sign): Ditto. - * keylist.c (print_time, list_cert_std, list_cert_colon): Ditto. - * certdump.c (gpgsm_print_time, gpgsm_dump_time, gpgsm_dump_cert): - Ditto. - -2003-10-25 Werner Koch <wk@gnupg.org> - - * certreqgen.c (read_parameters): Fixed faulty of !spacep(). - -2003-08-20 Marcus Brinkmann <marcus@g10code.de> - - * encrypt.c (encode_session_key): Allocate enough space. Cast key - byte to unsigned char to prevent sign extension. - (encrypt_dek): Check return value before error. - -2003-08-14 Timo Schulz <twoaday@freakmail.de> - - * encrypt.c (encode_session_key): Use new Libgcrypt interface. - -2003-07-31 Werner Koch <wk@gnupg.org> - - * Makefile.am (gpgsm_LDADD): Added INTLLIBS. - -2003-07-29 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Add secmem features and set the random seed file. - (gpgsm_exit): Update the random seed file and enable debug output. - -2003-07-27 Werner Koch <wk@gnupg.org> - - Adjusted for gcry_mpi_print and gcry_mpi_scan API change. - -2003-06-24 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_status_with_err_code): New. - * verify.c (gpgsm_verify): Use it here instead of the old - tokenizing version. - - * verify.c (strtimestamp): Renamed to strtimestamp_r - - Adjusted for changes in the libgcrypt API. Some more fixes for the - libgpg-error stuff. - -2003-06-04 Werner Koch <wk@gnupg.org> - - * call-agent.c (init_membuf,put_membuf,get_membuf): Removed. - Include new membuf header and changed used type. - - Renamed error codes from INVALID to INV and removed _ERROR suffixes. - -2003-06-03 Werner Koch <wk@gnupg.org> - - Changed all error codes in all files to the new libgpg-error scheme. - - * gpgsm.h: Include gpg-error.h . - * Makefile.am: Link with libgpg-error. - -2003-04-29 Werner Koch <wk@gnupg.org> - - * Makefile.am: Use libassuan. Don't override LDFLAGS anymore. - * server.c (register_commands): Adjust for new Assuan semantics. - -2002-12-03 Werner Koch <wk@gnupg.org> - - * call-agent.c (gpgsm_agent_passwd): New. - * gpgsm.c (main): New command --passwd and --call-protect-tool - (run_protect_tool): New. - -2002-11-25 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Handle content-type attribute. - -2002-11-13 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Try to use $GPG_TTY instead of - ttyname. Changed ttyname to test stdin becuase it can be assumed - that output redirection is more common that input redirection. - -2002-11-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New command --call-dirmngr. - * call-dirmngr.c (gpgsm_dirmngr_run_command) - (run_command_inq_cb,run_command_cb) - (run_command_status_cb): New. - -2002-11-11 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cms_signature): Don't double free - s_sig but free s_pkey at leave. - -2002-11-10 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Removed duplicate --list-secret-key entry. - -2002-09-19 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cert_sig): Add cert hash debugging. - - * certchain.c (find_up): Print info when the cert was not found - by the autorithyKeyIdentifier. - -2002-09-03 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Disable the internal libgcrypt locking. - -2002-08-21 Werner Koch <wk@gnupg.org> - - * import.c (print_imported_summary): Cleaned up. Print new - not_imported value. - (check_and_store): Update non_imported counter. - (print_import_problem): New. - (check_and_store): Print error status message. - * server.c (get_status_string): Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Use the log file only in server mode. - - * import.c (print_imported_summary): New. - (check_and_store): Update the counters, take new argument. - (import_one): Factored out core of gpgsm_import. - (gpgsm_import): Print counters. - (gpgsm_import_files): New. - * gpgsm.c (main): Use the new function for import. - -2002-08-19 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Return a better error status token. - * verify.c (gpgsm_verify): Don't error on messages with no signing - time or no message digest. This is only the case for messages - without any signed attributes. - -2002-08-16 Werner Koch <wk@gnupg.org> - - * certpath.c: Renamed to .. - * certchain.c: this. Renamed all all other usages of "path" in the - context of certificates to "chain". - - * call-agent.c (learn_cb): Special treatment when the issuer - certificate is missing. - -2002-08-10 Werner Koch <wk@gnupg.org> - - * Makefile.am (INCLUDES): Add definition for localedir. - - * keylist.c (list_cert_colon): Print the short fingerprint in the - key ID field. - * fingerprint.c (gpgsm_get_short_fingerprint): New. - * verify.c (gpgsm_verify): Print more verbose info for a good - signature. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * decrypt.c (prepare_decryption): Hack to detected already - unpkcsedone keys. - - * gpgsm.c (emergency_cleanup): New. - (main): Initialize the signal handler. - - * sign.c (gpgsm_sign): Reset the hash context for subsequent - signers and release it at the end. - -2002-08-05 Werner Koch <wk@gnupg.org> - - * server.c (cmd_signer): New command "SIGNER" - (register_commands): Register it. - (cmd_sign): Pass the signer list to gpgsm_sign. - * certlist.c (gpgsm_add_to_certlist): Add SECRET argument, check - for secret key if set and changed all callers. - * sign.c (gpgsm_sign): New argument SIGNERLIST and implemt - multiple signers. - * gpgsm.c (main): Support more than one -u. - - * server.c (cmd_recipient): Return reason code 1 for No_Public_Key - which is actually what gets returned from add_to_certlist. - -2002-07-26 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup. - (gpgsm_check_cms_signature): Ditto. - -2002-07-22 Werner Koch <wk@gnupg.org> - - * keydb.c (keydb_add_resource): Register a lock file. - (lock_all, unlock_all): Implemented. - - * delete.c: New. - * gpgsm.c: Made --delete-key work. - * server.c (cmd_delkeys): New. - (register_commands): New command DELKEYS. - - * decrypt.c (gpgsm_decrypt): Print a convenience note when RC2 is - used and a STATUS_ERROR with the algorithm oid. - -2002-07-03 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_status2): Insert a blank between all optional - arguments when using assuan. - * server.c (cmd_recipient): No more need for extra blank in constants. - * import.c (print_imported_status): Ditto. - * gpgsm.c (main): Ditto. - -2002-07-02 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Extend the STATUS_BADSIG line with - the fingerprint. - - * certpath.c (check_cert_policy): Don't use log_error to print a - warning. - - * keydb.c (keydb_store_cert): Add optional ar EXISTED and changed - all callers. - * call-agent.c (learn_cb): Print info message only for real imports. - - * import.c (gpgsm_import): Moved duplicated code to ... - (check_and_store): new function. Added magic to import the entire - chain. Print status only for real imports and moved printing code - to .. - (print_imported_status): New. - - * call-dirmngr.c (gpgsm_dirmngr_isvalid): print status of dirmngr - call in very verbose mode. - - * gpgsm.c (main): Use the same error codes for STATUS_INV_RECP as - with the server mode. - -2002-06-29 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --auto-issuer-key-retrieve. - * certpath.c (find_up): Try to retrieve an issuer key from an - external source and from the ephemeral key DB. - (find_up_store_certs_cb): New. - - * keydb.c (keydb_set_ephemeral): Does now return the old - state. Call the backend only when required. - - * call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR. - (lookup_status_cb): Issue status only when CTRL is not NULL. - (gpgsm_dirmngr_lookup): Document that CTRL is optional. - - * call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT. - -2002-06-28 Werner Koch <wk@gnupg.org> - - * server.c (cmd_recipient): Add more reason codes. - -2002-06-27 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_basic_cert_check): Use - --debug-no-path-validation to also bypass this basic check. - - * gpgsm.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - - * call-agent.c (start_agent): Create and pass the list of FD to - keep in the child to assuan. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-06-26 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Print an STATUS_IMPORTED. - - * gpgsm.c: --debug-no-path-validation does not take an argument. - -2002-06-25 Werner Koch <wk@gnupg.org> - - * certdump.c (print_dn_part): Always print a leading slash, - removed NEED_DELIM arg and changed caller. - - * export.c (gpgsm_export): Print LFs to FP and not stdout. - (print_short_info): Ditto. Make use of gpgsm_print_name. - - * server.c (cmd_export): Use output-fd instead of data lines; this - was actually the specified way. - -2002-06-24 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Removed duped help entry for --list-keys. - - * gpgsm.c, gpgsm.h: New option --debug-no-path-validation. - - * certpath.c (gpgsm_validate_path): Use it here instead of the - debug flag hack. - - * certpath.c (check_cert_policy): Return No_Policy_Match if the - policy file could not be opened. - -2002-06-20 Werner Koch <wk@gnupg.org> - - * certlist.c (gpgsm_add_to_certlist): Fixed locating of a - certificate with the required key usage. - - * gpgsm.c (main): Fixed a segv when using --outfile without an - argument. - - * keylist.c (print_capabilities): Also check for non-repudiation - and data encipherment. - * certlist.c (cert_usage_p): Test for signing and encryption was - swapped. Add a case for certification usage, handle - non-repudiation and data encipherment. - (gpgsm_cert_use_cert_p): New. - (gpgsm_add_to_certlist): Added a CTRL argument and changed all - callers to pass it. - * certpath.c (gpgsm_validate_path): Use it here to print a status - message. Added a CTRL argument and changed all callers to pass it. - * decrypt.c (gpgsm_decrypt): Print a status message for wrong key - usage. - * verify.c (gpgsm_verify): Ditto. - * keydb.c (classify_user_id): Allow a colon delimited fingerprint. - -2002-06-19 Werner Koch <wk@gnupg.org> - - * call-agent.c (learn_cb): Use log_info instead of log_error on - successful import. - - * keydb.c (keydb_set_ephemeral): New. - (keydb_store_cert): New are ephemeral, changed all callers. - * keylist.c (list_external_cb): Store cert as ephemeral. - * export.c (gpgsm_export): Kludge to export epehmeral certificates. - - * gpgsm.c (main): New command --list-external-keys. - -2002-06-17 Werner Koch <wk@gnupg.org> - - * certreqgen.c (read_parameters): Improved error handling. - (gpgsm_genkey): Print error message. - -2002-06-13 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New option --log-file. - -2002-06-12 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (lookup_status_cb): New. - (gpgsm_dirmngr_lookup): Use the status CB. Add new arg CTRL and - changed caller to pass it. - - * gpgsm.c (open_fwrite): New. - (main): Allow --output for --verify. - - * sign.c (hash_and_copy_data): New. - (gpgsm_sign): Implemented normal (non-detached) signatures. - * gpgsm.c (main): Ditto. - - * certpath.c (gpgsm_validate_path): Special error handling for - no policy match. - -2002-06-10 Werner Koch <wk@gnupg.org> - - * server.c (get_status_string): Add STATUS_ERROR. - - * certpath.c (gpgsm_validate_path): Tweaked the error checking to - return error codes in a more sensitive way. - * verify.c (gpgsm_verify): Send status TRUST_NEVER also for a bad - CA certificate and when the certificate has been revoked. Issue - TRUST_FULLY even when the cert has expired. Append an error token - to these status lines. Issue the new generic error status when a - cert was not found and when leaving the function. - -2002-06-04 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New command --list-sigs - * keylist.c (list_cert_std): New. Use it whenever colon mode is - not used. - (list_cert_chain): New. - -2002-05-31 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Don't print the "go ahead" message for an - invalid command. - -2002-05-23 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Add error messages. - -2002-05-21 Werner Koch <wk@gnupg.org> - - * keylist.c (list_internal_keys): Renamed from gpgsm_list_keys. - (list_external_keys): New. - (gpgsm_list_keys): Dispatcher for above. - * call-dirmngr.c (lookup_cb,pattern_from_strlist) - (gpgsm_dirmngr_lookup): New. - * server.c (option_handler): Handle new option --list-mode. - (do_listkeys): Handle options and actually use the mode argument. - (get_status_string): New code TRUNCATED. - - * import.c (gpgsm_import): Try to identify the type of input and - handle certs-only messages. - -2002-05-14 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --faked-system-time - * sign.c (gpgsm_sign): And use it here. - * certpath.c (gpgsm_validate_path): Ditto. - -2002-05-03 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Added EXPTIME arg and changed - all callers. - * verify.c (gpgsm_verify): Tweaked usage of log_debug and - log_error. Return EXPSIG status and add expiretime to VALIDSIG. - -2002-04-26 Werner Koch <wk@gnupg.org> - - * gpgsm.h (DBG_AGENT,DBG_AGENT_VALUE): Replaced by DBG_ASSUAN_*. - Changed all users. - - * call-agent.c (start_agent): Be more silent without -v. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-04-25 Werner Koch <wk@gnupg.org> - - * call-agent.c (start_agent): Make copies of old locales and check - for setlocale. - -2002-04-25 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (start_agent): Fix error handling logic so the - locale is always correctly reset. - -2002-04-25 Marcus Brinkmann <marcus@g10code.de> - - * server.c (option_handler): Accept display, ttyname, ttytype, - lc_ctype and lc_messages options. - * gpgsm.c (main): Allocate memory for these options. - * gpgsm.h (struct opt): Make corresponding members non-const. - -2002-04-24 Marcus Brinkmann <marcus@g10code.de> - - * gpgsm.h (struct opt): New members display, ttyname, ttytype, - lc_ctype, lc_messages. - * gpgsm.c (enum cmd_and_opt_values): New members oDisplay, - oTTYname, oTTYtype, oLCctype, oLCmessages. - (opts): New entries for these options. - (main): Handle these new options. - * call-agent.c (start_agent): Set the various display and tty - parameter after resetting. - -2002-04-18 Werner Koch <wk@gnupg.org> - - * certreqgen.c (gpgsm_genkey): Write status output on success. - -2002-04-15 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Check ksba version. - - * certpath.c (find_up): New to use the authorithKeyIdentifier. - Use it in all other functions to locate the signing cert.. - -2002-04-11 Werner Koch <wk@gnupg.org> - - * certlist.c (cert_usable_p): New. - (gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New. - (gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New. - (gpgsm_add_to_certlist): Check the key usage. - * sign.c (gpgsm_sign): Ditto. - * verify.c (gpgsm_verify): Print a message wehn an unsuitable - certificate was used. - * decrypt.c (gpgsm_decrypt): Ditto - * keylist.c (print_capabilities): Determine values from the cert. - -2002-03-28 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Fixed listing of crt record; the - issuer is not at the right place. Print a chainingID. - * certpath.c (gpgsm_walk_cert_chain): Be a bit more silent on - common errors. - -2002-03-21 Werner Koch <wk@gnupg.org> - - * export.c: New. - * gpgsm.c: Add command --export. - * server.c (cmd_export): New. - -2002-03-13 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Allow multiple recipients. - -2002-03-12 Werner Koch <wk@gnupg.org> - - * certpath.c (check_cert_policy): Print the policy list. - - * verify.c (gpgsm_verify): Detect certs-only message. - -2002-03-11 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Print a notice about imported certificates - when in verbose mode. - - * gpgsm.c (main): Print INV_RECP status. - * server.c (cmd_recipient): Ditto. - - * server.c (gpgsm_status2): New. Allows for a list of strings. - (gpgsm_status): Divert to gpgsm_status2. - - * encrypt.c (gpgsm_encrypt): Don't use a default key when no - recipients are given. Print a NO_RECP status. - -2002-03-06 Werner Koch <wk@gnupg.org> - - * server.c (cmd_listkeys, cmd_listsecretkeys): Divert to - (do_listkeys): new. Add pattern parsing. - - * keylist.c (gpgsm_list_keys): Handle selection pattern. - - * gpgsm.c: New command --learn-card - * call-agent.c (learn_cb,gpgsm_agent_learn): New. - - * gpgsm.c (main): Print error messages for non-implemented commands. - - * base64.c (base64_reader_cb): Use case insensitive compare of the - Content-Type string to detect plain base-64. - -2002-03-05 Werner Koch <wk@gnupg.org> - - * gpgsm.c, gpgsm.h: Add local_user. - * sign.c (gpgsm_get_default_cert): New. - (get_default_signer): Use the new function if local_user is not - set otherwise used that value. - * encrypt.c (get_default_recipient): Removed. - (gpgsm_encrypt): Use gpgsm_get_default_cert. - - * verify.c (gpgsm_verify): Better error text for a bad signature - found by comparing the hashs. - -2002-02-27 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c, call-agent.c: Add 2 more arguments to all uses - of assuan_transact. - -2002-02-25 Werner Koch <wk@gnupg.org> - - * server.c (option_handler): Allow to use -2 for "send all certs - except the root cert". - * sign.c (add_certificate_list): Implement it here. - * certpath.c (gpgsm_is_root_cert): New. - -2002-02-19 Werner Koch <wk@gnupg.org> - - * certpath.c (check_cert_policy): New. - (gpgsm_validate_path): And call it from here. - * gpgsm.c (main): New options --policy-file, - --disable-policy-checks and --enable-policy-checks. - * gpgsm.h (opt): Added policy_file, no_policy_checks. - -2002-02-18 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Ask the agent to add the - certificate into the trusted list. - * call-agent.c (gpgsm_agent_marktrusted): New. - -2002-02-07 Werner Koch <wk@gnupg.org> - - * certlist.c (gpgsm_add_to_certlist): Check that the specified - name identifies a certificate unambiguously. - (gpgsm_find_cert): Ditto. - - * server.c (cmd_listkeys): Check that the data stream is available. - (cmd_listsecretkeys): Ditto. - (has_option): New. - (cmd_sign): Fix ambiguousity in option recognition. - - * gpgsm.c (main): Enable --logger-fd. - - * encrypt.c (gpgsm_encrypt): Increased buffer size for better - performance. - - * call-agent.c (gpgsm_agent_pksign): Check the S-Exp received from - the agent. - - * keylist.c (list_cert_colon): Filter out control characters. - -2002-02-06 Werner Koch <wk@gnupg.org> - - * decrypt.c (gpgsm_decrypt): Bail out after an decryption error. - - * server.c (reset_notify): Close input and output FDs. - (cmd_encrypt,cmd_decrypt,cmd_verify,cmd_sign.cmd_import) - (cmd_genkey): Close the FDs and release the recipient list even in - the error case. - -2002-02-01 Marcus Brinkmann <marcus@g10code.de> - - * sign.c (gpgsm_sign): Do not release certificate twice. - -2002-01-29 Werner Koch <wk@gnupg.org> - - * call-agent.c (gpgsm_agent_havekey): New. - * keylist.c (list_cert_colon): New arg HAVE_SECRET, print "crs" - when we know that the secret key is available. - (gpgsm_list_keys): New arg MODE, check whether a secret key is - available. Changed all callers. - * gpgsm.c (main): New command --list-secret-keys. - * server.c (cmd_listsecretkeys): New. - (cmd_listkeys): Return secret keys with "crs" record. - -2002-01-28 Werner Koch <wk@gnupg.org> - - * certreqgen.c (create_request): Store the email address in the req. - -2002-01-25 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): Disable core dumps. - - * sign.c (add_certificate_list): New. - (gpgsm_sign): Add the certificates to the CMS object. - * certpath.c (gpgsm_walk_cert_chain): New. - * gpgsm.h (server_control_s): Add included_certs. - * gpgsm.c: Add option --include-certs. - (gpgsm_init_default_ctrl): New. - (main): Call it. - * server.c (gpgsm_server): Ditto. - (option_handler): Support --include-certs. - -2002-01-23 Werner Koch <wk@gnupg.org> - - * certpath.c (gpgsm_validate_path): Print the DN of a missing issuer. - * certdump.c (gpgsm_dump_string): New. - (print_dn): Replaced by above. - -2002-01-22 Werner Koch <wk@gnupg.org> - - * certpath.c (unknown_criticals): New. - (allowed_ca): New. - (gpgsm_validate_path): Check validity, CA attribute, path length - and unknown critical extensions. - -2002-01-21 Werner Koch <wk@gnupg.org> - - * gpgsm.c: Add option --enable-crl-checks. - - * call-agent.c (start_agent): Implemented socket based access. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-01-20 Werner Koch <wk@gnupg.org> - - * server.c (option_handler): New. - (gpgsm_server): Register it with assuan. - -2002-01-19 Werner Koch <wk@gnupg.org> - - * server.c (gpgsm_server): Use assuan_deinit_server and setup - assuan logging if enabled. - * call-agent.c (inq_ciphertext_cb): Don't show the session key in - an Assuan log file. - - * gpgsm.c (my_strusage): Take bugreport address from configure.ac - -2002-01-15 Werner Koch <wk@gnupg.org> - - * import.c (gpgsm_import): Just do a basic cert check before - storing it. - * certpath.c (gpgsm_basic_cert_check): New. - - * keydb.c (keydb_store_cert): New. - * import.c (store_cert): Removed and change all caller to use - the new function. - * verify.c (store_cert): Ditto. - - * certlist.c (gpgsm_add_to_certlist): Validate the path - - * certpath.c (gpgsm_validate_path): Check the trust list. - * call-agent.c (gpgsm_agent_istrusted): New. - -2002-01-14 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c (inq_certificate): Changed for new interface semantic. - * certlist.c (gpgsm_find_cert): New. - -2002-01-13 Werner Koch <wk@gnupg.org> - - * fingerprint.c (gpgsm_get_certid): Print the serial and not the - hash after the dot. - -2002-01-11 Werner Koch <wk@gnupg.org> - - * call-dirmngr.c: New. - * certpath.c (gpgsm_validate_path): Check the CRL here. - * fingerprint.c (gpgsm_get_certid): New. - * gpgsm.c: New options --dirmngr-program and --disable-crl-checks. - -2002-01-10 Werner Koch <wk@gnupg.org> - - * base64.c (gpgsm_create_writer): Allow to set the object name - -2002-01-08 Werner Koch <wk@gnupg.org> - - * keydb.c (spacep): Removed because it is now in util.c - - * server.c (cmd_genkey): New. - * certreqgen.c: New. The parameter handling code has been taken - from gnupg/g10/keygen.c version 1.0.6. - * call-agent.c (gpgsm_agent_genkey): New. - -2002-01-02 Werner Koch <wk@gnupg.org> - - * server.c (rc_to_assuan_status): Removed and changed all callers - to use map_to_assuan_status. - -2001-12-20 Werner Koch <wk@gnupg.org> - - * verify.c (gpgsm_verify): Implemented non-detached signature - verification. Add OUT_FP arg, initialize a writer and changed all - callers. - * server.c (cmd_verify): Pass an out_fp if one has been set. - - * base64.c (base64_reader_cb): Try to detect an S/MIME body part. - - * certdump.c (print_sexp): Renamed to gpgsm_dump_serial, made - global. - (print_time): Renamed to gpgsm_dump_time, made global. - (gpgsm_dump_serial): Take a real S-Expression as argument and - print the first item. - * keylist.c (list_cert_colon): Ditto. - * keydb.c (keydb_search_issuer_sn): Ditto. - * decrypt.c (print_integer_sexp): Removed and made callers - use gpgsm_dump_serial. - * verify.c (print_time): Removed, made callers use gpgsm_dump_time. - -2001-12-19 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (start_agent): Add new argument to assuan_pipe_connect. - -2001-12-18 Werner Koch <wk@gnupg.org> - - * verify.c (print_integer_sexp): Renamed from print_integer and - print the serial number according to the S-Exp rules. - * decrypt.c (print_integer_sexp): Ditto. - -2001-12-17 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Changed for new return value of - get_serial. - * keydb.c (keydb_search_issuer_sn): Ditto. - * certcheck.c (gpgsm_check_cert_sig): Likewise for other S-Exp - returingin functions. - * fingerprint.c (gpgsm_get_keygrip): Ditto. - * encrypt.c (encrypt_dek): Ditto - * certcheck.c (gpgsm_check_cms_signature): Ditto - * decrypt.c (prepare_decryption): Ditto. - * call-agent.c (gpgsm_agent_pkdecrypt): Removed arg ciphertextlen, - use KsbaSexp type and calculate the length. - - * certdump.c (print_sexp): Remaned from print_integer, changed caller. - - * Makefile.am: Use the LIBGCRYPT and LIBKSBA variables. - - * fingerprint.c (gpgsm_get_keygrip): Use the new - gcry_pk_get_keygrip to calculate the grip - note the algorithm and - therefore the grip values changed. - -2001-12-15 Werner Koch <wk@gnupg.org> - - * certcheck.c (gpgsm_check_cms_signature): Removed the faked-key - kludge. - (gpgsm_create_cms_signature): Removed the commented fake key - code. This makes the function pretty simple. - - * gpgsm.c (main): Renamed the default key database to "keyring.kbx". - - * decrypt.c (gpgsm_decrypt): Write STATUS_DECRYPTION_*. - * sign.c (gpgsm_sign): Write a STATUS_SIG_CREATED. - -2001-12-14 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Kludge to show an email address - encoded in the subject's DN. - - * verify.c (gpgsm_verify): Add hash debug helpers - * sign.c (gpgsm_sign): Ditto. - - * base64.c (base64_reader_cb): Reset the linelen when we need to - skip the line and adjusted test; I somehow forgot about DeMorgan. - - * server.c (cmd_encrypt,cmd_decrypt,cmd_sign,cmd_verify) - (cmd_import): Close the FDs on success. - (close_message_fd): New. - (input_notify): Setting autodetect_encoding to 0 after initializing - it to 0 is pretty pointless. Easy to fix. - - * gpgsm.c (main): New option --debug-wait n, so that it is - possible to attach gdb when used in server mode. - - * sign.c (get_default_signer): Use keydb_classify_name here. - -2001-12-14 Marcus Brinkmann <marcus@g10code.de> - - * call-agent.c (LINELENGTH): Removed. - (gpgsm_agent_pksign): Use ASSUAN_LINELENGTH, not LINELENGTH. - (gpgsm_agent_pkdecrypt): Likewise. - -2001-12-13 Werner Koch <wk@gnupg.org> - - * keylist.c (list_cert_colon): Print alternative names of subject - and a few other values. - -2001-12-12 Werner Koch <wk@gnupg.org> - - * gpgsm.c (main): New options --assume-{armor,base64,binary}. - * base64.c (base64_reader_cb): Fixed non-autodetection mode. - -2001-12-04 Werner Koch <wk@gnupg.org> - - * call-agent.c (read_from_agent): Check for inquire responses. - (request_reply): Handle them using a new callback arg, changed all - callers. - (gpgsm_agent_pkdecrypt): New. - -2001-11-27 Werner Koch <wk@gnupg.org> - - * base64.c: New. Changed all other functions to use this instead - of direct creation of ksba_reader/writer. - * gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used. - -2001-11-26 Werner Koch <wk@gnupg.org> - - * gpgsm.c: New option --agent-program - * call-agent.c (start_agent): Allow to override the default path - to the agent. - - * keydb.c (keydb_add_resource): Create keybox - - * keylist.c (gpgsm_list_keys): Fixed non-server keylisting. - - * server.c (rc_to_assuan_status): New. Use it for all commands. - - - Copyright 2001, 2002, 2003 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/sm/Makefile.am b/sm/Makefile.am deleted file mode 100644 index 1ac7cbe84..000000000 --- a/sm/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - - -bin_PROGRAMS = gpgsm - -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(KSBA_CFLAGS) - -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl -include $(top_srcdir)/am/cmacros.am - - -gpgsm_SOURCES = \ - gpgsm.c gpgsm.h \ - misc.c \ - keydb.c keydb.h \ - server.c \ - call-agent.c \ - call-dirmngr.c \ - fingerprint.c \ - base64.c \ - certlist.c \ - certdump.c \ - certcheck.c \ - certchain.c \ - keylist.c \ - verify.c \ - sign.c \ - encrypt.c \ - decrypt.c \ - import.c \ - export.c \ - delete.c \ - certreqgen.c - - -gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a ../common/libcommon.a \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(KSBA_LIBS) -lgpg-error \ - $(INTLLIBS) diff --git a/sm/base64.c b/sm/base64.c deleted file mode 100644 index 4cc6ffa27..000000000 --- a/sm/base64.c +++ /dev/null @@ -1,655 +0,0 @@ -/* base64.c - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" - -#include <ksba.h> - -#include "i18n.h" - -#ifdef HAVE_DOSISH_SYSTEM - #define LF "\r\n" -#else - #define LF "\n" -#endif - -/* data used by the reader callbacks */ -struct reader_cb_parm_s { - FILE *fp; - unsigned char line[1024]; - int linelen; - int readpos; - int have_lf; - unsigned long line_counter; - - int allow_multi_pem; /* Allow processing of multiple PEM objects. */ - int autodetect; /* Try to detect the input encoding. */ - int assume_pem; /* Assume input encoding is PEM. */ - int assume_base64; /* Assume input is base64 encoded. */ - - int identified; - int is_pem; - int is_base64; - int stop_seen; - int might_be_smime; - - int eof_seen; - - struct { - int idx; - unsigned char val; - int stop_seen; - } base64; -}; - -/* data used by the writer callbacks */ -struct writer_cb_parm_s { - FILE *fp; - const char *pem_name; - - int wrote_begin; - int did_finish; - - struct { - int idx; - int quad_count; - unsigned char radbuf[4]; - } base64; - -}; - - -/* context for this module's functions */ -struct base64_context_s { - union { - struct reader_cb_parm_s rparm; - struct writer_cb_parm_s wparm; - } u; -}; - - -/* The base-64 character list */ -static unsigned char bintoasc[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -/* The reverse base-64 list */ -static unsigned char asctobin[256] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - - -static int -has_only_base64 (const unsigned char *line, int linelen) -{ - if (linelen < 20) - return 0; - for (; linelen; line++, linelen--) - { - if (*line == '\n' || (linelen > 1 && *line == '\r' && line[1] == '\n')) - break; - if ( !strchr (bintoasc, *line) ) - return 0; - } - return 1; /* yes */ -} - -static int -is_empty_line (const unsigned char *line, int linelen) -{ - if (linelen >= 2 && *line == '\r' && line[1] == '\n') - return 1; - if (linelen >= 1 && *line == '\n') - return 1; - return 0; -} - - -static int -base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c, c2; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - next: - if (!parm->linelen) - { - /* read an entire line or up to the size of the buffer */ - parm->line_counter++; - parm->have_lf = 0; - for (n=0; n < DIM(parm->line);) - { - c = getc (parm->fp); - if (c == EOF) - { - parm->eof_seen = 1; - if (ferror (parm->fp)) - return -1; - break; - } - parm->line[n++] = c; - if (c == '\n') - { - parm->have_lf = 1; - /* Fixme: we need to skip overlong lines while detecting - the dashed lines */ - break; - } - } - parm->linelen = n; - if (!n) - return -1; /* eof */ - parm->readpos = 0; - } - - if (!parm->identified) - { - if (!parm->autodetect) - { - if (parm->assume_pem) - { - /* wait for the header line */ - parm->linelen = parm->readpos = 0; - if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11) - || !strncmp (parm->line+11, "PGP ", 4)) - goto next; - parm->is_pem = 1; - } - else if (parm->assume_base64) - parm->is_base64 = 1; - } - else if (parm->line_counter == 1 && !parm->have_lf) - { - /* first line too long - assume DER encoding */ - parm->is_pem = 0; - } - else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30) - { - /* the very first byte does pretty much look like a SEQUENCE tag*/ - parm->is_pem = 0; - } - else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) - && strncmp (parm->line+11, "PGP ", 4) ) - { - /* Fixme: we must only compare if the line really starts at - the beginning */ - parm->is_pem = 1; - parm->linelen = parm->readpos = 0; - } - else if ( parm->have_lf && parm->line_counter == 1 - && parm->linelen >= 13 - && !ascii_memcasecmp (parm->line, "Content-Type:", 13)) - { /* might be a S/MIME body */ - parm->might_be_smime = 1; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 1 - && is_empty_line (parm->line, parm->linelen)) - { - parm->might_be_smime = 2; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 2) - { - parm->might_be_smime = 0; - if ( !has_only_base64 (parm->line, parm->linelen)) - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->is_pem = 1; - } - else - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->identified = 1; - parm->base64.stop_seen = 0; - parm->base64.idx = 0; - } - - - n = 0; - if (parm->is_pem || parm->is_base64) - { - if (parm->is_pem && parm->have_lf - && !strncmp (parm->line, "-----END ", 9)) - { - parm->identified = 0; - parm->linelen = parm->readpos = 0; - - /* If the caller want to read multiple PEM objects from one - file, we have to reset our internal state and return a - EOF immediately. The caller is the expected to use - ksba_reader_clear to clear the EOF condition and continue - to read. If we don't want to do that we just return 0 - bytes which will force the ksba_reader to skip until - EOF. */ - if (parm->allow_multi_pem) - { - parm->identified = 0; - parm->autodetect = 0; - parm->assume_pem = 1; - parm->stop_seen = 0; - return -1; /* Send EOF now. */ - } - } - else if (parm->stop_seen) - { /* skip the rest of the line */ - parm->linelen = parm->readpos = 0; - } - else - { - int idx = parm->base64.idx; - unsigned char val = parm->base64.val; - - while (n < count && parm->readpos < parm->linelen ) - { - c = parm->line[parm->readpos++]; - if (c == '\n' || c == ' ' || c == '\r' || c == '\t') - continue; - if (c == '=') - { /* pad character: stop */ - if (idx == 1) - buffer[n++] = val; - parm->stop_seen = 1; - break; - } - if( (c = asctobin[(c2=c)]) == 255 ) - { - log_error (_("invalid radix64 character %02x skipped\n"), - c2); - continue; - } - switch (idx) - { - case 0: - val = c << 2; - break; - case 1: - val |= (c>>4)&3; - buffer[n++] = val; - val = (c<<4)&0xf0; - break; - case 2: - val |= (c>>2)&15; - buffer[n++] = val; - val = (c<<6)&0xc0; - break; - case 3: - val |= c&0x3f; - buffer[n++] = val; - break; - } - idx = (idx+1) % 4; - } - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - - parm->base64.idx = idx; - parm->base64.val = val; - } - } - else - { /* DER encoded */ - while (n < count && parm->readpos < parm->linelen) - buffer[n++] = parm->line[parm->readpos++]; - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - } - - *nread = n; - return 0; -} - - - -static int -simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c = 0; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - for (n=0; n < count; n++) - { - c = getc (parm->fp); - if (c == EOF) - { - parm->eof_seen = 1; - if ( ferror (parm->fp) ) - return -1; - if (n) - break; /* return what we have before an EOF */ - return -1; - } - *(byte *)buffer++ = c; - } - - *nread = n; - return 0; -} - - - - -static int -base64_writer_cb (void *cb_value, const void *buffer, size_t count) -{ - struct writer_cb_parm_s *parm = cb_value; - unsigned char radbuf[4]; - int i, c, idx, quad_count; - const unsigned char *p; - FILE *fp = parm->fp; - - if (!count) - return 0; - - if (!parm->wrote_begin) - { - if (parm->pem_name) - { - fputs ("-----BEGIN ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - parm->wrote_begin = 1; - parm->base64.idx = 0; - parm->base64.quad_count = 0; - } - - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - for (p=buffer; count; p++, count--) - { - radbuf[idx++] = *p; - if (idx > 2) - { - idx = 0; - c = bintoasc[(*radbuf >> 2) & 077]; - putc (c, fp); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - putc (c, fp); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - putc (c, fp); - c = bintoasc[radbuf[2]&077]; - putc (c, fp); - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - } - for (i=0; i < idx; i++) - parm->base64.radbuf[i] = radbuf[i]; - parm->base64.idx = idx; - parm->base64.quad_count = quad_count; - - return ferror (fp) ? gpg_error_from_errno (errno) : 0; -} - -static int -base64_finish_write (struct writer_cb_parm_s *parm) -{ - unsigned char radbuf[4]; - int i, c, idx, quad_count; - FILE *fp = parm->fp; - - if (!parm->wrote_begin) - return 0; /* nothing written */ - - /* flush the base64 encoding */ - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - if (idx) - { - c = bintoasc[(*radbuf>>2)&077]; - putc (c, fp); - if (idx == 1) - { - c = bintoasc[((*radbuf << 4) & 060) & 077]; - putc (c, fp); - putc ('=', fp); - putc ('=', fp); - } - else - { - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - putc (c, fp); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; - putc (c, fp); - putc ('=', fp); - - } - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - - if (quad_count) - fputs (LF, fp); - - if (parm->pem_name) - { - fputs ("-----END ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - return ferror (fp)? gpg_error (gpg_err_code_from_errno (errno)) : 0; -} - - - - -/* Create a reader for the given file descriptor. Depending on the - control information an input decoding is automagically choosen. - The function returns a Base64Context object which must be passed to - the gpgme_destroy_reader function. The created KsbaReader object - is also returned, but the caller must not call the - ksba_reader_release function on. If ALLOW_MULTI_PEM is true, the - reader expects that the caller uses ksba_reader_clear after EOF - until no more objects were found. */ -int -gpgsm_create_reader (Base64Context *ctx, - CTRL ctrl, FILE *fp, int allow_multi_pem, - ksba_reader_t *r_reader) -{ - int rc; - ksba_reader_t r; - - *r_reader = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return OUT_OF_CORE (errno); - (*ctx)->u.rparm.allow_multi_pem = allow_multi_pem; - - rc = ksba_reader_new (&r); - if (rc) - { - xfree (*ctx); *ctx = NULL; - return rc; - } - - (*ctx)->u.rparm.fp = fp; - if (ctrl->is_pem) - { - (*ctx)->u.rparm.assume_pem = 1; - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->is_base64) - { - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->autodetect_encoding) - { - (*ctx)->u.rparm.autodetect = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else - rc = ksba_reader_set_cb (r, simple_reader_cb, &(*ctx)->u.rparm); - - if (rc) - { - ksba_reader_release (r); - xfree (*ctx); *ctx = NULL; - return rc; - } - - *r_reader = r; - return 0; -} - - -int -gpgsm_reader_eof_seen (Base64Context ctx) -{ - return ctx && ctx->u.rparm.eof_seen; -} - -void -gpgsm_destroy_reader (Base64Context ctx) -{ - xfree (ctx); -} - - - -/* Create a writer for the given stream. Depending on the control - information an output encoding is automagically choosen. The - function returns a Base64Context object which must be passed to the - gpgme_destroy_writer function. The created KsbaWriter object is - also returned, but the caller must not call the ksba_reader_release - function on. */ -int -gpgsm_create_writer (Base64Context *ctx, - CTRL ctrl, FILE *fp, ksba_writer_t *r_writer) -{ - int rc; - ksba_writer_t w; - - *r_writer = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return OUT_OF_CORE (errno); - - rc = ksba_writer_new (&w); - if (rc) - { - xfree (*ctx); *ctx = NULL; - return rc; - } - - if (ctrl->create_pem || ctrl->create_base64) - { - (*ctx)->u.wparm.fp = fp; - if (ctrl->create_pem) - (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name - : "CMS OBJECT"; - rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm); - } - else - rc = ksba_writer_set_file (w, fp); - - if (rc) - { - ksba_writer_release (w); - xfree (*ctx); *ctx = NULL; - return rc; - } - - *r_writer = w; - return 0; -} - - -int -gpgsm_finish_writer (Base64Context ctx) -{ - struct writer_cb_parm_s *parm; - - if (!ctx) - return gpg_error (GPG_ERR_INV_VALUE); - parm = &ctx->u.wparm; - if (parm->did_finish) - return 0; /* already done */ - parm->did_finish = 1; - if (!parm->fp) - return 0; /* callback was not used */ - return base64_finish_write (parm); -} - -void -gpgsm_destroy_writer (Base64Context ctx) -{ - xfree (ctx); -} diff --git a/sm/call-agent.c b/sm/call-agent.c deleted file mode 100644 index 2e8c75496..000000000 --- a/sm/call-agent.c +++ /dev/null @@ -1,635 +0,0 @@ -/* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> -#include "i18n.h" -#include "asshelp.h" -#include "keydb.h" /* fixme: Move this to import.c */ -#include "../common/membuf.h" - - -static ASSUAN_CONTEXT agent_ctx = NULL; -static int force_pipe_server = 0; - -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; - size_t ciphertextlen; -}; - -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; - size_t sexplen; -}; - -struct learn_parm_s { - int error; - ASSUAN_CONTEXT ctx; - membuf_t *data; -}; - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_agent (ctrl_t ctrl) -{ - int rc = 0; - char *infostr, *p; - assuan_context_t ctx; - - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the agent (which is suitable given that - the agent is not MT. */ - - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - gpgsm_status (ctrl, STATUS_PROGRESS, "starting_agent ? 0 0"); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (ctrl); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - return send_pinentry_environment (agent_ctx, - opt.display, opt.ttyname, opt.ttytype, - opt.lc_ctype, opt.lc_messages); -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - membuf_t *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - - - -/* Call the agent to do a sign operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, - unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen ) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - *r_buf = NULL; - rc = start_agent (ctrl); - if (rc) - return rc; - - if (digestlen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - sprintf (line, "SETHASH %d ", digestalgo); - p = line + strlen (line); - for (i=0; i < digestlen ; i++, p += 2 ) - sprintf (p, "%02X", digest[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - rc = assuan_transact (agent_ctx, "PKSIGN", - membuf_data_cb, &data, NULL, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - *r_buf = get_membuf (&data, r_buflen); - - if (!gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)) - { - xfree (*r_buf); *r_buf = NULL; - return gpg_error (GPG_ERR_INV_VALUE); - } - - return *r_buf? 0 : OUT_OF_CORE (errno); -} - - - - -/* Handle a CIPHERTEXT inquiry. Note, we only send the data, - assuan_transact talkes care of flushing and writing the end */ -static AssuanError -inq_ciphertext_cb (void *opaque, const char *keyword) -{ - struct cipher_parm_s *parm = opaque; - AssuanError rc; - - assuan_begin_confidential (parm->ctx); - rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen); - assuan_end_confidential (parm->ctx); - return rc; -} - - -/* Call the agent to do a decrypt operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, - ksba_const_sexp_t ciphertext, - char **r_buf, size_t *r_buflen ) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - membuf_t data; - struct cipher_parm_s cipher_parm; - size_t n, len; - char *buf, *endp; - size_t ciphertextlen; - - if (!keygrip || strlen(keygrip) != 40 || !ciphertext || !r_buf || !r_buflen) - return gpg_error (GPG_ERR_INV_VALUE); - *r_buf = NULL; - - ciphertextlen = gcry_sexp_canon_len (ciphertext, 0, NULL, NULL); - if (!ciphertextlen) - return gpg_error (GPG_ERR_INV_VALUE); - - rc = start_agent (ctrl); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - assert ( DIM(line) >= 50 ); - snprintf (line, DIM(line)-1, "SETKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - init_membuf (&data, 1024); - cipher_parm.ctx = agent_ctx; - cipher_parm.ciphertext = ciphertext; - cipher_parm.ciphertextlen = ciphertextlen; - rc = assuan_transact (agent_ctx, "PKDECRYPT", - membuf_data_cb, &data, - inq_ciphertext_cb, &cipher_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - - put_membuf (&data, "", 1); /* make sure it is 0 terminated */ - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - /* FIXME: We would better a return a full S-exp and not just a part */ - assert (len); - len--; /* remove the terminating 0 */ - n = strtoul (buf, &endp, 10); - if (!n || *endp != ':') - return gpg_error (GPG_ERR_INV_SEXP); - endp++; - if (endp-buf+n > len) - return gpg_error (GPG_ERR_INV_SEXP); /* oops len does not - match internal len*/ - memmove (buf, endp, n); - *r_buflen = n; - *r_buf = buf; - return 0; -} - - - - - -/* Handle a KEYPARMS inquiry. Note, we only send the data, - assuan_transact takes care of flushing and writing the end */ -static AssuanError -inq_genkey_parms (void *opaque, const char *keyword) -{ - struct genkey_parm_s *parm = opaque; - AssuanError rc; - - rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen); - return rc; -} - - - -/* Call the agent to generate a newkey */ -int -gpgsm_agent_genkey (ctrl_t ctrl, - ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - membuf_t data; - size_t len; - char *buf; - - *r_pubkey = NULL; - rc = start_agent (ctrl); - if (rc) - return rc; - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - gk_parm.ctx = agent_ctx; - gk_parm.sexp = keyparms; - gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); - if (!gk_parm.sexplen) - return gpg_error (GPG_ERR_INV_VALUE); - rc = assuan_transact (agent_ctx, "GENKEY", - membuf_data_cb, &data, - inq_genkey_parms, &gk_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - buf = get_membuf (&data, &len); - if (!buf) - return gpg_error (GPG_ERR_ENOMEM); - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_SEXP); - } - *r_pubkey = buf; - return 0; -} - - -/* Ask the agent whether the certificate is in the list of trusted - keys */ -int -gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert) -{ - int rc; - char *fpr; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return gpg_error (GPG_ERR_GENERAL); - } - - snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr); - line[DIM(line)-1] = 0; - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - -/* Ask the agent to mark CERT as a trusted Root-CA one */ -int -gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert) -{ - int rc; - char *fpr, *dn; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return gpg_error (GPG_ERR_GENERAL); - } - - dn = ksba_cert_get_issuer (cert, 0); - if (!dn) - { - xfree (fpr); - return gpg_error (GPG_ERR_GENERAL); - } - snprintf (line, DIM(line)-1, "MARKTRUSTED %s S %s", fpr, dn); - line[DIM(line)-1] = 0; - ksba_free (dn); - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - - -/* Ask the agent whether the a corresponding secret key is available - for the given keygrip */ -int -gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - -static AssuanError -learn_cb (void *opaque, const void *buffer, size_t length) -{ - struct learn_parm_s *parm = opaque; - size_t len; - char *buf; - ksba_cert_t cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (parm->data, &len); - if (!buf) - { - parm->error = gpg_error (GPG_ERR_ENOMEM); - return 0; - } - - - /* FIXME: this should go into import.c */ - rc = ksba_cert_new (&cert); - if (rc) - { - parm->error = rc; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc)); - ksba_cert_release (cert); - parm->error = rc; - return 0; - } - - rc = gpgsm_basic_cert_check (cert); - if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT) - { /* For later use we store it in the ephemeral database. */ - log_info ("issuer certificate missing - storing as ephemeral\n"); - keydb_store_cert (cert, 1, NULL); - } - else if (rc) - log_error ("invalid certificate: %s\n", gpg_strerror (rc)); - else - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - if (opt.verbose > 1 && existed) - log_info ("certificate already in DB\n"); - else if (opt.verbose && !existed) - log_info ("certificate imported\n"); - } - } - - ksba_cert_release (cert); - init_membuf (parm->data, 4096); - return 0; -} - -/* Call the agent to learn about a smartcard */ -int -gpgsm_agent_learn (ctrl_t ctrl) -{ - int rc; - struct learn_parm_s learn_parm; - membuf_t data; - size_t len; - - rc = start_agent (ctrl); - if (rc) - return rc; - - init_membuf (&data, 4096); - learn_parm.error = 0; - learn_parm.ctx = agent_ctx; - learn_parm.data = &data; - rc = assuan_transact (agent_ctx, "LEARN --send", - learn_cb, &learn_parm, - NULL, NULL, NULL, NULL); - xfree (get_membuf (&data, &len)); - if (rc) - return map_assuan_err (rc); - return learn_parm.error; -} - - -/* Ask the agent to change the passphrase of the key identified by - HEXKEYGRIP. If DESC is not NULL, display instead of the default - description message. */ -int -gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (ctrl); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); - - if (desc) - { - snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - } - - snprintf (line, DIM(line)-1, "PASSWD %s", hexkeygrip); - line[DIM(line)-1] = 0; - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c deleted file mode 100644 index 15160dc41..000000000 --- a/sm/call-dirmngr.c +++ /dev/null @@ -1,785 +0,0 @@ -/* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <ctype.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> - -#include "i18n.h" -#include "keydb.h" - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - - -static ASSUAN_CONTEXT dirmngr_ctx = NULL; -static int force_pipe_server = 0; - -struct inq_certificate_parm_s { - ASSUAN_CONTEXT ctx; - ksba_cert_t cert; - ksba_cert_t issuer_cert; -}; - -struct isvalid_status_parm_s { - int seen; - unsigned char fpr[20]; -}; - - -struct lookup_parm_s { - CTRL ctrl; - ASSUAN_CONTEXT ctx; - void (*cb)(void *, ksba_cert_t); - void *cb_value; - struct membuf data; - int error; -}; - -struct run_command_parm_s { - ASSUAN_CONTEXT ctx; -}; - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - - - - -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int -start_dirmngr (void) -{ - int rc; - char *infostr, *p; - ASSUAN_CONTEXT ctx; - - if (dirmngr_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the dirmngr */ - /* Note: if you change this to multiple connections, you also need - to take care of the implicit option sending caching. */ - - infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running dirmngr - starting one\n")); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR; - if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) - pgmname = opt.dirmngr_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("dirmngr protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the dirmngr - trying fall back\n")); - force_pipe_server = 1; - return start_dirmngr (); - } - } - - if (rc) - { - log_error ("can't connect to the dirmngr: %s\n", assuan_strerror (rc)); - return gpg_error (GPG_ERR_NO_DIRMNGR); - } - dirmngr_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to dirmngr established\n"); - return 0; -} - - - -/* Handle a SENDCERT inquiry. */ -static AssuanError -inq_certificate (void *opaque, const char *line) -{ - struct inq_certificate_parm_s *parm = opaque; - AssuanError rc; - const unsigned char *der; - size_t derlen; - int issuer_mode = 0; - - if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) - { - line += 8; - } - else if (!strncmp (line, "SENDISSUERCERT", 14) - && (line[14] == ' ' || !line[14])) - { - line += 14; - issuer_mode = 1; - } - else - { - log_error ("unsupported inquiry `%s'\n", line); - return ASSUAN_Inquire_Unknown; - } - - if (!*line) - { /* Send the current certificate. */ - der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert, - &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - } - else if (issuer_mode) - { - log_error ("sending specific issuer certificate back " - "is not yet implemented\n"); - rc = ASSUAN_Inquire_Error; - } - else - { /* Send the given certificate. */ - int err; - ksba_cert_t cert; - - - err = gpgsm_find_cert (line, &cert); - if (err) - { - log_error ("certificate not found: %s\n", gpg_strerror (err)); - rc = ASSUAN_Inquire_Error; - } - else - { - der = ksba_cert_get_image (cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); - } - } - - return rc; -} - - -/* Take a 20 byte hexencoded string and put it into the the provided - 20 byte buffer FPR in binary format. */ -static int -unhexify_fpr (const char *hexstr, unsigned char *fpr) -{ - const char *s; - int n; - - for (s=hexstr, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n != 40)) - return 0; /* no fingerprint (invalid or wrong length). */ - n /= 2; - for (s=hexstr, n=0; *s; s += 2, n++) - fpr[n] = xtoi_2 (s); - return 1; /* okay */ -} - - -static assuan_error_t -isvalid_status_cb (void *opaque, const char *line) -{ - struct isvalid_status_parm_s *parm = opaque; - - if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24) - && (line[24]==' ' || !line[24])) - { - parm->seen++; - if (!line[24] || !unhexify_fpr (line+25, parm->fpr)) - parm->seen++; /* Bumb it to indicate an error. */ - } - return 0; -} - - - - -/* Call the directory manager to check whether the certificate is valid - Returns 0 for valid or usually one of the errors: - - GPG_ERR_CERTIFICATE_REVOKED - GPG_ERR_NO_CRL_KNOWN - GPG_ERR_CRL_TOO_OLD - - With USE_OCSP set to true, the dirmngr is asked to do an OCSP - request first. - */ -int -gpgsm_dirmngr_isvalid (ctrl_t ctrl, - ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp) -{ - static int did_options; - int rc; - char *certid; - char line[ASSUAN_LINELENGTH]; - struct inq_certificate_parm_s parm; - struct isvalid_status_parm_s stparm; - - - rc = start_dirmngr (); - if (rc) - return rc; - - if (use_ocsp) - { - certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - } - else - { - certid = gpgsm_get_certid (cert); - if (!certid) - { - log_error ("error getting the certificate ID\n"); - return gpg_error (GPG_ERR_GENERAL); - } - } - - if (opt.verbose > 1) - { - char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1); - log_info ("asking dirmngr about %s%s\n", fpr, - use_ocsp? " (using OCSP)":""); - xfree (fpr); - } - - parm.ctx = dirmngr_ctx; - parm.cert = cert; - parm.issuer_cert = issuer_cert; - - stparm.seen = 0; - memset (stparm.fpr, 0, 20); - - /* FIXME: If --disable-crl-checks has been set, we should pass an - option to dirmngr, so that no fallback CRL check is done after an - ocsp check. */ - - /* It is sufficient to send the options only once because we have - one connection per process only. */ - if (!did_options) - { - if (opt.force_crl_refresh) - assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1", - NULL, NULL, NULL, NULL, NULL, NULL); - did_options = 1; - } - snprintf (line, DIM(line)-1, "ISVALID %s", certid); - line[DIM(line)-1] = 0; - xfree (certid); - - rc = assuan_transact (dirmngr_ctx, line, NULL, NULL, - inq_certificate, &parm, - isvalid_status_cb, &stparm); - if (opt.verbose > 1) - log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay"); - rc = map_assuan_err (rc); - - if (!rc && stparm.seen) - { - /* Need to also check the certificate validity. */ - if (stparm.seen != 1) - { - log_error ("communication problem with dirmngr detected\n"); - rc = gpg_error (GPG_ERR_INV_CRL); - } - else - { - KEYDB_HANDLE kh; - ksba_cert_t rspcert = NULL; - - /* Fixme: First try to get the certificate from the - dirmngr's cache - it should be there. */ - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - if (!rc) - rc = keydb_search_fpr (kh, stparm.fpr); - if (!rc) - rc = keydb_get_cert (kh, &rspcert); - if (rc) - { - log_error ("unable to find the certificate used " - "by the dirmngr: %s\n", gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_INV_CRL); - } - keydb_release (kh); - - if (!rc) - { - /* fixme: We should refine the check to check for - certificates allowed for CRL/OCPS. */ - rc = gpgsm_cert_use_verify_p (rspcert); - if (rc) - rc = gpg_error (GPG_ERR_INV_CRL); - else - { - /* Note, the flag = 1: This avoids checking this - certificate over and over again. */ - rc = gpgsm_validate_chain (ctrl, rspcert, NULL, 0, NULL, 1); - if (rc) - { - log_error ("invalid certificate used for CRL/OCSP: %s\n", - gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_INV_CRL); - } - } - } - ksba_cert_release (rspcert); - } - } - return rc; -} - - - -/* Lookup helpers*/ -static AssuanError -lookup_cb (void *opaque, const void *buffer, size_t length) -{ - struct lookup_parm_s *parm = opaque; - size_t len; - char *buf; - ksba_cert_t cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (&parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (&parm->data, &len); - if (!buf) - { - parm->error = gpg_error (GPG_ERR_ENOMEM); - return 0; - } - - rc = ksba_cert_new (&cert); - if (rc) - { - parm->error = rc; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc)); - } - else - { - parm->cb (parm->cb_value, cert); - } - - ksba_cert_release (cert); - init_membuf (&parm->data, 4096); - return 0; -} - -/* Return a properly escaped pattern from NAMES. The only error - return is NULL to indicate a malloc failure. */ -static char * -pattern_from_strlist (STRLIST names) -{ - STRLIST sl; - int n; - const char *s; - char *pattern, *p; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++, n++) - { - if (*s == '%' || *s == ' ' || *s == '+') - n += 2; - } - n++; - } - - p = pattern = xtrymalloc (n+1); - if (!pattern) - return NULL; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++) - { - switch (*s) - { - case '%': - *p++ = '%'; - *p++ = '2'; - *p++ = '5'; - break; - case ' ': - *p++ = '%'; - *p++ = '2'; - *p++ = '0'; - break; - case '+': - *p++ = '%'; - *p++ = '2'; - *p++ = 'B'; - break; - default: - *p++ = *s; - break; - } - } - *p++ = ' '; - } - if (p == pattern) - *pattern = 0; /* is empty */ - else - p[-1] = '\0'; /* remove trailing blank */ - - return pattern; -} - -static AssuanError -lookup_status_cb (void *opaque, const char *line) -{ - struct lookup_parm_s *parm = opaque; - - if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9])) - { - if (parm->ctrl) - { - for (line +=9; *line == ' '; line++) - ; - gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line); - } - } - return 0; -} - - -/* Run the Directroy Managers lookup command using the pattern - compiled from the strings given in NAMES. The caller must provide - the callback CB which will be passed cert by cert. Note that CTRL - is optional. */ -int -gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names, - void (*cb)(void*, ksba_cert_t), void *cb_value) -{ - int rc; - char *pattern; - char line[ASSUAN_LINELENGTH]; - struct lookup_parm_s parm; - size_t len; - - rc = start_dirmngr (); - if (rc) - return rc; - - pattern = pattern_from_strlist (names); - if (!pattern) - return OUT_OF_CORE (errno); - snprintf (line, DIM(line)-1, "LOOKUP %s", pattern); - line[DIM(line)-1] = 0; - xfree (pattern); - - parm.ctrl = ctrl; - parm.ctx = dirmngr_ctx; - parm.cb = cb; - parm.cb_value = cb_value; - parm.error = 0; - init_membuf (&parm.data, 4096); - - rc = assuan_transact (dirmngr_ctx, line, lookup_cb, &parm, - NULL, NULL, lookup_status_cb, &parm); - xfree (get_membuf (&parm.data, &len)); - if (rc) - return map_assuan_err (rc); - return parm.error; -} - - - -/* Run Command helpers*/ - -/* Fairly simple callback to write all output of dirmngr to stdout. */ -static AssuanError -run_command_cb (void *opaque, const void *buffer, size_t length) -{ - if (buffer) - { - if ( fwrite (buffer, length, 1, stdout) != 1 ) - log_error ("error writing to stdout: %s\n", strerror (errno)); - } - return 0; -} - -/* Handle inquiries from the dirmngr COMMAND. */ -static AssuanError -run_command_inq_cb (void *opaque, const char *line) -{ - struct run_command_parm_s *parm = opaque; - AssuanError rc = 0; - - if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) ) - { /* send the given certificate */ - int err; - ksba_cert_t cert; - const unsigned char *der; - size_t derlen; - - line += 8; - if (!*line) - return ASSUAN_Inquire_Error; - - err = gpgsm_find_cert (line, &cert); - if (err) - { - log_error ("certificate not found: %s\n", gpg_strerror (err)); - rc = ASSUAN_Inquire_Error; - } - else - { - der = ksba_cert_get_image (cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); - } - } - else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) ) - { /* Simply show the message given in the argument. */ - line += 9; - log_info ("dirmngr: %s\n", line); - } - else - { - log_error ("unsupported inquiry `%s'\n", line); - rc = ASSUAN_Inquire_Unknown; - } - - return rc; -} - -static AssuanError -run_command_status_cb (void *opaque, const char *line) -{ - if (opt.verbose) - { - log_info ("dirmngr status: %s\n", line); - } - return 0; -} - - - -/* Pass COMMAND to dirmngr and print all output generated by Dirmngr - to stdout. A couple of inquiries are defined (see above). ARGC - arguments in ARGV are given to the Dirmngr. Spaces, plus and - percent characters within the argument strings are percent escaped - so that blanks can act as delimiters. */ -int -gpgsm_dirmngr_run_command (CTRL ctrl, const char *command, - int argc, char **argv) -{ - int rc; - int i; - const char *s; - char *line, *p; - size_t len; - struct run_command_parm_s parm; - - rc = start_dirmngr (); - if (rc) - return rc; - - parm.ctx = dirmngr_ctx; - - len = strlen (command) + 1; - for (i=0; i < argc; i++) - len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */ - line = xtrymalloc (len); - if (!line) - return OUT_OF_CORE (errno); - - p = stpcpy (line, command); - for (i=0; i < argc; i++) - { - *p++ = ' '; - for (s=argv[i]; *s; s++) - { - if (!isascii (*s)) - *p++ = *s; - else if (*s == ' ') - *p++ = '+'; - else if (!isprint (*s) || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else - *p++ = *s; - } - } - *p = 0; - - rc = assuan_transact (dirmngr_ctx, line, - run_command_cb, NULL, - run_command_inq_cb, &parm, - run_command_status_cb, NULL); - xfree (line); - log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay"); - return map_assuan_err (rc); -} diff --git a/sm/certchain.c b/sm/certchain.c deleted file mode 100644 index 3009c21aa..000000000 --- a/sm/certchain.c +++ /dev/null @@ -1,976 +0,0 @@ -/* certchain.c - certificate chain validation - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <stdarg.h> -#include <assert.h> - -#define JNLIB_NEED_LOG_LOGV /* We need log_logv. */ - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ -#include "i18n.h" - - -/* If LISTMODE is true, print FORMAT in liting mode to FP. If - LISTMODE is false, use the string to print an log_info or, if - IS_ERROR is true, an log_error. */ -static void -do_list (int is_error, int listmode, FILE *fp, const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format) ; - if (listmode) - { - if (fp) - { - fputs (" [", fp); - vfprintf (fp, format, arg_ptr); - fputs ("]\n", fp); - } - } - else - { - log_logv (is_error? JNLIB_LOG_ERROR: JNLIB_LOG_INFO, format, arg_ptr); - log_printf ("\n"); - } - va_end (arg_ptr); -} - -/* Return 0 if A and B are equal. */ -static int -compare_certs (ksba_cert_t a, ksba_cert_t b) -{ - const unsigned char *img_a, *img_b; - size_t len_a, len_b; - - img_a = ksba_cert_get_image (a, &len_a); - if (!img_a) - return 1; - img_b = ksba_cert_get_image (b, &len_b); - if (!img_b) - return 1; - return !(len_a == len_b && !memcmp (img_a, img_b, len_a)); -} - - -static int -unknown_criticals (ksba_cert_t cert, int listmode, FILE *fp) -{ - static const char *known[] = { - "2.5.29.15", /* keyUsage */ - "2.5.29.19", /* basic Constraints */ - "2.5.29.32", /* certificatePolicies */ - "2.5.29.37", /* extendedKeyUsage - handled by certlist.c */ - NULL - }; - int rc = 0, i, idx, crit; - const char *oid; - gpg_error_t err; - - for (idx=0; !(err=ksba_cert_get_extension (cert, idx, - &oid, &crit, NULL, NULL));idx++) - { - if (!crit) - continue; - for (i=0; known[i] && strcmp (known[i],oid); i++) - ; - if (!known[i]) - { - do_list (1, listmode, fp, - _("critical certificate extension %s is not supported"), - oid); - rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT); - } - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - rc = err; - - return rc; -} - -static int -allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, FILE *fp) -{ - gpg_error_t err; - int flag; - - err = ksba_cert_is_ca (cert, &flag, chainlen); - if (err) - return err; - if (!flag) - { - do_list (1, listmode, fp,_("issuer certificate is not marked as a CA")); - return gpg_error (GPG_ERR_BAD_CA_CERT); - } - return 0; -} - - -static int -check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist) -{ - gpg_error_t err; - char *policies; - FILE *fp; - int any_critical; - - err = ksba_cert_get_cert_policies (cert, &policies); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - return 0; /* no policy given */ - if (err) - return err; - - /* STRING is a line delimited list of certifiate policies as stored - in the certificate. The line itself is colon delimited where the - first field is the OID of the policy and the second field either - N or C for normal or critical extension */ - - if (opt.verbose > 1 && !listmode) - log_info ("certificate's policy list: %s\n", policies); - - /* The check is very minimal but won't give false positives */ - any_critical = !!strstr (policies, ":C"); - - if (!opt.policy_file) - { - xfree (policies); - if (any_critical) - { - do_list (1, listmode, fplist, - _("critical marked policy without configured policies")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - return 0; - } - - fp = fopen (opt.policy_file, "r"); - if (!fp) - { - log_error ("failed to open `%s': %s\n", - opt.policy_file, strerror (errno)); - xfree (policies); - /* With no critical policies this is only a warning */ - if (!any_critical) - { - do_list (0, listmode, fplist, - _("note: non-critical certificate policy not allowed")); - return 0; - } - do_list (1, listmode, fplist, - _("certificate policy not allowed")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - - for (;;) - { - int c; - char *p, line[256]; - char *haystack, *allowed; - - /* read line */ - do - { - if (!fgets (line, DIM(line)-1, fp) ) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - - xfree (policies); - if (feof (fp)) - { - fclose (fp); - /* With no critical policies this is only a warning */ - if (!any_critical) - { - do_list (0, listmode, fplist, - _("note: non-critical certificate policy not allowed")); - return 0; - } - do_list (1, listmode, fplist, - _("certificate policy not allowed")); - return gpg_error (GPG_ERR_NO_POLICY_MATCH); - } - fclose (fp); - return tmperr; - } - - if (!*line || line[strlen(line)-1] != '\n') - { - /* eat until end of line */ - while ( (c=getc (fp)) != EOF && c != '\n') - ; - fclose (fp); - xfree (policies); - return gpg_error (*line? GPG_ERR_LINE_TOO_LONG - : GPG_ERR_INCOMPLETE_LINE); - } - - /* Allow for empty lines and spaces */ - for (p=line; spacep (p); p++) - ; - } - while (!*p || *p == '\n' || *p == '#'); - - /* parse line */ - for (allowed=line; spacep (allowed); allowed++) - ; - p = strpbrk (allowed, " :\n"); - if (!*p || p == allowed) - { - fclose (fp); - xfree (policies); - return gpg_error (GPG_ERR_CONFIGURATION); - } - *p = 0; /* strip the rest of the line */ - /* See whether we find ALLOWED (which is an OID) in POLICIES */ - for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1) - { - if ( !(p == policies || p[-1] == '\n') ) - continue; /* Does not match the begin of a line. */ - if (p[strlen (allowed)] != ':') - continue; /* The length does not match. */ - /* Yep - it does match so return okay. */ - fclose (fp); - xfree (policies); - return 0; - } - } -} - - -static void -find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) -{ - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing issuer certificate as ephemeral\n"); - ++*(int*)cb_value; -} - - -static int -find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) -{ - ksba_name_t authid; - ksba_sexp_t authidno; - int rc = -1; - - if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno)) - { - const char *s = ksba_name_enum (authid, 0); - if (s && *authidno) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - - /* In case of an error try the ephemeral DB. We can't do - that in find-netx mode because we can't keep the search - state then. */ - if (rc == -1 && !find_next) - { - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - } - keydb_set_ephemeral (kh, old); - } - } - /* Print a note so that the user does not feel too helpless when - an issuer certificate was found and gpgsm prints BAD - signature because it is not the correct one. */ - if (rc == -1) - { - log_info ("issuer certificate (#"); - gpgsm_dump_serial (authidno); - log_printf ("/"); - gpgsm_dump_string (s); - log_printf (") not found\n"); - } - else if (rc) - log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc); - ksba_name_release (authid); - xfree (authidno); - /* Fixme: don't know how to do dirmngr lookup with serial+issuer. */ - } - - if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */ - rc = keydb_search_subject (kh, issuer); - if (rc == -1 && !find_next) - { - /* Not found, lets see whether we have one in the ephemeral key DB. */ - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - } - keydb_set_ephemeral (kh, old); - } - - if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - { - STRLIST names = NULL; - int count = 0; - char *pattern; - const char *s; - - if (opt.verbose) - log_info (_("looking up issuer at external location\n")); - /* dirmngr is confused about unknown attributes so as a quick - and ugly hack we locate the CN and use this and the - following. Fixme: we should have far better parsing in the - dirmngr. */ - s = strstr (issuer, "CN="); - if (!s || s == issuer || s[-1] != ',') - s = issuer; - - pattern = xtrymalloc (strlen (s)+2); - if (!pattern) - return OUT_OF_CORE (errno); - strcpy (stpcpy (pattern, "/"), s); - add_to_strlist (&names, pattern); - xfree (pattern); - rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count); - free_strlist (names); - if (opt.verbose) - log_info (_("number of issuers matching: %d\n"), count); - if (rc) - { - log_error ("external key lookup failed: %s\n", gpg_strerror (rc)); - rc = -1; - } - else if (!count) - rc = -1; - else - { - int old; - /* The issuers are currently stored in the ephemeral key - DB, so we temporary switch to ephemeral mode. */ - old = keydb_set_ephemeral (kh, 1); - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - keydb_set_ephemeral (kh, old); - } - } - return rc; -} - - -/* Return the next certificate up in the chain starting at START. - Returns -1 when there are no more certificates. */ -int -gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - - *r_next = NULL; - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - issuer = ksba_cert_get_issuer (start, 0); - subject = ksba_cert_get_subject (start, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - if (!subject) - { - log_error ("no subject found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (!strcmp (issuer, subject)) - { - rc = -1; /* we are at the root */ - goto leave; - } - - rc = find_up (kh, start, issuer, 0); - if (rc) - { - /* it is quite common not to have a certificate, so better don't - print an error here */ - if (rc != -1 && opt.verbose > 1) - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - rc = keydb_get_cert (kh, r_next); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - } - - leave: - xfree (issuer); - xfree (subject); - keydb_release (kh); - return rc; -} - - -/* Check whether the CERT is a root certificate. Returns True if this - is the case. */ -int -gpgsm_is_root_cert (ksba_cert_t cert) -{ - char *issuer; - char *subject; - int yes; - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - yes = (issuer && subject && !strcmp (issuer, subject)); - xfree (issuer); - xfree (subject); - return yes; -} - - -/* This is a helper for gpgsm_validate_chain. */ -static gpg_error_t -is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp, - ksba_cert_t subject_cert, ksba_cert_t issuer_cert, - int *any_revoked, int *any_no_crl, int *any_crl_too_old) -{ - if (!opt.no_crl_check || ctrl->use_ocsp) - { - gpg_error_t err; - - err = gpgsm_dirmngr_isvalid (ctrl, - subject_cert, issuer_cert, ctrl->use_ocsp); - if (err) - { - /* Fixme: We should change the wording because we may - have used OCSP. */ - switch (gpg_err_code (err)) - { - case GPG_ERR_CERT_REVOKED: - do_list (1, lm, fp, _("certificate has been revoked")); - *any_revoked = 1; - /* Store that in the keybox so that key listings are - able to return the revoked flag. We don't care - about error, though. */ - keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0, - VALIDITY_REVOKED); - break; - case GPG_ERR_NO_CRL_KNOWN: - do_list (1, lm, fp, _("no CRL found for certificate")); - *any_no_crl = 1; - break; - case GPG_ERR_CRL_TOO_OLD: - do_list (1, lm, fp, _("the available CRL is too old")); - if (!lm) - log_info (_("please make sure that the " - "\"dirmngr\" is properly installed\n")); - *any_crl_too_old = 1; - break; - default: - do_list (1, lm, fp, _("checking the CRL failed: %s"), - gpg_strerror (err)); - return err; - } - } - } - return 0; -} - - - -/* Validate a chain and optionally return the nearest expiration time - in R_EXPTIME. With LISTMODE set to 1 a special listmode is - activated where only information about the certificate is printed - to FP and no output is send to the usual log stream. - - Defined flag bits: 0 - do not do any dirmngr isvalid checks. -*/ -int -gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int listmode, FILE *fp, unsigned int flags) -{ - int rc = 0, depth = 0, maxdepth; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - ksba_cert_t subject_cert = NULL, issuer_cert = NULL; - ksba_isotime_t current_time; - ksba_isotime_t exptime; - int any_expired = 0; - int any_revoked = 0; - int any_no_crl = 0; - int any_crl_too_old = 0; - int any_no_policy_match = 0; - int lm = listmode; - - gnupg_get_isotime (current_time); - if (r_exptime) - *r_exptime = 0; - *exptime = 0; - - if (opt.no_chain_validation && !listmode) - { - log_info ("WARNING: bypassing certificate chain validation\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (DBG_X509 && !listmode) - gpgsm_dump_cert ("subject", cert); - - subject_cert = cert; - maxdepth = 50; - - for (;;) - { - xfree (issuer); - xfree (subject); - issuer = ksba_cert_get_issuer (subject_cert, 0); - subject = ksba_cert_get_subject (subject_cert, 0); - - if (!issuer) - { - do_list (1, lm, fp, _("no issuer found in certificate")); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - { - ksba_isotime_t not_before, not_after; - - rc = ksba_cert_get_validity (subject_cert, 0, not_before); - if (!rc) - rc = ksba_cert_get_validity (subject_cert, 1, not_after); - if (rc) - { - do_list (1, lm, fp, _("certificate with invalid validity: %s"), - gpg_strerror (rc)); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (*not_after) - { - if (!*exptime) - gnupg_copy_time (exptime, not_after); - else if (strcmp (not_after, exptime) < 0 ) - gnupg_copy_time (exptime, not_after); - } - - if (*not_before && strcmp (current_time, not_before) < 0 ) - { - do_list (1, lm, fp, _("certificate not yet valid")); - if (!lm) - { - log_info ("(valid from "); - gpgsm_dump_time (not_before); - log_printf (")\n"); - } - rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG); - goto leave; - } - if (*not_after && strcmp (current_time, not_after) > 0 ) - { - do_list (opt.ignore_expiration?0:1, lm, fp, - _("certificate has expired")); - if (!lm) - { - log_info ("(expired at "); - gpgsm_dump_time (not_after); - log_printf (")\n"); - } - if (opt.ignore_expiration) - log_info ("WARNING: ignoring expiration\n"); - else - any_expired = 1; - } - } - - rc = unknown_criticals (subject_cert, listmode, fp); - if (rc) - goto leave; - - if (!opt.no_policy_check) - { - rc = check_cert_policy (subject_cert, listmode, fp); - if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH) - { - any_no_policy_match = 1; - rc = 1; - } - else if (rc) - goto leave; - } - - - /* Is this a self-signed certificate? */ - if (subject && !strcmp (issuer, subject)) - { /* Yes. */ - if (gpgsm_check_cert_sig (subject_cert, subject_cert) ) - { - do_list (1, lm, fp, - _("selfsigned certificate has a BAD signature")); - rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN - : GPG_ERR_BAD_CERT); - goto leave; - } - rc = allowed_ca (subject_cert, NULL, listmode, fp); - if (rc) - goto leave; - - rc = gpgsm_agent_istrusted (ctrl, subject_cert); - if (!rc) - ; - else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) - { - do_list (0, lm, fp, _("root certificate is not marked trusted")); - if (!lm) - { - int rc2; - char *fpr = gpgsm_get_fingerprint_string (subject_cert, - GCRY_MD_SHA1); - log_info (_("fingerprint=%s\n"), fpr? fpr : "?"); - xfree (fpr); - rc2 = gpgsm_agent_marktrusted (ctrl, subject_cert); - if (!rc2) - { - log_info (_("root certificate has now" - " been marked as trusted\n")); - rc = 0; - } - else - { - gpgsm_dump_cert ("issuer", subject_cert); - log_info ("after checking the fingerprint, you may want " - "to add it manually to the list of trusted " - "certificates.\n"); - } - } - } - else - { - log_error (_("checking the trust list failed: %s\n"), - gpg_strerror (rc)); - } - - /* Check for revocations etc. */ - if ((flags & 1)) - rc = 0; - else - rc = is_cert_still_valid (ctrl, lm, fp, - subject_cert, subject_cert, - &any_revoked, &any_no_crl, - &any_crl_too_old); - if (rc) - goto leave; - - break; /* Okay: a self-signed certicate is an end-point. */ - } - - depth++; - if (depth > maxdepth) - { - do_list (1, lm, fp, _("certificate chain too long\n")); - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, subject_cert, issuer, 0); - if (rc) - { - if (rc == -1) - { - do_list (0, lm, fp, _("issuer certificate not found")); - if (!lm) - { - log_info ("issuer certificate: #/"); - gpgsm_dump_string (issuer); - log_printf ("\n"); - } - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - try_another_cert: - if (DBG_X509) - { - log_debug ("got issuer's certificate:\n"); - gpgsm_dump_cert ("issuer", issuer_cert); - } - - rc = gpgsm_check_cert_sig (issuer_cert, subject_cert); - if (rc) - { - do_list (0, lm, fp, _("certificate has a BAD signature")); - if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE) - { - /* We now try to find other issuer certificates which - might have been used. This is rquired because some - CAs are reusing the issuer and subject DN for new - root certificates. */ - rc = find_up (kh, subject_cert, issuer, 1); - if (!rc) - { - ksba_cert_t tmp_cert; - - rc = keydb_get_cert (kh, &tmp_cert); - if (rc || !compare_certs (issuer_cert, tmp_cert)) - { - /* The find next did not work or returned an - identical certificate. We better stop here - to avoid infinite checks. */ - rc = gpg_error (GPG_ERR_BAD_SIGNATURE); - ksba_cert_release (tmp_cert); - } - else - { - do_list (0, lm, fp, _("found another possible matching " - "CA certificate - trying again")); - ksba_cert_release (issuer_cert); - issuer_cert = tmp_cert; - goto try_another_cert; - } - } - } - - /* We give a more descriptive error code than the one - returned from the signature checking. */ - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - - { - int chainlen; - rc = allowed_ca (issuer_cert, &chainlen, listmode, fp); - if (rc) - goto leave; - if (chainlen >= 0 && (depth - 1) > chainlen) - { - do_list (1, lm, fp, - _("certificate chain longer than allowed by CA (%d)"), - chainlen); - rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN); - goto leave; - } - } - - if (!listmode) - { - rc = gpgsm_cert_use_cert_p (issuer_cert); - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage", - numbuf, NULL); - goto leave; - } - } - - /* Check for revocations etc. */ - if ((flags & 1)) - rc = 0; - else - rc = is_cert_still_valid (ctrl, lm, fp, - subject_cert, issuer_cert, - &any_revoked, &any_no_crl, &any_crl_too_old); - if (rc) - goto leave; - - - if (opt.verbose && !listmode) - log_info ("certificate is good\n"); - - keydb_search_reset (kh); - subject_cert = issuer_cert; - issuer_cert = NULL; - } - - if (!listmode) - { - if (opt.no_policy_check) - log_info ("policies not checked due to %s option\n", - "--disable-policy-checks"); - if (opt.no_crl_check && !ctrl->use_ocsp) - log_info ("CRLs not checked due to %s option\n", - "--disable-crl-checks"); - } - - if (!rc) - { /* If we encountered an error somewhere during the checks, set - the error code to the most critical one */ - if (any_revoked) - rc = gpg_error (GPG_ERR_CERT_REVOKED); - else if (any_no_crl) - rc = gpg_error (GPG_ERR_NO_CRL_KNOWN); - else if (any_crl_too_old) - rc = gpg_error (GPG_ERR_CRL_TOO_OLD); - else if (any_no_policy_match) - rc = gpg_error (GPG_ERR_NO_POLICY_MATCH); - else if (any_expired) - rc = gpg_error (GPG_ERR_CERT_EXPIRED); - } - - leave: - if (r_exptime) - gnupg_copy_time (r_exptime, exptime); - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - if (subject_cert != cert) - ksba_cert_release (subject_cert); - return rc; -} - - -/* Check that the given certificate is valid but DO NOT check any - constraints. We assume that the issuers certificate is already in - the DB and that this one is valid; which it should be because it - has been checked using this function. */ -int -gpgsm_basic_cert_check (ksba_cert_t cert) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - ksba_cert_t issuer_cert = NULL; - - if (opt.no_chain_validation) - { - log_info ("WARNING: bypassing basic certificate checks\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - - if (subject && !strcmp (issuer, subject)) - { - if (gpgsm_check_cert_sig (cert, cert) ) - { - log_error ("selfsigned certificate has a BAD signature\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - } - else - { - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, cert, issuer, 0); - if (rc) - { - if (rc == -1) - { - log_info ("issuer certificate (#/"); - gpgsm_dump_string (issuer); - log_printf (") not found\n"); - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_MISSING_CERT); - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (gpgsm_check_cert_sig (issuer_cert, cert) ) - { - log_error ("certificate has a BAD signature\n"); - rc = gpg_error (GPG_ERR_BAD_CERT); - goto leave; - } - if (opt.verbose) - log_info ("certificate is good\n"); - } - - leave: - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - return rc; -} - diff --git a/sm/certcheck.c b/sm/certcheck.c deleted file mode 100644 index b5ed9914a..000000000 --- a/sm/certcheck.c +++ /dev/null @@ -1,303 +0,0 @@ -/* certcheck.c - check one certificate - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static int -do_encode_md (gcry_md_hd_t md, int algo, unsigned int nbits, - gcry_mpi_t *r_val) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i, n; - byte asn[100]; - size_t asnlen; - size_t len; - - asnlen = DIM(asn); - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - log_error ("no object identifier for algo %d\n", algo); - return gpg_error (GPG_ERR_INTERNAL); - } - - len = gcry_md_get_algo_dlen (algo); - - if ( len + asnlen + 4 > nframe ) - { - log_error ("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); - return gpg_error (GPG_ERR_INTERNAL); - } - - /* We encode the MD in this way: - * - * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) - * - * PAD consists of FF bytes. - */ - frame = xtrymalloc (nframe); - if (!frame) - return OUT_OF_CORE (errno); - n = 0; - frame[n++] = 0; - frame[n++] = 1; /* block type */ - i = nframe - len - asnlen -3 ; - assert ( i > 1 ); - memset ( frame+n, 0xff, i ); n += i; - frame[n++] = 0; - memcpy ( frame+n, asn, asnlen ); n += asnlen; - memcpy ( frame+n, gcry_md_read(md, algo), len ); n += len; - assert ( n == nframe ); - if (DBG_X509) - { - int j; - log_debug ("encoded hash:"); - for (j=0; j < nframe; j++) - log_printf (" %02X", frame[j]); - log_printf ("\n"); - } - - gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, n, &nframe); - xfree (frame); - return 0; -} - - -/* - Check the signature on CERT using the ISSUER-CERT. This function - does only test the cryptographic signature and nothing else. It is - assumed that the ISSUER_CERT is valid. */ -int -gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) -{ - const char *algoid; - gcry_md_hd_t md; - int rc, algo; - gcry_mpi_t frame; - ksba_sexp_t p; - size_t n; - gcry_sexp_t s_sig, s_hash, s_pkey; - - algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - return gpg_error (GPG_ERR_GENERAL); - } - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - return rc; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "hash.cert"); - - rc = ksba_cert_hash (cert, 1, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - return rc; - } - gcry_md_final (md); - - p = ksba_cert_get_sig_val (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - return gpg_error (GPG_ERR_BUG); - } - if (DBG_X509) - { - int j; - log_debug ("signature value:"); - for (j=0; j < n; j++) - log_printf (" %02X", p[j]); - log_printf ("\n"); - } - - rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - return rc; - } - - p = ksba_cert_get_public_key (issuer_cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - gcry_sexp_release (s_sig); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - return rc; - } - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - -int -gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, - gcry_md_hd_t md, int algo) -{ - int rc; - ksba_sexp_t p; - gcry_mpi_t frame; - gcry_sexp_t s_sig, s_hash, s_pkey; - size_t n; - - n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return rc; - } - - p = ksba_cert_get_public_key (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - ksba_free (p); - gcry_sexp_release (s_sig); - return gpg_error (GPG_ERR_BUG); - } - if (DBG_X509) - log_printhex ("public key: ", p, n); - - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_sig); - return rc; - } - - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc)); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return rc; -} - - - -int -gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, - gcry_md_hd_t md, int mdalgo, char **r_sigval) -{ - int rc; - char *grip, *desc; - size_t siglen; - - grip = gpgsm_get_keygrip_hexstring (cert); - if (!grip) - return gpg_error (GPG_ERR_BAD_CERT); - - desc = gpgsm_format_keydesc (cert); - - rc = gpgsm_agent_pksign (ctrl, grip, desc, gcry_md_read(md, mdalgo), - gcry_md_get_algo_dlen (mdalgo), mdalgo, - r_sigval, &siglen); - xfree (desc); - xfree (grip); - return rc; -} - - - diff --git a/sm/certdump.c b/sm/certdump.c deleted file mode 100644 index 21581dca3..000000000 --- a/sm/certdump.c +++ /dev/null @@ -1,696 +0,0 @@ -/* certdump.c - Dump a certificate for debugging - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -struct dn_array_s { - char *key; - char *value; - int multivalued; - int done; -}; - - -/* print the first element of an S-Expression */ -void -gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - fputs (_("none"), fp); - else if (*p != '(') - fputs ("[Internal error - not an S-expression]", fp); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - fputs ("[Internal Error - invalid S-expression]", fp); - else - { - for (p++; n; n--, p++) - fprintf (fp, "%02X", *p); - } - } -} - - -void -gpgsm_dump_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - log_printf ("none"); - else if (*p != '(') - log_printf ("ERROR - not an S-expression"); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - log_printf ("ERROR - invalid S-expression"); - else - { - for (p++; n; n--, p++) - log_printf ("%02X", *p); - } - } -} - - -char * -gpgsm_format_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - char *buffer; - int i; - - if (!p) - return NULL; - - if (*p != '(') - BUG (); /* Not a valid S-expression. */ - - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - BUG (); /* Not a valid S-expression. */ - p++; - - buffer = xtrymalloc (n*2+1); - if (buffer) - { - for (i=0; n; n--, p++, i+=2) - sprintf (buffer+i, "%02X", *(unsigned char *)p); - buffer[i] = 0; - } - return buffer; -} - - - - -void -gpgsm_print_time (FILE *fp, ksba_isotime_t t) -{ - if (!t || !*t) - fputs (_("none"), fp); - else - fprintf (fp, "%.4s-%.2s-%.2s %.2s:%.2s:%s", t, t+4, t+6, t+9, t+11, t+13); -} - -void -gpgsm_dump_time (ksba_isotime_t t) -{ - if (!t || !*t) - log_printf (_("[none]")); - else - log_printf ("%.4s-%.2s-%.2s %.2s:%.2s:%s", - t, t+4, t+6, t+9, t+11, t+13); -} - - - - -void -gpgsm_dump_string (const char *string) -{ - - if (!string) - log_printf ("[error]"); - else - { - const unsigned char *s; - - for (s=string; *s; s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } - if (!*s && *string != '[') - log_printf ("%s", string); - else - { - log_printf ( "[ "); - log_printhex (NULL, string, strlen (string)); - log_printf ( " ]"); - } - } -} - - -/* This simple dump function is mainly used for debugging purposes. */ -void -gpgsm_dump_cert (const char *text, ksba_cert_t cert) -{ - ksba_sexp_t sexp; - unsigned char *p; - char *dn; - ksba_isotime_t t; - - log_debug ("BEGIN Certificate `%s':\n", text? text:""); - if (cert) - { - sexp = ksba_cert_get_serial (cert); - log_debug (" serial: "); - gpgsm_dump_serial (sexp); - ksba_free (sexp); - log_printf ("\n"); - - ksba_cert_get_validity (cert, 0, t); - log_debug (" notBefore: "); - gpgsm_dump_time (t); - log_printf ("\n"); - ksba_cert_get_validity (cert, 1, t); - log_debug (" notAfter: "); - gpgsm_dump_time (t); - log_printf ("\n"); - - dn = ksba_cert_get_issuer (cert, 0); - log_debug (" issuer: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - dn = ksba_cert_get_subject (cert, 0); - log_debug (" subject: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); - - p = gpgsm_get_fingerprint_string (cert, 0); - log_debug (" SHA1 Fingerprint: %s\n", p); - xfree (p); - } - log_debug ("END Certificate\n"); -} - - - -/* helper for the rfc2253 string parser */ -static const unsigned char * -parse_dn_part (struct dn_array_s *array, const unsigned char *string) -{ - static struct { - const char *label; - const char *oid; - } label_map[] = { - /* Warning: When adding new labels, make sure that the buffer - below we be allocated large enough. */ - {"EMail", "1.2.840.113549.1.9.1" }, - {"T", "2.5.4.12" }, - {"GN", "2.5.4.42" }, - {"SN", "2.5.4.4" }, - {"NameDistinguisher", "0.2.262.1.10.7.20"}, - {"ADDR", "2.5.4.16" }, - {"BC", "2.5.4.15" }, - {"D", "2.5.4.13" }, - {"PostalCode", "2.5.4.17" }, - {"Pseudo", "2.5.4.65" }, - {"SerialNumber", "2.5.4.5" }, - {NULL, NULL} - }; - const unsigned char *s, *s1; - size_t n; - unsigned char *p; - int i; - - /* Parse attributeType */ - for (s = string+1; *s && *s != '='; s++) - ; - if (!*s) - return NULL; /* error */ - n = s - string; - if (!n) - return NULL; /* empty key */ - - /* We need to allocate a few bytes more due to the possible mapping - from the shorter OID to the longer label. */ - array->key = p = xtrymalloc (n+10); - if (!array->key) - return NULL; - memcpy (p, string, n); - p[n] = 0; - trim_trailing_spaces (p); - - if (digitp (p)) - { - for (i=0; label_map[i].label; i++ ) - if ( !strcmp (p, label_map[i].oid) ) - { - strcpy (p, label_map[i].label); - break; - } - } - string = s + 1; - - if (*string == '#') - { /* hexstring */ - string++; - for (s=string; hexdigitp (s); s++) - s++; - n = s - string; - if (!n || (n & 1)) - return NULL; /* Empty or odd number of digits. */ - n /= 2; - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s1=string; n; s1 += 2, n--, p++) - { - *p = xtoi_2 (s1); - if (!*p) - *p = 0x01; /* Better print a wrong value than truncating - the string. */ - } - *p = 0; - } - else - { /* regular v3 quoted string */ - for (n=0, s=string; *s; s++) - { - if (*s == '\\') - { /* pair */ - s++; - if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' - || *s == '\\' || *s == '\"' || *s == ' ') - n++; - else if (hexdigitp (s) && hexdigitp (s+1)) - { - s++; - n++; - } - else - return NULL; /* invalid escape sequence */ - } - else if (*s == '\"') - return NULL; /* invalid encoding */ - else if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) - break; - else - n++; - } - - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s=string; n; s++, n--) - { - if (*s == '\\') - { - s++; - if (hexdigitp (s)) - { - *p++ = xtoi_2 (s); - s++; - } - else - *p++ = *s; - } - else - *p++ = *s; - } - *p = 0; - } - return s; -} - - -/* Parse a DN and return an array-ized one. This is not a validating - parser and it does not support any old-stylish syntax; KSBA is - expected to return only rfc2253 compatible strings. */ -static struct dn_array_s * -parse_dn (const unsigned char *string) -{ - struct dn_array_s *array; - size_t arrayidx, arraysize; - int i; - - arraysize = 7; /* C,ST,L,O,OU,CN,email */ - arrayidx = 0; - array = xtrymalloc ((arraysize+1) * sizeof *array); - if (!array) - return NULL; - while (*string) - { - while (*string == ' ') - string++; - if (!*string) - break; /* ready */ - if (arrayidx >= arraysize) - { - struct dn_array_s *a2; - - arraysize += 5; - a2 = xtryrealloc (array, (arraysize+1) * sizeof *array); - if (!a2) - goto failure; - array = a2; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - string = parse_dn_part (array+arrayidx, string); - if (!string) - goto failure; - while (*string == ' ') - string++; - array[arrayidx].multivalued = (*string == '+'); - array[arrayidx].done = 0; - arrayidx++; - if (*string && *string != ',' && *string != ';' && *string != '+') - goto failure; /* invalid delimiter */ - if (*string) - string++; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - return array; - - failure: - for (i=0; i < arrayidx; i++) - { - xfree (array[i].key); - xfree (array[i].value); - } - xfree (array); - return NULL; -} - - -static void -print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key) -{ - struct dn_array_s *first_dn = dn; - - for (; dn->key; dn++) - { - if (!dn->done && !strcmp (dn->key, key)) - { - /* Forward to the last multi-valued RDN, so that we can - print them all in reverse in the correct order. Note - that this overrides the the standard sequence but that - seems to a reasonable thing to do with multi-valued - RDNs. */ - while (dn->multivalued && dn[1].key) - dn++; - next: - if (!dn->done && dn->value && *dn->value) - { - fprintf (fp, "/%s=", dn->key); - print_sanitized_utf8_string (fp, dn->value, '/'); - } - dn->done = 1; - if (dn > first_dn && dn[-1].multivalued) - { - dn--; - goto next; - } - } - } -} - -/* Print all parts of a DN in a "standard" sequence. We first print - all the known parts, followed by the uncommon ones */ -static void -print_dn_parts (FILE *fp, struct dn_array_s *dn) -{ - const char *stdpart[] = { - "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL - }; - int i; - - for (i=0; stdpart[i]; i++) - print_dn_part (fp, dn, stdpart[i]); - - /* Now print the rest without any specific ordering */ - for (; dn->key; dn++) - print_dn_part (fp, dn, dn->key); -} - - - -void -gpgsm_print_name (FILE *fp, const char *name) -{ - const unsigned char *s; - int i; - - s = name; - if (!s) - { - fputs (_("[Error - No name]"), fp); - } - else if (*s == '<') - { - const unsigned char *s2 = strchr (s+1, '>'); - if (s2) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); - } - else if (*s == '(') - fputs (_("[Error - unknown encoding]"), fp); - else if (!((*s >= '0' && *s < '9') - || (*s >= 'A' && *s <= 'Z') - || (*s >= 'a' && *s <= 'z'))) - fputs (_("[Error - invalid encoding]"), fp); - else - { - struct dn_array_s *dn = parse_dn (s); - if (!dn) - fputs (_("[Error - invalid DN]"), fp); - else - { - print_dn_parts (fp, dn); - for (i=0; dn[i].key; i++) - { - xfree (dn[i].key); - xfree (dn[i].value); - } - xfree (dn); - } - } -} - - - -/* A cookie structure used for the memory stream. */ -struct format_name_cookie -{ - char *buffer; /* Malloced buffer with the data to deliver. */ - size_t size; /* Allocated size of this buffer. */ - size_t len; /* strlen (buffer). */ - int error; /* system error code if any. */ -}; - -/* The writer function for the memory stream. */ -static int -format_name_writer (void *cookie, const char *buffer, size_t size) -{ - struct format_name_cookie *c = cookie; - char *p; - - if (c->buffer) - p = xtryrealloc (c->buffer, c->size + size + 1); - else - p = xtrymalloc (size + 1); - if (!p) - { - c->error = errno; - xfree (c->buffer); - errno = c->error; - return -1; - } - c->buffer = p; - memcpy (p + c->len, buffer, size); - c->len += size; - p[c->len] = 0; /* Terminate string. */ - - return size; -} - -/* Format NAME which is expected to be in rfc2253 format into a better - human readable format. Caller must free the returned string. NULL - is returned in case of an error. */ -char * -gpgsm_format_name (const char *name) -{ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) - FILE *fp; - struct format_name_cookie cookie; - - memset (&cookie, 0, sizeof cookie); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = format_name_writer; - - fp = fopencookie (&cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (&cookie, NULL, format_name_writer, NULL, NULL); - } -#endif /*!HAVE_FOPENCOOKIE*/ - if (!fp) - { - int save_errno = errno; - log_error ("error creating memory stream: %s\n", strerror (errno)); - errno = save_errno; - return NULL; - } - gpgsm_print_name (fp, name); - fclose (fp); - if (cookie.error || !cookie.buffer) - { - xfree (cookie.buffer); - errno = cookie.error; - return NULL; - } - return cookie.buffer; -#else /* No fun - use the name verbatim. */ - return xtrystrdup (name); -#endif /* No fun. */ -} - - -/* Create a key description for the CERT, this may be passed to the - pinentry. The caller must free the returned string. NULL may be - returned on error. */ -char * -gpgsm_format_keydesc (ksba_cert_t cert) -{ - int rc; - char *name, *subject, *buffer, *p; - const char *s; - ksba_isotime_t t; - char created[20]; - char *sn; - ksba_sexp_t sexp; - char *orig_codeset = NULL; - - name = ksba_cert_get_subject (cert, 0); - subject = name? gpgsm_format_name (name) : NULL; - ksba_free (name); name = NULL; - - sexp = ksba_cert_get_serial (cert); - sn = sexp? gpgsm_format_serial (sexp) : NULL; - ksba_free (sexp); - - ksba_cert_get_validity (cert, 0, t); - if (t && *t) - sprintf (created, "%.4s-%.2s-%.2s", t, t+4, t+6); - else - *created = 0; - - -#ifdef ENABLE_NLS - /* The Assuan agent protol requires us to transmit utf-8 strings */ - orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); -#ifdef HAVE_LANGINFO_CODESET - if (!orig_codeset) - orig_codeset = nl_langinfo (CODESET); -#endif - if (orig_codeset) - { /* We only switch when we are able to restore the codeset later. */ - orig_codeset = xstrdup (orig_codeset); - if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) - orig_codeset = NULL; - } -#endif - - - rc = asprintf (&name, - _("Please enter the passphrase to unlock the" - " secret key for:\n" - "\"%s\"\n" - "S/N %s, ID %08lX, created %s" ), - subject? subject:"?", - sn? sn: "?", - gpgsm_get_short_fingerprint (cert), - created); - -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - - if (rc < 0) - { - int save_errno = errno; - xfree (subject); - xfree (sn); - errno = save_errno; - return NULL; - } - - xfree (subject); - xfree (sn); - - buffer = p = xtrymalloc (strlen (name) * 3 + 1); - for (s=name; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *(unsigned char *)s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p = 0; - free (name); - - return buffer; -} diff --git a/sm/certlist.c b/sm/certlist.c deleted file mode 100644 index 96acf90f7..000000000 --- a/sm/certlist.c +++ /dev/null @@ -1,427 +0,0 @@ -/* certlist.c - build list of certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static const char oid_kp_serverAuth[] = "1.3.6.1.5.5.7.3.1"; -static const char oid_kp_clientAuth[] = "1.3.6.1.5.5.7.3.2"; -static const char oid_kp_codeSigning[] = "1.3.6.1.5.5.7.3.3"; -static const char oid_kp_emailProtection[]= "1.3.6.1.5.5.7.3.4"; -static const char oid_kp_timeStamping[] = "1.3.6.1.5.5.7.3.8"; -static const char oid_kp_ocspSigning[] = "1.3.6.1.5.6.7.3.9"; - -/* Return 0 if the cert is usable for encryption. A MODE of 0 checks - for signing a MODE of 1 checks for encryption, a MODE of 2 checks - for verification and a MODE of 3 for decryption (just for - debugging) */ -static int -cert_usage_p (ksba_cert_t cert, int mode) -{ - gpg_error_t err; - unsigned int use; - char *extkeyusages; - - err = ksba_cert_get_ext_key_usages (cert, &extkeyusages); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - err = 0; /* no policy given */ - if (!err) - { - unsigned int extusemask = ~0; /* Allow all. */ - - if (extkeyusages) - { - char *p, *pend; - int any_critical = 0; - - extusemask = 0; - - p = extkeyusages; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - /* Only care about critical flagged usages. */ - if ( *pend == 'C' ) - { - any_critical = 1; - if ( !strcmp (p, oid_kp_serverAuth)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_KEY_ENCIPHERMENT - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_clientAuth)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_codeSigning)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE); - else if ( !strcmp (p, oid_kp_emailProtection)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_NON_REPUDIATION - | KSBA_KEYUSAGE_KEY_ENCIPHERMENT - | KSBA_KEYUSAGE_KEY_AGREEMENT); - else if ( !strcmp (p, oid_kp_timeStamping)) - extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE - | KSBA_KEYUSAGE_NON_REPUDIATION); - } - - if ((p = strchr (pend, '\n'))) - p++; - } - xfree (extkeyusages); - extkeyusages = NULL; - - if (!any_critical) - extusemask = ~0; /* Reset to the don't care mask. */ - } - - - err = ksba_cert_get_key_usage (cert, &use); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - { - err = 0; - if (opt.verbose && mode < 2) - log_info (_("no key usage specified - assuming all usages\n")); - use = ~0; - } - - /* Apply extKeyUsage. */ - use &= extusemask; - - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - gpg_strerror (err)); - xfree (extkeyusages); - return err; - } - - if (mode == 4) - { - if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN))) - return 0; - log_info (_("certificate should have not " - "been used for certification\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); - } - - if ((use & ((mode&1)? - (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT): - (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - ) - return 0; - - log_info (mode==3? _("certificate should have not been used for encryption\n"): - mode==2? _("certificate should have not been used for signing\n"): - mode==1? _("certificate is not usable for encryption\n"): - _("certificate is not usable for signing\n")); - return gpg_error (GPG_ERR_WRONG_KEY_USAGE); -} - - -/* Return 0 if the cert is usable for signing */ -int -gpgsm_cert_use_sign_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 0); -} - - -/* Return 0 if the cert is usable for encryption */ -int -gpgsm_cert_use_encrypt_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 1); -} - -int -gpgsm_cert_use_verify_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 2); -} - -int -gpgsm_cert_use_decrypt_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 3); -} - -int -gpgsm_cert_use_cert_p (ksba_cert_t cert) -{ - return cert_usage_p (cert, 4); -} - - -static int -same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert) -{ - char *subject2 = ksba_cert_get_subject (cert, 0); - char *issuer2 = ksba_cert_get_subject (cert, 0); - int tmp; - - tmp = (subject && subject2 - && !strcmp (subject, subject2) - && issuer && issuer2 - && !strcmp (issuer, issuer2)); - xfree (subject2); - xfree (issuer2); - return tmp; -} - -/* Return true if CERT is already contained in CERTLIST. */ -static int -is_cert_in_certlist (ksba_cert_t cert, certlist_t certlist) -{ - const unsigned char *img_a, *img_b; - size_t len_a, len_b; - - img_a = ksba_cert_get_image (cert, &len_a); - if (img_a) - { - for ( ; certlist; certlist = certlist->next) - { - img_b = ksba_cert_get_image (certlist->cert, &len_b); - if (img_b && len_a == len_b && !memcmp (img_a, img_b, len_a)) - return 1; /* Already contained. */ - } - } - return 0; -} - - -/* Add CERT to the list of certificates at CERTADDR but avoid - duplicates. */ -int -gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, - certlist_t *listaddr, int is_encrypt_to) -{ - if (!is_cert_in_certlist (cert, *listaddr)) - { - certlist_t cl = xtrycalloc (1, sizeof *cl); - if (!cl) - return OUT_OF_CORE (errno); - cl->cert = cert; - ksba_cert_ref (cert); - cl->next = *listaddr; - cl->is_encrypt_to = is_encrypt_to; - *listaddr = cl; - } - return 0; -} - -/* Add a certificate to a list of certificate and make sure that it is - a valid certificate. With SECRET set to true a secret key must be - available for the certificate. IS_ENCRYPT_TO sets the corresponding - flag in the new create LISTADDR item. */ -int -gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, - CERTLIST *listaddr, int is_encrypt_to) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - ksba_cert_t cert = NULL; - - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - else - { - int wrong_usage = 0; - char *subject = NULL; - char *issuer = NULL; - - get_next: - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - rc = secret? gpgsm_cert_use_sign_p (cert) - : gpgsm_cert_use_encrypt_p (cert); - if (gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE) - { - /* There might be another certificate with the - correct usage, so we try again */ - if (!wrong_usage) - { /* save the first match */ - wrong_usage = rc; - subject = ksba_cert_get_subject (cert, 0); - issuer = ksba_cert_get_subject (cert, 0); - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else if (same_subject_issuer (subject, issuer, cert)) - { - wrong_usage = rc; - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else - wrong_usage = rc; - - } - } - /* We want the error code from the first match in this case. */ - if (rc && wrong_usage) - rc = wrong_usage; - - if (!rc) - { - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - ksba_cert_t cert2 = NULL; - - /* We have to ignore ambigious names as long as - there only fault is a bad key usage */ - if (!keydb_get_cert (kh, &cert2)) - { - int tmp = (same_subject_issuer (subject, issuer, cert2) - && ((gpg_err_code ( - secret? gpgsm_cert_use_sign_p (cert2) - : gpgsm_cert_use_encrypt_p (cert2) - ) - ) == GPG_ERR_WRONG_KEY_USAGE)); - ksba_cert_release (cert2); - if (tmp) - goto next_ambigious; - } - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - } - } - xfree (subject); - xfree (issuer); - - if (!rc && !is_cert_in_certlist (cert, *listaddr)) - { - if (!rc && secret) - { - char *p; - - rc = gpg_error (GPG_ERR_NO_SECKEY); - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (ctrl, p)) - rc = 0; - xfree (p); - } - } - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0); - if (!rc) - { - CERTLIST cl = xtrycalloc (1, sizeof *cl); - if (!cl) - rc = OUT_OF_CORE (errno); - else - { - cl->cert = cert; cert = NULL; - cl->next = *listaddr; - cl->is_encrypt_to = is_encrypt_to; - *listaddr = cl; - } - } - } - } - } - - keydb_release (kh); - ksba_cert_release (cert); - return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc; -} - -void -gpgsm_release_certlist (CERTLIST list) -{ - while (list) - { - CERTLIST cl = list->next; - ksba_cert_release (list->cert); - xfree (list); - list = cl; - } -} - - -/* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done */ -int -gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - - *r_cert = NULL; - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = gpg_error (GPG_ERR_ENOMEM); - else - { - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, r_cert); - if (!rc) - { - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else - { - if (!rc) - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - ksba_cert_release (*r_cert); - *r_cert = NULL; - } - } - } - } - - keydb_release (kh); - return rc == -1? gpg_error (GPG_ERR_NO_PUBKEY): rc; -} - diff --git a/sm/certreqgen.c b/sm/certreqgen.c deleted file mode 100644 index 969ed14b0..000000000 --- a/sm/certreqgen.c +++ /dev/null @@ -1,739 +0,0 @@ -/* certreqgen.c - Generate a key and a certification request - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* -The format of the native parameter file is follows: - o Text only, line length is limited to about 1000 chars. - o You must use UTF-8 encoding to specify non-ascii characters. - o Empty lines are ignored. - o Leading and trailing spaces are ignored. - o A hash sign as the first non white space character is a comment line. - o Control statements are indicated by a leading percent sign, the - arguments are separated by white space from the keyword. - o Parameters are specified by a keyword, followed by a colon. Arguments - are separated by white space. - o The first parameter must be "Key-Type", control statements - may be placed anywhere. - o Key generation takes place when either the end of the parameter file - is reached, the next "Key-Type" parameter is encountered or at the - controlstatement "%commit" - o Control statements: - %echo <text> - Print <text>. - %dry-run - Suppress actual key generation (useful for syntax checking). - %commit - Perform the key generation. Note that an implicit commit is done - at the next "Key-Type" parameter. - %certfile <filename> - Do not write the certificate to the keyDB but to <filename>. - This must be given before the first - commit to take place, duplicate specification of the same filename - is ignored, the last filename before a commit is used. - The filename is used until a new filename is used (at commit points) - and all keys are written to that file. If a new filename is given, - this file is created (and overwrites an existing one). - Both control statements must be given. - o The order of the parameters does not matter except for "Key-Type" - which must be the first parameter. The parameters are only for the - generated keyblock and parameters from previous key generations are not - used. Some syntactically checks may be performed. - The currently defined parameters are: - Key-Type: <algo> - Starts a new parameter block by giving the type of the - primary key. The algorithm must be capable of signing. - This is a required parameter. For now the only supported - algorithm is "rsa". - Key-Length: <length-in-bits> - Length of the key in bits. Default is 1024. - Key-Usage: <usage-list> - Space or comma delimited list of key usage, allowed values are - "encrypt" and "sign". This is used to generate the KeyUsage extension. - Please make sure that the algorithm is capable of this usage. Default - is to allow encrypt and sign. - Name-DN: subject name - This is the DN name of the subject in rfc2253 format. - Name-Email: <string> - The ist the email address - -Here is an example: -$ cat >foo <<EOF -%echo Generating a standard key -Key-Type: RSA -Key-Length: 1024 -Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE -Name-Email: joe@foo.bar -# Do a commit here, so that we can later print "done" :-) -%commit -%echo done -EOF -*/ - - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -enum para_name { - pKEYTYPE, - pKEYLENGTH, - pKEYUSAGE, - pNAMEDN, - pNAMEEMAIL -}; - -struct para_data_s { - struct para_data_s *next; - int lnr; - enum para_name key; - union { - unsigned int usage; - char value[1]; - } u; -}; - -struct reqgen_ctrl_s { - int lnr; - int dryrun; - ksba_writer_t writer; -}; - - -static const char oidstr_keyUsage[] = "2.5.29.15"; - - -static int proc_parameters (ctrl_t ctrl, - struct para_data_s *para, - struct reqgen_ctrl_s *outctrl); -static int create_request (ctrl_t ctrl, - struct para_data_s *para, - ksba_const_sexp_t public, - struct reqgen_ctrl_s *outctrl); - - - -static void -release_parameter_list (struct para_data_s *r) -{ - struct para_data_s *r2; - - for (; r ; r = r2) - { - r2 = r->next; - xfree(r); - } -} - -static struct para_data_s * -get_parameter (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r; - - for (r = para; r && r->key != key; r = r->next) - ; - return r; -} - -static const char * -get_parameter_value (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - return (r && *r->u.value)? r->u.value : NULL; -} - -static int -get_parameter_algo (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - if (!r) - return -1; - if (digitp (r->u.value)) - return atoi( r->u.value ); - return gcry_pk_map_name (r->u.value); -} - -/* Parse the usage parameter. Returns 0 on success. Note that we - only care about sign and encrypt and don't (yet) allow all the - other X.509 usage to be specified; instead we will use a fixed - mapping to the X.509 usage flags. */ -static int -parse_parameter_usage (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - char *p, *pn; - unsigned int use; - - if (!r) - return 0; /* none (this is an optional parameter)*/ - - use = 0; - pn = r->u.value; - while ( (p = strsep (&pn, " \t,")) ) - { - if (!*p) - ; - else if ( !ascii_strcasecmp (p, "sign") ) - use |= GCRY_PK_USAGE_SIGN; - else if ( !ascii_strcasecmp (p, "encrypt") ) - use |= GCRY_PK_USAGE_ENCR; - else - { - log_error ("line %d: invalid usage list\n", r->lnr); - return -1; /* error */ - } - } - r->u.usage = use; - return 0; -} - - -static unsigned int -get_parameter_uint (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - - if (!r) - return 0; - - if (r->key == pKEYUSAGE) - return r->u.usage; - - return (unsigned int)strtoul (r->u.value, NULL, 10); -} - - - -/* Read the certificate generation parameters from FP and generate - (all) certificate requests. */ -static int -read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer) -{ - static struct { - const char *name; - enum para_name key; - } keywords[] = { - { "Key-Type", pKEYTYPE}, - { "Key-Length", pKEYLENGTH }, - { "Key-Usage", pKEYUSAGE }, - { "Name-DN", pNAMEDN }, - { "Name-Email", pNAMEEMAIL }, - { NULL, 0 } - }; - char line[1024], *p; - const char *err = NULL; - struct para_data_s *para, *r; - int i, rc = 0, any = 0; - struct reqgen_ctrl_s outctrl; - - memset (&outctrl, 0, sizeof (outctrl)); - outctrl.writer = writer; - - err = NULL; - para = NULL; - while (fgets (line, DIM(line)-1, fp) ) - { - char *keyword, *value; - - outctrl.lnr++; - if (*line && line[strlen(line)-1] != '\n') - { - err = "line too long"; - break; - } - for (p=line; spacep (p); p++) - ; - if (!*p || *p == '#') - continue; - - keyword = p; - if (*keyword == '%') - { - for (; *p && !spacep (p); p++) - ; - if (*p) - *p++ = 0; - for (; spacep (p); p++) - ; - value = p; - trim_trailing_spaces (value); - - if (!ascii_strcasecmp (keyword, "%echo")) - log_info ("%s\n", value); - else if (!ascii_strcasecmp (keyword, "%dry-run")) - outctrl.dryrun = 1; - else if (!ascii_strcasecmp( keyword, "%commit")) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - else - log_info ("skipping control `%s' (%s)\n", keyword, value); - - continue; - } - - - if (!(p = strchr (p, ':')) || p == keyword) - { - err = "missing colon"; - break; - } - if (*p) - *p++ = 0; - for (; spacep (p); p++) - ; - if (!*p) - { - err = "missing argument"; - break; - } - value = p; - trim_trailing_spaces (value); - - for (i=0; (keywords[i].name - && ascii_strcasecmp (keywords[i].name, keyword)); i++) - ; - if (!keywords[i].name) - { - err = "unknown keyword"; - break; - } - if (keywords[i].key != pKEYTYPE && !para) - { - err = "parameter block does not start with \"Key-Type\""; - break; - } - - if (keywords[i].key == pKEYTYPE && para) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - else - { - for (r = para; r && r->key != keywords[i].key; r = r->next) - ; - if (r) - { - err = "duplicate keyword"; - break; - } - } - - r = xtrycalloc (1, sizeof *r + strlen( value )); - if (!r) - { - err = "out of core"; - break; - } - r->lnr = outctrl.lnr; - r->key = keywords[i].key; - strcpy (r->u.value, value); - r->next = para; - para = r; - } - - if (err) - { - log_error ("line %d: %s\n", outctrl.lnr, err); - rc = gpg_error (GPG_ERR_GENERAL); - } - else if (ferror(fp)) - { - log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) ); - rc = gpg_error (GPG_ERR_GENERAL); - } - else if (para) - { - rc = proc_parameters (ctrl, para, &outctrl); - if (rc) - goto leave; - any = 1; - } - - if (!rc && !any) - rc = gpg_error (GPG_ERR_NO_DATA); - - leave: - release_parameter_list (para); - return rc; -} - -/* check whether there are invalid characters in the email address S */ -static int -has_invalid_email_chars (const char *s) -{ - int at_seen=0; - static char valid_chars[] = "01234567890_-." - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for (; *s; s++) - { - if (*s & 0x80) - return 1; - if (*s == '@') - at_seen++; - else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+')) - return 1; - else if (at_seen && !strchr (valid_chars, *s)) - return 1; - } - return at_seen != 1; -} - - -/* Check that all required parameters are given and perform the action */ -static int -proc_parameters (ctrl_t ctrl, - struct para_data_s *para, struct reqgen_ctrl_s *outctrl) -{ - struct para_data_s *r; - const char *s; - int i; - unsigned int nbits; - char numbuf[20]; - unsigned char keyparms[100]; - int rc; - ksba_sexp_t public; - - /* check that we have all required parameters */ - assert (get_parameter (para, pKEYTYPE)); - - /* We can only use RSA for now. There is a with pkcs-10 on how to - use ElGamal because it is expected that a PK algorithm can always - be used for signing. */ - i = get_parameter_algo (para, pKEYTYPE); - if (i < 1 || i != GCRY_PK_RSA ) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid algorithm\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - - /* check the keylength */ - if (!get_parameter (para, pKEYLENGTH)) - nbits = 1024; - else - nbits = get_parameter_uint (para, pKEYLENGTH); - if (nbits < 512 || nbits > 4096) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid key length %u (valid are 512 to 4096)\n", - r->lnr, nbits); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - - /* check the usage */ - if (parse_parameter_usage (para, pKEYUSAGE)) - return gpg_error (GPG_ERR_INV_PARAMETER); - - /* check that there is a subject name and that this DN fits our - requirements */ - if (!(s=get_parameter_value (para, pNAMEDN))) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: no subject name given\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - /* fixme check s */ - - /* check that the optional email address is okay */ - if ((s=get_parameter_value (para, pNAMEEMAIL))) - { - if (has_invalid_email_chars (s) - || *s == '@' - || s[strlen(s)-1] == '@' - || s[strlen(s)-1] == '.' - || strstr(s, "..")) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: not a valid email address\n", r->lnr); - return gpg_error (GPG_ERR_INV_PARAMETER); - } - } - - sprintf (numbuf, "%u", nbits); - snprintf (keyparms, DIM (keyparms)-1, - "(6:genkey(3:rsa(5:nbits%d:%s)))", strlen (numbuf), numbuf); - rc = gpgsm_agent_genkey (ctrl, keyparms, &public); - if (rc) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: key generation failed: %s\n", - r->lnr, gpg_strerror (rc)); - return rc; - } - - rc = create_request (ctrl, para, public, outctrl); - xfree (public); - - return rc; -} - - -/* Parameters are checked, the key pair has been created. Now - generate the request and write it out */ -static int -create_request (ctrl_t ctrl, - struct para_data_s *para, ksba_const_sexp_t public, - struct reqgen_ctrl_s *outctrl) -{ - ksba_certreq_t cr; - gpg_error_t err; - gcry_md_hd_t md; - ksba_stop_reason_t stopreason; - int rc = 0; - const char *s; - unsigned int use; - - err = ksba_certreq_new (&cr); - if (err) - return err; - - rc = gcry_md_open (&md, GCRY_MD_SHA1, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "cr.cri"); - - ksba_certreq_set_hash_function (cr, HASH_FNC, md); - ksba_certreq_set_writer (cr, outctrl->writer); - - err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN)); - if (err) - { - log_error ("error setting the subject's name: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - s = get_parameter_value (para, pNAMEEMAIL); - if (s) - { - char *buf; - - buf = xtrymalloc (strlen (s) + 3); - if (!buf) - { - rc = OUT_OF_CORE (errno); - goto leave; - } - *buf = '<'; - strcpy (buf+1, s); - strcat (buf+1, ">"); - err = ksba_certreq_add_subject (cr, buf); - xfree (buf); - if (err) - { - log_error ("error setting the subject's alternate name: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - - err = ksba_certreq_set_public_key (cr, public); - if (err) - { - log_error ("error setting the public key: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - - use = get_parameter_uint (para, pKEYUSAGE); - if (use == GCRY_PK_USAGE_SIGN) - { - /* For signing only we encode the bits: - KSBA_KEYUSAGE_DIGITAL_SIGNATURE - KSBA_KEYUSAGE_NON_REPUDIATION */ - err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, - "\x03\x02\x06\xC0", 4); - } - else if (use == GCRY_PK_USAGE_ENCR) - { - /* For encrypt only we encode the bits: - KSBA_KEYUSAGE_KEY_ENCIPHERMENT - KSBA_KEYUSAGE_DATA_ENCIPHERMENT */ - err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, - "\x03\x02\x04\x30", 4); - } - else - err = 0; /* Both or none given: don't request one. */ - if (err) - { - log_error ("error setting the key usage: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - - do - { - err = ksba_certreq_build (cr, &stopreason); - if (err) - { - log_error ("ksba_certreq_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - if (stopreason == KSBA_SR_NEED_SIG) - { - gcry_sexp_t s_pkey; - size_t n; - unsigned char grip[20], hexgrip[41]; - char *sigval; - size_t siglen; - - n = gcry_sexp_canon_len (public, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - err = gpg_error (GPG_ERR_BUG); - goto leave; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if ( !gcry_pk_get_keygrip (s_pkey, grip) ) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("can't figure out the keygrip\n"); - gcry_sexp_release (s_pkey); - goto leave; - } - gcry_sexp_release (s_pkey); - for (n=0; n < 20; n++) - sprintf (hexgrip+n*2, "%02X", grip[n]); - - rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, - &sigval, &siglen); - if (rc) - { - log_error ("signing failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_certreq_set_sig_val (cr, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the sig_val: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - while (stopreason != KSBA_SR_READY); - - - leave: - gcry_md_close (md); - ksba_certreq_release (cr); - return rc; -} - - - -/* Create a new key by reading the parameters from in_fd. Multiple - keys may be created */ -int -gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp) -{ - int rc; - FILE *in_fp; - Base64Context b64writer = NULL; - ksba_writer_t writer; - - in_fp = fdopen (dup (in_fd), "rb"); - if (!in_fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - return tmperr; - } - - ctrl->pem_name = "NEW CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = read_parameters (ctrl, in_fp, writer); - if (rc) - { - log_error ("error creating certificate request: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - gpgsm_status (ctrl, STATUS_KEY_CREATED, "P"); - log_info ("certificate request created\n"); - - leave: - gpgsm_destroy_writer (b64writer); - fclose (in_fp); - return rc; -} - diff --git a/sm/decrypt.c b/sm/decrypt.c deleted file mode 100644 index 8ac2e23fe..000000000 --- a/sm/decrypt.c +++ /dev/null @@ -1,512 +0,0 @@ -/* decrypt.c - Decrypt a message - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -struct decrypt_filter_parm_s { - int algo; - int mode; - int blklen; - gcry_cipher_hd_t hd; - char iv[16]; - size_t ivlen; - int any_data; /* dod we push anything through the filter at all? */ - unsigned char lastblock[16]; /* to strip the padding we have to - keep this one */ - char helpblock[16]; /* needed because there is no block buffering in - libgcrypt (yet) */ - int helpblocklen; -}; - - - -/* Decrypt the session key and fill in the parm structure. The - algo and the IV is expected to be already in PARM. */ -static int -prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc, - ksba_const_sexp_t enc_val, - struct decrypt_filter_parm_s *parm) -{ - char *seskey = NULL; - size_t n, seskeylen; - int rc; - - rc = gpgsm_agent_pkdecrypt (ctrl, hexkeygrip, desc, enc_val, - &seskey, &seskeylen); - if (rc) - { - log_error ("error decrypting session key: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (DBG_CRYPTO) - log_printhex ("pkcs1 encoded session key:", seskey, seskeylen); - - n=0; - if (seskeylen == 24) - { - /* Smells like a 3-des key. This might happen because a SC has - already done the unpacking. */ - } - else - { - if (n + 7 > seskeylen ) - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - - /* FIXME: Actually the leading zero is required but due to the way - we encode the output in libgcrypt as an MPI we are not able to - encode that leading zero. However, when using a Smartcard we are - doing it the right way and therefore we have to skip the zero. This - should be fixed in gpg-agent of course. */ - if (!seskey[n]) - n++; - - if (seskey[n] != 2 ) /* Wrong block type version. */ - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - - for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */ - ; - n++; /* and the zero byte */ - if (n >= seskeylen ) - { - rc = gpg_error (GPG_ERR_INV_SESSION_KEY); - goto leave; - } - } - - if (DBG_CRYPTO) - log_printhex ("session key:", seskey+n, seskeylen-n); - - rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0); - if (rc) - { - log_error ("error creating decryptor: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n); - if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY) - { - log_info (_("WARNING: message was encrypted with " - "a weak key in the symmetric cipher.\n")); - rc = 0; - } - if (rc) - { - log_error("key setup failed: %s\n", gpg_strerror(rc) ); - goto leave; - } - - gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen); - - leave: - xfree (seskey); - return rc; -} - - -/* This function is called by the KSBA writer just before the actual - write is done. The function must take INLEN bytes from INBUF, - decrypt it and store it inoutbuf which has a maximum size of - maxoutlen. The valid bytes in outbuf should be return in outlen. - Due to different buffer sizes or different length of input and - output, it may happen that fewer bytes are process or fewer bytes - are written. */ -static gpg_error_t -decrypt_filter (void *arg, - const void *inbuf, size_t inlen, size_t *inused, - void *outbuf, size_t maxoutlen, size_t *outlen) -{ - struct decrypt_filter_parm_s *parm = arg; - int blklen = parm->blklen; - size_t orig_inlen = inlen; - - /* fixme: Should we issue an error when we have not seen one full block? */ - if (!inlen) - return gpg_error (GPG_ERR_BUG); - - if (maxoutlen < 2*parm->blklen) - return gpg_error (GPG_ERR_BUG); - /* make some space becuase we will later need an extra block at the end */ - maxoutlen -= blklen; - - if (parm->helpblocklen) - { - int i, j; - - for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++) - parm->helpblock[i] = ((const char*)inbuf)[j]; - inlen -= j; - if (blklen > maxoutlen) - return gpg_error (GPG_ERR_BUG); - if (i < blklen) - { - parm->helpblocklen = i; - *outlen = 0; - } - else - { - parm->helpblocklen = 0; - if (parm->any_data) - { - memcpy (outbuf, parm->lastblock, blklen); - *outlen =blklen; - } - else - *outlen = 0; - gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen, - parm->helpblock, blklen); - parm->any_data = 1; - } - *inused = orig_inlen - inlen; - return 0; - } - - - if (inlen > maxoutlen) - inlen = maxoutlen; - if (inlen % blklen) - { /* store the remainder away */ - parm->helpblocklen = inlen%blklen; - inlen = inlen/blklen*blklen; - memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen); - } - - *inused = inlen + parm->helpblocklen; - if (inlen) - { - assert (inlen >= blklen); - if (parm->any_data) - { - gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen, - inbuf, inlen); - memcpy (outbuf, parm->lastblock, blklen); - memcpy (parm->lastblock,(char*)outbuf+inlen, blklen); - *outlen = inlen; - } - else - { - gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen); - memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen); - *outlen = inlen - blklen; - parm->any_data = 1; - } - } - else - *outlen = 0; - return 0; -} - - - -/* Perform a decrypt operation. */ -int -gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp) -{ - int rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - ksba_reader_t reader; - ksba_writer_t writer; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh; - int recp; - FILE *in_fp = NULL; - struct decrypt_filter_parm_s dfparm; - - memset (&dfparm, 0, sizeof dfparm); - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - - in_fp = fdopen ( dup (in_fd), "rb"); - if (!in_fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, writer); - if (rc) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - /* parser loop */ - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA - || stopreason == KSBA_SR_DETACHED_DATA) - { - int algo, mode; - const char *algoid; - int any_key = 0; - - algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/); - algo = gcry_cipher_map_name (algoid); - mode = gcry_cipher_mode_from_oid (algoid); - if (!algo || !mode) - { - rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?"); - if (algoid && !strcmp (algoid, "1.2.840.113549.3.2")) - log_info (_("(this is the RC2 algorithm)\n")); - else if (!algoid) - log_info (_("(this does not seem to be an encrypted" - " message)\n")); - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm", - numbuf, algoid?algoid:"?", NULL); - } - - /* If it seems that this is not an ecrypted message we - return a more sensible error code. */ - if (!algoid) - rc = gpg_error (GPG_ERR_NO_DATA); - - goto leave; - } - dfparm.algo = algo; - dfparm.mode = mode; - dfparm.blklen = gcry_cipher_get_algo_blklen (algo); - if (dfparm.blklen > sizeof (dfparm.helpblock)) - return gpg_error (GPG_ERR_BUG); - - rc = ksba_cms_get_content_enc_iv (cms, - dfparm.iv, - sizeof (dfparm.iv), - &dfparm.ivlen); - if (rc) - { - log_error ("error getting IV: %s\n", gpg_strerror (rc)); - goto leave; - } - - for (recp=0; !any_key; recp++) - { - char *issuer; - ksba_sexp_t serial; - ksba_sexp_t enc_val; - char *hexkeygrip = NULL; - char *desc = NULL; - - rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial); - if (rc == -1 && recp) - break; /* no more recipients */ - if (rc) - log_error ("recp %d - error getting info: %s\n", - recp, gpg_strerror (rc)); - else - { - ksba_cert_t cert = NULL; - - log_debug ("recp %d - issuer: `%s'\n", - recp, issuer? issuer:"[NONE]"); - log_debug ("recp %d - serial: ", recp); - gpgsm_dump_serial (serial); - log_printf ("\n"); - - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - log_error ("failed to find the certificate: %s\n", - gpg_strerror(rc)); - goto oops; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gpg_strerror (rc)); - goto oops; - } - /* Just in case there is a problem with the own - certificate we print this message - should never - happen of course */ - rc = gpgsm_cert_use_decrypt_p (cert); - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage", - numbuf, NULL); - rc = 0; - } - - hexkeygrip = gpgsm_get_keygrip_hexstring (cert); - desc = gpgsm_format_keydesc (cert); - - oops: - xfree (issuer); - xfree (serial); - ksba_cert_release (cert); - } - - if (!hexkeygrip) - ; - else if (!(enc_val = ksba_cms_get_enc_val (cms, recp))) - log_error ("recp %d - error getting encrypted session key\n", - recp); - else - { - rc = prepare_decryption (ctrl, - hexkeygrip, desc, enc_val, &dfparm); - xfree (enc_val); - if (rc) - { - log_info ("decrypting session key failed: %s\n", - gpg_strerror (rc)); - } - else - { /* setup the bulk decrypter */ - any_key = 1; - ksba_writer_set_filter (writer, - decrypt_filter, - &dfparm); - } - } - xfree (hexkeygrip); - xfree (desc); - } - if (!any_key) - { - rc = gpg_error (GPG_ERR_NO_SECKEY); - goto leave; - } - } - else if (stopreason == KSBA_SR_END_DATA) - { - ksba_writer_set_filter (writer, NULL, NULL); - if (dfparm.any_data) - { /* write the last block with padding removed */ - int i, npadding = dfparm.lastblock[dfparm.blklen-1]; - if (!npadding || npadding > dfparm.blklen) - { - log_error ("invalid padding with value %d\n", npadding); - rc = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - rc = ksba_writer_write (writer, - dfparm.lastblock, - dfparm.blklen - npadding); - if (rc) - goto leave; - - for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++) - { - if (dfparm.lastblock[i] != npadding) - { - log_error ("inconsistent padding\n"); - rc = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - } - } - } - - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL); - - - leave: - if (rc) - { - gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL); - log_error ("message decryption failed: %s <%s>\n", - gpg_strerror (rc), gpg_strsource (rc)); - } - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - if (in_fp) - fclose (in_fp); - if (dfparm.hd) - gcry_cipher_close (dfparm.hd); - return rc; -} - - diff --git a/sm/delete.c b/sm/delete.c deleted file mode 100644 index 11a0a5476..000000000 --- a/sm/delete.c +++ /dev/null @@ -1,172 +0,0 @@ -/* delete.c - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -/* Delete a certificate or an secret key from a key database. */ -static int -delete_one (CTRL ctrl, const char *username) -{ - int rc = 0; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - ksba_cert_t cert = NULL; - int duplicates = 0; - - rc = keydb_classify_name (username, &desc); - if (rc) - { - log_error (_("certificate `%s' not found: %s\n"), - username, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL); - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - char fpr[20]; - - gpgsm_get_fingerprint (cert, 0, fpr, NULL); - - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - ksba_cert_t cert2 = NULL; - char fpr2[20]; - - /* We ignore all duplicated certificates which might have - been inserted due to program bugs. */ - if (!keydb_get_cert (kh, &cert2)) - { - gpgsm_get_fingerprint (cert2, 0, fpr2, NULL); - ksba_cert_release (cert2); - if (!memcmp (fpr, fpr2, 20)) - { - duplicates++; - goto next_ambigious; - } - } - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - } - } - if (rc) - { - if (rc == -1) - rc = gpg_error (GPG_ERR_NO_PUBKEY); - log_error (_("certificate `%s' not found: %s\n"), - username, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL); - goto leave; - } - - /* We need to search again to get back to the right position. */ - rc = keydb_lock (kh); - if (rc) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (rc)); - goto leave; - } - - do - { - keydb_search_reset (kh); - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_error ("problem re-searching certificate: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = keydb_delete (kh); - if (rc) - goto leave; - if (opt.verbose) - { - if (duplicates) - log_info (_("duplicated certificate `%s' deleted\n"), username); - else - log_info (_("certificate `%s' deleted\n"), username); - } - } - while (duplicates--); - - leave: - keydb_release (kh); - ksba_cert_release (cert); - return rc; -} - - - -/* Delete the certificates specified by NAMES. */ -int -gpgsm_delete (CTRL ctrl, STRLIST names) -{ - int rc; - - if (!names) - { - log_error ("nothing to delete\n"); - return gpg_error (GPG_ERR_NO_DATA); - } - - for (; names; names=names->next ) - { - rc = delete_one (ctrl, names->d); - if (rc) - { - log_error (_("deleting certificate \"%s\" failed: %s\n"), - names->d, gpg_strerror (rc) ); - return rc; - } - } - - return 0; -} diff --git a/sm/encrypt.c b/sm/encrypt.c deleted file mode 100644 index 50da92c32..000000000 --- a/sm/encrypt.c +++ /dev/null @@ -1,511 +0,0 @@ -/* encrypt.c - Encrypt a message - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -struct dek_s { - const char *algoid; - int algo; - gcry_cipher_hd_t chd; - char key[32]; - int keylen; - char iv[32]; - int ivlen; -}; -typedef struct dek_s *DEK; - -struct encrypt_cb_parm_s { - FILE *fp; - DEK dek; - int eof_seen; - int ready; - int readerror; - int bufsize; - unsigned char *buffer; - int buflen; -}; - - - - - -/* Initialize the data encryption key (session key). */ -static int -init_dek (DEK dek) -{ - int rc=0, mode, i; - - dek->algo = gcry_cipher_map_name (dek->algoid); - mode = gcry_cipher_mode_from_oid (dek->algoid); - if (!dek->algo || !mode) - { - log_error ("unsupported algorithm `%s'\n", dek->algoid); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - } - - /* Extra check for algorithms we considere to be to weak for - encryption, qlthough we suppor them fro decryption. Note that - there is another check below discriminating on the key length. */ - switch (dek->algo) - { - case GCRY_CIPHER_DES: - case GCRY_CIPHER_RFC2268_40: - log_error ("cipher algorithm `%s' not allowed: too weak\n", - gcry_cipher_algo_name (dek->algo)); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - default: - break; - } - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - if (!dek->keylen || dek->keylen > sizeof (dek->key)) - return gpg_error (GPG_ERR_BUG); - - dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo); - if (!dek->ivlen || dek->ivlen > sizeof (dek->iv)) - return gpg_error (GPG_ERR_BUG); - - /* Make sure we don't use weak keys. */ - if (dek->keylen < 100/8) - { - log_error ("key length of `%s' too small\n", dek->algoid); - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - } - - rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE); - if (rc) - { - log_error ("failed to create cipher context: %s\n", gpg_strerror (rc)); - return rc; - } - - for (i=0; i < 8; i++) - { - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen); - if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY) - break; - log_info(_("weak key created - retrying\n") ); - } - if (rc) - { - log_error ("failed to set the key: %s\n", gpg_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return rc; - } - - gcry_create_nonce (dek->iv, dek->ivlen); - rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen); - if (rc) - { - log_error ("failed to set the IV: %s\n", gpg_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return rc; - } - - return 0; -} - - -static int -encode_session_key (DEK dek, gcry_sexp_t * r_data) -{ - gcry_sexp_t data; - char * p, tmp[3]; - int i; - int rc; - - p = xmalloc (64 + 2 * dek->keylen); - strcpy (p, "(data\n (flags pkcs1)\n (value #"); - for (i=0; i < dek->keylen; i++) - { - sprintf (tmp, "%02x", (unsigned char) dek->key[i]); - strcat (p, tmp); - } - strcat (p, "#))\n"); - rc = gcry_sexp_sscan (&data, NULL, p, strlen (p)); - xfree (p); - *r_data = data; - return rc; -} - - -/* encrypt the DEK under the key contained in CERT and return it as a - canonical S-Exp in encval */ -static int -encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) -{ - gcry_sexp_t s_ciph, s_data, s_pkey; - int rc; - ksba_sexp_t buf; - size_t len; - - *encval = NULL; - - /* get the key from the cert */ - buf = ksba_cert_get_public_key (cert); - if (!buf) - { - log_error ("no public key for recipient\n"); - return gpg_error (GPG_ERR_NO_PUBKEY); - } - len = gcry_sexp_canon_len (buf, 0, NULL, NULL); - if (!len) - { - log_error ("libksba did not return a proper S-Exp\n"); - return gpg_error (GPG_ERR_BUG); - } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); - xfree (buf); buf = NULL; - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return rc; - } - - /* put the encoded cleartext into a simple list */ - rc = encode_session_key (dek, &s_data); - if (rc) - { - log_error ("encode_session_key failed: %s\n", gpg_strerror (rc)); - return rc; - } - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - /* reformat it */ - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xtrymalloc (len); - if (!buf) - { - gpg_error_t tmperr = OUT_OF_CORE (errno); - gcry_sexp_release (s_ciph); - return tmperr; - } - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - - *encval = buf; - return 0; -} - - - -/* do the actual encryption */ -static int -encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct encrypt_cb_parm_s *parm = cb_value; - int blklen = parm->dek->ivlen; - unsigned char *p; - size_t n; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - if (parm->ready) - return -1; - - if (count < blklen) - BUG (); - - if (!parm->eof_seen) - { /* fillup the buffer */ - p = parm->buffer; - for (n=parm->buflen; n < parm->bufsize; n++) - { - int c = getc (parm->fp); - if (c == EOF) - { - if (ferror (parm->fp)) - { - parm->readerror = errno; - return -1; - } - parm->eof_seen = 1; - break; - } - p[n] = c; - } - parm->buflen = n; - } - - n = parm->buflen < count? parm->buflen : count; - n = n/blklen * blklen; - if (n) - { /* encrypt the stuff */ - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - /* Who cares about cycles, take the easy way and shift the buffer */ - parm->buflen -= n; - memmove (parm->buffer, parm->buffer+n, parm->buflen); - } - else if (parm->eof_seen) - { /* no complete block but eof: add padding */ - /* fixme: we should try to do this also in the above code path */ - int i, npad = blklen - (parm->buflen % blklen); - p = parm->buffer; - for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++) - p[n] = npad; - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - parm->ready = 1; - } - - return 0; -} - - - - -/* Perform an encrypt operation. - - Encrypt the data received on DATA-FD and write it to OUT_FP. The - recipients are take from the certificate given in recplist; if this - is NULL it will be encrypted for a default recipient */ -int -gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp) -{ - int rc = 0; - Base64Context b64writer = NULL; - gpg_error_t err; - ksba_writer_t writer; - ksba_reader_t reader = NULL; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh = NULL; - struct encrypt_cb_parm_s encparm; - DEK dek = NULL; - int recpno; - FILE *data_fp = NULL; - CERTLIST cl; - - memset (&encparm, 0, sizeof encparm); - - /* Check that the certificate list is not empty and that at least - one certificate is not flagged as encrypt_to; i.e. is a real - recipient. */ - for (cl = recplist; cl; cl = cl->next) - if (!cl->is_encrypt_to) - break; - if (!cl) - { - log_error(_("no valid recipients given\n")); - gpgsm_status (ctrl, STATUS_NO_RECP, "0"); - rc = gpg_error (GPG_ERR_NO_PUBKEY); - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - data_fp = fdopen ( dup (data_fd), "rb"); - if (!data_fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - err = ksba_reader_new (&reader); - if (err) - rc = err; - if (!rc) - rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm); - if (rc) - goto leave; - - encparm.fp = data_fp; - - ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_new (&cms); - if (err) - { - rc = err; - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, reader, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* We are going to create enveloped data with uninterpreted data as - inner content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* Create a session key */ - dek = xtrycalloc_secure (1, sizeof *dek); - if (!dek) - rc = OUT_OF_CORE (errno); - else - { - dek->algoid = opt.def_cipher_algoid; - rc = init_dek (dek); - } - if (rc) - { - log_error ("failed to create the session key: %s\n", - gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen); - if (err) - { - log_error ("ksba_cms_set_content_enc_algo failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - encparm.dek = dek; - /* Use a ~8k (AES) or ~4k (3DES) buffer */ - encparm.bufsize = 500 * dek->ivlen; - encparm.buffer = xtrymalloc (encparm.bufsize); - if (!encparm.buffer) - { - rc = OUT_OF_CORE (errno); - goto leave; - } - - /* Gather certificates of recipients, encrypt the session key for - each and store them in the CMS object */ - for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next) - { - char *encval; - - rc = encrypt_dek (dek, cl->cert, &encval); - if (rc) - { - log_error ("encryption failed for recipient no. %d: %s\n", - recpno, gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_add_recipient (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_recipient failed: %s\n", - gpg_strerror (err)); - rc = err; - xfree (encval); - goto leave; - } - - err = ksba_cms_set_enc_val (cms, recpno, encval); - xfree (encval); - if (err) - { - log_error ("ksba_cms_set_enc_val failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* Main control loop for encryption. */ - recpno = 0; - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - } - while (stopreason != KSBA_SR_READY); - - if (encparm.readerror) - { - log_error ("error reading input: %s\n", strerror (encparm.readerror)); - rc = gpg_error (gpg_err_code_from_errno (encparm.readerror)); - goto leave; - } - - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - log_info ("encrypted data created\n"); - - leave: - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - ksba_reader_release (reader); - keydb_release (kh); - xfree (dek); - if (data_fp) - fclose (data_fp); - xfree (encparm.buffer); - return rc; -} diff --git a/sm/export.c b/sm/export.c deleted file mode 100644 index 3f7457502..000000000 --- a/sm/export.c +++ /dev/null @@ -1,736 +0,0 @@ -/* export.c - * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -/* A table to store a fingerprint as used in a duplicates table. We - don't need to hash here because a fingerprint is alrady a perfect - hash value. This we use the most significant bits to index the - table and then use a linked list for the overflow. Possible - enhancement for very large number of certictates: Add a second - level table and then resort to a linked list. */ -struct duptable_s -{ - struct duptable_s *next; - - /* Note that we only need to store 19 bytes because the first byte - is implictly given by the table index (we require at least 8 - bits). */ - unsigned char fpr[19]; -}; -typedef struct duptable_s *duptable_t; -#define DUPTABLE_BITS 12 -#define DUPTABLE_SIZE (1 << DUPTABLE_BITS) - - -static void print_short_info (ksba_cert_t cert, FILE *fp); -static gpg_error_t export_p12 (const unsigned char *certimg, size_t certimglen, - const char *prompt, const char *keygrip, - FILE **retfp); - - -/* Create a table used to indetify duplicated certificates. */ -static duptable_t * -create_duptable (void) -{ - return xtrycalloc (DUPTABLE_SIZE, sizeof (duptable_t)); -} - -static void -destroy_duptable (duptable_t *table) -{ - int idx; - duptable_t t, t2; - - if (table) - { - for (idx=0; idx < DUPTABLE_SIZE; idx++) - for (t = table[idx]; t; t = t2) - { - t2 = t->next; - xfree (t); - } - xfree (table); - } -} - -/* Insert the 20 byte fingerprint FPR into TABLE. Sets EXITS to true - if the fingerprint already exists in the table. */ -static gpg_error_t -insert_duptable (duptable_t *table, unsigned char *fpr, int *exists) -{ - size_t idx; - duptable_t t; - - *exists = 0; - idx = fpr[0]; -#if DUPTABLE_BITS > 16 || DUPTABLE_BITS < 8 -#error cannot handle a table larger than 16 bits or smaller than 8 bits -#elif DUPTABLE_BITS > 8 - idx <<= (DUPTABLE_BITS - 8); - idx |= (fpr[1] & ~(~0 << 4)); -#endif - - for (t = table[idx]; t; t = t->next) - if (!memcmp (t->fpr, fpr+1, 19)) - break; - if (t) - { - *exists = 1; - return 0; - } - /* Insert that fingerprint. */ - t = xtrymalloc (sizeof *t); - if (!t) - return gpg_error_from_errno (errno); - memcpy (t->fpr, fpr+1, 19); - t->next = table[idx]; - table[idx] = t; - return 0; -} - - - - -/* Export all certificates or just those given in NAMES. */ -void -gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp) -{ - KEYDB_HANDLE hd = NULL; - KEYDB_SEARCH_DESC *desc = NULL; - int ndesc; - Base64Context b64writer = NULL; - ksba_writer_t writer; - STRLIST sl; - ksba_cert_t cert = NULL; - int rc=0; - int count = 0; - int i; - duptable_t *dtable; - - - dtable = create_duptable (); - if (!dtable) - { - log_error ("creating duplicates table failed: %s\n", strerror (errno)); - goto leave; - } - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("allocating memory for export failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - } - - /* If all specifications are done by fingerprint, we switch to - ephemeral mode so that _all_ currently available and matching - certificates are exported. - - fixme: we should in this case keep a list of certificates to - avoid accidential export of duplicate certificates. */ - if (names && ndesc) - { - for (i=0; (i < ndesc - && (desc[i].mode == KEYDB_SEARCH_MODE_FPR - || desc[i].mode == KEYDB_SEARCH_MODE_FPR20 - || desc[i].mode == KEYDB_SEARCH_MODE_FPR16)); i++) - ; - if (i == ndesc) - keydb_set_ephemeral (hd, 1); - } - - while (!(rc = keydb_search (hd, desc, ndesc))) - { - unsigned char fpr[20]; - int exists; - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - gpgsm_get_fingerprint (cert, 0, fpr, NULL); - rc = insert_duptable (dtable, fpr, &exists); - if (rc) - { - log_error ("inserting into duplicates table fauiled: %s\n", - gpg_strerror (rc)); - goto leave; - } - - if (!exists && count && !ctrl->create_pem) - { - log_info ("exporting more than one certificate " - "is not possible in binary mode\n"); - log_info ("ignoring other certificates\n"); - break; - } - - if (!exists) - { - const unsigned char *image; - size_t imagelen; - - image = ksba_cert_get_image (cert, &imagelen); - if (!image) - { - log_error ("ksba_cert_get_image failed\n"); - goto leave; - } - - - if (ctrl->create_pem) - { - if (count) - putc ('\n', fp); - print_short_info (cert, fp); - putc ('\n', fp); - } - count++; - - if (!b64writer) - { - ctrl->pem_name = "CERTIFICATE"; - rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - rc = ksba_writer_write (writer, image, imagelen); - if (rc) - { - log_error ("write error: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (ctrl->create_pem) - { - /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_destroy_writer (b64writer); - b64writer = NULL; - } - } - - ksba_cert_release (cert); - cert = NULL; - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - else if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - leave: - gpgsm_destroy_writer (b64writer); - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); - destroy_duptable (dtable); -} - - -/* Export a certificates and its private key. */ -void -gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - Base64Context b64writer = NULL; - ksba_writer_t writer; - ksba_cert_t cert = NULL; - int rc=0; - const unsigned char *image; - size_t imagelen; - char *keygrip = NULL; - char *prompt; - char buffer[1024]; - int nread; - FILE *datafp = NULL; - - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - desc = xtrycalloc (1, sizeof *desc); - if (!desc) - { - log_error ("allocating memory for export failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - rc = keydb_classify_name (name, desc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - name, gpg_strerror (rc)); - goto leave; - } - - /* Lookup the certificate an make sure that it is unique. */ - rc = keydb_search (hd, desc, 1); - if (!rc) - { - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = keydb_search (hd, desc, 1); - if (!rc) - rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME); - else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - if (rc) - { - log_error ("key `%s' not found: %s\n", - name, gpg_strerror (rc)); - goto leave; - } - } - - keygrip = gpgsm_get_keygrip_hexstring (cert); - if (!keygrip || gpgsm_agent_havekey (ctrl, keygrip)) - { - /* Note, that the !keygrip case indicates a bad certificate. */ - rc = gpg_error (GPG_ERR_NO_SECKEY); - log_error ("can't export key `%s': %s\n", name, gpg_strerror (rc)); - goto leave; - } - - image = ksba_cert_get_image (cert, &imagelen); - if (!image) - { - log_error ("ksba_cert_get_image failed\n"); - goto leave; - } - - if (ctrl->create_pem) - { - print_short_info (cert, fp); - putc ('\n', fp); - } - - ctrl->pem_name = "PKCS12"; - rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - - prompt = gpgsm_format_keydesc (cert); - rc = export_p12 (image, imagelen, prompt, keygrip, &datafp); - xfree (prompt); - if (rc) - goto leave; - rewind (datafp); - while ( (nread = fread (buffer, 1, sizeof buffer, datafp)) > 0 ) - if ((rc = ksba_writer_write (writer, buffer, nread))) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (ferror (datafp)) - { - rc = gpg_error_from_errno (rc); - log_error ("error reading temporary file: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (ctrl->create_pem) - { - /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - gpgsm_destroy_writer (b64writer); - b64writer = NULL; - } - - ksba_cert_release (cert); - cert = NULL; - - leave: - if (datafp) - fclose (datafp); - gpgsm_destroy_writer (b64writer); - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); -} - - -/* Print some info about the certifciate CERT to FP */ -static void -print_short_info (ksba_cert_t cert, FILE *fp) -{ - char *p; - ksba_sexp_t sexp; - int idx; - - for (idx=0; (p = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (!idx? "Issuer ...: " - : "\n aka ...: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); - - fputs ("Serial ...: ", fp); - sexp = ksba_cert_get_serial (cert); - if (sexp) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp, "%02X", *s); - } - xfree (sexp); - } - putc ('\n', fp); - - for (idx=0; (p = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (!idx? "Subject ..: " - : "\n aka ..: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); -} - - -static gpg_error_t -popen_protect_tool (const char *pgmname, - FILE *infile, FILE *outfile, FILE **statusfile, - const char *prompt, const char *keygrip, - pid_t *pid) -{ - gpg_error_t err; - int fd, fdout, rp[2]; - int n, i; - - fflush (infile); - rewind (infile); - fd = fileno (infile); - fdout = fileno (outfile); - if (fd == -1 || fdout == -1) - log_fatal ("no file descriptor for temporary file: %s\n", - strerror (errno)); - - /* Now start the protect-tool. */ - if (pipe (rp) == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating a pipe: %s\n"), strerror (errno)); - return err; - } - - *pid = fork (); - if (*pid == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error forking process: %s\n"), strerror (errno)); - close (rp[0]); - close (rp[1]); - return err; - } - - if (!*pid) - { /* Child. */ - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - /* Connect the infile to stdin. */ - if (fd != 0 && dup2 (fd, 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - - /* Connect the outfile to stdout. */ - if (fdout != 1 && dup2 (fdout, 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Connect stderr to our pipe. */ - if (rp[1] != 2 && dup2 (rp[1], 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - setup_pinentry_env (); - - execlp (pgmname, arg0, - "--homedir", opt.homedir, - "--p12-export", - "--prompt", prompt?prompt:"", - "--", - keygrip, - NULL); - /* No way to print anything, as we have closed all streams. */ - _exit (31); - } - - /* Parent. */ - close (rp[1]); - *statusfile = fdopen (rp[0], "r"); - if (!*statusfile) - { - err = gpg_error_from_errno (errno); - log_error ("can't fdopen pipe for reading: %s", strerror (errno)); - kill (*pid, SIGTERM); - return err; - } - - return 0; -} - - -static gpg_error_t -export_p12 (const unsigned char *certimg, size_t certimglen, - const char *prompt, const char *keygrip, - FILE **retfp) -{ - const char *pgmname; - gpg_error_t err = 0, child_err = 0; - int i, c, cont_line; - unsigned int pos; - FILE *infp = NULL, *outfp = NULL, *fp = NULL; - char buffer[1024]; - pid_t pid = -1; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgmname = opt.protect_tool_program; - - infp = tmpfile (); - if (!infp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - if (fwrite (certimg, certimglen, 1, infp) != 1) - { - err = gpg_error_from_errno (errno); - log_error (_("error writing to temporary file: %s\n"), - strerror (errno)); - goto cleanup; - } - - outfp = tmpfile (); - if (!outfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - err = popen_protect_tool (pgmname, infp, outfp, &fp, prompt, keygrip, &pid); - if (err) - { - pid = -1; - goto cleanup; - } - fclose (infp); - infp = NULL; - - /* Read stderr of the protect tool. */ - pos = 0; - cont_line = 0; - while ((c=getc (fp)) != EOF) - { - /* fixme: We could here grep for status information of the - protect tool to figure out better error codes for - CHILD_ERR. */ - buffer[pos++] = c; - if (pos >= sizeof buffer - 5 || c == '\n') - { - buffer[pos - (c == '\n')] = 0; - if (cont_line) - log_printf ("%s", buffer); - else - log_info ("%s", buffer); - pos = 0; - cont_line = (c != '\n'); - } - } - - if (pos) - { - buffer[pos] = 0; - if (cont_line) - log_printf ("%s\n", buffer); - else - log_info ("%s\n", buffer); - } - else if (cont_line) - log_printf ("\n"); - - /* If we found no error in the output of the child, setup a suitable - error code, which will later be reset if the exit status of the - child is 0. */ - if (!child_err) - child_err = gpg_error (GPG_ERR_DECRYPT_FAILED); - - cleanup: - if (infp) - fclose (infp); - if (fp) - fclose (fp); - if (pid != -1) - { - int status; - - while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - log_error (_("waiting for protect-tools to terminate failed: %s\n"), - strerror (errno)); - else if (WIFEXITED (status) && WEXITSTATUS (status) == 31) - log_error (_("error running `%s': probably not installed\n"), pgmname); - else if (WIFEXITED (status) && WEXITSTATUS (status)) - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - else if (!WIFEXITED (status)) - log_error (_("error running `%s': terminated\n"), pgmname); - else - child_err = 0; - } - if (!err) - err = child_err; - if (err) - { - if (outfp) - fclose (outfp); - } - else - *retfp = outfp; - return err; -} - diff --git a/sm/fingerprint.c b/sm/fingerprint.c deleted file mode 100644 index 7fe619c18..000000000 --- a/sm/fingerprint.c +++ /dev/null @@ -1,331 +0,0 @@ -/* fingerprint.c - Get the fingerprint - * Copyright (C) 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -/* Return the fingerprint of the certificate (we can't put this into - libksba because we need libgcrypt support). The caller must - provide an array of sufficient length or NULL so that the function - allocates the array. If r_len is not NULL, the length of the - digest is returned; well, this can also be done by using - gcry_md_get_algo_dlen(). If algo is 0, a SHA-1 will be used. - - If there is a problem , the function does never return NULL but a - digest of all 0xff. - */ -char * -gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len) -{ - gcry_md_hd_t md; - int rc, len; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len); - if (!array) - array = xmalloc (len); - - if (r_len) - *r_len = len; - - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - - rc = ksba_cert_hash (cert, 0, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc)); - gcry_md_close (md); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - gcry_md_final (md); - memcpy (array, gcry_md_read(md, algo), len ); - return array; -} - - -/* Return an allocated buffer with the formatted fingerprint */ -char * -gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), i? ":%02X":"%02X", digest[i]); - return buf; -} - -/* Return an allocated buffer with the formatted fingerprint as one - large hexnumber */ -char * -gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), "%02X", digest[i]); - return buf; -} - -/* Return a certificate ID. These are the last 4 bytes of the SHA-1 - fingerprint. */ -unsigned long -gpgsm_get_short_fingerprint (ksba_cert_t cert) -{ - unsigned char digest[20]; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); - return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]); -} - - -/* Return the so called KEYGRIP which is the SHA-1 hash of the public - key parameters expressed as an canoncial encoded S-Exp. array must - be 20 bytes long. returns the array or a newly allocated one if the - passed one was NULL */ -char * -gpgsm_get_keygrip (ksba_cert_t cert, char *array) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return NULL; /* oops */ - - if (DBG_X509) - log_debug ("get_keygrip for public key\n"); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return NULL; - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); - return NULL; - } - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - { - rc = gpg_error (GPG_ERR_GENERAL); - log_error ("can't calculate keygrip\n"); - return NULL; - } - if (DBG_X509) - log_printhex ("keygrip=", array, 20); - - return array; -} - -/* Return an allocated buffer with the keygrip of CERT in from of an - hexstring. NULL is returned in case of error */ -char * -gpgsm_get_keygrip_hexstring (ksba_cert_t cert) -{ - unsigned char grip[20]; - char *buf, *p; - int i; - - gpgsm_get_keygrip (cert, grip); - buf = p = xmalloc (20*2+1); - for (i=0; i < 20; i++, p += 2 ) - sprintf (p, "%02X", grip[i]); - return buf; -} - - -/* Return the PK algorithm used by CERT as well as the length in bits - of the public key at NBITS. */ -int -gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) -{ - gcry_sexp_t s_pkey; - int rc; - ksba_sexp_t p; - size_t n; - gcry_sexp_t l1, l2; - const char *name; - char namebuf[128]; - - if (nbits) - *nbits = 0; - - p = ksba_cert_get_public_key (cert); - if (!p) - return 0; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - xfree (p); - return 0; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, p, n); - xfree (p); - if (rc) - return 0; - - if (nbits) - *nbits = gcry_pk_get_nbits (s_pkey); - - /* Breaking the algorithm out of the S-exp is a bit of a challenge ... */ - l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); - if (!l1) - { - gcry_sexp_release (s_pkey); - return 0; - } - l2 = gcry_sexp_cadr (l1); - gcry_sexp_release (l1); - l1 = l2; - name = gcry_sexp_nth_data (l1, 0, &n); - if (name) - { - if (n > sizeof namebuf -1) - n = sizeof namebuf -1; - memcpy (namebuf, name, n); - namebuf[n] = 0; - } - else - *namebuf = 0; - gcry_sexp_release (l1); - gcry_sexp_release (s_pkey); - return gcry_pk_map_name (namebuf); -} - - - - -/* For certain purposes we need a certificate id which has an upper - limit of the size. We use the hash of the issuer name and the - serial number for this. In most cases the serial number is not - that large and the resulting string can be passed on an assuan - command line. Everything is hexencoded with the serialnumber - delimited from the hash by a dot. - - The caller must free the string. -*/ -char * -gpgsm_get_certid (ksba_cert_t cert) -{ - ksba_sexp_t serial; - unsigned char *p; - char *endp; - unsigned char hash[20]; - unsigned long n; - char *certid; - int i; - - p = ksba_cert_get_issuer (cert, 0); - if (!p) - return NULL; /* Ooops: No issuer */ - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, p, strlen (p)); - xfree (p); - - serial = ksba_cert_get_serial (cert); - if (!serial) - return NULL; /* oops: no serial number */ - p = serial; - if (*p != '(') - { - log_error ("Ooops: invalid serial number\n"); - xfree (serial); - return NULL; - } - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p != ':') - { - log_error ("Ooops: invalid serial number (no colon)\n"); - xfree (serial); - return NULL; - } - p++; - - certid = xtrymalloc ( 40 + 1 + n*2 + 1); - if (!certid) - { - xfree (serial); - return NULL; /* out of core */ - } - - for (i=0, endp = certid; i < 20; i++, endp += 2 ) - sprintf (endp, "%02X", hash[i]); - *endp++ = '.'; - for (i=0; i < n; i++, endp += 2) - sprintf (endp, "%02X", p[i]); - *endp = 0; - - xfree (serial); - return certid; -} - - - - - - diff --git a/sm/gpgsm.c b/sm/gpgsm.c deleted file mode 100644 index bf053b7a5..000000000 --- a/sm/gpgsm.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* gpgsm.c - GnuPG for S/MIME - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <fcntl.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <assuan.h> /* malloc hooks */ - -#include "../kbx/keybox.h" /* malloc hooks */ -#include "i18n.h" -#include "keydb.h" -#include "sysutils.h" - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - aDetachedSign = 'b', - aSym = 'c', - aDecrypt = 'd', - aEncr = 'e', - oInteractive = 'i', - aListKeys = 'k', - aListSecretKeys = 'K', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oRecipient = 'r', - aSign = 's', - oTextmodeShort= 't', - oUser = 'u', - oVerbose = 'v', - oCompress = 'z', - oNotation = 'N', - oBatch = 500, - aClearsign, - aStore, - aKeygen, - aSignEncr, - aSignKey, - aLSignKey, - aListPackets, - aEditKey, - aDeleteKey, - aImport, - aVerify, - aVerifyFiles, - aListExternalKeys, - aListSigs, - aSendKeys, - aRecvKeys, - aExport, - aExportSecretKeyP12, - aCheckKeys, /* nyi */ - aServer, - aLearnCard, - aCallDirmngr, - aCallProtectTool, - aPasswd, - aGPGConfList, - aDumpKeys, - aDumpSecretKeys, - aDumpExternalKeys, - aKeydbClearSomeCertFlags, - - oOptions, - oDebug, - oDebugLevel, - oDebugAll, - oDebugWait, - oDebugAllowCoreDump, - oDebugNoChainValidation, - oDebugIgnoreExpiration, - oLogFile, - - oEnableSpecialFilenames, - - oAgentProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - - oDirmngrProgram, - oProtectToolProgram, - oFakedSystemTime, - - - oAssumeArmor, - oAssumeBase64, - oAssumeBinary, - - oBase64, - oNoArmor, - - oDisableCRLChecks, - oEnableCRLChecks, - oForceCRLRefresh, - - oDisableOCSP, - oEnableOCSP, - - oIncludeCerts, - oPolicyFile, - oDisablePolicyChecks, - oEnablePolicyChecks, - oAutoIssuerKeyRetrieve, - - - oTextmode, - oFingerprint, - oWithFingerprint, - oWithMD5Fingerprint, - oAnswerYes, - oAnswerNo, - oKeyring, - oSecretKeyring, - oDefaultKey, - oDefRecipient, - oDefRecipientSelf, - oNoDefRecipient, - oStatusFD, - oNoComment, - oNoVersion, - oEmitVersion, - oCompletesNeeded, - oMarginalsNeeded, - oMaxCertDepth, - oLoadExtension, - oRFC1991, - oOpenPGP, - oCipherAlgo, - oDigestAlgo, - oCompressAlgo, - oCommandFD, - oNoVerbose, - oTrustDBName, - oNoSecmemWarn, - oNoDefKeyring, - oNoGreeting, - oNoTTY, - oNoOptions, - oNoBatch, - oHomedir, - oWithColons, - oWithKeyData, - oWithValidation, - oSkipVerify, - oCompressKeys, - oCompressSigs, - oAlwaysTrust, - oRunAsShmCP, - oSetFilename, - oSetPolicyURL, - oUseEmbeddedFilename, - oComment, - oDefaultComment, - oThrowKeyid, - oForceV3Sigs, - oForceMDC, - oS2KMode, - oS2KDigest, - oS2KCipher, - oCharset, - oNotDashEscaped, - oEscapeFrom, - oLockOnce, - oLockMultiple, - oLockNever, - oKeyServer, - oEncryptTo, - oNoEncryptTo, - oLoggerFD, - oUtf8Strings, - oNoUtf8Strings, - oDisableCipherAlgo, - oDisablePubkeyAlgo, - oAllowNonSelfsignedUID, - oAllowFreeformUID, - oNoLiteral, - oSetFilesize, - oHonorHttpProxy, - oFastListMode, - oListOnly, - oIgnoreTimeConflict, - oNoRandomSeedFile, - oNoAutoKeyRetrieve, - oUseAgent, - oMergeOnly, - oTryAllSecrets, - oTrustedKey, - oEmuMDEncodeBug, - aDummy - }; - - -static ARGPARSE_OPTS opts[] = { - - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aSign, "sign", 256, N_("|[FILE]|make a signature")}, - { aClearsign, "clearsign", 256, N_("|[FILE]|make a clear text signature") }, - { aDetachedSign, "detach-sign", 256, N_("make a detached signature")}, - { aEncr, "encrypt", 256, N_("encrypt data")}, - { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { aVerify, "verify" , 256, N_("verify a signature")}, - { aVerifyFiles, "verify-files" , 256, "@" }, - { aListKeys, "list-keys", 256, N_("list keys")}, - { aListExternalKeys, "list-external-keys", 256, N_("list external keys")}, - { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, - { aListSigs, "list-sigs", 256, N_("list certificate chain")}, - { aListSigs, "check-sigs",256, "@"}, - { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")}, - { aKeygen, "gen-key", 256, N_("generate a new key pair")}, - { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")}, - { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, - { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, - { aImport, "import", 256 , N_("import certificates")}, - { aExport, "export", 256 , N_("export certificates")}, - { aLearnCard, "learn-card", 256 ,N_("register a smartcard")}, - { aServer, "server", 256, N_("run in server mode")}, - { aCallDirmngr, "call-dirmngr", 256, N_("pass a command to the dirmngr")}, - { aCallProtectTool, "call-protect-tool", 256, - N_("invoke gpg-protect-tool")}, - { aPasswd, "passwd", 256, N_("change a passphrase")}, - { aGPGConfList, "gpgconf-list", 256, "@" }, - - { aDumpKeys, "dump-keys", 256, "@"}, - { aDumpExternalKeys, "dump-external-keys", 256, "@"}, - { aDumpSecretKeys, "dump-secret-keys", 256, "@"}, - { aKeydbClearSomeCertFlags, "keydb-clear-some-cert-flags", 256, "@"}, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oBase64, "base64", 0, N_("create base-64 encoded output")}, - - { oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")}, - { oAssumeBase64, "assume-base64", 0, - N_("assume input is in base-64 format")}, - { oAssumeBinary, "assume-binary", 0, - N_("assume input is in binary format")}, - - { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - - - { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, - { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, - { oForceCRLRefresh, "force-crl-refresh", 0, "@"}, - - { oDisableOCSP, "disable-ocsp", 0, "@" }, - { oEnableOCSP, "enable-ocsp", 0, N_("check validity using OCSP")}, - - { oIncludeCerts, "include-certs", 1, - N_("|N|number of certificates to include") }, - - { oPolicyFile, "policy-file", 2, - N_("|FILE|take policy information from FILE") }, - - { oDisablePolicyChecks, "disable-policy-checks", 0, - N_("do not check certificate policies")}, - { oEnablePolicyChecks, "enable-policy-checks", 0, "@"}, - - { oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0, - N_("fetch missing issuer certificates")}, - -#if 0 - { oDefRecipient, "default-recipient" ,2, - N_("|NAME|use NAME as default recipient")}, - { oDefRecipientSelf, "default-recipient-self" ,0, - N_("use the default key as default recipient")}, - { oNoDefRecipient, "no-default-recipient", 0, "@" }, -#endif - { oEncryptTo, "encrypt-to", 2, "@" }, - { oNoEncryptTo, "no-encrypt-to", 0, "@" }, - - { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, - -#if 0 - { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, - { oTextmodeShort, NULL, 0, "@"}, - { oTextmode, "textmode", 0, N_("use canonical text mode")}, -#endif - - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") }, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, -#if 0 - { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") }, - { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") }, -#endif - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */ - /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/ - { oBatch, "batch", 0, N_("batch mode: never ask")}, - { oAnswerYes, "yes", 0, N_("assume yes on most questions")}, - { oAnswerNo, "no", 0, N_("assume no on most questions")}, - - { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, - { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, - { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")}, - { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") }, - { oOptions, "options" , 2, N_("read options from file")}, - - { oDebug, "debug" ,4|16, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugWait, "debug-wait" ,1, "@"}, - { oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" }, - { oDebugNoChainValidation, "debug-no-chain-validation", 0, "@"}, - { oDebugIgnoreExpiration, "debug-ignore-expiration", 0, "@"}, - { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { aDummy, "no-comment", 0, "@"}, - { aDummy, "completes-needed", 1, "@"}, - { aDummy, "marginals-needed", 1, "@"}, - { oMaxCertDepth, "max-cert-depth", 1, "@" }, - { aDummy, "trusted-key", 2, "@"}, - { oLoadExtension, "load-extension" ,2, - N_("|FILE|load extension module FILE")}, - { aDummy, "rfc1991", 0, "@"}, - { aDummy, "openpgp", 0, "@"}, - { aDummy, "s2k-mode", 1, "@"}, - { aDummy, "s2k-digest-algo",2, "@"}, - { aDummy, "s2k-cipher-algo",2, "@"}, - { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, - { oDigestAlgo, "digest-algo", 2 , - N_("|NAME|use message digest algorithm NAME")}, -#if 0 - { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")}, -#endif - { aDummy, "throw-keyid", 0, "@"}, - { aDummy, "notation-data", 2, "@"}, - { aExportSecretKeyP12, "export-secret-key-p12", 256, "@"}, - - - { 302, NULL, 0, N_( - "@\n(See the man page for a complete listing of all commands and options)\n" - )}, - - { 303, NULL, 0, N_("@\nExamples:\n\n" - " -se -r Bob [file] sign and encrypt for user Bob\n" - " --clearsign [file] make a clear text signature\n" - " --detach-sign [file] make a detached signature\n" - " --list-keys [names] show keys\n" - " --fingerprint [names] show fingerprints\n" ) }, - - /* hidden options */ - { oNoVerbose, "no-verbose", 0, "@"}, - - { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - - - { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, - { oNoArmor, "no-armor", 0, "@"}, - { oNoArmor, "no-armour", 0, "@"}, - { oNoDefKeyring, "no-default-keyring", 0, "@" }, - { oNoGreeting, "no-greeting", 0, "@" }, - { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ - { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - { oAgentProgram, "agent-program", 2 , "@" }, - { oDisplay, "display", 2, "@" }, - { oTTYname, "ttyname", 2, "@" }, - { oTTYtype, "ttytype", 2, "@" }, - { oLCctype, "lc-ctype", 2, "@" }, - { oLCmessages, "lc-messages", 2, "@" }, - { oDirmngrProgram, "dirmngr-program", 2 , "@" }, - { oProtectToolProgram, "protect-tool-program", 2 , "@" }, - { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */ - - - { oNoBatch, "no-batch", 0, "@" }, - { oWithColons, "with-colons", 0, "@"}, - { oWithKeyData,"with-key-data", 0, "@"}, - { oWithValidation, "with-validation", 0, "@"}, - { oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"}, - { aListKeys, "list-key", 0, "@" }, /* alias */ - { aListSigs, "list-sig", 0, "@" }, /* alias */ - { aListSigs, "check-sig",0, "@" }, /* alias */ - { oSkipVerify, "skip-verify",0, "@" }, - { oCompressKeys, "compress-keys",0, "@"}, - { oCompressSigs, "compress-sigs",0, "@"}, - { oAlwaysTrust, "always-trust", 0, "@"}, - { oNoVersion, "no-version", 0, "@"}, - { oLockOnce, "lock-once", 0, "@" }, - { oLockMultiple, "lock-multiple", 0, "@" }, - { oLockNever, "lock-never", 0, "@" }, - { oLoggerFD, "logger-fd",1, "@" }, - { oWithFingerprint, "with-fingerprint", 0, "@" }, - { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" }, - { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" }, - { oHonorHttpProxy,"honor-http-proxy", 0, "@" }, - { oListOnly, "list-only", 0, "@"}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, - { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, -{0} }; - - - -int gpgsm_errors_seen = 0; - -/* It is possible that we are currentlu running under setuid permissions */ -static int maybe_setuid = 1; - -/* Option --enable-special-filenames */ -static int allow_special_filenames; - - -static char *build_list (const char *text, - const char *(*mapf)(int), int (*chkf)(int)); -static void set_cmd (enum cmd_and_opt_values *ret_cmd, - enum cmd_and_opt_values new_cmd ); - -static void emergency_cleanup (void); -static int check_special_filename (const char *fname); -static int open_read (const char *filename); -static FILE *open_fwrite (const char *filename); -static void run_protect_tool (int argc, char **argv); - - -static int -our_pk_test_algo (int algo) -{ - return 1; -} - -static int -our_cipher_test_algo (int algo) -{ - return 1; -} - -static int -our_md_test_algo (int algo) -{ - return 1; -} - -static const char * -my_strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers; - const char *p; - - switch (level) - { - case 11: p = "gpgsm (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpgsm [options] [files] (-h for help)"); - break; - case 41: - p = _("Syntax: gpgsm [options] [files]\n" - "sign, check, encrypt or decrypt using the S/MIME protocol\n" - "default operation depends on the input data\n"); - break; - - case 31: p = "\nHome: "; break; - case 32: p = opt.homedir; break; - case 33: p = _("\nSupported algorithms:\n"); break; - case 34: - if (!ciphers) - ciphers = build_list ("Cipher: ", gcry_cipher_algo_name, - our_cipher_test_algo ); - p = ciphers; - break; - case 35: - if (!pubkeys) - pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name, - our_pk_test_algo ); - p = pubkeys; - break; - case 36: - if (!digests) - digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo ); - p = digests; - break; - - default: p = NULL; break; - } - return p; -} - - -static char * -build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int)) -{ - int i; - size_t n=strlen(text)+2; - char *list, *p; - - if (maybe_setuid) { - gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */ - } - - for (i=1; i < 110; i++ ) - if (!chkf(i)) - n += strlen(mapf(i)) + 2; - list = xmalloc (21 + n); - *list = 0; - for (p=NULL, i=1; i < 110; i++) - { - if (!chkf(i)) - { - if( !p ) - p = stpcpy (list, text ); - else - p = stpcpy (p, ", "); - p = stpcpy (p, mapf(i) ); - } - } - if (p) - p = stpcpy(p, "\n" ); - return list; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file (PACKAGE_GT); -#else -# ifdef ENABLE_NLS -# ifdef HAVE_LC_MESSAGES - setlocale (LC_TIME, ""); - setlocale (LC_MESSAGES, ""); -# else - setlocale (LC_ALL, "" ); -# endif - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -# endif -#endif -} - - -static void -wrong_args (const char *text) -{ - fputs (_("usage: gpgsm [options] "), stderr); - fputs (text, stderr); - putc ('\n', stderr); - gpgsm_exit (2); -} - - -/* Setup the debugging. With a LEVEL of NULL only the active debug - flags are propagated to the subsystems. With LEVEL set, a specific - set of debug flags is set; thus overriding all flags already - set. */ -static void -set_debug (const char *level) -{ - if (!level) - ; - else if (!strcmp (level, "none")) - opt.debug = 0; - else if (!strcmp (level, "basic")) - opt.debug = DBG_ASSUAN_VALUE; - else if (!strcmp (level, "advanced")) - opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE; - else if (!strcmp (level, "expert")) - opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE - |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE); - else if (!strcmp (level, "guru")) - opt.debug = ~0; - else - { - log_error (_("invalid debug-level `%s' given\n"), level); - gpgsm_exit(2); - } - - - if (opt.debug && !opt.verbose) - { - opt.verbose = 1; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - } - if (opt.debug && opt.quiet) - opt.quiet = 0; - - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CRYPTO_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); -} - - - -static void -set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd) -{ - enum cmd_and_opt_values cmd = *ret_cmd; - - if (!cmd || cmd == new_cmd) - cmd = new_cmd; - else if ( cmd == aSign && new_cmd == aEncr ) - cmd = aSignEncr; - else if ( cmd == aEncr && new_cmd == aSign ) - cmd = aSignEncr; - else if ( (cmd == aSign && new_cmd == aClearsign) - || (cmd == aClearsign && new_cmd == aSign) ) - cmd = aClearsign; - else - { - log_error(_("conflicting commands\n")); - gpgsm_exit(2); - } - - *ret_cmd = cmd; -} - - -/* Helper to add recipients to a list. */ -static void -do_add_recipient (ctrl_t ctrl, const char *name, - certlist_t *recplist, int is_encrypt_to) -{ - int rc = gpgsm_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to); - if (rc) - { - log_error (_("can't encrypt to `%s': %s\n"), name, gpg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - "0", - name, NULL); - } -} - - -int -main ( int argc, char **argv) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - char **orig_argv; - const char *fname; - /* char *username;*/ - int may_coredump; - STRLIST sl, remusr= NULL, locusr=NULL; - STRLIST nrings=NULL; - int detached_sig = 0; - FILE *configfp = NULL; - char *configname = NULL; - unsigned configlineno; - int parse_debug = 0; - int no_more_options = 0; - int default_config =1; - int default_keyring = 1; - char *logfile = NULL; - int greeting = 0; - int nogreeting = 0; - int debug_wait = 0; - const char *debug_level = NULL; - int use_random_seed = 1; - int with_fpr = 0; - char *def_digest_string = NULL; - enum cmd_and_opt_values cmd = 0; - struct server_control_s ctrl; - CERTLIST recplist = NULL; - CERTLIST signerlist = NULL; - int do_not_setup_keys = 0; - - /* trap_unaligned ();*/ - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* We don't need any locking in libgcrypt unless we use any kind of - threading. */ - gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); - - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to secmem_init() - somewhere after the option parsing */ - log_set_prefix ("gpgsm", 1); - - /* Try to auto set the character set. */ - set_native_charset (NULL); - - /* Check that the libraries are suitable. Do it here because the - option parse may need services of the library */ - if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) - { - log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), - NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); - } - if (!ksba_check_version (NEED_KSBA_VERSION) ) - { - log_fatal( _("libksba is too old (need %s, have %s)\n"), - NEED_KSBA_VERSION, ksba_check_version (NULL) ); - } - - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - gnupg_init_signals (0, emergency_cleanup); - - create_dotlock (NULL); /* register locking cleanup */ - i18n_init(); - - opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/ -#ifdef __MINGW32__ - opt.homedir = read_w32_registry_string ( NULL, - "Software\\GNU\\GnuPG", "HomeDir" ); -#else - opt.homedir = getenv ("GNUPGHOME"); -#endif - if (!opt.homedir || !*opt.homedir ) - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - - /* first check whether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ - while (arg_parse( &pargs, opts)) - { - if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll) - parse_debug++; - else if (pargs.r_opt == oOptions) - { /* yes there is one, so we do not try the default one but - read the config file when it is encountered at the - commandline */ - default_config = 0; - } - else if (pargs.r_opt == oNoOptions) - default_config = 0; /* --no-options */ - else if (pargs.r_opt == oHomedir) - opt.homedir = pargs.r.ret_str; - else if (pargs.r_opt == aCallProtectTool) - break; /* This break makes sure that --version and --help are - passed to the protect-tool. */ - } - - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are now working under our real uid - */ - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - assuan_set_assuan_log_stream (log_get_stream ()); - assuan_set_assuan_log_prefix (log_get_prefix (NULL)); - - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - /* Setup a default control structure for command line mode */ - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - ctrl.no_server = 1; - ctrl.status_fd = -1; /* not status output */ - ctrl.autodetect_encoding = 1; - - /* set the default option file */ - if (default_config ) - configname = make_filename (opt.homedir, "gpgsm.conf", NULL); - /* cet the default policy file */ - opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags = 1; /* do not remove the args */ - - next_pass: - if (configname) { - configlineno = 0; - configfp = fopen (configname, "r"); - if (!configfp) - { - if (default_config) - { - if (parse_debug) - log_info (_("NOTE: no default option file `%s'\n"), configname); - } - else - { - log_error (_("option file `%s': %s\n"), configname, strerror(errno)); - gpgsm_exit(2); - } - xfree(configname); - configname = NULL; - } - if (parse_debug && configname) - log_info (_("reading options from `%s'\n"), configname); - default_config = 0; - } - - while (!no_more_options - && optfile_parse (configfp, configname, &configlineno, &pargs, opts)) - { - switch (pargs.r_opt) - { - case aGPGConfList: - set_cmd (&cmd, pargs.r_opt); - do_not_setup_keys = 1; - nogreeting = 1; - break; - - case aServer: - opt.batch = 1; - set_cmd (&cmd, aServer); - break; - - case aCallDirmngr: - opt.batch = 1; - set_cmd (&cmd, aCallDirmngr); - do_not_setup_keys = 1; - break; - - case aCallProtectTool: - opt.batch = 1; - set_cmd (&cmd, aCallProtectTool); - no_more_options = 1; /* Stop parsing. */ - do_not_setup_keys = 1; - break; - - case aDeleteKey: - set_cmd (&cmd, aDeleteKey); - /*greeting=1;*/ - do_not_setup_keys = 1; - break; - - case aDetachedSign: - detached_sig = 1; - set_cmd (&cmd, aSign ); - break; - - case aKeygen: - set_cmd (&cmd, aKeygen); - greeting=1; - do_not_setup_keys = 1; - break; - - case aCheckKeys: - case aImport: - case aSendKeys: - case aRecvKeys: - case aExport: - case aExportSecretKeyP12: - case aDumpKeys: - case aDumpExternalKeys: - case aDumpSecretKeys: - case aListKeys: - case aListExternalKeys: - case aListSecretKeys: - case aListSigs: - case aLearnCard: - case aPasswd: - case aKeydbClearSomeCertFlags: - do_not_setup_keys = 1; - set_cmd (&cmd, pargs.r_opt); - break; - - case aSym: - case aDecrypt: - case aEncr: - case aSign: - case aClearsign: - case aVerify: - set_cmd (&cmd, pargs.r_opt); - break; - - /* output encoding selection */ - case oArmor: - ctrl.create_pem = 1; - break; - case oBase64: - ctrl.create_pem = 0; - ctrl.create_base64 = 1; - break; - case oNoArmor: - ctrl.create_pem = 0; - ctrl.create_base64 = 0; - break; - - /* Input encoding selection */ - case oAssumeArmor: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 1; - ctrl.is_base64 = 0; - break; - case oAssumeBase64: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 1; - break; - case oAssumeBinary: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 0; - break; - - case oDisableCRLChecks: - opt.no_crl_check = 1; - break; - case oEnableCRLChecks: - opt.no_crl_check = 0; - break; - case oForceCRLRefresh: - opt.force_crl_refresh = 1; - break; - - case oDisableOCSP: - ctrl.use_ocsp = opt.enable_ocsp = 0; - break; - case oEnableOCSP: - ctrl.use_ocsp = opt.enable_ocsp = 1; - break; - - case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break; - - case oPolicyFile: - xfree (opt.policy_file); - if (*pargs.r.ret_str) - opt.policy_file = xstrdup (pargs.r.ret_str); - else - opt.policy_file = NULL; - break; - - case oDisablePolicyChecks: - opt.no_policy_check = 1; - break; - case oEnablePolicyChecks: - opt.no_policy_check = 0; - break; - - case oAutoIssuerKeyRetrieve: - opt.auto_issuer_key_retrieve = 1; - break; - - case oOutput: opt.outfile = pargs.r.ret_str; break; - - - case oQuiet: opt.quiet = 1; break; - case oNoTTY: /* fixme:tty_no_terminal(1);*/ break; - case oDryRun: opt.dry_run = 1; break; - - case oVerbose: - opt.verbose++; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - case oNoVerbose: - opt.verbose = 0; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - - case oLogFile: logfile = pargs.r.ret_str; break; - - case oBatch: - opt.batch = 1; - greeting = 0; - break; - case oNoBatch: opt.batch = 0; break; - - case oAnswerYes: opt.answer_yes = 1; break; - case oAnswerNo: opt.answer_no = 1; break; - - case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugLevel: debug_level = pargs.r.ret_str; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugAllowCoreDump: - may_coredump = enable_core_dumps (); - break; - case oDebugNoChainValidation: opt.no_chain_validation = 1; break; - case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break; - - case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break; - case oLoggerFD: log_set_fd (pargs.r.ret_int ); break; - case oWithMD5Fingerprint: - opt.with_md5_fingerprint=1; /*fall thru*/ - case oWithFingerprint: - with_fpr=1; /*fall thru*/ - case oFingerprint: - opt.fingerprint++; - break; - - case oOptions: - /* config files may not be nested (silently ignore them) */ - if (!configfp) - { - xfree(configname); - configname = xstrdup (pargs.r.ret_str); - goto next_pass; - } - break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break; - case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break; - case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break; - case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; - case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; - case oProtectToolProgram: - opt.protect_tool_program = pargs.r.ret_str; - break; - - case oFakedSystemTime: - gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0); - break; - - case oNoDefKeyring: default_keyring = 0; break; - case oNoGreeting: nogreeting = 1; break; - - case oDefaultKey: - /* fixme:opt.def_secret_key = pargs.r.ret_str;*/ - break; - case oDefRecipient: - if (*pargs.r.ret_str) - opt.def_recipient = xstrdup (pargs.r.ret_str); - break; - case oDefRecipientSelf: - xfree (opt.def_recipient); - opt.def_recipient = NULL; - opt.def_recipient_self = 1; - break; - case oNoDefRecipient: - xfree (opt.def_recipient); - opt.def_recipient = NULL; - opt.def_recipient_self = 0; - break; - - case oWithKeyData: opt.with_key_data=1; /* fall thru */ - case oWithColons: ctrl.with_colons = 1; break; - case oWithValidation: ctrl.with_validation=1; break; - - case oSkipVerify: opt.skip_verify=1; break; - - case oNoEncryptTo: opt.no_encrypt_to = 1; break; - case oEncryptTo: /* Store the recipient in the second list */ - sl = add_to_strlist (&remusr, pargs.r.ret_str); - sl->flags = 1; - break; - - case oRecipient: /* store the recipient */ - add_to_strlist ( &remusr, pargs.r.ret_str); - break; - - case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break; - case oTextmode: /*fixme:opt.textmode=1;*/ break; - - case oUser: /* store the local users, the first one is the default */ - if (!opt.local_user) - opt.local_user = pargs.r.ret_str; - add_to_strlist (&locusr, pargs.r.ret_str); - break; - - case oNoSecmemWarn: - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - break; - - case oCipherAlgo: - opt.def_cipher_algoid = pargs.r.ret_str; - break; - - case oDisableCipherAlgo: - { - int algo = gcry_cipher_map_name (pargs.r.ret_str); - gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo); - } - break; - case oDisablePubkeyAlgo: - { - int algo = gcry_pk_map_name (pargs.r.ret_str); - gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo ); - } - break; - - case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - case oNoRandomSeedFile: use_random_seed = 0; break; - - case oEnableSpecialFilenames: allow_special_filenames =1; break; - - - case aDummy: - break; - default: - pargs.err = configfp? 1:2; - break; - } - } - - if (configfp) - { - fclose (configfp); - configfp = NULL; - /* Keep a copy of the config filename. */ - opt.config_filename = configname; - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - - if (!opt.config_filename) - opt.config_filename = make_filename (opt.homedir, "gpgsm.conf", NULL); - - if (log_get_errorcount(0)) - gpgsm_exit(2); - - if (nogreeting) - greeting = 0; - - if (greeting) - { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); - } -# ifdef IS_DEVELOPMENT_VERSION - if (!opt.batch) - { - log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n"); - log_info ("It is only intended for test purposes and should NOT be\n"); - log_info ("used in a production environment or with production keys!\n"); - } -# endif - - if (may_coredump && !opt.quiet) - log_info (_("WARNING: program may create a core file!\n")); - - if (logfile && cmd == aServer) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - if (gnupg_faked_time_p ()) - { - gnupg_isotime_t tbuf; - - log_info (_("WARNING: running with faked system time: ")); - gnupg_get_isotime (tbuf); - gpgsm_dump_time (tbuf); - log_printf ("\n"); - } - -/*FIXME if (opt.batch) */ -/* tty_batchmode (1); */ - - gcry_control (GCRYCTL_RESUME_SECMEM_WARN); - - set_debug (debug_level); - - /* Although we alwasy use gpgsm_exit, we better install a regualr - exit handler so that at least the secure memory gets wiped - out. */ - if (atexit (emergency_cleanup)) - { - log_error ("atexit failed\n"); - gpgsm_exit (2); - } - - /* Must do this after dropping setuid, because the mapping functions - may try to load an module and we may have disabled an algorithm. */ - if ( !gcry_cipher_map_name (opt.def_cipher_algoid) - || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid)) - log_error (_("selected cipher algorithm is invalid\n")); - - if (def_digest_string) - { - opt.def_digest_algo = gcry_md_map_name (def_digest_string); - xfree (def_digest_string); - def_digest_string = NULL; - if (our_md_test_algo(opt.def_digest_algo) ) - log_error (_("selected digest algorithm is invalid\n")); - } - - if (log_get_errorcount(0)) - gpgsm_exit(2); - - /* Set the random seed file. */ - if (use_random_seed) { - char *p = make_filename (opt.homedir, "random_seed", NULL); - gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); - xfree(p); - } - - - if (!cmd && opt.fingerprint && !with_fpr) - set_cmd (&cmd, aListKeys); - - if (!nrings && default_keyring) /* add default keybox */ - keydb_add_resource ("pubring.kbx", 0, 0); - for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 0, 0); - FREE_STRLIST(nrings); - - if (!do_not_setup_keys) - { - for (sl = locusr; sl ; sl = sl->next) - { - int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0); - if (rc) - { - log_error (_("can't sign using `%s': %s\n"), - sl->d, gpg_strerror (rc)); - gpgsm_status2 (&ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - gpg_err_code (rc) == GPG_ERR_NO_SECKEY? "9": - "0", - sl->d, NULL); - } - } - - /* Build the recipient list. We first add the regular ones and then - the encrypt-to ones because the underlying function will silenty - ignore duplicates and we can't allow to keep a duplicate which is - flagged as encrypt-to as the actually encrypt function would then - complain about no (regular) recipients. */ - for (sl = remusr; sl; sl = sl->next) - if (!(sl->flags & 1)) - do_add_recipient (&ctrl, sl->d, &recplist, 0); - if (!opt.no_encrypt_to) - { - for (sl = remusr; sl; sl = sl->next) - if ((sl->flags & 1)) - do_add_recipient (&ctrl, sl->d, &recplist, 1); - } - } - - if (log_get_errorcount(0)) - gpgsm_exit(1); /* must stop for invalid recipients */ - - fname = argc? *argv : NULL; - - switch (cmd) - { - case aGPGConfList: - { /* List options and default values in the GPG Conf format. */ - - /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ - /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL - /* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - /* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) - /* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) - /* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - - printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, opt.config_filename); - - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - printf ("disable-crl-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("enable-ocsp:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("include-certs:%lu:1:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("disable-policy-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("auto-issuer-key-retrieve:%lu:\n", - GC_OPT_FLAG_NONE ); - - } - break; - - case aServer: - if (debug_wait) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - gpgsm_server (recplist); - break; - - case aCallDirmngr: - if (!argc) - wrong_args ("--call-dirmngr <command> {args}"); - else - if (gpgsm_dirmngr_run_command (&ctrl, *argv, argc-1, argv+1)) - gpgsm_exit (1); - break; - - case aCallProtectTool: - run_protect_tool (argc, argv); - break; - - case aEncr: /* encrypt the given file */ - if (!argc) - gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */ - else - wrong_args ("--encrypt [datafile]"); - break; - - case aSign: /* sign the given file */ - /* FIXME: We don't handle --output yet. We should also allow - to concatenate multiple files for signing because that is - what gpg does.*/ - if (!argc) - gpgsm_sign (&ctrl, signerlist, - 0, detached_sig, stdout); /* create from stdin */ - else if (argc == 1) - gpgsm_sign (&ctrl, signerlist, - open_read (*argv), detached_sig, stdout); /* from file */ - else - wrong_args ("--sign [datafile]"); - break; - - case aSignEncr: /* sign and encrypt the given file */ - log_error ("this command has not yet been implemented\n"); - break; - - case aClearsign: /* make a clearsig */ - log_error ("this command has not yet been implemented\n"); - break; - - case aVerify: - { - FILE *fp = NULL; - - if (argc == 2 && opt.outfile) - log_info ("option --output ignored for a detached signature\n"); - else if (opt.outfile) - fp = open_fwrite (opt.outfile); - - if (!argc) - gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */ - else if (argc == 1) - gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */ - else if (argc == 2) /* detached signature (sig, detached) */ - gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); - else - wrong_args ("--verify [signature [detached_data]]"); - - if (fp && fp != stdout) - fclose (fp); - } - break; - - case aVerifyFiles: - log_error (_("this command has not yet been implemented\n")); - break; - - case aDecrypt: - if (!argc) - gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */ - else - wrong_args ("--decrypt [filename]"); - break; - - case aDeleteKey: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_delete (&ctrl, sl); - free_strlist(sl); - break; - - case aListSigs: - ctrl.with_chain = 1; - case aListKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6))); - free_strlist(sl); - break; - - case aDumpKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6))); - free_strlist(sl); - break; - - case aListExternalKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, - (0 | (1<<7))); - free_strlist(sl); - break; - - case aDumpExternalKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, - (256 | (1<<7))); - free_strlist(sl); - break; - - case aListSecretKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6))); - free_strlist(sl); - break; - - case aDumpSecretKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6))); - free_strlist(sl); - break; - - case aKeygen: /* generate a key */ - log_error ("this function is not yet available from the commandline\n"); - break; - - case aImport: - gpgsm_import_files (&ctrl, argc, argv, open_read); - break; - - case aExport: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_export (&ctrl, sl, stdout); - free_strlist(sl); - break; - - case aExportSecretKeyP12: - if (argc == 1) - gpgsm_p12_export (&ctrl, *argv, stdout); - else - wrong_args ("--export-secret-key-p12 KEY-ID"); - break; - - case aSendKeys: - case aRecvKeys: - log_error ("this command has not yet been implemented\n"); - break; - - - case aLearnCard: - if (argc) - wrong_args ("--learn-card"); - else - { - int rc = gpgsm_agent_learn (&ctrl); - if (rc) - log_error ("error learning card: %s\n", gpg_strerror (rc)); - } - break; - - case aPasswd: - if (argc != 1) - wrong_args ("--passwd <key-Id>"); - else - { - int rc; - ksba_cert_t cert = NULL; - char *grip = NULL; - - rc = gpgsm_find_cert (*argv, &cert); - if (rc) - ; - else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) - rc = gpg_error (GPG_ERR_BUG); - else - { - char *desc = gpgsm_format_keydesc (cert); - rc = gpgsm_agent_passwd (&ctrl, grip, desc); - xfree (desc); - } - if (rc) - log_error ("error changing passphrase: %s\n", gpg_strerror (rc)); - xfree (grip); - ksba_cert_release (cert); - } - break; - - case aKeydbClearSomeCertFlags: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - keydb_clear_some_cert_flags (&ctrl, sl); - free_strlist(sl); - break; - - - default: - log_error ("invalid command (there is no implicit command)\n"); - break; - } - - /* cleanup */ - gpgsm_release_certlist (recplist); - gpgsm_release_certlist (signerlist); - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - gpgsm_exit(0); - return 8; /*NEVER REACHED*/ -} - -/* Note: This function is used by signal handlers!. */ -static void -emergency_cleanup (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM ); -} - - -void -gpgsm_exit (int rc) -{ - gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); - if (opt.debug & DBG_MEMSTAT_VALUE) - { - gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); - gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); - } - if (opt.debug) - gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); - emergency_cleanup (); - rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0; - exit (rc); -} - - -void -gpgsm_init_default_ctrl (struct server_control_s *ctrl) -{ - ctrl->include_certs = 1; /* only include the signer's cert */ - ctrl->use_ocsp = opt.enable_ocsp; -} - - - -/* Check whether the filename has the form "-&nnnn", where n is a - non-zero number. Returns this number or -1 if it is not the case. */ -static int -check_special_filename (const char *fname) -{ - if (allow_special_filenames - && fname && *fname == '-' && fname[1] == '&' ) { - int i; - - fname += 2; - for (i=0; isdigit (fname[i]); i++ ) - ; - if ( !fname[i] ) - return atoi (fname); - } - return -1; -} - - - -/* Open the FILENAME for read and return the filedescriptor. Stop - with an error message in case of problems. "-" denotes stdin and - if special filenames are allowed the given fd is opened instead. */ -static int -open_read (const char *filename) -{ - int fd; - - if (filename[0] == '-' && !filename[1]) - return 0; /* stdin */ - fd = check_special_filename (filename); - if (fd != -1) - return fd; - fd = open (filename, O_RDONLY); - if (fd == -1) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fd; -} - -/* Open FILENAME for fwrite and return the stream. Stop with an error - message in case of problems. "-" denotes stdout and if special - filenames are allowed the given fd is opened instead. Caller must - close the returned stream unless it is stdout. */ -static FILE * -open_fwrite (const char *filename) -{ - int fd; - FILE *fp; - - if (filename[0] == '-' && !filename[1]) - return stdout; - - fd = check_special_filename (filename); - if (fd != -1) - { - fp = fdopen (dup (fd), "wb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - gpgsm_exit (2); - } - return fp; - } - fp = fopen (filename, "wb"); - if (!fp) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fp; -} - - -static void -run_protect_tool (int argc, char **argv) -{ - const char *pgm; - char **av; - int i; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgm = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgm = opt.protect_tool_program; - - av = xcalloc (argc+2, sizeof *av); - av[0] = strrchr (pgm, '/'); - if (!av[0]) - av[0] = xstrdup (pgm); - for (i=1; argc; i++, argc--, argv++) - av[i] = *argv; - av[i] = NULL; - execv (pgm, av); - log_error ("error executing `%s': %s\n", pgm, strerror (errno)); - gpgsm_exit (2); -} diff --git a/sm/gpgsm.h b/sm/gpgsm.h deleted file mode 100644 index 786a97353..000000000 --- a/sm/gpgsm.h +++ /dev/null @@ -1,311 +0,0 @@ -/* gpgsm.h - Global definitions for GpgSM - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPGSM_H -#define GPGSM_H - -#ifdef GPG_ERR_SOURCE_DEFAULT -#error GPG_ERR_SOURCE_DEFAULT already defined -#endif -#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGSM -#include <gpg-error.h> - -#include <ksba.h> -#include "../common/util.h" -#include "../common/errors.h" - -#define OUT_OF_CORE(a) (gpg_error (gpg_err_code_from_errno ((a)))) - -#define MAX_DIGEST_LEN 24 - -/* A large struct named "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int batch; /* run in batch mode, i.e w/o any user interaction */ - int answer_yes; /* assume yes on most questions */ - int answer_no; /* assume no on most questions */ - int dry_run; /* don't change any persistent data */ - - const char *homedir; /* Configuration directory name */ - const char *config_filename; /* Name of the used config file. */ - const char *agent_program; - char *display; - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - - const char *dirmngr_program; - const char *protect_tool_program; - char *outfile; /* name of output file */ - - int with_key_data;/* include raw key in the column delimted output */ - - int fingerprint; /* list fingerprints in all key listings */ - - int with_md5_fingerprint; /* Also print an MD5 fingerprint for - standard key listings. */ - - int armor; /* force base64 armoring (see also ctrl.with_base64) */ - int no_armor; /* don't try to figure out whether data is base64 armored*/ - - const char *def_cipher_algoid; /* cipher algorithm to use if - nothing else is specified */ - - int def_digest_algo; /* Ditto for hash algorithm */ - int def_compress_algo; /* Ditto for compress algorithm */ - - char *def_recipient; /* userID of the default recipient */ - int def_recipient_self; /* The default recipient is the default key */ - - int no_encrypt_to; /* Ignore all as encrypt to marked recipients. */ - - char *local_user; /* NULL or argument to -u */ - - int always_trust; /* Trust the given keys even if there is no - valid certification chain */ - int skip_verify; /* do not check signatures on data */ - - int lock_once; /* Keep lock once they are set */ - - int ignore_time_conflict; /* Ignore certain time conflicts */ - - int no_crl_check; /* Don't do a CRL check */ - int force_crl_refresh; /* Force refreshing the CRL. */ - int enable_ocsp; /* Default to use OCSP checks. */ - - char *policy_file; /* full pathname of policy file */ - int no_policy_check; /* ignore certificate policies */ - int no_chain_validation; /* Bypass all cert chain validity tests */ - int ignore_expiration; /* Ignore the notAfter validity checks. */ - - int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */ -} opt; - - -#define DBG_X509_VALUE 1 /* debug x.509 data reading/writing */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 /* debug assuan communication */ - -#define DBG_X509 (opt.debug & DBG_X509_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) - -struct server_local_s; - -/* Note that the default values for this are set by - gpgsm_init_default_ctrl() */ -struct server_control_s { - int no_server; /* We are not running under server control */ - int status_fd; /* Only for non-server mode */ - struct server_local_s *server_local; - int with_colons; /* Use column delimited output format */ - int with_chain; /* Include the certifying certs in a listing */ - int with_validation;/* Validate each key while listing. */ - - int autodetect_encoding; /* Try to detect the input encoding */ - int is_pem; /* Is in PEM format */ - int is_base64; /* is in plain base-64 format */ - - int create_base64; /* Create base64 encoded output */ - int create_pem; /* create PEM output */ - const char *pem_name; /* PEM name to use */ - - int include_certs; /* -1 to send all certificates in the chain - along with a signature or the number of - certificates up the chain (0 = none, 1 = only - signer) */ - int use_ocsp; /* Set to true if OCSP should be used. */ -}; -typedef struct server_control_s *CTRL; -typedef struct server_control_s *ctrl_t; - -/* data structure used in base64.c */ -typedef struct base64_context_s *Base64Context; - - -struct certlist_s { - struct certlist_s *next; - ksba_cert_t cert; - int is_encrypt_to; /* True if the certificate has been set through - the --encrypto-to option. */ -}; -typedef struct certlist_s *CERTLIST; -typedef struct certlist_s *certlist_t; - -/*-- gpgsm.c --*/ -void gpgsm_exit (int rc); -void gpgsm_init_default_ctrl (struct server_control_s *ctrl); - -/*-- server.c --*/ -void gpgsm_server (certlist_t default_recplist); -void gpgsm_status (ctrl_t ctrl, int no, const char *text); -void gpgsm_status2 (ctrl_t ctrl, int no, ...); -void gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, - gpg_err_code_t ec); - -/*-- fingerprint --*/ -char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, - char *array, int *r_len); -char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo); -char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo); -unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert); -char *gpgsm_get_keygrip (ksba_cert_t cert, char *array); -char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert); -int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); -char *gpgsm_get_certid (ksba_cert_t cert); - - -/*-- base64.c --*/ -int gpgsm_create_reader (Base64Context *ctx, - ctrl_t ctrl, FILE *fp, int allow_multi_pem, - ksba_reader_t *r_reader); -int gpgsm_reader_eof_seen (Base64Context ctx); -void gpgsm_destroy_reader (Base64Context ctx); -int gpgsm_create_writer (Base64Context *ctx, - ctrl_t ctrl, FILE *fp, ksba_writer_t *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); - - -/*-- certdump.c --*/ -void gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p); -void gpgsm_print_time (FILE *fp, ksba_isotime_t t); -void gpgsm_print_name (FILE *fp, const char *string); - -void gpgsm_dump_cert (const char *text, ksba_cert_t cert); -void gpgsm_dump_serial (ksba_const_sexp_t p); -void gpgsm_dump_time (ksba_isotime_t t); -void gpgsm_dump_string (const char *string); - -char *gpgsm_format_serial (ksba_const_sexp_t p); -char *gpgsm_format_name (const char *name); - -char *gpgsm_format_keydesc (ksba_cert_t cert); - - -/*-- certcheck.c --*/ -int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert); -int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, - gcry_md_hd_t md, int hash_algo); -/* fixme: move create functions to another file */ -int gpgsm_create_cms_signature (ctrl_t ctrl, - ksba_cert_t cert, gcry_md_hd_t md, int mdalgo, - char **r_sigval); - - -/*-- certchain.c --*/ -int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next); -int gpgsm_is_root_cert (ksba_cert_t cert); -int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, - ksba_isotime_t r_exptime, - int listmode, FILE *listfp, - unsigned int flags); -int gpgsm_basic_cert_check (ksba_cert_t cert); - -/*-- certlist.c --*/ -int gpgsm_cert_use_sign_p (ksba_cert_t cert); -int gpgsm_cert_use_encrypt_p (ksba_cert_t cert); -int gpgsm_cert_use_verify_p (ksba_cert_t cert); -int gpgsm_cert_use_decrypt_p (ksba_cert_t cert); -int gpgsm_cert_use_cert_p (ksba_cert_t cert); -int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, - certlist_t *listaddr, int is_encrypt_to); -int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, - certlist_t *listaddr, int is_encrypt_to); -void gpgsm_release_certlist (certlist_t list); -int gpgsm_find_cert (const char *name, ksba_cert_t *r_cert); - -/*-- keylist.c --*/ -gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names, - FILE *fp, unsigned int mode); - -/*-- import.c --*/ -int gpgsm_import (ctrl_t ctrl, int in_fd); -int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, - int (*of)(const char *fname)); - -/*-- export.c --*/ -void gpgsm_export (ctrl_t ctrl, STRLIST names, FILE *fp); -void gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp); - -/*-- delete.c --*/ -int gpgsm_delete (ctrl_t ctrl, STRLIST names); - -/*-- verify.c --*/ -int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp); - -/*-- sign.c --*/ -int gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert); -int gpgsm_sign (ctrl_t ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp); - -/*-- encrypt.c --*/ -int gpgsm_encrypt (ctrl_t ctrl, CERTLIST recplist, int in_fd, FILE *out_fp); - -/*-- decrypt.c --*/ -int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp); - -/*-- certreqgen.c --*/ -int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp); - -/*-- call-agent.c --*/ -int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, - unsigned char *digest, - size_t digestlen, - int digestalgo, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, - ksba_const_sexp_t ciphertext, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_genkey (ctrl_t ctrl, - ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey); -int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert); -int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip); -int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert); -int gpgsm_agent_learn (ctrl_t ctrl); -int gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc); - -/*-- call-dirmngr.c --*/ -int gpgsm_dirmngr_isvalid (ctrl_t ctrl, - ksba_cert_t cert, ksba_cert_t issuer_cert, - int use_ocsp); -int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names, - void (*cb)(void*, ksba_cert_t), void *cb_value); -int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, - int argc, char **argv); - - -/*-- misc.c --*/ -void setup_pinentry_env (void); - - - -#endif /*GPGSM_H*/ diff --git a/sm/import.c b/sm/import.c deleted file mode 100644 index c5581eb64..000000000 --- a/sm/import.c +++ /dev/null @@ -1,725 +0,0 @@ -/* import.c - Import certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#include <signal.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - -struct stats_s { - unsigned long count; - unsigned long imported; - unsigned long unchanged; - unsigned long not_imported; - unsigned long secret_read; - unsigned long secret_imported; - unsigned long secret_dups; - }; - - -static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp, - struct stats_s *stats); - - - -static void -print_imported_status (CTRL ctrl, ksba_cert_t cert, int new_cert) -{ - char *fpr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (new_cert) - gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL); - - gpgsm_status2 (ctrl, STATUS_IMPORT_OK, - new_cert? "1":"0", fpr, NULL); - - xfree (fpr); -} - - -/* Print an IMPORT_PROBLEM status. REASON is one of: - 0 := "No specific reason given". - 1 := "Invalid Certificate". - 2 := "Issuer Certificate missing". - 3 := "Certificate Chain too long". - 4 := "Error storing certificate". -*/ -static void -print_import_problem (CTRL ctrl, ksba_cert_t cert, int reason) -{ - char *fpr = NULL; - char buf[25]; - int i; - - sprintf (buf, "%d", reason); - if (cert) - { - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - /* detetect an error (all high) value */ - for (i=0; fpr[i] == 'F'; i++) - ; - if (!fpr[i]) - { - xfree (fpr); - fpr = NULL; - } - } - gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL); - xfree (fpr); -} - - -void -print_imported_summary (CTRL ctrl, struct stats_s *stats) -{ - char buf[14*25]; - - if (!opt.quiet) - { - log_info (_("total number processed: %lu\n"), stats->count); - if (stats->imported) - { - log_info (_(" imported: %lu"), stats->imported ); - log_printf ("\n"); - } - if (stats->unchanged) - log_info (_(" unchanged: %lu\n"), stats->unchanged); - if (stats->secret_read) - log_info (_(" secret keys read: %lu\n"), stats->secret_read ); - if (stats->secret_imported) - log_info (_(" secret keys imported: %lu\n"), stats->secret_imported ); - if (stats->secret_dups) - log_info (_(" secret keys unchanged: %lu\n"), stats->secret_dups ); - if (stats->not_imported) - log_info (_(" not imported: %lu\n"), stats->not_imported); - } - - sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", - stats->count, - 0l /*stats->no_user_id*/, - stats->imported, - 0l /*stats->imported_rsa*/, - stats->unchanged, - 0l /*stats->n_uids*/, - 0l /*stats->n_subk*/, - 0l /*stats->n_sigs*/, - 0l /*stats->n_revoc*/, - stats->secret_read, - stats->secret_imported, - stats->secret_dups, - 0l /*stats->skipped_new_keys*/, - stats->not_imported - ); - gpgsm_status (ctrl, STATUS_IMPORT_RES, buf); -} - - - -static void -check_and_store (CTRL ctrl, struct stats_s *stats, ksba_cert_t cert, int depth) -{ - int rc; - - if (stats) - stats->count++; - if ( depth >= 50 ) - { - log_error (_("certificate chain too long\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, 3); - return; - } - - /* Some basic checks, but don't care about missing certificates; - this is so that we are able to import entire certificate chains - w/o requirening a special order (i.e. root-CA first). This used - to be different but because gpgsm_verify even imports - certificates without any checks, it doesn't matter much and the - code gets much cleaner. A housekeeping function to remove - certificates w/o an anchor would be nice, though. */ - rc = gpgsm_basic_cert_check (cert); - if (!rc || gpg_err_code (rc) == GPG_ERR_MISSING_CERT) - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - ksba_cert_t next = NULL; - - if (!existed) - { - print_imported_status (ctrl, cert, 1); - if (stats) - stats->imported++; - } - else - { - print_imported_status (ctrl, cert, 0); - if (stats) - stats->unchanged++; - } - - if (opt.verbose > 1 && existed) - { - if (depth) - log_info ("issuer certificate already in DB\n"); - else - log_info ("certificate already in DB\n"); - } - else if (opt.verbose && !existed) - { - if (depth) - log_info ("issuer certificate imported\n"); - else - log_info ("certificate imported\n"); - } - - /* Now lets walk up the chain and import all certificates up - the chain. This is required in case we already stored - parent certificates in the ephemeral keybox. Do not - update the statistics, though. */ - if (!gpgsm_walk_cert_chain (cert, &next)) - { - check_and_store (ctrl, NULL, next, depth+1); - ksba_cert_release (next); - } - } - else - { - log_error (_("error storing certificate\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, 4); - } - } - else - { - log_error (_("basic certificate checks failed - not imported\n")); - if (stats) - stats->not_imported++; - print_import_problem (ctrl, cert, - gpg_err_code (rc) == GPG_ERR_MISSING_CERT? 2 : - gpg_err_code (rc) == GPG_ERR_BAD_CERT? 1 : 0); - } -} - - - - -static int -import_one (CTRL ctrl, struct stats_s *stats, int in_fd) -{ - int rc; - Base64Context b64reader = NULL; - ksba_reader_t reader; - ksba_cert_t cert = NULL; - ksba_cms_t cms = NULL; - FILE *fp = NULL; - ksba_content_type_t ct; - int any = 0; - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - - /* We need to loop here to handle multiple PEM objects in one - file. */ - do - { - ksba_cms_release (cms); cms = NULL; - ksba_cert_release (cert); cert = NULL; - - ct = ksba_cms_identify (reader); - if (ct == KSBA_CT_SIGNED_DATA) - { /* This is probably a signed-only message - import the certs */ - ksba_stop_reason_t stopreason; - int i; - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, NULL); - if (rc) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - log_info ("not a certs-only message\n"); - } - while (stopreason != KSBA_SR_READY); - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - check_and_store (ctrl, stats, cert, 0); - ksba_cert_release (cert); - cert = NULL; - } - if (!i) - log_error ("no certificate found\n"); - else - any = 1; - } - else if (ct == KSBA_CT_PKCS12) - { /* This seems to be a pkcs12 message. We use an external - tool to parse the message and to store the private keys. - We need to use a another reader here to parse the - certificate we included in the p12 file; then we continue - to look for other pkcs12 files (works only if they are in - PEM format. */ - FILE *certfp; - Base64Context b64p12rdr; - ksba_reader_t p12rdr; - - rc = parse_p12 (reader, &certfp, stats); - if (!rc) - { - any = 1; - - rewind (certfp); - rc = gpgsm_create_reader (&b64p12rdr, ctrl, certfp, 1, &p12rdr); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - fclose (certfp); - goto leave; - } - - do - { - ksba_cert_release (cert); cert = NULL; - rc = ksba_cert_new (&cert); - if (!rc) - { - rc = ksba_cert_read_der (cert, p12rdr); - if (!rc) - check_and_store (ctrl, stats, cert, 0); - } - ksba_reader_clear (p12rdr, NULL, NULL); - } - while (!rc && !gpgsm_reader_eof_seen (b64p12rdr)); - - if (gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - gpgsm_destroy_reader (b64p12rdr); - fclose (certfp); - if (rc) - goto leave; - } - } - else if (ct == KSBA_CT_NONE) - { /* Failed to identify this message - assume a certificate */ - - rc = ksba_cert_new (&cert); - if (rc) - goto leave; - - rc = ksba_cert_read_der (cert, reader); - if (rc) - goto leave; - - check_and_store (ctrl, stats, cert, 0); - any = 1; - } - else - { - log_error ("can't extract certificates from input\n"); - rc = gpg_error (GPG_ERR_NO_DATA); - } - - ksba_reader_clear (reader, NULL, NULL); - } - while (!gpgsm_reader_eof_seen (b64reader)); - - leave: - if (any && gpg_err_code (rc) == GPG_ERR_EOF) - rc = 0; - ksba_cms_release (cms); - ksba_cert_release (cert); - gpgsm_destroy_reader (b64reader); - if (fp) - fclose (fp); - return rc; -} - - -int -gpgsm_import (CTRL ctrl, int in_fd) -{ - int rc; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - rc = import_one (ctrl, &stats, in_fd); - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gpg_strerror (rc)); - return rc; -} - - -int -gpgsm_import_files (CTRL ctrl, int nfiles, char **files, - int (*of)(const char *fname)) -{ - int rc = 0; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - - if (!nfiles) - rc = import_one (ctrl, &stats, 0); - else - { - for (; nfiles && !rc ; nfiles--, files++) - { - int fd = of (*files); - rc = import_one (ctrl, &stats, fd); - close (fd); - if (rc == -1) - rc = 0; - } - } - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gpg_strerror (rc)); - return rc; -} - - -/* Fork and exec the protecttool, connect the file descriptor of - INFILE to stdin, return a new stream in STATUSFILE, write the - output to OUTFILE and the pid of the process in PID. Returns 0 on - success or an error code. */ -static gpg_error_t -popen_protect_tool (const char *pgmname, - FILE *infile, FILE *outfile, FILE **statusfile, pid_t *pid) -{ - gpg_error_t err; - int fd, fdout, rp[2]; - int n, i; - - fflush (infile); - rewind (infile); - fd = fileno (infile); - fdout = fileno (outfile); - if (fd == -1 || fdout == -1) - log_fatal ("no file descriptor for temporary file: %s\n", - strerror (errno)); - - /* Now start the protect-tool. */ - if (pipe (rp) == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating a pipe: %s\n"), strerror (errno)); - return err; - } - - *pid = fork (); - if (*pid == -1) - { - err = gpg_error_from_errno (errno); - log_error (_("error forking process: %s\n"), strerror (errno)); - close (rp[0]); - close (rp[1]); - return err; - } - - if (!*pid) - { /* Child. */ - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - /* Connect the infile to stdin. */ - if (fd != 0 && dup2 (fd, 0) == -1) - log_fatal ("dup2 stdin failed: %s\n", strerror (errno)); - - /* Connect the outfile to stdout. */ - if (fdout != 1 && dup2 (fdout, 1) == -1) - log_fatal ("dup2 stdout failed: %s\n", strerror (errno)); - - /* Connect stderr to our pipe. */ - if (rp[1] != 2 && dup2 (rp[1], 2) == -1) - log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); - - /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; - - setup_pinentry_env (); - - execlp (pgmname, arg0, - "--homedir", opt.homedir, - "--p12-import", - "--store", - "--no-fail-on-exist", - "--enable-status-msg", - "--", - NULL); - /* No way to print anything, as we have closed all streams. */ - _exit (31); - } - - /* Parent. */ - close (rp[1]); - *statusfile = fdopen (rp[0], "r"); - if (!*statusfile) - { - err = gpg_error_from_errno (errno); - log_error ("can't fdopen pipe for reading: %s", strerror (errno)); - kill (*pid, SIGTERM); - return err; - } - - return 0; -} - - -/* Assume that the reader is at a pkcs#12 message and try to import - certificates from that stupid format. We will alos store secret - keys. All of the pkcs#12 parsing and key storing is handled by the - gpg-protect-tool, we merely have to take care of receiving the - certificates. On success RETFP returns a temporary file with - certificates. */ -static gpg_error_t -parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats) -{ - const char *pgmname; - gpg_error_t err = 0, child_err = 0; - int i, c, cont_line; - unsigned int pos; - FILE *tmpfp, *certfp = NULL, *fp = NULL; - char buffer[1024]; - size_t nread; - pid_t pid = -1; - - if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; - else - pgmname = opt.protect_tool_program; - - *retfp = NULL; - - /* To avoid an extra feeder process or doing selects and because - gpg-protect-tool will anyway parse the entire pkcs#12 message in - memory, we simply use tempfiles here and pass them to - the gpg-protect-tool. */ - tmpfp = tmpfile (); - if (!tmpfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - while (!(err = ksba_reader_read (reader, buffer, sizeof buffer, &nread))) - { - if (nread && fwrite (buffer, nread, 1, tmpfp) != 1) - { - err = gpg_error_from_errno (errno); - log_error (_("error writing to temporary file: %s\n"), - strerror (errno)); - goto cleanup; - } - } - if (gpg_err_code (err) == GPG_ERR_EOF) - err = 0; - if (err) - { - log_error (_("error reading input: %s\n"), gpg_strerror (err)); - goto cleanup; - } - - certfp = tmpfile (); - if (!certfp) - { - err = gpg_error_from_errno (errno); - log_error (_("error creating temporary file: %s\n"), strerror (errno)); - goto cleanup; - } - - err = popen_protect_tool (pgmname, tmpfp, certfp, &fp, &pid); - if (err) - { - pid = -1; - goto cleanup; - } - fclose (tmpfp); - tmpfp = NULL; - - /* Read stderr of the protect tool. */ - pos = 0; - cont_line = 0; - while ((c=getc (fp)) != EOF) - { - /* fixme: We could here grep for status information of the - protect tool to figure out better error codes for - CHILD_ERR. */ - buffer[pos++] = c; - if (pos >= sizeof buffer - 5 || c == '\n') - { - buffer[pos - (c == '\n')] = 0; - if (cont_line) - log_printf ("%s", buffer); - else - { - if (!strncmp (buffer, "gpg-protect-tool: [PROTECT-TOOL:] ",34)) - { - char *p, *pend; - - p = buffer + 34; - pend = strchr (p, ' '); - if (pend) - *pend = 0; - if ( !strcmp (p, "secretkey-stored")) - { - stats->count++; - stats->secret_read++; - stats->secret_imported++; - } - else if ( !strcmp (p, "secretkey-exists")) - { - stats->count++; - stats->secret_read++; - stats->secret_dups++; - } - else if ( !strcmp (p, "bad-passphrase")) - ; - } - else - log_info ("%s", buffer); - } - pos = 0; - cont_line = (c != '\n'); - } - } - - if (pos) - { - buffer[pos] = 0; - if (cont_line) - log_printf ("%s\n", buffer); - else - log_info ("%s\n", buffer); - } - - /* If we found no error in the output of the cild, setup a suitable - error code, which will later be reset if the exit status of the - child is 0. */ - if (!child_err) - child_err = gpg_error (GPG_ERR_DECRYPT_FAILED); - - - cleanup: - if (tmpfp) - fclose (tmpfp); - if (fp) - fclose (fp); - if (pid != -1) - { - int status; - - while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - log_error (_("waiting for protect-tool to terminate failed: %s\n"), - strerror (errno)); - else if (WIFEXITED (status) && WEXITSTATUS (status) == 31) - log_error (_("error running `%s': probably not installed\n"), pgmname); - else if (WIFEXITED (status) && WEXITSTATUS (status)) - log_error (_("error running `%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - else if (!WIFEXITED (status)) - log_error (_("error running `%s': terminated\n"), pgmname); - else - child_err = 0; - } - if (!err) - err = child_err; - if (err) - { - if (certfp) - fclose (certfp); - } - else - *retfp = certfp; - return err; -} diff --git a/sm/keydb.c b/sm/keydb.c deleted file mode 100644 index 6c5c77364..000000000 --- a/sm/keydb.c +++ /dev/null @@ -1,1532 +0,0 @@ -/* keydb.c - key database dispatcher - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "gpgsm.h" -#include "../kbx/keybox.h" -#include "keydb.h" -#include "i18n.h" - -#define DIRSEP_C '/' - -static int active_handles; - -typedef enum { - KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYBOX -} KeydbResourceType; -#define MAX_KEYDB_RESOURCES 20 - -struct resource_item { - KeydbResourceType type; - union { - KEYBOX_HANDLE kr; - } u; - void *token; - int secret; - DOTLOCK lockhandle; -}; - -static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; -static int used_resources; - -struct keydb_handle { - int locked; - int found; - int current; - int is_ephemeral; - int used; /* items in active */ - struct resource_item active[MAX_KEYDB_RESOURCES]; -}; - - -static int lock_all (KEYDB_HANDLE hd); -static void unlock_all (KEYDB_HANDLE hd); - - -/* - * Register a resource (which currently may only be a keybox file). - * The first keybox which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - */ -int -keydb_add_resource (const char *url, int force, int secret) -{ - static int any_secret, any_public; - const char *resname = url; - char *filename = NULL; - int rc = 0; - FILE *fp; - KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; - const char *created_fname = NULL; - - /* Do we have an URL? - gnupg-kbx:filename := this is a plain keybox - filename := See what is is, but create as plain keybox. - */ - if (strlen (resname) > 10) - { - if (!strncmp (resname, "gnupg-kbx:", 10) ) - { - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - resname += 10; - } -#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) - { - log_error ("invalid key resource URL `%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } -#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ - } - - if (*resname != DIRSEP_C ) - { /* do tilde expansion etc */ - if (strchr(resname, DIRSEP_C) ) - filename = make_filename (resname, NULL); - else - filename = make_filename (opt.homedir, resname, NULL); - } - else - filename = xstrdup (resname); - - if (!force) - force = secret? !any_secret : !any_public; - - /* see whether we can determine the filetype */ - if (rt == KEYDB_RESOURCE_TYPE_NONE) - { - FILE *fp2 = fopen( filename, "rb" ); - - if (fp2) { - u32 magic; - - /* FIXME: check for the keybox magic */ - if (fread( &magic, 4, 1, fp2) == 1 ) - { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - no more support */ - else - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - else /* maybe empty: assume ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - fclose (fp2); - } - else /* no file yet: create ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - - switch (rt) - { - case KEYDB_RESOURCE_TYPE_NONE: - log_error ("unknown type of key resource `%s'\n", url ); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - - case KEYDB_RESOURCE_TYPE_KEYBOX: - fp = fopen (filename, "rb"); - if (!fp && !force) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - goto leave; - } - - if (!fp) - { /* no file */ -#if 0 /* no autocreate of the homedirectory yet */ - { - char *last_slash_in_filename; - - last_slash_in_filename = strrchr (filename, DIRSEP_C); - *last_slash_in_filename = 0; - if (access (filename, F_OK)) - { /* on the first time we try to create the default - homedir and in this case the process will be - terminated, so that on the next invocation can - read the options file in on startup */ - try_make_homedir (filename); - rc = gpg_error (GPG_ERR_FILE_OPEN_ERROR); - *last_slash_in_filename = DIRSEP_C; - goto leave; - } - *last_slash_in_filename = DIRSEP_C; - } -#endif - fp = fopen (filename, "w"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error (_("error creating keybox `%s': %s\n"), - filename, strerror(errno)); - if (errno == ENOENT) - log_info (_("you may want to start the gpg-agent first\n")); - goto leave; - } - - if (!opt.quiet) - log_info (_("keybox `%s' created\n"), filename); - created_fname = filename; - } - fclose (fp); - fp = NULL; - /* now register the file */ - { - - void *token = keybox_register_file (filename, secret); - if (!token) - ; /* already registered - ignore it */ - else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = gpg_error (GPG_ERR_RESOURCE_LIMIT); - else - { - all_resources[used_resources].type = rt; - all_resources[used_resources].u.kr = NULL; /* Not used here */ - all_resources[used_resources].token = token; - all_resources[used_resources].secret = secret; - - all_resources[used_resources].lockhandle - = create_dotlock (filename); - if (!all_resources[used_resources].lockhandle) - log_fatal ( _("can't create lock for `%s'\n"), filename); - - /* Do a compress run if needed and the file is not locked. */ - if (!make_dotlock (all_resources[used_resources].lockhandle, 0)) - { - KEYBOX_HANDLE kbxhd = keybox_new (token, secret); - - if (kbxhd) - { - keybox_compress (kbxhd); - keybox_release (kbxhd); - } - release_dotlock (all_resources[used_resources].lockhandle); - } - - used_resources++; - } - } - - - break; - default: - log_error ("resource type of `%s' not supported\n", url); - rc = gpg_error (GPG_ERR_NOT_SUPPORTED); - goto leave; - } - - /* fixme: check directory permissions and print a warning */ - - leave: - if (rc) - log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc)); - else if (secret) - any_secret = 1; - else - any_public = 1; - xfree (filename); - return rc; -} - - -KEYDB_HANDLE -keydb_new (int secret) -{ - KEYDB_HANDLE hd; - int i, j; - - hd = xcalloc (1, sizeof *hd); - hd->found = -1; - - assert (used_resources <= MAX_KEYDB_RESOURCES); - for (i=j=0; i < used_resources; i++) - { - if (!all_resources[i].secret != !secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - hd->active[j].type = all_resources[i].type; - hd->active[j].token = all_resources[i].token; - hd->active[j].secret = all_resources[i].secret; - hd->active[j].lockhandle = all_resources[i].lockhandle; - hd->active[j].u.kr = keybox_new (all_resources[i].token, secret); - if (!hd->active[j].u.kr) - { - xfree (hd); - return NULL; /* fixme: release all previously allocated handles*/ - } - j++; - break; - } - } - hd->used = j; - - active_handles++; - return hd; -} - -void -keydb_release (KEYDB_HANDLE hd) -{ - int i; - - if (!hd) - return; - assert (active_handles > 0); - active_handles--; - - unlock_all (hd); - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_release (hd->active[i].u.kr); - break; - } - } - - xfree (hd); -} - - -/* Return the name of the current resource. This is function first - looks for the last found found, then for the current search - position, and last returns the first available resource. The - returned string is only valid as long as the handle exists. This - function does only return NULL if no handle is specified, in all - other error cases an empty string is returned. */ -const char * -keydb_get_resource_name (KEYDB_HANDLE hd) -{ - int idx; - const char *s = NULL; - - if (!hd) - return NULL; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - idx = 0; - - switch (hd->active[idx].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - s = NULL; - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - s = keybox_get_resource_name (hd->active[idx].u.kr); - break; - } - - return s? s: ""; -} - -/* Switch the handle into ephemeral mode and return the orginal value. */ -int -keydb_set_ephemeral (KEYDB_HANDLE hd, int yes) -{ - int i; - - if (!hd) - return 0; - - yes = !!yes; - if (hd->is_ephemeral != yes) - { - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_set_ephemeral (hd->active[i].u.kr, yes); - break; - } - } - } - - i = hd->is_ephemeral; - hd->is_ephemeral = yes; - return i; -} - - -/* If the keyring has not yet been locked, lock it now. This - operation is required before any update opeations; it is optionaly - for an insert operation. The lock is released with - keydb_released. */ -gpg_error_t -keydb_lock (KEYDB_HANDLE hd) -{ - if (!hd) - return gpg_error (GPG_ERR_INV_HANDLE); - if (hd->locked) - return 0; /* Already locked. */ - return lock_all (hd); -} - - - -static int -lock_all (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - /* Fixme: This locking scheme may lead to deadlock if the resources - are not added in the same order by all processes. We are - currently only allowing one resource so it is not a problem. */ - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - rc = make_dotlock (hd->active[i].lockhandle, -1); - break; - } - if (rc) - break; - } - - if (rc) - { - /* revert the already set locks */ - for (i--; i >= 0; i--) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - break; - } - } - } - else - hd->locked = 1; - - /* make_dotlock () does not yet guarantee that errno is set, thus - we can't rely on the error reason and will simply use - EACCES. */ - return rc? gpg_error (GPG_ERR_EACCES) : 0; -} - -static void -unlock_all (KEYDB_HANDLE hd) -{ - int i; - - if (!hd->locked) - return; - - for (i=hd->used-1; i >= 0; i--) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - break; - } - } - hd->locked = 0; -} - - -#if 0 -/* - * Return the last found keybox. Caller must free it. - * The returned keyblock has the kbode flag bit 0 set for the node with - * the public key used to locate the keyblock or flag bit 1 set for - * the user ID node. - */ -int -keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) -{ - int rc = 0; - - if (!hd) - return G10ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb); - break; - } - - return rc; -} - -/* - * update the current keyblock with KB - */ -int -keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = 0; - - if (!hd) - return G10ERR_INV_ARG; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * Insert a new KB into one of the resources. - */ -int -keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb) -{ - int rc = -1; - int idx; - - if (!hd) - return G10ERR_INV_ARG; - - if( opt.dry_run ) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return G10ERR_GENERAL; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - -#endif /*disabled code*/ - - - -/* - Return the last found object. Caller must free it. The returned - keyblock has the kbode flag bit 0 set for the node with the public - key used to locate the keyblock or flag bit 1 set for the user ID - node. */ -int -keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert) -{ - int rc = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert); - break; - } - - return rc; -} - -/* Return a flag of the last found object. WHICH is the flag requested; - it should be one of the KEYBOX_FLAG_ values. If the operation is - successful, the flag value will be stored at the address given by - VALUE. Return 0 on success or an error code. */ -gpg_error_t -keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value) -{ - int err = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - err = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value); - break; - } - - return err; -} - -/* Set a flag of the last found object. WHICH is the flag to be set; it - should be one of the KEYBOX_FLAG_ values. If the operation is - successful, the flag value will be stored in the keybox. Note, - that some flag values can't be updated and thus may return an - error, some other flag values may be masked out before an update. - Returns 0 on success or an error code. */ -gpg_error_t -keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value) -{ - int err = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return gpg_error (GPG_ERR_NOTHING_FOUND); - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - err = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value); - break; - } - - return err; -} - -/* - * Insert a new Certificate into one of the resources. - */ -int -keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert) -{ - int rc = -1; - int idx; - char digest[20]; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if (opt.dry_run) - return 0; - - if ( hd->found >= 0 && hd->found < hd->used) - idx = hd->found; - else if ( hd->current >= 0 && hd->current < hd->used) - idx = hd->current; - else - return gpg_error (GPG_ERR_GENERAL); - - rc = lock_all (hd); - if (rc) - return rc; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[idx].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - - -/* update the current keyblock with KB */ -int -keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert) -{ - int rc = 0; - char digest[20]; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if (opt.dry_run) - return 0; - - rc = lock_all (hd); - if (rc) - return rc; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * The current keyblock or cert will be deleted. - */ -int -keydb_delete (KEYDB_HANDLE hd) -{ - int rc = -1; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - if( opt.dry_run ) - return 0; - - if (!hd->locked) - return gpg_error (GPG_ERR_NOT_LOCKED); - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = gpg_error (GPG_ERR_GENERAL); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_delete (hd->active[hd->found].u.kr); - break; - } - - unlock_all (hd); - return rc; -} - - - -/* - * Locate the default writable key resource, so that the next - * operation (which is only relevant for inserts) will be done on this - * resource. - */ -int -keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) -{ - int rc; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - rc = keydb_search_reset (hd); /* this does reset hd->current */ - if (rc) - return rc; - - for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (keybox_is_writable (hd->active[hd->current].token)) - return 0; /* found (hd->current is set to it) */ - break; - } - } - - return -1; -} - -/* - * Rebuild the caches of all key resources. - */ -void -keydb_rebuild_caches (void) -{ - int i; - - for (i=0; i < used_resources; i++) - { - if (all_resources[i].secret) - continue; - switch (all_resources[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: -/* rc = keybox_rebuild_cache (all_resources[i].token); */ -/* if (rc) */ -/* log_error (_("failed to rebuild keybox cache: %s\n"), */ -/* g10_errstr (rc)); */ - break; - } - } -} - - - -/* - * Start the next search on this handle right at the beginning - */ -int -keydb_search_reset (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - hd->current = 0; - hd->found = -1; - /* and reset all resources */ - for (i=0; !rc && i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search_reset (hd->active[i].u.kr); - break; - } - } - return rc; /* fixme: we need to map error codes or share them with - all modules*/ -} - -/* - * Search through all keydb resources, starting at the current position, - * for a keyblock which contains one of the keys described in the DESC array. - */ -int -keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) -{ - int rc = -1; - - if (!hd) - return gpg_error (GPG_ERR_INV_VALUE); - - while (rc == -1 && hd->current >= 0 && hd->current < hd->used) - { - switch (hd->active[hd->current].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - BUG(); /* we should never see it here */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc); - break; - } - if (rc == -1) /* EOF -> switch to next resource */ - hd->current++; - else if (!rc) - hd->found = hd->current; - } - - return rc; -} - - -int -keydb_search_first (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_next (KEYDB_HANDLE hd) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_LONG_KID; -/* desc.u.kid[0] = kid[0]; */ -/* desc.u.kid[1] = kid[1]; */ - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) -{ - KEYDB_SEARCH_DESC desc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_FPR; - memcpy (desc.u.fpr, fpr, 20); - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, ksba_const_sexp_t serial) -{ - KEYDB_SEARCH_DESC desc; - int rc; - const unsigned char *s; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN; - s = serial; - if (*s !='(') - return gpg_error (GPG_ERR_INV_VALUE); - s++; - for (desc.snlen = 0; digitp (s); s++) - desc.snlen = 10*desc.snlen + atoi_1 (s); - if (*s !=':') - return gpg_error (GPG_ERR_INV_VALUE); - desc.sn = s+1; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_subject (KEYDB_HANDLE hd, const char *name) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_SUBJECT; - desc.u.name = name; - rc = keydb_search (hd, &desc, 1); - return rc; -} - - -static int -hextobyte (const unsigned char *s) -{ - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if ( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if ( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if ( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if ( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if ( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - - -static int -classify_user_id (const char *name, - KEYDB_SEARCH_DESC *desc, - int *force_exact ) -{ - const char *s; - int hexprefix = 0; - int hexlength; - int mode = 0; - - /* clear the structure so that the mode field is set to zero unless - * we set it to the correct value right at the end of this function */ - memset (desc, 0, sizeof *desc); - *force_exact = 0; - /* Skip leading spaces. Fixme: what about trailing white space? */ - for(s = name; *s && spacep (s); s++ ) - ; - - switch (*s) - { - case 0: /* empty string is an error */ - return 0; - - case '.': /* an email address, compare from end */ - mode = KEYDB_SEARCH_MODE_MAILEND; - s++; - desc->u.name = s; - break; - - case '<': /* an email address */ - mode = KEYDB_SEARCH_MODE_MAIL; - s++; - desc->u.name = s; - break; - - case '@': /* part of an email address */ - mode = KEYDB_SEARCH_MODE_MAILSUB; - s++; - desc->u.name = s; - break; - - case '=': /* exact compare */ - mode = KEYDB_SEARCH_MODE_EXACT; - s++; - desc->u.name = s; - break; - - case '*': /* case insensitive substring search */ - mode = KEYDB_SEARCH_MODE_SUBSTR; - s++; - desc->u.name = s; - break; - - case '+': /* compare individual words */ - mode = KEYDB_SEARCH_MODE_WORDS; - s++; - desc->u.name = s; - break; - - case '/': /* subject's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBJECT; - break; - - case '#': - { - const char *si; - - s++; - if ( *s == '/') - { /* "#/" indicates an issuer's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER; - } - else - { /* serialnumber + optional issuer ID */ - for (si=s; *si && *si != '/'; si++) - { - if (!strchr("01234567890abcdefABCDEF", *si)) - return 0; /* invalid digit in serial number*/ - } - desc->sn = s; - desc->snlen = -1; - if (!*si) - mode = KEYDB_SEARCH_MODE_SN; - else - { - s = si+1; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER_SN; - } - } - } - break; - - case ':': /*Unified fingerprint */ - { - const char *se, *si; - int i; - - se = strchr (++s,':'); - if (!se) - return 0; - for (i=0,si=s; si < se; si++, i++ ) - { - if (!strchr("01234567890abcdefABCDEF", *si)) - return 0; /* invalid digit */ - } - if (i != 32 && i != 40) - return 0; /* invalid length of fpr*/ - for (i=0,si=s; si < se; i++, si +=2) - desc->u.fpr[i] = hextobyte(si); - for (; i < 20; i++) - desc->u.fpr[i]= 0; - s = se + 1; - mode = KEYDB_SEARCH_MODE_FPR; - } - break; - - default: - if (s[0] == '0' && s[1] == 'x') - { - hexprefix = 1; - s += 2; - } - - hexlength = strspn(s, "0123456789abcdefABCDEF"); - if (hexlength >= 8 && s[hexlength] =='!') - { - *force_exact = 1; - hexlength++; /* just for the following check */ - } - - /* check if a hexadecimal number is terminated by EOS or blank */ - if (hexlength && s[hexlength] && !spacep (s+hexlength)) - { - if (hexprefix) /* a "0x" prefix without correct */ - return 0; /* termination is an error */ - /* The first chars looked like a hex number, but really is - not */ - hexlength = 0; - } - - if (*force_exact) - hexlength--; /* remove the bang */ - - if (hexlength == 8 - || (!hexprefix && hexlength == 9 && *s == '0')) - { /* short keyid */ - unsigned long kid; - if (hexlength == 9) - s++; - kid = strtoul( s, NULL, 16 ); - desc->u.kid[4] = kid >> 24; - desc->u.kid[5] = kid >> 16; - desc->u.kid[6] = kid >> 8; - desc->u.kid[7] = kid; - mode = KEYDB_SEARCH_MODE_SHORT_KID; - } - else if (hexlength == 16 - || (!hexprefix && hexlength == 17 && *s == '0')) - { /* complete keyid */ - unsigned long kid0, kid1; - char buf[9]; - if (hexlength == 17) - s++; - mem2str(buf, s, 9 ); - kid0 = strtoul (buf, NULL, 16); - kid1 = strtoul (s+8, NULL, 16); - desc->u.kid[0] = kid0 >> 24; - desc->u.kid[1] = kid0 >> 16; - desc->u.kid[2] = kid0 >> 8; - desc->u.kid[3] = kid0; - desc->u.kid[4] = kid1 >> 24; - desc->u.kid[5] = kid1 >> 16; - desc->u.kid[6] = kid1 >> 8; - desc->u.kid[7] = kid1; - mode = KEYDB_SEARCH_MODE_LONG_KID; - } - else if (hexlength == 32 - || (!hexprefix && hexlength == 33 && *s == '0')) - { /* md5 fingerprint */ - int i; - if (hexlength == 33) - s++; - memset(desc->u.fpr+16, 0, 4); - for (i=0; i < 16; i++, s+=2) - { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR16; - } - else if (hexlength == 40 - || (!hexprefix && hexlength == 41 && *s == '0')) - { /* sha1/rmd160 fingerprint */ - int i; - if (hexlength == 41) - s++; - for (i=0; i < 20; i++, s+=2) - { - int c = hextobyte(s); - if (c == -1) - return 0; - desc->u.fpr[i] = c; - } - mode = KEYDB_SEARCH_MODE_FPR20; - } - else if (!hexprefix) - { - /* The fingerprint in an X.509 listing is often delimited by - colons, so we try to single this case out. */ - mode = 0; - hexlength = strspn (s, ":0123456789abcdefABCDEF"); - if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) - { - int i; - - for (i=0; i < 20; i++, s += 3) - { - int c = hextobyte(s); - if (c == -1 || (i < 19 && s[2] != ':')) - break; - desc->u.fpr[i] = c; - } - if (i == 20) - mode = KEYDB_SEARCH_MODE_FPR20; - } - if (!mode) /* default is substring search */ - { - *force_exact = 0; - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBSTR; - } - } - else - { /* hex number with a prefix but a wrong length */ - return 0; - } - } - - desc->mode = mode; - return mode; -} - - -int -keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc) -{ - int dummy; - KEYDB_SEARCH_DESC dummy_desc; - - if (!desc) - desc = &dummy_desc; - - if (!classify_user_id (name, desc, &dummy)) - return gpg_error (GPG_ERR_INV_NAME); - return 0; -} - - -/* Store the certificate in the key DB but make sure that it does not - already exists. We do this simply by comparing the fingerprint. - If EXISTED is not NULL it will be set to true if the certificate - was already in the DB. */ -int -keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) -{ - KEYDB_HANDLE kh; - int rc; - unsigned char fpr[20]; - - if (existed) - *existed = 0; - - if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL)) - { - log_error (_("failed to get the fingerprint\n")); - return gpg_error (GPG_ERR_GENERAL); - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocate keyDB handle\n")); - return gpg_error (GPG_ERR_ENOMEM);; - } - - if (ephemeral) - keydb_set_ephemeral (kh, 1); - - rc = keydb_search_fpr (kh, fpr); - if (rc != -1) - { - keydb_release (kh); - if (!rc) - { - if (existed) - *existed = 1; - return 0; /* okay */ - } - log_error (_("problem looking for existing certificate: %s\n"), - gpg_strerror (rc)); - return rc; - } - - rc = keydb_locate_writable (kh, 0); - if (rc) - { - log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc)); - keydb_release (kh); - return rc; - } - - rc = keydb_insert_cert (kh, cert); - if (rc) - { - log_error (_("error storing certificate: %s\n"), gpg_strerror (rc)); - keydb_release (kh); - return rc; - } - keydb_release (kh); - return 0; -} - - -/* This is basically keydb_set_flags but it implements a complete - transaction by locating the certificate in the DB and updating the - flags. */ -gpg_error_t -keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value) -{ - KEYDB_HANDLE kh; - gpg_error_t err; - unsigned char fpr[20]; - unsigned int old_value; - - if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL)) - { - log_error (_("failed to get the fingerprint\n")); - return gpg_error (GPG_ERR_GENERAL); - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocate keyDB handle\n")); - return gpg_error (GPG_ERR_ENOMEM);; - } - - err = keydb_lock (kh); - if (err) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - - err = keydb_search_fpr (kh, fpr); - if (err) - { - log_error (_("problem re-searching certificate: %s\n"), - gpg_strerror (err)); - keydb_release (kh); - return err; - } - - err = keydb_get_flags (kh, which, idx, &old_value); - if (err) - { - log_error (_("error getting stored flags: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - if (value != old_value) - { - err = keydb_set_flags (kh, which, idx, value); - if (err) - { - log_error (_("error storing flags: %s\n"), gpg_strerror (err)); - keydb_release (kh); - return err; - } - } - keydb_release (kh); - return 0; -} - - -/* Reset all the certificate flags we have stored with the certificates - for performance reasons. */ -void -keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names) -{ - gpg_error_t err; - KEYDB_HANDLE hd = NULL; - KEYDB_SEARCH_DESC *desc = NULL; - int ndesc; - STRLIST sl; - int rc=0; - unsigned int old_value, value; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("allocating memory failed: %s\n", - gpg_strerror (OUT_OF_CORE (errno))); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - } - - err = keydb_lock (hd); - if (err) - { - log_error (_("error locking keybox: %s\n"), gpg_strerror (err)); - goto leave; - } - - while (!(rc = keydb_search (hd, desc, ndesc))) - { - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value); - if (err) - { - log_error (_("error getting stored flags: %s\n"), - gpg_strerror (err)); - goto leave; - } - - value = (old_value & ~VALIDITY_REVOKED); - if (value != old_value) - { - err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value); - if (err) - { - log_error (_("error storing flags: %s\n"), gpg_strerror (err)); - goto leave; - } - } - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - - leave: - xfree (desc); - keydb_release (hd); -} - - diff --git a/sm/keydb.h b/sm/keydb.h deleted file mode 100644 index 924ad77c4..000000000 --- a/sm/keydb.h +++ /dev/null @@ -1,85 +0,0 @@ -/* keydb.h - Key database - * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GNUPG_KEYDB_H -#define GNUPG_KEYDB_H - -#include <ksba.h> - -#include "../kbx/keybox-search-desc.h" - -typedef struct keydb_handle *KEYDB_HANDLE; - -/* Flag value used with KEYBOX_FLAG_VALIDITY. */ -#define VALIDITY_REVOKED (1<<5) - - -/*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret); -KEYDB_HANDLE keydb_new (int secret); -void keydb_release (KEYDB_HANDLE hd); -int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); -const char *keydb_get_resource_name (KEYDB_HANDLE hd); -gpg_error_t keydb_lock (KEYDB_HANDLE hd); - -#if 0 /* pgp stuff */ -int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); -int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb); -int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb); -#endif - -gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, - unsigned int *value); -gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, - unsigned int value); -int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert); -int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert); -int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert); - -int keydb_delete (KEYDB_HANDLE hd); - -int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); -void keydb_rebuild_caches (void); - -int keydb_search_reset (KEYDB_HANDLE hd); -int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keydb_search_first (KEYDB_HANDLE hd); -int keydb_search_next (KEYDB_HANDLE hd); -int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); -int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); -int keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer); -int keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, const unsigned char *serial); -int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer); - -int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc); - -int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed); -gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, - unsigned int value); - -void keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names); - - -#endif /*GNUPG_KEYDB_H*/ - - - - diff --git a/sm/keylist.c b/sm/keylist.c deleted file mode 100644 index 27c67ded3..000000000 --- a/sm/keylist.c +++ /dev/null @@ -1,1252 +0,0 @@ -/* keylist.c - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" - -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ -#include "i18n.h" - -struct list_external_parm_s { - ctrl_t ctrl; - FILE *fp; - int print_header; - int with_colons; - int with_chain; - int raw_mode; -}; - - -/* This table is to map Extended Key Usage OIDs to human readable - names. */ -struct { - const char *oid; - const char *name; -} key_purpose_map[] = { - { "1.3.6.1.5.5.7.3.1", "serverAuth" }, - { "1.3.6.1.5.5.7.3.2", "clientAuth" }, - { "1.3.6.1.5.5.7.3.3", "codeSigning" }, - { "1.3.6.1.5.5.7.3.4", "emailProtection" }, - { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" }, - { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" }, - { "1.3.6.1.5.5.7.3.7", "ipsecUser" }, - { "1.3.6.1.5.5.7.3.8", "timeStamping" }, - { "1.3.6.1.5.5.7.3.9", "ocspSigning" }, - { "1.3.6.1.5.5.7.3.10", "dvcs" }, - { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" }, - { "1.3.6.1.5.5.7.3.13", "eapOverPPP" }, - { "1.3.6.1.5.5.7.3.14", "wlanSSID" }, - { NULL, NULL } -}; - - -/* A table mapping OIDs to a descriptive string. */ -static struct { - char *oid; - char *name; - unsigned int flag; -} oidtranstbl[] = { - - /* Algorithms. */ - { "1.2.840.10040.4.1", "dsa" }, - { "1.2.840.10040.4.3", "dsaWithSha1" }, - - { "1.2.840.113549.1.1.1", "rsaEncryption" }, - { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" }, - { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" }, - { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" }, - { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" }, - { "1.2.840.113549.1.1.7", "rsaOAEP" }, - { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" }, - { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" }, - { "1.2.840.113549.1.1.10", "rsaPSS" }, - { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" }, - { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" }, - { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" }, - - { "1.3.14.3.2.26", "sha1" }, - { "1.3.14.3.2.29", "sha-1WithRSAEncryption" }, - { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" }, - - - /* Telesec extensions. */ - { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" }, - { "0.2.262.1.10.12.1", "telesecCertIdExt" }, - { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" }, - { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" }, - { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" }, - { "0.2.262.1.10.12.5", "telesecCRLFilterExt"}, - { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" }, - - /* PKIX private extensions. */ - { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" }, - { "1.3.6.1.5.5.7.1.2", "biometricInfo" }, - { "1.3.6.1.5.5.7.1.3", "qcStatements" }, - { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" }, - { "1.3.6.1.5.5.7.1.5", "acTargeting" }, - { "1.3.6.1.5.5.7.1.6", "acAaControls" }, - { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" }, - { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" }, - { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" }, - { "1.3.6.1.5.5.7.1.10", "acProxying" }, - { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" }, - - /* X.509 id-ce */ - { "2.5.29.14", "subjectKeyIdentifier"}, - { "2.5.29.15", "keyUsage", 1 }, - { "2.5.29.16", "privateKeyUsagePeriod" }, - { "2.5.29.17", "subjectAltName", 1 }, - { "2.5.29.18", "issuerAltName", 1 }, - { "2.5.29.19", "basicConstraints", 1}, - { "2.5.29.20", "cRLNumber" }, - { "2.5.29.21", "cRLReason" }, - { "2.5.29.22", "expirationDate" }, - { "2.5.29.23", "instructionCode" }, - { "2.5.29.24", "invalidityDate" }, - { "2.5.29.27", "deltaCRLIndicator" }, - { "2.5.29.28", "issuingDistributionPoint" }, - { "2.5.29.29", "certificateIssuer" }, - { "2.5.29.30", "nameConstraints" }, - { "2.5.29.31", "cRLDistributionPoints", 1 }, - { "2.5.29.32", "certificatePolicies", 1 }, - { "2.5.29.32.0", "anyPolicy" }, - { "2.5.29.33", "policyMappings" }, - { "2.5.29.35", "authorityKeyIdentifier", 1 }, - { "2.5.29.36", "policyConstraints" }, - { "2.5.29.37", "extKeyUsage", 1 }, - { "2.5.29.46", "freshestCRL" }, - { "2.5.29.54", "inhibitAnyPolicy" }, - - /* Netscape certificate extensions. */ - { "2.16.840.1.113730.1.1", "netscape-cert-type" }, - { "2.16.840.1.113730.1.2", "netscape-base-url" }, - { "2.16.840.1.113730.1.3", "netscape-revocation-url" }, - { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" }, - { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" }, - { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" }, - { "2.16.840.1.113730.1.9", "netscape-homePage-url" }, - { "2.16.840.1.113730.1.10", "netscape-entitylogo" }, - { "2.16.840.1.113730.1.11", "netscape-userPicture" }, - { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" }, - { "2.16.840.1.113730.1.13", "netscape-comment" }, - - { NULL } -}; - - -/* Return the description for OID; if no description is available - NULL is returned. */ -static const char * -get_oid_desc (const char *oid, unsigned int *flag) -{ - int i; - - if (oid) - for (i=0; oidtranstbl[i].oid; i++) - if (!strcmp (oidtranstbl[i].oid, oid)) - { - if (flag) - *flag = oidtranstbl[i].flag; - return oidtranstbl[i].name; - } - if (flag) - *flag = 0; - return NULL; -} - - -static void -print_key_data (ksba_cert_t cert, FILE *fp) -{ -#if 0 - int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0; - int i; - - for(i=0; i < n; i++ ) - { - fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) ); - mpi_print(stdout, pk->pkey[i], 1 ); - putchar(':'); - putchar('\n'); - } -#endif -} - -static void -print_capabilities (ksba_cert_t cert, FILE *fp) -{ - gpg_error_t err; - unsigned int use; - - err = ksba_cert_get_key_usage (cert, &use); - if (gpg_err_code (err) == GPG_ERR_NO_DATA) - { - putc ('e', fp); - putc ('s', fp); - putc ('c', fp); - putc ('E', fp); - putc ('S', fp); - putc ('C', fp); - return; - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - gpg_strerror (err)); - return; - } - - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('e', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('s', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('c', fp); - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('E', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('S', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('C', fp); -} - - -static void -print_time (gnupg_isotime_t t, FILE *fp) -{ - if (!t || !*t) - ; - else - fputs (t, fp); -} - - -/* return an allocated string with the email address extracted from a - DN */ -static char * -email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - - -/* List one certificate in colon mode */ -static void -list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, - FILE *fp, int have_secret) -{ - int rc; - int idx; - char truststring[2]; - char *p; - ksba_sexp_t sexp; - char *fpr; - ksba_isotime_t t; - gpg_error_t valerr; - int algo; - unsigned int nbits; - const char *chain_id; - char *chain_id_buffer = NULL; - int is_root = 0; - - if (ctrl->with_validation) - valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0); - else - valerr = 0; - - - /* We need to get the fingerprint and the chaining ID in advance. */ - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - { - ksba_cert_t next; - - rc = gpgsm_walk_cert_chain (cert, &next); - if (!rc) /* We known the issuer's certificate. */ - { - p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1); - chain_id_buffer = p; - chain_id = chain_id_buffer; - ksba_cert_release (next); - } - else if (rc == -1) /* We have reached the root certificate. */ - { - chain_id = fpr; - is_root = 1; - } - else - chain_id = NULL; - } - - - fputs (have_secret? "crs:":"crt:", fp); - truststring[0] = 0; - truststring[1] = 0; - if ((validity & VALIDITY_REVOKED) - || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED) - *truststring = 'r'; - else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED) - *truststring = 'e'; - else if (valerr) - *truststring = 'i'; - else - { - /* Lets also check whether the certificate under question - expired. This is merely a hack until we found a proper way - to store the expiration flag in the keybox. */ - ksba_isotime_t current_time, not_after; - - gnupg_get_isotime (current_time); - if (!opt.ignore_expiration - && !ksba_cert_get_validity (cert, 1, not_after) - && *not_after && strcmp (current_time, not_after) > 0 ) - *truststring = 'e'; - } - - /* Is we have no truststring yet (i.e. the certificate might be - good) and this is a root certificate, we ask the agent whether - this is a trusted root certificate. */ - if (!*truststring && is_root) - { - rc = gpgsm_agent_istrusted (ctrl, cert); - if (!rc) - *truststring = 'u'; /* Yes, we trust this one (ultimately). */ - else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) - *truststring = 'n'; /* No, we do not trust this one. */ - /* (in case of an error we can't tell anything.) */ - } - - if (*truststring) - fputs (truststring, fp); - - algo = gpgsm_get_key_algo_info (cert, &nbits); - fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24); - - /* We assume --fixed-list-mode for gpgsm */ - ksba_cert_get_validity (cert, 0, t); - print_time (t, fp); - putc (':', fp); - ksba_cert_get_validity (cert, 1, t); - print_time ( t, fp); - putc (':', fp); - /* Field 8, serial number: */ - if ((sexp = ksba_cert_get_serial (cert))) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp,"%02X", *s); - } - xfree (sexp); - } - putc (':', fp); - /* Field 9, ownertrust - not used here */ - putc (':', fp); - /* field 10, old user ID - we use it here for the issuer DN */ - if ((p = ksba_cert_get_issuer (cert,0))) - { - print_sanitized_string (fp, p, ':'); - xfree (p); - } - putc (':', fp); - /* Field 11, signature class - not used */ - putc (':', fp); - /* Field 12, capabilities: */ - print_capabilities (cert, fp); - putc (':', fp); - putc ('\n', fp); - - /* FPR record */ - fprintf (fp, "fpr:::::::::%s:::", fpr); - /* Print chaining ID (field 13)*/ - if (chain_id) - fputs (chain_id, fp); - putc (':', fp); - putc ('\n', fp); - xfree (fpr); fpr = NULL; chain_id = NULL; - xfree (chain_id_buffer); chain_id_buffer = NULL; - - if (opt.with_key_data) - { - if ( (p = gpgsm_get_keygrip_hexstring (cert))) - { - fprintf (fp, "grp:::::::::%s:\n", p); - xfree (p); - } - print_key_data (cert, fp); - } - - for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++) - { - fprintf (fp, "uid:%s::::::::", truststring); - print_sanitized_string (fp, p, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - if (!idx) - { - /* It would be better to get the faked email address from - the keydb. But as long as we don't have a way to pass - the meta data back, we just check it the same way as the - code used to create the keybox meta data does */ - char *pp = email_kludge (p); - if (pp) - { - fprintf (fp, "uid:%s::::::::", truststring); - print_sanitized_string (fp, pp, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - xfree (pp); - } - } - xfree (p); - } -} - - -static void -print_name_raw (FILE *fp, const char *string) -{ - if (!string) - fputs ("[error]", fp); - else - print_sanitized_string (fp, string, 0); -} - -static void -print_names_raw (FILE *fp, int indent, ksba_name_t name) -{ - int idx; - const char *s; - int indent_all; - - if ((indent_all = (indent < 0))) - indent = - indent; - - if (!name) - { - fputs ("none\n", fp); - return; - } - - for (idx=0; (s = ksba_name_enum (name, idx)); idx++) - { - char *p = ksba_name_get_uri (name, idx); - printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s); - xfree (p); - } -} - - -/* List one certificate in raw mode useful to have a closer look at - the certificate. This one does not beautification and only minimal - output sanitation. It is mainly useful for debugging. */ -static void -list_cert_raw (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, - int with_validation) -{ - gpg_error_t err; - size_t off, len; - ksba_sexp_t sexp; - char *dn; - ksba_isotime_t t; - int idx, i; - int is_ca, chainlen; - unsigned int kusage; - char *string, *p, *pend; - const char *oid, *s; - ksba_name_t name, name2; - unsigned int reason; - - sexp = ksba_cert_get_serial (cert); - fputs ("Serial number: ", fp); - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - - dn = ksba_cert_get_issuer (cert, 0); - fputs (" Issuer: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (" aka: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = ksba_cert_get_subject (cert, 0); - fputs (" Subject: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (" aka: ", fp); - print_name_raw (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = gpgsm_get_fingerprint_string (cert, 0); - fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error"); - xfree (dn); - - dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5); - fprintf (fp, " md5_fpr: %s\n", dn?dn:"error"); - xfree (dn); - - ksba_cert_get_validity (cert, 0, t); - fputs (" notBefore: ", fp); - gpgsm_print_time (fp, t); - putc ('\n', fp); - fputs (" notAfter: ", fp); - ksba_cert_get_validity (cert, 1, t); - gpgsm_print_time (fp, t); - putc ('\n', fp); - - oid = ksba_cert_get_digest_algo (cert); - s = get_oid_desc (oid, NULL); - fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":""); - - { - const char *algoname; - unsigned int nbits; - - algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); - fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?"); - } - - /* authorityKeyIdentifier */ - fputs (" authKeyId: ", fp); - err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp); - if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) - { - if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name) - fputs ("[none]\n", fp); - else - { - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - print_names_raw (fp, -15, name); - ksba_name_release (name); - } - } - else - fputs ("[?]\n", fp); - - fputs (" keyUsage:", fp); - err = ksba_cert_get_key_usage (cert, &kusage); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, " [error: %s]", gpg_strerror (err)); - else - { - if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE)) - fputs (" digitalSignature", fp); - if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION)) - fputs (" nonRepudiation", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) - fputs (" keyEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT)) - fputs (" dataEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT)) - fputs (" keyAgreement", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - fputs (" certSign", fp); - if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN)) - fputs (" crlSign", fp); - if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY)) - fputs (" encipherOnly", fp); - if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY)) - fputs (" decipherOnly", fp); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - fputs (" extKeyUsage: ", fp); - err = ksba_cert_get_ext_key_usages (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp); - p = pend; - if (*p != 'C') - fputs (" (suggested)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs ("\n ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - - fputs (" policies: ", fp); - err = ksba_cert_get_cert_policies (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (p, fp); - p = pend; - if (*p == 'C') - fputs (" (critical)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs ("\n ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - else - fputs ("[none]\n", fp); - - fputs (" chainLength: ", fp); - err = ksba_cert_is_ca (cert, &is_ca, &chainlen); - if (err || is_ca) - { - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else if (chainlen == -1) - fputs ("unlimited", fp); - else - fprintf (fp, "%d", chainlen); - putc ('\n', fp); - } - else - fputs ("not a CA\n", fp); - - - /* CRL distribution point */ - for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2, - &reason)) ;idx++) - { - fputs (" crlDP: ", fp); - print_names_raw (fp, 15, name); - if (reason) - { - fputs (" reason: ", fp); - if ( (reason & KSBA_CRLREASON_UNSPECIFIED)) - fputs (" unused", stdout); - if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE)) - fputs (" keyCompromise", stdout); - if ( (reason & KSBA_CRLREASON_CA_COMPROMISE)) - fputs (" caCompromise", stdout); - if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED)) - fputs (" affiliationChanged", stdout); - if ( (reason & KSBA_CRLREASON_SUPERSEDED)) - fputs (" superseded", stdout); - if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION)) - fputs (" cessationOfOperation", stdout); - if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD)) - fputs (" certificateHold", stdout); - putchar ('\n'); - } - fputs (" issuer: ", fp); - print_names_raw (fp, 23, name2); - ksba_name_release (name); - ksba_name_release (name2); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" crlDP: [error]\n", fp); - else if (!idx) - fputs (" crlDP: [none]\n", fp); - - - /* authorityInfoAccess. */ - for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string, - &name)); idx++) - { - fputs (" authInfo: ", fp); - s = get_oid_desc (string, NULL); - fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":""); - print_names_raw (fp, -15, name); - ksba_name_release (name); - ksba_free (string); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" authInfo: [error]\n", fp); - else if (!idx) - fputs (" authInfo: [none]\n", fp); - - /* subjectInfoAccess. */ - for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string, - &name)); idx++) - { - fputs (" subjectInfo: ", fp); - s = get_oid_desc (string, NULL); - fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":""); - print_names_raw (fp, -15, name); - ksba_name_release (name); - ksba_free (string); - } - if (err && gpg_err_code (err) != GPG_ERR_EOF) - fputs (" subjInfo: [error]\n", fp); - else if (!idx) - fputs (" subjInfo: [none]\n", fp); - - - for (idx=0; !(err=ksba_cert_get_extension (cert, idx, - &oid, &i, &off, &len));idx++) - { - unsigned int flag; - - s = get_oid_desc (oid, &flag); - - if (!(flag & 1)) - fprintf (fp, " %s: %s%s%s%s [%d octets]\n", - i? "critExtn":" extn", - oid, s?" (":"", s?s:"", s?")":"", (int)len); - } - - - if (with_validation) - { - err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0); - if (!err) - fprintf (fp, " [certificate is good]\n"); - else - fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err)); - } -} - - - - -/* List one certificate in standard mode */ -static void -list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, - int with_validation) -{ - gpg_error_t err; - ksba_sexp_t sexp; - char *dn; - ksba_isotime_t t; - int idx, i; - int is_ca, chainlen; - unsigned int kusage; - char *string, *p, *pend; - - sexp = ksba_cert_get_serial (cert); - fputs ("Serial number: ", fp); - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - - dn = ksba_cert_get_issuer (cert, 0); - fputs (" Issuer: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = ksba_cert_get_subject (cert, 0); - fputs (" Subject: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - ksba_cert_get_validity (cert, 0, t); - fputs (" validity: ", fp); - gpgsm_print_time (fp, t); - fputs (" through ", fp); - ksba_cert_get_validity (cert, 1, t); - gpgsm_print_time (fp, t); - putc ('\n', fp); - - - { - const char *algoname; - unsigned int nbits; - - algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); - fprintf (fp, " key type: %u bit %s\n", nbits, algoname? algoname:"?"); - } - - - err = ksba_cert_get_key_usage (cert, &kusage); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs (" key usage:", fp); - if (err) - fprintf (fp, " [error: %s]", gpg_strerror (err)); - else - { - if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE)) - fputs (" digitalSignature", fp); - if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION)) - fputs (" nonRepudiation", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) - fputs (" keyEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT)) - fputs (" dataEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT)) - fputs (" keyAgreement", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - fputs (" certSign", fp); - if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN)) - fputs (" crlSign", fp); - if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY)) - fputs (" encipherOnly", fp); - if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY)) - fputs (" decipherOnly", fp); - } - putc ('\n', fp); - } - - err = ksba_cert_get_ext_key_usages (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs ("ext key usage: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - p = string; - while (p && (pend=strchr (p, ':'))) - { - *pend++ = 0; - for (i=0; key_purpose_map[i].oid; i++) - if ( !strcmp (key_purpose_map[i].oid, p) ) - break; - fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp); - p = pend; - if (*p != 'C') - fputs (" (suggested)", fp); - if ((p = strchr (p, '\n'))) - { - p++; - fputs (", ", fp); - } - } - xfree (string); - } - putc ('\n', fp); - } - - err = ksba_cert_get_cert_policies (cert, &string); - if (gpg_err_code (err) != GPG_ERR_NO_DATA) - { - fputs (" policies: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else - { - for (p=string; *p; p++) - { - if (*p == '\n') - *p = ','; - } - print_sanitized_string (fp, string, 0); - xfree (string); - } - putc ('\n', fp); - } - - err = ksba_cert_is_ca (cert, &is_ca, &chainlen); - if (err || is_ca) - { - fputs (" chain length: ", fp); - if (err) - fprintf (fp, "[error: %s]", gpg_strerror (err)); - else if (chainlen == -1) - fputs ("unlimited", fp); - else - fprintf (fp, "%d", chainlen); - putc ('\n', fp); - } - - if (opt.with_md5_fingerprint) - { - dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5); - fprintf (fp, " md5 fpr: %s\n", dn?dn:"error"); - xfree (dn); - } - - dn = gpgsm_get_fingerprint_string (cert, 0); - fprintf (fp, " fingerprint: %s\n", dn?dn:"error"); - xfree (dn); - - if (with_validation) - { - err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0); - if (!err) - fprintf (fp, " [certificate is good]\n"); - else - fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err)); - } -} - - -/* Same as standard mode mode list all certifying certs too. */ -static void -list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode, - FILE *fp, int with_validation) -{ - ksba_cert_t next = NULL; - - if (raw_mode) - list_cert_raw (ctrl, cert, fp, 0, with_validation); - else - list_cert_std (ctrl, cert, fp, 0, with_validation); - ksba_cert_ref (cert); - while (!gpgsm_walk_cert_chain (cert, &next)) - { - ksba_cert_release (cert); - fputs ("Certified by\n", fp); - if (raw_mode) - list_cert_raw (ctrl, next, fp, 0, with_validation); - else - list_cert_std (ctrl, next, fp, 0, with_validation); - cert = next; - } - ksba_cert_release (cert); - putc ('\n', fp); -} - - - -/* List all internal keys or just the keys given as NAMES. MODE is a - bit vector to specify what keys are to be included; see - gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw - output mode will be used intead of the standard beautified one. - */ -static gpg_error_t -list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp, - unsigned int mode, int raw_mode) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - STRLIST sl; - int ndesc; - ksba_cert_t cert = NULL; - gpg_error_t rc = 0; - const char *lastresname, *resname; - int have_secret; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - rc = gpg_error_from_errno (errno); - log_error ("out of core\n"); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gpg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - - } - - /* It would be nice to see which of the given users did actually - match one in the keyring. To implement this we need to have a - found flag for each entry in desc and to set this we must check - all those entries after a match to mark all matched one - - currently we stop at the first match. To do this we need an - extra flag to enable this feature so */ - - lastresname = NULL; - while (!(rc = keydb_search (hd, desc, ndesc))) - { - unsigned int validity; - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity); - if (rc) - { - log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc)); - goto leave; - } - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - resname = keydb_get_resource_name (hd); - - if (lastresname != resname ) - { - int i; - - if (ctrl->no_server) - { - fprintf (fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', fp); - lastresname = resname; - } - } - - have_secret = 0; - if (mode) - { - char *p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - rc = gpgsm_agent_havekey (ctrl, p); - if (!rc) - have_secret = 1; - else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY) - goto leave; - rc = 0; - xfree (p); - } - } - - if (!mode - || ((mode & 1) && !have_secret) - || ((mode & 2) && have_secret) ) - { - if (ctrl->with_colons) - list_cert_colon (ctrl, cert, validity, fp, have_secret); - else if (ctrl->with_chain) - list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation); - else - { - if (raw_mode) - list_cert_raw (ctrl, cert, fp, have_secret, - ctrl->with_validation); - else - list_cert_std (ctrl, cert, fp, have_secret, - ctrl->with_validation); - putc ('\n', fp); - } - } - ksba_cert_release (cert); - cert = NULL; - } - if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 ) - rc = 0; - if (rc) - log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); - - leave: - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); - return rc; -} - - - -static void -list_external_cb (void *cb_value, ksba_cert_t cert) -{ - struct list_external_parm_s *parm = cb_value; - - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing certificate as ephemeral\n"); - - if (parm->print_header) - { - const char *resname = "[external keys]"; - int i; - - fprintf (parm->fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', parm->fp); - parm->print_header = 0; - } - - if (parm->with_colons) - list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0); - else if (parm->with_chain) - list_cert_chain (parm->ctrl, cert, parm->raw_mode, parm->fp, 0); - else - { - if (parm->raw_mode) - list_cert_raw (parm->ctrl, cert, parm->fp, 0, 0); - else - list_cert_std (parm->ctrl, cert, parm->fp, 0, 0); - putc ('\n', parm->fp); - } -} - - -/* List external keys similar to internal one. Note: mode does not - make sense here because it would be unwise to list external secret - keys */ -static gpg_error_t -list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode) -{ - int rc; - struct list_external_parm_s parm; - - parm.fp = fp; - parm.ctrl = ctrl, - parm.print_header = ctrl->no_server; - parm.with_colons = ctrl->with_colons; - parm.with_chain = ctrl->with_chain; - parm.raw_mode = raw_mode; - - rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm); - if (rc) - log_error ("listing external keys failed: %s\n", gpg_strerror (rc)); - return rc; -} - -/* List all keys or just the key given as NAMES. - MODE controls the operation mode: - Bit 0-2: - 0 = list all public keys but don't flag secret ones - 1 = list only public keys - 2 = list only secret keys - 3 = list secret and public keys - Bit 6: list internal keys - Bit 7: list external keys - Bit 8: Do a raw format dump. - */ -gpg_error_t -gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode) -{ - gpg_error_t err = 0; - - if ((mode & (1<<6))) - err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256)); - if (!err && (mode & (1<<7))) - err = list_external_keys (ctrl, names, fp, (mode&256)); - return err; -} diff --git a/sm/misc.c b/sm/misc.c deleted file mode 100644 index 281056177..000000000 --- a/sm/misc.c +++ /dev/null @@ -1,65 +0,0 @@ -/* misc.c - Miscellaneous fucntions - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif - -#include "gpgsm.h" - - -/* Setup the environment so that the pinentry is able to get all - required information. This is used prior to an exec of the - protect-tool. */ -void -setup_pinentry_env (void) -{ - char *lc; - - if (opt.display) - setenv ("DISPLAY", opt.display, 1); - if (opt.ttyname) - setenv ("GPG_TTY", opt.ttyname, 1); - if (opt.ttytype) - setenv ("TERM", opt.ttytype, 1); - - if (opt.lc_ctype) - setenv ("LC_CTYPE", opt.lc_ctype, 1); -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - else if ( (lc = setlocale (LC_CTYPE, "")) ) - setenv ("LC_CTYPE", lc, 1); -#endif - - if (opt.lc_messages) - setenv ("LC_MESSAGES", opt.lc_messages, 1); -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - else if ( (lc = setlocale (LC_MESSAGES, "")) ) - setenv ("LC_MESSAGES", lc, 1); -#endif - -} - diff --git a/sm/server.c b/sm/server.c deleted file mode 100644 index 72bf74afa..000000000 --- a/sm/server.c +++ /dev/null @@ -1,1121 +0,0 @@ -/* server.c - Server mode and main entry point - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> -#include <unistd.h> - -#include <assuan.h> - -#include "gpgsm.h" - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - - -/* The filepointer for status message used in non-server mode */ -static FILE *statusfp; - -/* Data used to assuciate an Assuan context with local server data */ -struct server_local_s { - assuan_context_t assuan_ctx; - int message_fd; - int list_internal; - int list_external; - certlist_t recplist; - certlist_t signerlist; - certlist_t default_recplist; /* As set by main() - don't release. */ -}; - - - -/* Note that it is sufficient to allocate the target string D as - long as the source string S, i.e.: strlen(s)+1; */ -static void -strcpy_escaped_plus (char *d, const unsigned char *s) -{ - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d++ = xtoi_2 ( s); - s += 2; - } - else if (*s == '+') - *d++ = ' ', s++; - else - *d++ = *s++; - } - *d = 0; -} - - - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - -static void -close_message_fd (CTRL ctrl) -{ - if (ctrl->server_local->message_fd != -1) - { - close (ctrl->server_local->message_fd); - ctrl->server_local->message_fd = -1; - } -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - if (!strcmp (key, "include-certs")) - { - int i = *value? atoi (value) : -1; - if (ctrl->include_certs < -2) - return ASSUAN_Parameter_Error; - ctrl->include_certs = i; - } - else if (!strcmp (key, "display")) - { - if (opt.display) - free (opt.display); - opt.display = strdup (value); - if (!opt.display) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttyname")) - { - if (opt.ttyname) - free (opt.ttyname); - opt.ttyname = strdup (value); - if (!opt.ttyname) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttytype")) - { - if (opt.ttytype) - free (opt.ttytype); - opt.ttytype = strdup (value); - if (!opt.ttytype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-ctype")) - { - if (opt.lc_ctype) - free (opt.lc_ctype); - opt.lc_ctype = strdup (value); - if (!opt.lc_ctype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-messages")) - { - if (opt.lc_messages) - free (opt.lc_messages); - opt.lc_messages = strdup (value); - if (!opt.lc_messages) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "list-mode")) - { - int i = *value? atoi (value) : 0; - if (!i || i == 1) /* default and mode 1 */ - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 0; - } - else if (i == 2) - { - ctrl->server_local->list_internal = 0; - ctrl->server_local->list_external = 1; - } - else if (i == 3) - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 1; - } - else - return ASSUAN_Parameter_Error; - } - else if (!strcmp (key, "with-validation")) - { - int i = *value? atoi (value) : 0; - ctrl->with_validation = i; - } - else - return ASSUAN_Invalid_Option; - - return 0; -} - - - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - gpgsm_release_certlist (ctrl->server_local->recplist); - gpgsm_release_certlist (ctrl->server_local->signerlist); - ctrl->server_local->recplist = NULL; - ctrl->server_local->signerlist = NULL; - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); -} - - -static void -input_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->autodetect_encoding = 0; - ctrl->is_pem = 0; - ctrl->is_base64 = 0; - if (strstr (line, "--armor")) - ctrl->is_pem = 1; - else if (strstr (line, "--base64")) - ctrl->is_base64 = 1; - else if (strstr (line, "--binary")) - ; - else - ctrl->autodetect_encoding = 1; -} - -static void -output_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->create_pem = 0; - ctrl->create_base64 = 0; - if (strstr (line, "--armor")) - ctrl->create_pem = 1; - else if (strstr (line, "--base64")) - ctrl->create_base64 = 1; /* just the raw output */ -} - - - -/* RECIPIENT <userID> - - Set the recipient for the encryption. <userID> should be the - internal representation of the key; the server may accept any other - way of specification [we will support this]. If this is a valid and - trusted recipient the server does respond with OK, otherwise the - return is an ERR with the reason why the recipient can't be used, - the encryption will then not be done for this recipient. If the - policy is not to encrypt at all if not all recipients are valid, the - client has to take care of this. All RECIPIENT commands are - cumulative until a RESET or an successful ENCRYPT command. */ -static int -cmd_recipient (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0); - if (rc) - { - gpg_err_code_t r = gpg_err_code (rc); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - "0", - line, NULL); - } - - return map_to_assuan_status (rc); -} - -/* SIGNER <userID> - - Set the signer's keys for the signature creation. <userID> should - be the internal representation of the key; the server may accept any - other way of specification [we will support this]. If this is a - valid and usable signing key the server does respond with OK, - otherwise it returns an ERR with the reason why the key can't be - used, the signing will then not be done for this key. If the policy - is not to sign at all if not all signer keys are valid, the client - has to take care of this. All SIGNER commands are cumulative until - a RESET but they are *not* reset by an SIGN command becuase it can - be expected that set of signers are used for more than one sign - operation. - - Note that this command returns an INV_RECP status which is a bit - strange, but they are very similar. */ -static int -cmd_signer (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 1, - &ctrl->server_local->signerlist, 0); - if (rc) - { - gpg_err_code_t r = gpg_err_code (rc); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - r == GPG_ERR_NO_SECKEY? "9": - "0", - line, NULL); - } - return map_to_assuan_status (rc); -} - - -/* ENCRYPT - - Do the actual encryption process. Takes the plaintext from the INPUT - command, writes to the ciphertext to the file descriptor set with - the OUTPUT command, take the recipients form all the recipients set - so far. If this command fails the clients should try to delete all - output currently done or otherwise mark it as invalid. GPGSM does - ensure that there won't be any security problem with leftover data - on the output in this case. - - This command should in general not fail, as all necessary checks - have been done while setting the recipients. The input and output - pipes are closed. */ -static int -cmd_encrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - certlist_t cl; - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - - /* Now add all encrypt-to marked recipients from the default - list. */ - rc = 0; - if (!opt.no_encrypt_to) - { - for (cl=ctrl->server_local->recplist; !rc && cl; cl = cl->next) - if (cl->is_encrypt_to) - rc = gpgsm_add_cert_to_certlist (ctrl, cl->cert, - &ctrl->server_local->recplist, 1); - } - if (!rc) - rc = gpgsm_encrypt (assuan_get_pointer (ctx), - ctrl->server_local->recplist, - inp_fd, out_fp); - fclose (out_fp); - - gpgsm_release_certlist (ctrl->server_local->recplist); - ctrl->server_local->recplist = NULL; - /* Close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return map_to_assuan_status (rc); -} - -/* DECRYPT - - This performs the decrypt operation after doing some check on the - internal state. (e.g. that only needed data has been set). Because - it utilizes the GPG-Agent for the session key decryption, there is - no need to ask the client for a protecting passphrase - GpgAgent - does take care of this by requesting this from the user. */ -static int -cmd_decrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* VERIFY - - This does a verify operation on the message send to the input-FD. - The result is written out using status lines. If an output FD was - given, the signed text will be written to that. - - If the signature is a detached one, the server will inquire about - the signed material and the client must provide it. - */ -static int -cmd_verify (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_input_fd (ctx); - int out_fd = assuan_get_output_fd (ctx); - FILE *out_fp = NULL; - - if (fd == -1) - return set_error (No_Input, NULL); - - if (out_fd != -1) - { - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - } - - rc = gpgsm_verify (assuan_get_pointer (ctx), fd, - ctrl->server_local->message_fd, out_fp); - if (out_fp) - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* SIGN [--detached] - - Sign the data set with the INPUT command and write it to the sink - set by OUTPUT. With "--detached" specified, a detached signature is - created (surprise). */ -static int -cmd_sign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int detached; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - detached = has_option (line, "--detached"); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - - rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, - inp_fd, detached, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* IMPORT - - Import the certificates read form the input-fd, return status - message for each imported one. The import checks the validity of - the certificate but not of the entire chain. It is possible to - import expired certificates. */ -static int -cmd_import (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - int fd = assuan_get_input_fd (ctx); - - if (fd == -1) - return set_error (No_Input, NULL); - - rc = gpgsm_import (assuan_get_pointer (ctx), fd); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -static int -cmd_export (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_output_fd (ctx); - FILE *out_fp; - char *p; - STRLIST list, sl; - - if (fd == -1) - return set_error (No_Output, NULL); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - out_fp = fdopen ( dup(fd), "w"); - if (!out_fp) - { - free_strlist (list); - return set_error (General_Error, "fdopen() failed"); - } - - gpgsm_export (ctrl, list, out_fp); - fclose (out_fp); - free_strlist (list); - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return 0; -} - - -static int -cmd_delkeys (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - char *p; - STRLIST list, sl; - int rc; - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - rc = gpgsm_delete (ctrl, list); - free_strlist (list); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - -/* MESSAGE FD=<n> - - Set the file descriptor to read a message which is used with - detached signatures */ -static int -cmd_message (ASSUAN_CONTEXT ctx, char *line) -{ - char *endp; - int fd; - CTRL ctrl = assuan_get_pointer (ctx); - - if (strncmp (line, "FD=", 3)) - return set_error (Syntax_Error, "FD=<n> expected"); - line += 3; - if (!digitp (line)) - return set_error (Syntax_Error, "number required"); - fd = strtoul (line, &endp, 10); - if (*endp) - return set_error (Syntax_Error, "garbage found"); - if (fd == -1) - return set_error (No_Input, NULL); - - ctrl->server_local->message_fd = fd; - return 0; -} - - -static int -do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode) -{ - CTRL ctrl = assuan_get_pointer (ctx); - FILE *fp = assuan_get_data_fp (ctx); - char *p; - STRLIST list, sl; - unsigned int listmode; - gpg_error_t err; - - if (!fp) - return set_error (General_Error, "no data stream"); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - ctrl->with_colons = 1; - listmode = mode; - if (ctrl->server_local->list_internal) - listmode |= (1<<6); - if (ctrl->server_local->list_external) - listmode |= (1<<7); - err = gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode); - free_strlist (list); - return map_to_assuan_status (err); -} - -static int -cmd_listkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 3); -} - -static int -cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 2); -} - - -/* GENKEY - - Read the parameters in native format from the input fd and write a - certificate request to the output. - */ -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_genkey (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fds */ - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "RECIPIENT", cmd_recipient }, - { "SIGNER", cmd_signer }, - { "ENCRYPT", cmd_encrypt }, - { "DECRYPT", cmd_decrypt }, - { "VERIFY", cmd_verify }, - { "SIGN", cmd_sign }, - { "IMPORT", cmd_import }, - { "EXPORT", cmd_export }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, - { "MESSAGE", cmd_message }, - { "LISTKEYS", cmd_listkeys }, - { "LISTSECRETKEYS",cmd_listsecretkeys }, - { "GENKEY", cmd_genkey }, - { "DELKEYS", cmd_delkeys }, - { NULL } - }; - int i, rc; - - for (i=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, table[i].name, table[i].handler); - if (rc) - return rc; - } - return 0; -} - -/* Startup the server. DEFAULT_RECPLIST is the list of recipients as - set from the command line or config file. We only require those - marked as encrypt-to. */ -void -gpgsm_server (certlist_t default_recplist) -{ - int rc; - int filedes[2]; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - static const char hello[] = ("GNU Privacy Guard's S/M server " - VERSION " ready"); - - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - - /* For now we use a simple pipe based server so that we can work - from scripts. We will later add options to run as a daemon and - wait for requests on a Unix domain socket */ - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to the register commands with Assuan: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - if (opt.verbose || opt.debug) - { - char *tmp = NULL; - const char *s1 = getenv ("GPG_AGENT_INFO"); - const char *s2 = getenv ("DIRMNGR_INFO"); - - if (asprintf (&tmp, - "Home: %s\n" - "Config: %s\n" - "AgentInfo: %s\n" - "DirmngrInfo: %s\n" - "%s", - opt.homedir, - opt.config_filename, - s1?s1:"[not set]", - s2?s2:"[not set]", - hello) > 0) - { - assuan_set_hello_line (ctx, tmp); - free (tmp); - } - } - else - assuan_set_hello_line (ctx, hello); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_input_notify (ctx, input_notify); - assuan_register_output_notify (ctx, output_notify); - assuan_register_option_handler (ctx, option_handler); - - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; - ctrl.server_local->list_internal = 1; - ctrl.server_local->list_external = 0; - ctrl.server_local->default_recplist = default_recplist; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - gpgsm_release_certlist (ctrl.server_local->recplist); - ctrl.server_local->recplist = NULL; - gpgsm_release_certlist (ctrl.server_local->signerlist); - ctrl.server_local->signerlist = NULL; - - assuan_deinit_server (ctx); -} - - -static const char * -get_status_string ( int no ) -{ - const char *s; - - switch (no) - { - case STATUS_ENTER : s = "ENTER"; break; - case STATUS_LEAVE : s = "LEAVE"; break; - case STATUS_ABORT : s = "ABORT"; break; - case STATUS_NEWSIG : s = "NEWSIG"; break; - case STATUS_GOODSIG: s = "GOODSIG"; break; - case STATUS_SIGEXPIRED: s = "SIGEXPIRED"; break; - case STATUS_KEYREVOKED: s = "KEYREVOKED"; break; - case STATUS_BADSIG : s = "BADSIG"; break; - case STATUS_ERRSIG : s = "ERRSIG"; break; - case STATUS_BADARMOR : s = "BADARMOR"; break; - case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break; - case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break; - case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break; - case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break; - case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break; - case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break; - case STATUS_GET_BOOL : s = "GET_BOOL"; break; - case STATUS_GET_LINE : s = "GET_LINE"; break; - case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break; - case STATUS_GOT_IT : s = "GOT_IT"; break; - case STATUS_SHM_INFO : s = "SHM_INFO"; break; - case STATUS_SHM_GET : s = "SHM_GET"; break; - case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break; - case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break; - case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break; - case STATUS_VALIDSIG : s = "VALIDSIG"; break; - case STATUS_SIG_ID : s = "SIG_ID"; break; - case STATUS_ENC_TO : s = "ENC_TO"; break; - case STATUS_NODATA : s = "NODATA"; break; - case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break; - case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break; - case STATUS_NO_SECKEY : s = "NO_SECKEY"; break; - case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break; - case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break; - case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break; - case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break; - case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break; - case STATUS_GOODMDC : s = "GOODMDC"; break; - case STATUS_BADMDC : s = "BADMDC"; break; - case STATUS_ERRMDC : s = "ERRMDC"; break; - case STATUS_IMPORTED : s = "IMPORTED"; break; - case STATUS_IMPORT_OK : s = "IMPORT_OK"; break; - case STATUS_IMPORT_RES : s = "IMPORT_RES"; break; - case STATUS_FILE_START : s = "FILE_START"; break; - case STATUS_FILE_DONE : s = "FILE_DONE"; break; - case STATUS_FILE_ERROR : s = "FILE_ERROR"; break; - case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break; - case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break; - case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break; - case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break; - case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break; - case STATUS_PROGRESS : s = "PROGRESS"; break; - case STATUS_SIG_CREATED : s = "SIG_CREATED"; break; - case STATUS_SESSION_KEY : s = "SESSION_KEY"; break; - case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break; - case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break; - case STATUS_POLICY_URL : s = "POLICY_URL" ; break; - case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break; - case STATUS_END_STREAM : s = "END_STREAM"; break; - case STATUS_KEY_CREATED : s = "KEY_CREATED"; break; - case STATUS_UNEXPECTED : s = "UNEXPECTED"; break; - case STATUS_INV_RECP : s = "INV_RECP"; break; - case STATUS_NO_RECP : s = "NO_RECP"; break; - case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break; - case STATUS_EXPSIG : s = "EXPSIG"; break; - case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; - case STATUS_TRUNCATED : s = "TRUNCATED"; break; - case STATUS_ERROR : s = "ERROR"; break; - case STATUS_IMPORT_PROBLEM : s = "IMPORT_PROBLEM"; break; - default: s = "?"; break; - } - return s; -} - - -void -gpgsm_status2 (CTRL ctrl, int no, ...) -{ - va_list arg_ptr; - const char *text; - - va_start (arg_ptr, no); - - if (ctrl->no_server) - { - if (ctrl->status_fd == -1) - return; /* no status wanted */ - if (!statusfp) - { - if (ctrl->status_fd == 1) - statusfp = stdout; - else if (ctrl->status_fd == 2) - statusfp = stderr; - else - statusfp = fdopen (ctrl->status_fd, "w"); - - if (!statusfp) - { - log_fatal ("can't open fd %d for status output: %s\n", - ctrl->status_fd, strerror(errno)); - } - } - - fputs ("[GNUPG:] ", statusfp); - fputs (get_status_string (no), statusfp); - - while ( (text = va_arg (arg_ptr, const char*) )) - { - putc ( ' ', statusfp ); - for (; *text; text++) - { - if (*text == '\n') - fputs ( "\\n", statusfp ); - else if (*text == '\r') - fputs ( "\\r", statusfp ); - else - putc ( *(const byte *)text, statusfp ); - } - } - putc ('\n', statusfp); - fflush (statusfp); - } - else - { - ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx; - char buf[950], *p; - size_t n; - - p = buf; - n = 0; - while ( (text = va_arg (arg_ptr, const char *)) ) - { - if (n) - { - *p++ = ' '; - n++; - } - for ( ; *text && n < DIM (buf)-2; n++) - *p++ = *text++; - } - *p = 0; - assuan_write_status (ctx, get_status_string (no), buf); - } - - va_end (arg_ptr); -} - -void -gpgsm_status (CTRL ctrl, int no, const char *text) -{ - gpgsm_status2 (ctrl, no, text, NULL); -} - -void -gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text, - gpg_err_code_t ec) -{ - char buf[30]; - - sprintf (buf, "%u", (unsigned int)ec); - if (text) - gpgsm_status2 (ctrl, no, text, buf, NULL); - else - gpgsm_status2 (ctrl, no, buf, NULL); -} - -#if 0 -/* - * Write a status line with a buffer using %XX escapes. If WRAP is > - * 0 wrap the line after this length. If STRING is not NULL it will - * be prepended to the buffer, no escaping is done for string. - * A wrap of -1 forces spaces not to be encoded as %20. - */ -void -write_status_text_and_buffer ( int no, const char *string, - const char *buffer, size_t len, int wrap ) -{ - const char *s, *text; - int esc, first; - int lower_limit = ' '; - size_t n, count, dowrap; - - if( !statusfp ) - return; /* not enabled */ - - if (wrap == -1) { - lower_limit--; - wrap = 0; - } - - text = get_status_string (no); - count = dowrap = first = 1; - do { - if (dowrap) { - fprintf (statusfp, "[GNUPG:] %s ", text ); - count = dowrap = 0; - if (first && string) { - fputs (string, statusfp); - count += strlen (string); - } - first = 0; - } - for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { - if ( *s == '%' || *(const byte*)s <= lower_limit - || *(const byte*)s == 127 ) - esc = 1; - if ( wrap && ++count > wrap ) { - dowrap=1; - break; - } - } - if (esc) { - s--; n++; - } - if (s != buffer) - fwrite (buffer, s-buffer, 1, statusfp ); - if ( esc ) { - fprintf (statusfp, "%%%02X", *(const byte*)s ); - s++; n--; - } - buffer = s; - len = n; - if ( dowrap && len ) - putc ( '\n', statusfp ); - } while ( len ); - - putc ('\n',statusfp); - fflush (statusfp); -} -#endif diff --git a/sm/sign.c b/sm/sign.c deleted file mode 100644 index 5deef6088..000000000 --- a/sm/sign.c +++ /dev/null @@ -1,666 +0,0 @@ -/* sign.c - Sign a message - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - - -static void -hash_data (int fd, gcry_md_hd_t md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - -static int -hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer) -{ - gpg_error_t err; - FILE *fp; - char buffer[4096]; - int nread; - int rc = 0; - int any = 0; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return tmperr; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - if (nread) - { - any = 1; - gcry_md_write (md, buffer, nread); - err = ksba_writer_write_octet_string (writer, buffer, nread, 0); - if (err) - { - log_error ("write failed: %s\n", gpg_strerror (err)); - rc = err; - } - } - } - while (nread && !rc); - if (ferror (fp)) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - } - fclose (fp); - if (!any) - { - /* We can't allow to sign an empty message because it does not - make much sense and more seriously, ksba-cms_build has - already written the tag for data and now expects an octet - string but an octet string of zeize 0 is illegal. */ - log_error ("cannot sign an empty message\n"); - rc = gpg_error (GPG_ERR_NO_DATA); - } - if (!rc) - { - err = ksba_writer_write_octet_string (writer, NULL, 0, 1); - if (err) - { - log_error ("write failed: %s\n", gpg_strerror (err)); - rc = err; - } - } - - return rc; -} - - -/* Get the default certificate which is defined as the first one our - keyDB returns and has a secret key available. */ -int -gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert) -{ - KEYDB_HANDLE hd; - ksba_cert_t cert = NULL; - int rc; - char *p; - - hd = keydb_new (0); - if (!hd) - return gpg_error (GPG_ERR_GENERAL); - rc = keydb_search_first (hd); - if (rc) - { - keydb_release (hd); - return rc; - } - - do - { - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); - keydb_release (hd); - return rc; - } - - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (ctrl, p)) - { - xfree (p); - keydb_release (hd); - *r_cert = cert; - return 0; /* got it */ - } - xfree (p); - } - - ksba_cert_release (cert); - cert = NULL; - } - while (!(rc = keydb_search_next (hd))); - if (rc && rc != -1) - log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); - - ksba_cert_release (cert); - keydb_release (hd); - return rc; -} - - -static ksba_cert_t -get_default_signer (ctrl_t ctrl) -{ - KEYDB_SEARCH_DESC desc; - ksba_cert_t cert = NULL; - KEYDB_HANDLE kh = NULL; - int rc; - - if (!opt.local_user) - { - rc = gpgsm_get_default_cert (ctrl, &cert); - if (rc) - { - if (rc != -1) - log_debug ("failed to find default certificate: %s\n", - gpg_strerror (rc)); - return NULL; - } - return cert; - } - - rc = keydb_classify_name (opt.local_user, &desc); - if (rc) - { - log_error ("failed to find default signer: %s\n", gpg_strerror (rc)); - return NULL; - } - - kh = keydb_new (0); - if (!kh) - return NULL; - - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_debug ("failed to find default certificate: rc=%d\n", rc); - } - else - { - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_debug ("failed to get cert: rc=%d\n", rc); - } - } - - keydb_release (kh); - return cert; -} - -/* Depending on the options in CTRL add the certificate CERT as well as - other certificate up in the chain to the Root-CA to the CMS - object. */ -static int -add_certificate_list (CTRL ctrl, ksba_cms_t cms, ksba_cert_t cert) -{ - gpg_error_t err; - int rc = 0; - ksba_cert_t next = NULL; - int n; - int not_root = 0; - - ksba_cert_ref (cert); - - n = ctrl->include_certs; - log_debug ("adding certificates at level %d\n", n); - if (n == -2) - { - not_root = 1; - n = -1; - } - if (n < 0 || n > 50) - n = 50; /* We better apply an upper bound */ - - /* First add my own certificate unless we don't want any certificate - included at all. */ - if (n) - { - if (not_root && gpgsm_is_root_cert (cert)) - err = 0; - else - err = ksba_cms_add_cert (cms, cert); - if (err) - goto ksba_failure; - if (n>0) - n--; - } - /* Walk the chain to include all other certificates. Note that a -1 - used for N makes sure that there is no limit and all certs get - included. */ - while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) ) - { - if (not_root && gpgsm_is_root_cert (next)) - err = 0; - else - err = ksba_cms_add_cert (cms, next); - ksba_cert_release (cert); - cert = next; next = NULL; - if (err) - goto ksba_failure; - } - ksba_cert_release (cert); - - return rc == -1? 0: rc; - - ksba_failure: - ksba_cert_release (cert); - log_error ("ksba_cms_add_cert failed: %s\n", gpg_strerror (err)); - return err; -} - - - - -/* Perform a sign operation. - - Sign the data received on DATA-FD in embedded mode or in detached - mode when DETACHED is true. Write the signature to OUT_FP. The - keys used to sign are taken from SIGNERLIST or the default one will - be used if the value of this argument is NULL. */ -int -gpgsm_sign (CTRL ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp) -{ - int i, rc; - gpg_error_t err; - Base64Context b64writer = NULL; - ksba_writer_t writer; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - KEYDB_HANDLE kh = NULL; - gcry_md_hd_t data_md = NULL; - int signer; - const char *algoid; - int algo; - ksba_isotime_t signed_at; - CERTLIST cl; - int release_signerlist = 0; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - ctrl->pem_name = "SIGNED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - err = ksba_cms_new (&cms); - if (err) - { - rc = err; - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, NULL, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* We are going to create signed data with data as encap. content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_SIGNED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - - /* If no list of signers is given, use a default one. */ - if (!signerlist) - { - ksba_cert_t cert = get_default_signer (ctrl); - if (!cert) - { - log_error ("no default signer found\n"); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - /* Although we don't check for ambigious specification we will - check that the signer's certificate is is usable and - valid. */ - rc = gpgsm_cert_use_sign_p (cert); - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, NULL, 0, NULL, 0); - if (rc) - goto leave; - - /* That one is fine - create signerlist. */ - signerlist = xtrycalloc (1, sizeof *signerlist); - if (!signerlist) - { - rc = OUT_OF_CORE (errno); - ksba_cert_release (cert); - goto leave; - } - signerlist->cert = cert; - release_signerlist = 1; - } - - - /* Gather certificates of signers and store them in the CMS object. */ - for (cl=signerlist; cl; cl = cl->next) - { - rc = gpgsm_cert_use_sign_p (cl->cert); - if (rc) - goto leave; - - err = ksba_cms_add_signer (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_signer failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - rc = add_certificate_list (ctrl, cms, cl->cert); - if (rc) - { - log_error ("failed to store list of certificates: %s\n", - gpg_strerror(rc)); - goto leave; - } - /* Set the hash algorithm we are going to use */ - err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/); - if (err) - { - log_debug ("ksba_cms_add_digest_algo failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* Prepare hashing (actually we are figuring out what we have set above)*/ - rc = gcry_md_open (&data_md, 0, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "sign.data"); - - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - gcry_md_enable (data_md, algo); - } - - if (detached) - { /* we hash the data right now so that we can store the message - digest. ksba_cms_build() takes this as an flag that detached - data is expected. */ - unsigned char *digest; - size_t digest_len; - /* Fixme do this for all signers and get the algo to use from - the signer's certificate - does not make mich sense, but we - should do this consistent as we have already done it above. */ - algo = GCRY_MD_SHA1; - hash_data (data_fd, data_md); - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - - gnupg_get_isotime (signed_at); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_signing_time (cms, signer, signed_at); - if (err) - { - log_error ("ksba_cms_set_signing_time failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - - /* We need to write at least a minimal list of our capabilities to - try to convince some MUAs to use 3DEs and not the crippled - RC2. Our list is: - - aes128-CBC - des-EDE3-CBC - */ - err = ksba_cms_add_smime_capability (cms, "2.16.840.1.101.3.4.1.2", NULL, 0); - if (!err) - err = ksba_cms_add_smime_capability (cms, "1.2.840.113549.3.7", NULL, 0); - if (err) - { - log_error ("ksba_cms_add_smime_capability failed: %s\n", - gpg_strerror (err)); - goto leave; - } - - - /* Main building loop. */ - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); - rc = err; - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - { /* hash the data and store the message digest */ - unsigned char *digest; - size_t digest_len; - - assert (!detached); - /* Fixme: get the algo to use from the signer's certificate - - does not make much sense, but we should do this - consistent as we have already done it above. Code is - mostly duplicated above. */ - - algo = GCRY_MD_SHA1; - rc = hash_and_copy_data (data_fd, data_md, writer); - if (rc) - goto leave; - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, - digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - gpg_strerror (err)); - rc = err; - goto leave; - } - } - } - else if (stopreason == KSBA_SR_NEED_SIG) - { /* calculate the signature for all signers */ - gcry_md_hd_t md; - - algo = GCRY_MD_SHA1; - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "sign.attr"); - ksba_cms_set_hash_function (cms, HASH_FNC, md); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - char *sigval = NULL; - char *buf, *fpr; - - if (signer) - gcry_md_reset (md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_debug ("hashing signed attrs failed: %s\n", - gpg_strerror (rc)); - gcry_md_close (md); - goto leave; - } - - rc = gpgsm_create_cms_signature (ctrl, cl->cert, - md, algo, &sigval); - if (rc) - { - gcry_md_close (md); - goto leave; - } - - err = ksba_cms_set_sig_val (cms, signer, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the signature: %s\n", - gpg_strerror (err)); - rc = err; - gcry_md_close (md); - goto leave; - } - - /* write a status message */ - fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1); - if (!fpr) - { - rc = gpg_error (GPG_ERR_ENOMEM); - gcry_md_close (md); - goto leave; - } - { - int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL); - rc = asprintf (&buf, "%c %d %d 00 %s %s", - detached? 'D':'S', - pkalgo, - algo, - signed_at, - fpr); - } - xfree (fpr); - if (rc < 0) - { - rc = gpg_error (GPG_ERR_ENOMEM); - gcry_md_close (md); - goto leave; - } - rc = 0; - gpgsm_status (ctrl, STATUS_SIG_CREATED, buf); - free (buf); /* yes, we must use the regular free() here */ - } - gcry_md_close (md); - - } - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - log_info ("signature created\n"); - - - leave: - if (rc) - log_error ("error creating signature: %s <%s>\n", - gpg_strerror (rc), gpg_strsource (rc) ); - if (release_signerlist) - gpgsm_release_certlist (signerlist); - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - return rc; -} diff --git a/sm/verify.c b/sm/verify.c deleted file mode 100644 index 410e86de7..000000000 --- a/sm/verify.c +++ /dev/null @@ -1,540 +0,0 @@ -/* verify.c - Verify a messages signature - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -static char * -strtimestamp_r (ksba_isotime_t atime) -{ - char *buffer = xmalloc (15); - - if (!atime || !*atime) - strcpy (buffer, "none"); - else - sprintf (buffer, "%.4s-%.2s-%.2s", atime, atime+4, atime+6); - return buffer; -} - - - -/* Hash the data for a detached signature */ -static void -hash_data (int fd, gcry_md_hd_t md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - - - - -/* Perform a verify operation. To verify detached signatures, data_fd - must be different than -1. With OUT_FP given and a non-detached - signature, the signed material is written to that stream. */ -int -gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) -{ - int i, rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - ksba_reader_t reader; - ksba_writer_t writer = NULL; - ksba_cms_t cms = NULL; - ksba_stop_reason_t stopreason; - ksba_cert_t cert; - KEYDB_HANDLE kh; - gcry_md_hd_t data_md = NULL; - int signer; - const char *algoid; - int algo; - int is_detached; - FILE *fp = NULL; - char *p; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - rc = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, 0, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (out_fp) - { - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - rc = ksba_cms_new (&cms); - if (rc) - goto leave; - - rc = ksba_cms_set_reader_writer (cms, reader, writer); - if (rc) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - gpg_strerror (rc)); - goto leave; - } - - rc = gcry_md_open (&data_md, 0, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "vrfy.data"); - - is_detached = 0; - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - if (stopreason == KSBA_SR_NEED_HASH) - { - is_detached = 1; - if (opt.verbose) - log_info ("detached signature\n"); - } - - if (stopreason == KSBA_SR_NEED_HASH - || stopreason == KSBA_SR_BEGIN_DATA) - { /* We are now able to enable the hash algorithms */ - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - log_error ("unknown hash algorithm `%s'\n", - algoid? algoid:"?"); - else - gcry_md_enable (data_md, algo); - } - if (is_detached) - { - if (data_fd == -1) - log_info ("detached signature w/o data " - "- assuming certs-only\n"); - else - hash_data (data_fd, data_md); - } - else - { - ksba_cms_set_hash_function (cms, HASH_FNC, data_md); - } - } - else if (stopreason == KSBA_SR_END_DATA) - { /* The data bas been hashed */ - - } - } - while (stopreason != KSBA_SR_READY); - - if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - } - - if (data_fd != -1 && !is_detached) - { - log_error ("data given for a non-detached signature\n"); - rc = gpg_error (GPG_ERR_CONFLICT); - goto leave; - } - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - /* Fixme: it might be better to check the validity of the - certificate first before entering it into the DB. This way - we would avoid cluttering the DB with invalid - certificates. */ - keydb_store_cert (cert, 0, NULL); - ksba_cert_release (cert); - } - - cert = NULL; - for (signer=0; ; signer++) - { - char *issuer = NULL; - ksba_sexp_t sigval = NULL; - ksba_isotime_t sigtime, keyexptime; - ksba_sexp_t serial; - char *msgdigest = NULL; - size_t msgdigestlen; - char *ctattr; - - rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial); - if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA - && data_fd == -1 && is_detached) - { - log_info ("certs-only message accepted\n"); - rc = 0; - break; - } - if (rc) - { - if (signer && rc == -1) - rc = 0; - break; - } - - gpgsm_status (ctrl, STATUS_NEWSIG, NULL); - - if (DBG_X509) - { - log_debug ("signer %d - issuer: `%s'\n", - signer, issuer? issuer:"[NONE]"); - log_debug ("signer %d - serial: ", signer); - gpgsm_dump_serial (serial); - log_printf ("\n"); - } - - rc = ksba_cms_get_signing_time (cms, signer, sigtime); - if (gpg_err_code (rc) == GPG_ERR_NO_DATA) - *sigtime = 0; - else if (rc) - { - log_error ("error getting signing time: %s\n", gpg_strerror (rc)); - *sigtime = 0; /* (we can't encode an error in the time string.) */ - } - - rc = ksba_cms_get_message_digest (cms, signer, - &msgdigest, &msgdigestlen); - if (!rc) - { - size_t is_enabled; - - algoid = ksba_cms_get_digest_algo (cms, signer); - algo = gcry_md_map_name (algoid); - if (DBG_X509) - log_debug ("signer %d - digest algo: %d\n", signer, algo); - is_enabled = sizeof algo; - if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED, - &algo, &is_enabled) - || !is_enabled) - { - log_error ("digest algo %d has not been enabled\n", algo); - goto next_signer; - } - } - else if (gpg_err_code (rc) == GPG_ERR_NO_DATA) - { - assert (!msgdigest); - rc = 0; - algoid = NULL; - algo = 0; - } - else /* real error */ - break; - - rc = ksba_cms_get_sigattr_oids (cms, signer, - "1.2.840.113549.1.9.3", &ctattr); - if (!rc) - { - const char *s; - - if (DBG_X509) - log_debug ("signer %d - content-type attribute: %s", - signer, ctattr); - - s = ksba_cms_get_content_oid (cms, 1); - if (!s || strcmp (ctattr, s)) - { - log_error ("content-type attribute does not match " - "actual content-type\n"); - ksba_free (ctattr); - ctattr = NULL; - goto next_signer; - } - ksba_free (ctattr); - ctattr = NULL; - } - else if (rc != -1) - { - log_error ("error getting content-type attribute: %s\n", - gpg_strerror (rc)); - goto next_signer; - } - rc = 0; - - - sigval = ksba_cms_get_sig_val (cms, signer); - if (!sigval) - { - log_error ("no signature value available\n"); - goto next_signer; - } - if (DBG_X509) - log_debug ("signer %d - signature available", signer); - - /* Find the certificate of the signer */ - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - if (rc == -1) - { - log_error ("certificate not found\n"); - rc = gpg_error (GPG_ERR_NO_PUBKEY); - } - else - log_error ("failed to find the certificate: %s\n", - gpg_strerror(rc)); - { - char numbuf[50]; - sprintf (numbuf, "%d", rc); - - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey", - numbuf, NULL); - } - /* fixme: we might want to append the issuer and serial - using our standard notation */ - goto next_signer; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gpg_strerror (rc)); - goto next_signer; - } - - log_info (_("Signature made ")); - if (*sigtime) - gpgsm_dump_time (sigtime); - else - log_printf (_("[date not given]")); - log_printf (_(" using certificate ID %08lX\n"), - gpgsm_get_short_fingerprint (cert)); - - - if (msgdigest) - { /* Signed attributes are available. */ - gcry_md_hd_t md; - unsigned char *s; - - /* check that the message digest in the signed attributes - matches the one we calculated on the data */ - s = gcry_md_read (data_md, algo); - if ( !s || !msgdigestlen - || gcry_md_get_algo_dlen (algo) != msgdigestlen - || !s || memcmp (s, msgdigest, msgdigestlen) ) - { - char *fpr; - - log_error ("invalid signature: message digest attribute " - "does not match calculated one\n"); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - - rc = gcry_md_open (&md, algo, 0); - if (rc) - { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); - goto next_signer; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "vrfy.attr"); - - ksba_cms_set_hash_function (cms, HASH_FNC, md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_error ("hashing signed attrs failed: %s\n", - gpg_strerror (rc)); - gcry_md_close (md); - goto next_signer; - } - rc = gpgsm_check_cms_signature (cert, sigval, md, algo); - gcry_md_close (md); - } - else - { - rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo); - } - - if (rc) - { - char *fpr; - - log_error ("invalid signature: %s\n", gpg_strerror (rc)); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/ - if (rc) - { - gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage", - gpg_err_code (rc)); - rc = 0; - } - - if (DBG_X509) - log_debug ("signature okay - checking certs\n"); - rc = gpgsm_validate_chain (ctrl, cert, keyexptime, 0, NULL, 0); - if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED) - { - gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL); - rc = 0; - } - else - gpgsm_status (ctrl, STATUS_GOODSIG, NULL); - - { - char *buf, *fpr, *tstr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - tstr = strtimestamp_r (sigtime); - buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120); - sprintf (buf, "%s %s %s %s", fpr, tstr, - *sigtime? sigtime : "0", - *keyexptime? keyexptime : "0" ); - xfree (tstr); - xfree (fpr); - gpgsm_status (ctrl, STATUS_VALIDSIG, buf); - xfree (buf); - } - - if (rc) /* of validate_chain */ - { - log_error ("invalid certification chain: %s\n", gpg_strerror (rc)); - if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN - || gpg_err_code (rc) == GPG_ERR_BAD_CERT - || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT - || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED) - gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL, - gpg_err_code (rc)); - else - gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, - gpg_err_code (rc)); - goto next_signer; - } - - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - log_info (!i? _("Good signature from") - : _(" aka")); - log_printf (" \""); - gpgsm_print_name (log_get_stream (), p); - log_printf ("\"\n"); - ksba_free (p); - } - - gpgsm_status (ctrl, STATUS_TRUST_FULLY, NULL); - - - next_signer: - rc = 0; - xfree (issuer); - xfree (serial); - xfree (sigval); - xfree (msgdigest); - ksba_cert_release (cert); - cert = NULL; - } - rc = 0; - - leave: - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - if (fp) - fclose (fp); - - if (rc) - { - char numbuf[50]; - sprintf (numbuf, "%d", rc ); - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave", - numbuf, NULL); - } - - return rc; -} - diff --git a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 b/tests/567064FE6D14A17B2D811ABB407728BC558AA455 deleted file mode 100644 index cf0535ff7..000000000 --- a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 +++ /dev/null @@ -1,18 +0,0 @@ -(private-key - (oid.1.2.840.113549.1.1.1 - (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) - (e #010001#) - (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) - (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) - (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) - (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) - ) -) - - - - - - - - diff --git a/tests/ChangeLog b/tests/ChangeLog deleted file mode 100644 index 68f9b4e21..000000000 --- a/tests/ChangeLog +++ /dev/null @@ -1,73 +0,0 @@ -2004-02-20 Werner Koch <wk@gnupg.org> - - * Makefile.am: Reset GPG_AGENT_INFO here - * runtest: and not anymore here. - -2002-12-04 Werner Koch <wk@gnupg.org> - - * inittests (gpgsm.conf): Fake system time. - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH here. - (TESTS_ENVIRONMENT): Do it here. And also frob $(LIBGCRYPT_LIBS) - and $(PTH_LIBS). - -2002-10-31 Neal H. Walfield <neal@g10code.de> - - * asschk.c (die): New macro. - (read_assuan): If in verbose mode, dump the string that was read. - (write_assuan): Be more verbose on failure. - -2002-09-04 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but - rather prepend it. Be more robust and prefer printf over echo -n. - -2002-09-04 Marcus Brinkmann <marcus@g10code.de> - - * asschk.c (start_server): Close the parent's file descriptors in - the child. - (read_assuan): Variable NREAD removed. Cut off the received line - currectly if more than one line was read. - -2002-09-03 Neal H. Walfield <neal@g10code.de> - - * Makefile.am (inittests.stamp): Construct an LD_LIBRARY_PATH from - LDFLAGS. - -2002-08-09 Werner Koch <wk@gnupg.org> - - * asschk.c (cmd_getenv): New. - (expand_line): Allow / as variable name delimiter. - * sm-sign+verify, sm-verify: Use $srcdir so that a VPATH build works. - - * Makefile.am: Fixes for make dist. - * samplekets/Makefile.am: New. - -2002-08-08 Werner Koch <wk@gnupg.org> - - * asschk.c: Added some new features. - * runtest, inittests: New. - * text-1.txt, text-2.txt, text-3.txt: New. - * text-1.osig.pem, text-1.dsig.pem, text-1.osig-bad.pem: New. - * text-2.osig.pem, text-2.osig-bad.pem: New. - * samplekeys : New directory - * sm-verify, sm-sign+verify: The first test scripts. - -2002-08-06 Werner Koch <wk@gnupg.org> - - * Makefile.am, asschk.c: New. - - - Copyright 2002 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 791829a07..000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,77 +0,0 @@ -# Makefile.am -tests makefile for libxtime -# Copyright (C) 2002 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -## Process this file with automake to produce Makefile.in - -GPGSM = ../sm/gpgsm - -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` GPG_AGENT_INFO= LC_ALL=C GPGSM=$(GPGSM) \ - LD_LIBRARY_PATH=$$(seen=0; \ - for i in $(LDFLAGS) $(LIBGCRYPT_LIBS) $(PTH_LIBS); \ - do \ - if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ - then \ - if test $$seen = 0; \ - then \ - seen=1; \ - else \ - printf ":"; \ - fi; \ - printf "%s" "$${i}" | sed 's/^-L//'; \ - fi; \ - done; \ - if test $$seen != 0 \ - && test x$${LD_LIBRARY_PATH} != x; \ - then \ - printf ":"; \ - fi; \ - printf "%s" "$${LD_LIBRARY_PATH}") $(srcdir)/runtest - -testscripts = sm-sign+verify sm-verify - -EXTRA_DIST = runtest inittests $(testscripts) \ - text-1.txt text-2.txt text-3.txt \ - text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ - text-2.osig.pem text-2.osig-bad.pem \ - samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ - samplekeys/cert_g10code_pete1.pem \ - samplekeys/cert_g10code_test1.pem \ - samplekeys/cert_g10code_theo1.pem - -TESTS = $(testscripts) - -CLEANFILES = inittests.stamp x y y z out err - *.lock .\#lk* - -DISTCLEANFILES = pubring.kbx~ random_seed - -noinst_PROGRAMS = asschk - -asschk_SOURCES = asschk.c - - -all-local: inittests.stamp - -clean-local: - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean - -inittests.stamp: inittests - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests - echo timestamp >./inittests.stamp - diff --git a/tests/asschk.c b/tests/asschk.c deleted file mode 100644 index 83a8ca5af..000000000 --- a/tests/asschk.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* asschk.c - Assuan Server Checker - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* This is a simple stand-alone Assuan server test program. We don't - want to use the assuan library because we don't want to hide errors - in that library. - - The script language is line based. Empty lines or lines containing - only white spaces are ignored, line with a hash sign as first non - white space character are treated as comments. - - A simple macro mechanism is implemnted. Macros are expanded before - a line is processed but after comment processing. Macros are only - expanded once and non existing macros expand to the empty string. - A macro is dereferenced by prefixing its name with a dollar sign; - the end of the name is currently indicated by a white space, a - dollar sign or a slash. To use a dollor sign verbatim, double it. - - A macro is assigned by prefixing a statement with the macro name - and an equal sign. The value is assigned verbatim if it does not - resemble a command, otherwise the return value of the command will - get assigned. The command "let" may be used to assign values - unambigiously and it should be used if the value starts with a - letter. - - Conditions are not yes implemented except for a simple evaluation - which yields false for an empty string or the string "0". The - result may be negated by prefixing with a '!'. - - The general syntax of a command is: - - [<name> =] <statement> [<args>] - - If NAME is not specifed but the statement returns a value it is - assigned to the name "?" so that it can be referenced using "$?". - The following commands are implemented: - - let <value> - Return VALUE. - - echo <value> - Print VALUE. - - openfile <filename> - Open file FILENAME for read access and retrun the file descriptor. - - createfile <filename> - Create file FILENAME, open for write access and retrun the file - descriptor. - - pipeserver <program> - Connect to the Assuan server PROGRAM. - - send <line> - Send LINE to the server. - - expect-ok - Expect an OK response from the server. Status and data out put - is ignored. - - expect-err - Expect an ERR response from the server. Status and data out put - is ignored. - - count-status <code> - Initialize the assigned variable to 0 and assign it as an counter for - status code CODE. This command must be called with an assignment. - - quit - Terminate the process. - - quit-if <condition> - Terminate the process if CONDITION evaluates to true. - - fail-if <condition> - Terminate the process with an exit code of 1 if CONDITION - evaluates to true. - - cmpfiles <first> <second> - Returns true when the content of the files FIRST and SECOND match. - - getenv <name> - Return the value of the environment variable NAME. - -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <unistd.h> -#include <fcntl.h> - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -# define ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) -#else -# define ATTR_PRINTF(f,a) -#endif - -#define spacep(p) (*(p) == ' ' || *(p) == '\t') - -#define MAX_LINELEN 2048 - -typedef enum { - LINE_OK = 0, - LINE_ERR, - LINE_STAT, - LINE_DATA, - LINE_END, -} LINETYPE; - -typedef enum { - VARTYPE_SIMPLE = 0, - VARTYPE_FD, - VARTYPE_COUNTER -} VARTYPE; - - -struct variable_s { - struct variable_s *next; - VARTYPE type; - unsigned int count; - char *value; - char name[1]; -}; -typedef struct variable_s *VARIABLE; - - -static void die (const char *format, ...) ATTR_PRINTF(1,2); - - -/* Name of this program to be printed in error messages. */ -static const char *invocation_name; - -/* Talk a bit about what is going on. */ -static int opt_verbose; - -/* Option to ignore the echo command. */ -static int opt_no_echo; - -/* File descriptors used to communicate with the current server. */ -static int server_send_fd = -1; -static int server_recv_fd = -1; - -/* The Assuan protocol limits the line length to 1024, so we can - safely use a (larger) buffer. The buffer is filled using the - read_assuan(). */ -static char recv_line[MAX_LINELEN]; -/* Tell the status of the current line. */ -static LINETYPE recv_type; - -/* This is our variable storage. */ -static VARIABLE variable_list; - - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - -#define die(format, args...) (die) ("%s: " format, __FUNCTION__ , ##args) - -static void -err (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); -} - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core"); - return p; -} - -static void * -xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - die ("out of core"); - return p; -} - -static char * -xstrdup (const char *s) -{ - char *p = xmalloc (strlen (s)+1); - strcpy (p, s); - return p; -} - - -/* Write LENGTH bytes from BUFFER to FD. */ -static int -writen (int fd, const char *buffer, size_t length) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - - - - -/* Assuan specific stuff. */ - -/* Read a line from FD, store it in the global recv_line, analyze the - type and store that in recv_type. The function terminates on a - communication error. Returns a pointer into the inputline to the - first byte of the arguments. The parsing is very strict to match - excalty what we want to send. */ -static char * -read_assuan (int fd) -{ - static char pending[MAX_LINELEN]; - static size_t pending_len; - size_t nleft = sizeof recv_line; - char *buf = recv_line; - char *p; - - while (nleft > 0) - { - int n; - - if (pending_len) - { - if (pending_len >= nleft) - die ("received line too large"); - memcpy (buf, pending, pending_len); - n = pending_len; - pending_len = 0; - } - else - n = read (fd, buf, nleft); - - if (opt_verbose) - { - int i; - printf ("%s: read \"", __FUNCTION__); - for (i = 0; i < n; i ++) - putc (buf[i], stdout); - printf ("\"\n"); - } - - if (n < 0) - { - if (errno == EINTR) - continue; - die ("reading fd %d failed: %s", fd, strerror (errno)); - } - else if (!n) - die ("received incomplete line on fd %d", fd); - p = buf; - nleft -= n; - buf += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - if (n>1) - { - n--; - memcpy (pending, p + 1, n); - pending_len = n; - } - *p = '\0'; - break; - } - } - if (!nleft) - die ("received line too large"); - - p = recv_line; - if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) - { - recv_type = LINE_OK; - p += 3; - } - else if (p[0] == 'E' && p[1] == 'R' && p[2] == 'R' - && (p[3] == ' ' || !p[3])) - { - recv_type = LINE_ERR; - p += 4; - } - else if (p[0] == 'S' && (p[1] == ' ' || !p[1])) - { - recv_type = LINE_STAT; - p += 2; - } - else if (p[0] == 'D' && p[1] == ' ') - { - recv_type = LINE_DATA; - p += 2; - } - else if (p[0] == 'E' && p[1] == 'N' && p[2] == 'D' && !p[3]) - { - recv_type = LINE_END; - p += 3; - } - else - die ("invalid line type (%.5s)", p); - - return p; -} - -/* Write LINE to the server using FD. It is expected that the line - contains the terminating linefeed as last character. */ -static void -write_assuan (int fd, const char *line) -{ - char buffer[1026]; - size_t n = strlen (line); - - if (n > 1024) - die ("line too long for Assuan protocol"); - strcpy (buffer, line); - if (!n || buffer[n-1] != '\n') - buffer[n++] = '\n'; - - if (writen (fd, buffer, n)) - die ("sending line (\"%s\") to %d failed: %s", buffer, fd, - strerror (errno)); -} - - -/* Start the server with path PGMNAME and connect its stdout and - strerr to a newly created pipes; the file descriptors are then - store in the gloabl variables SERVER_SEND_FD and - SERVER_RECV_FD. The initial handcheck is performed.*/ -static void -start_server (const char *pgmname) -{ - int rp[2]; - int wp[2]; - pid_t pid; - - if (pipe (rp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - if (pipe (wp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - - fflush (stdout); - fflush (stderr); - pid = fork (); - if (pid < 0) - die ("fork failed"); - - if (!pid) - { - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (wp[0]); - } - if (rp[1] != STDOUT_FILENO) - { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (rp[1]); - } - if (!opt_verbose) - { - int fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); - if (dup2 (fd, STDERR_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (fd); - } - - close (wp[1]); - close (rp[0]); - execl (pgmname, arg0, "--server", NULL); - die ("exec failed for `%s': %s", pgmname, strerror (errno)); - } - close (wp[0]); - close (rp[1]); - server_send_fd = wp[1]; - server_recv_fd = rp[0]; - - read_assuan (server_recv_fd); - if (recv_type != LINE_OK) - die ("no greating message"); -} - - - - - -/* Script intepreter. */ - -static void -unset_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return; -/* fprintf (stderr, "unsetting `%s'\n", name); */ - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - free (var->value); - var->value = NULL; - var->type = 0; - var->count = 0; -} - - -static void -set_type_var (const char *name, const char *value, VARTYPE type) -{ - VARIABLE var; - - if (!name) - name = "?"; - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - { - var = xcalloc (1, sizeof *var + strlen (name)); - strcpy (var->name, name); - var->next = variable_list; - variable_list = var; - } - else - free (var->value); - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - var->type = type; - var->count = 0; - if (var->type == VARTYPE_COUNTER) - { - /* We need some extra sapce as scratch area for get_var. */ - var->value = xmalloc (strlen (value) + 1 + 20); - strcpy (var->value, value); - } - else - var->value = xstrdup (value); -} - -static void -set_var (const char *name, const char *value) -{ - set_type_var (name, value, 0); -} - - -static const char * -get_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return NULL; - if (var->type == VARTYPE_COUNTER && var->value) - { /* Use the scratch space allocated by set_var. */ - char *p = var->value + strlen(var->value)+1; - sprintf (p, "%u", var->count); - return p; - } - else - return var->value; -} - - -/* Incremente all counter type variables with NAME in their VALUE. */ -static void -inc_counter (const char *name) -{ - VARIABLE var; - - if (!*name) - return; - for (var=variable_list; var; var = var->next) - { - if (var->type == VARTYPE_COUNTER - && var->value && !strcmp (var->value, name)) - var->count++; - } -} - - -/* Expand variables in LINE and return a new allocated buffer if - required. The function might modify LINE if the expanded version - fits into it. */ -static char * -expand_line (char *buffer) -{ - char *line = buffer; - char *p, *pend; - const char *value; - size_t valuelen, n; - char *result = NULL; - - while (*line) - { - p = strchr (line, '$'); - if (!p) - return result; /* nothing more to expand */ - - if (p[1] == '$') /* quoted */ - { - memmove (p, p+1, strlen (p+1)+1); - line = p + 1; - continue; - } - for (pend=p+1; *pend && !spacep (pend) - && *pend != '$' && *pend != '/'; pend++) - ; - if (*pend) - { - int save = *pend; - *pend = 0; - value = get_var (p+1); - *pend = save; - } - else - value = get_var (p+1); - if (!value) - value = ""; - valuelen = strlen (value); - if (valuelen <= pend - p) - { - memcpy (p, value, valuelen); - p += valuelen; - n = pend - p; - if (n) - memmove (p, p+n, strlen (p+n)+1); - line = p; - } - else - { - char *src = result? result : buffer; - char *dst; - - dst = xmalloc (strlen (src) + valuelen + 1); - n = p - src; - memcpy (dst, src, n); - memcpy (dst + n, value, valuelen); - n += valuelen; - strcpy (dst + n, pend); - line = dst + n; - free (result); - result = dst; - } - } - return result; -} - - -/* Evaluate COND and return the result. */ -static int -eval_boolean (const char *cond) -{ - int true = 1; - - for ( ; *cond == '!'; cond++) - true = !true; - if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; -} - - - - - -static void -cmd_let (const char *assign_to, char *arg) -{ - set_var (assign_to, arg); -} - - -static void -cmd_echo (const char *assign_to, char *arg) -{ - if (!opt_no_echo) - printf ("%s\n", arg); -} - -static void -cmd_send (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "sending `%s'\n", arg); - write_assuan (server_send_fd, arg); -} - -static void -handle_status_line (char *arg) -{ - char *p; - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - int save = *p; - *p = 0; - inc_counter (arg); - *p = save; - } - else - inc_counter (arg); -} - -static void -cmd_expect_ok (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting OK\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_OK) - die ("expected OK but got `%s'", recv_line); -} - -static void -cmd_expect_err (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting ERR\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_ERR) - die ("expected ERR but got `%s'", recv_line); -} - -static void -cmd_count_status (const char *assign_to, char *arg) -{ - char *p; - - if (!*assign_to || !*arg) - die ("syntax error: count-status requires an argument and a variable"); - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - set_type_var (assign_to, arg, VARTYPE_COUNTER); -} - -static void -cmd_openfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_RDONLY); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error opening `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - -static void -cmd_createfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error creating `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - - -static void -cmd_pipeserver (const char *assign_to, char *arg) -{ - if (!*arg) - die ("syntax error: servername missing"); - - start_server (arg); -} - - -static void -cmd_quit_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (0); -} - -static void -cmd_fail_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (1); -} - - -static void -cmd_cmpfiles (const char *assign_to, char *arg) -{ - char *p = arg; - char *second; - FILE *fp1, *fp2; - char buffer1[2048]; /* note: both must be of equal size. */ - char buffer2[2048]; - size_t nread1, nread2; - int rc = 0; - - set_var (assign_to, "0"); - for (p=arg; *p && !spacep (p); p++) - ; - if (!*p) - die ("cmpfiles: syntax error"); - for (*p++ = 0; spacep (p); p++) - ; - second = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - - fp1 = fopen (arg, "rb"); - if (!fp1) - { - err ("can't open `%s': %s", arg, strerror (errno)); - return; - } - fp2 = fopen (second, "rb"); - if (!fp2) - { - err ("can't open `%s': %s", second, strerror (errno)); - fclose (fp1); - return; - } - while ( (nread1 = fread (buffer1, 1, sizeof buffer1, fp1))) - { - if (ferror (fp1)) - break; - nread2 = fread (buffer2, 1, sizeof buffer2, fp2); - if (ferror (fp2)) - break; - if (nread1 != nread2 || memcmp (buffer1, buffer2, nread1)) - { - rc = 1; - break; - } - } - if (feof (fp1) && feof (fp2) && !rc) - { - if (opt_verbose) - err ("files match"); - set_var (assign_to, "1"); - } - else if (!rc) - err ("cmpfiles: read error: %s", strerror (errno)); - else - err ("cmpfiles: mismatch"); - fclose (fp1); - fclose (fp2); -} - -static void -cmd_getenv (const char *assign_to, char *arg) -{ - const char *s; - s = *arg? getenv (arg):""; - set_var (assign_to, s? s:""); -} - - - - -/* Process the current script line LINE. */ -static int -interpreter (char *line) -{ - static struct { - const char *name; - void (*fnc)(const char*, char*); - } cmdtbl[] = { - { "let" , cmd_let }, - { "echo" , cmd_echo }, - { "send" , cmd_send }, - { "expect-ok" , cmd_expect_ok }, - { "expect-err", cmd_expect_err }, - { "count-status", cmd_count_status }, - { "openfile" , cmd_openfile }, - { "createfile", cmd_createfile }, - { "pipeserver", cmd_pipeserver }, - { "quit" , NULL }, - { "quit-if" , cmd_quit_if }, - { "fail-if" , cmd_fail_if }, - { "cmpfiles" , cmd_cmpfiles }, - { "getenv" , cmd_getenv }, - { NULL } - }; - char *p, *save_p; - int i, save_c; - char *stmt = NULL; - char *assign_to = NULL; - char *must_free = NULL; - - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - return 0; /* empty or comment */ - p = expand_line (line); - if (p) - { - must_free = p; - line = p; - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - { - free (must_free); - return 0; /* empty or comment */ - } - } - for (p=line; *p && !spacep (p) && *p != '='; p++) - ; - if (*p == '=') - { - *p = 0; - assign_to = line; - } - else if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p == '=') - assign_to = line; - } - if (!*line) - die ("syntax error"); - stmt = line; - save_c = 0; - save_p = NULL; - if (assign_to) - { /* this is an assignment */ - for (p++; spacep (p); p++) - ; - if (!*p) - { - unset_var (assign_to); - free (must_free); - return 0; - } - stmt = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - save_p = p; - save_c = *p; - for (*p++ = 0; spacep (p); p++) - ; - } - } - for (i=0; cmdtbl[i].name && strcmp (stmt, cmdtbl[i].name); i++) - ; - if (!cmdtbl[i].name) - { - if (!assign_to) - die ("invalid statement `%s'\n", stmt); - if (save_p) - *save_p = save_c; - set_var (assign_to, stmt); - free (must_free); - return 0; - } - - if (cmdtbl[i].fnc) - cmdtbl[i].fnc (assign_to, p); - free (must_free); - return cmdtbl[i].fnc? 0:1; -} - - - -int -main (int argc, char **argv) -{ - char buffer[2048]; - char *p, *pend; - - if (!argc) - invocation_name = "asschk"; - else - { - invocation_name = *argv++; - argc--; - p = strrchr (invocation_name, '/'); - if (p) - invocation_name = p+1; - } - - - set_var ("?","1"); /* defaults to true */ - - for (; argc; argc--, argv++) - { - p = *argv; - if (*p != '-') - break; - if (!strcmp (p, "--verbose")) - opt_verbose++; - else if (!strcmp (p, "--no-echo")) - opt_no_echo++; - else if (*p == '-' && p[1] == 'D') - { - p += 2; - pend = strchr (p, '='); - if (pend) - { - int tmp = *pend; - *pend = 0; - set_var (p, pend+1); - *pend = tmp; - } - else - set_var (p, "1"); - } - else if (*p == '-' && p[1] == '-' && !p[2]) - { - argc--; argv++; - break; - } - else - break; - } - if (argc) - die ("usage: asschk [--verbose] {-D<name>[=<value>]}"); - - - while (fgets (buffer, sizeof buffer, stdin)) - { - p = strchr (buffer,'\n'); - if (!p) - die ("incomplete script line"); - *p = 0; - if (interpreter (buffer)) - break; - fflush (stdout); - } - return 0; -} - diff --git a/tests/cert_cci_sphinx_ca.pem b/tests/cert_cci_sphinx_ca.pem deleted file mode 100644 index b426c2f33..000000000 --- a/tests/cert_cci_sphinx_ca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIEOp0SzjANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIyODE1MDEzNFoXDTAx -MDQxMTE0MDEzNFowNDELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRIwEAYDVQQD -EwlTUEhJTlgtQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP9STo2ReixFod9ItCJJ -QtmAs0Emajr9SvKmE8xzHmEmOP1rZzYZtqkSScIeVaOD1+6GMhNLHGxn+laAbANuxbV489yF -XjpiKlFKOKTzUyuZOO9BJDnRGaSyRyKICK9787RkP377lorO1eziqkCoxP75NIqVlOjajHVH -z0pzZCNNAgMBAAGjgeowgecwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8BAf8EBAMCAQYw -FgYDVR0gBA8wDTALBgkrBgEEAbMBAQEwTAYDVR0fBEUwQzBBoD+gPYY7bGRhcDovLy9jbj1U -RVNUX1BDQSxvPVRFU1RfUEtJLGM9REU/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3QwSAYDVR0j -BEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQDFAhU -RVNUX1BDQYIEOo0HwTARBgNVHQ4ECgQITJJvsx0o58QwDQYJKoZIhvcNAQEFBQADggEBAHjK -fRKOo2uzIyVH5s8ii+hIqJiPL6Z06siqo0XeVxoY3BTtfMo089q1krWJuSIoUPSeg4+OG7Go -Ga3qb33TF7zghUayLwWt4vsXBYkrU5VEEc6jN4NO80rPHsaMHPfGDko5BKmeXVkHPOBaFVLk -I6BuOCNQtRQrVaCbeEjqJkAWJtYG4Yhh63Vyv+bpfMfbm8oBE186pnUxZT1XHynIvrh5gjlX -9sbqqPPd5VqAmql+j4Hy1eC2XpU8JOqX1mif5uIdz0a8FtJP4bBX9lwL3zIhTtNOGiMYKxbT -TOpjDRA9dfpYS7qEq3kYNtqttfAxS67iq1BHafjskOF9jaStk+Y= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_wzs.pem b/tests/cert_cci_test_wzs.pem deleted file mode 100644 index 7ba60ce0c..000000000 --- a/tests/cert_cci_test_wzs.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN CERTIFICATE----- -LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEw -RlVSUzB0TFMwdENnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_zs.pem b/tests/cert_cci_test_zs.pem deleted file mode 100644 index 025a22c8c..000000000 --- a/tests/cert_cci_test_zs.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICyzCCAjSgAwIBAgIBBTANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxGDAWBgNVBAMTD1NQSElOWC1UZXN0LVdaUzAeFw0wMTA4MjQxMDA5MDNa -Fw0wMzA4MjQxMDA5MDNaMDkxCzAJBgNVBAYTAkRFMREwDwYDVQQKEwhDQ0kgR21iSDEXMBUG -A1UEAxMOU1BISU5YLVRlc3QtWlMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP+E1LeX -nwq5qAmfHX+zfabAaeMR9Ufow/1ojNg8md+XGVUFJ0a9GZJVQ4ngmxKHmO+6fT77Z0Sj7BQT -bxLbZEqvBxYDSoJgN6K7q2LdbTPIKMOzVF+TxtNyauZx+yxJxTMYYkyVmAlfjAx8Wlznf8Aj -kZywmjVtYWpoN0WedGsbAgMBAAGjgeEwgd4wVwYDVR0fBFAwTjBMoEqgSIZGbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1XWlMsIG89Q0NJIEdtYkgsIEM9REU/Y2VydGlmaWNhdGVSZXZvY2F0 -aW9uTGlzdDASBgNVHRMBAf8ECDAGAQH/AgEAMBEGA1UdIAQKMAgwBgYEgnEJCTAOBgNVHQ8B -Af8EBAMCAQYwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBH -bWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQEwDQYJKoZIhvcNAQEFBQADgYEAGWjq -TsoWQmUiY3c5Tju+jL51AapWWZbZP8xpBTFjXNRQcRPzWrtHCWS3fhae+aMyGFxiqEhGLePc -QvNdgZmZtzNYSfmeS3iji3zSj7CFmUQKwFrAXUDQNvkS+87FwVno8LilnC0zMfhSW699HtWe -DW/o0CuhXX6IJXXWuSudCH8= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user02.pem b/tests/cert_cci_user02.pem deleted file mode 100644 index b1fba0df7..000000000 --- a/tests/cert_cci_user02.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTYyMloX -DTAyMTIxMTA3MTYyMlowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD+Gt/ahGJL -uEUVFgceVUsShMgJirndaGjJb/kR3cHQ4Yh4XM9WvP2ze6SRb1cn3Xq9bR1RTFwRoupp9h94 -OwhxjhOTKtTtwFv/OcffJPwAF6K+ms5s8oSBzNX6mo+sLwoVWHaXaSP7rzvOhvYPJpCE6zrS -GO4aUcH50f63wusSKQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwMkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUZpxNoy1I5cIT -OmeF8LSUJjWnlaowTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -UU1L9U5LOBaa99Q2ogsLS3PuSOhMKSKWwK+rG5YzNGh9L3+Ecp6/cdZeGY8IV4kQHx2YDhon -tX+SfEnAU5WKN+YfxbLQz5jbDYeyIkFXPFn4Pzt4+1gFLOVvdHFJKT6tb0ZbbLkJkrK+gf29 -sFHz/tVEIiwvWdzCQh669TvmSLc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user03.pem b/tests/cert_cci_user03.pem deleted file mode 100644 index 44a8510d2..000000000 --- a/tests/cert_cci_user03.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NDMwNVoX -DTAyMTIxMTA4NDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWLHGzEVlh -NKr5RkWi80jZpuVg20C+1W4H/ez2fuGP8IXZAyy6MYPLQSsFuuwfTtLwFDccJ4PubN/JhSLj -37/AGyygJODQd41CcQxLyB4NqhsYz+dXJv/Rx/E9HDbgsf7fCVwmCpF71phTzeq+zzJYYlDK -uLLvr2auODr4h24jSwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwM0BjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU04AGVPNiznW2 -ZoKD0hqNulIe0zIwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -qvifydhixBkVQ0ZesWHXVDwhPOjWtHMuYafMP+9Vn46HCqsbl4gnQqwdwHKl2ox4qd4VOOu8 -PmfKgLysWq11tp/+LCFIEDSLHKCQ1YpBaAxbBg4JxqeTXDF3a3u1RnYOEaVhMZ6L91u16vHT -MJ93W8Fphgf2Fj7EUBPhpyhsnKw= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user04.pem b/tests/cert_cci_user04.pem deleted file mode 100644 index e76880162..000000000 --- a/tests/cert_cci_user04.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBGzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTIxM1oX -DTAyMTIxMTA3MTIxM1owODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrExMHDJKt -W6ByaO3hVYJCZXJmyMAhHxm31yLXzbd2V5R3Q6ZH4ARk00AMRPDgPLf/NK913OcUFJDrlhLh -aVUfdtz7V095S6Xl38gaClidx2ZJ2EwM4pNxCDeWS1ZFsJMGcis74L5QGrn3/L+76psz7erW -usP+qwy3+3HzL6/hWQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNEBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU/UkAw08BpS4w -bM1Eo5MTX21niG4wTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -3mZM7XFH3CuiGQYe7Wrom+t/QH9BWwORHrskGiVyzBh5Z40HboB8vIN6I6CrQYJHK9DGKnAL -x5AjZ8MUUG3le5M2G6QdhbtGW0jZg5nF1LHx8QYIx8NJSoYa6uPcfr7Q9WgMvTcmA+gXGgzY -Uqv0AMWOx0f3ww0gUpFYIp22ZCc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user06.pem b/tests/cert_cci_user06.pem deleted file mode 100644 index 7026112b4..000000000 --- a/tests/cert_cci_user06.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBIzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTEyNDMwNVoX -DTAyMTIxMTEyNDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA2MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQ/o0hz0Uz -OGOUfDkzeburb1AO9VChEkO+x8ROoepsjJjkNDtC/4924biA8irfAymzqWP/QwQryS4+Zy6S -O9Jl4yoYNswoZuVhTc+WBkjFMC6qz/Y8mZZb5Fgysf+KAz0Swm0FlWjCYNMcWUp4FHJluG1m -iBarOZRharIVj+HNBwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUSIIT/NH6GsX/ -f1C44FyKEokGNVswTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -aBq+Qi0+Cb8XpnZqUITOmRC9VspxnMcE5IskEtbb2aCU2WkCGCTYMrVzug3BIKo4eNnOHl4k -2oKL8tANapawZSMQb3DtnAvQykYK9DAMYjojOao/2doYKNFoUszg1k+PI+Q1IuV4VjM79R9s -OwpipIj2q08Kx0NrliREuzB75Sg= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user07.pem b/tests/cert_cci_user07.pem deleted file mode 100644 index 2dfadf872..000000000 --- a/tests/cert_cci_user07.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAmegAwIBAgIBIDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NTgzOFoX -DTAyMTIxMTA4NTgzOFowMzELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMREwDwYD -VQQDEwhTcGhpbngwNzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtV86FCbl5CQqthMK -vjWjCFOfQZW2v66oiIuE/WZjyOIu1n4FC6z0+pI3FmeKrKhiYeXP8A2J/BzwS9ZD+0as5EyU -+QUzMPdm8pkzvkZCUPKRVi2cyRrBwwqnhH8Bwk2L2o2WMe46D3WBx4hSG+vhQvNMP4nrIGbs -oh+3XJjkoXcCAwCnU6OCARowggEWMFYGA1UdHwRPME0wS6BJoEeGRWxkYXA6Ly8vY249U1BI -SU5YLVRlc3QtWlMsIG89Q0NJIEdtYkgsIGM9REU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlz -dDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE3NwaGlueDA3QGl0cy5jY2kuZGUwEQYDVR0g -BAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUdyGyVPOTruMiE7OLekoP -8oJttzcwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJI -MRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEABjjhOFKV -3cVF7EGsPfnCq9CYjanFr7jhPxEYG0BuY+x1zgpsTkJm4/wk+NhGo/sFjrq7YExkhQgQViGt -9UhnXZQPsayna1lmkwl/edzpR3A1ELbiULTVGdLarP3MmWEMzKl/Z6prbb+cD1Qwb8D5DG+Q -u3E39VxgzG8i9wMSFh8= ------END CERTIFICATE----- diff --git a/tests/cert_testpki_testpca.pem b/tests/cert_testpki_testpca.pem deleted file mode 100644 index 255d6f4af..000000000 --- a/tests/cert_testpki_testpca.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDzDCCArSgAwIBAgIEOo0HwTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIxNjExMDAwNloXDTA2 -MDIxNjExMDAwNlowMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQD -FAhURVNUX1BDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTELO2lGugWqO5B -cLGU61TMZzUoR0yDAhPOjNU/CkLy9x+bDLJFAuvYQOm7SRcbTNcviUyot064ROWCcVn51kNf -+fmZhTyMix36ffcEERO7NaN4ZN7eXi39u9udTfPoQjUpy2tBVOwHlzBdHhklG1hBodqlmbfE -5Yt6ku0jm4wfxoiqgbF2dh9PhuCClt4YuBcnELw52duAKYNiHwfIqrwgDvAdi/J+mdgcxy1Z -xl/oIIVEy5FiQlMkleCDxstuEhVde8/ZzzyDbC+22Ok5xr6wexgUK792G6NZ+q+0BK+9Hqtw -m8/7UHyuUGboyHAT8V7ecgrpEg5rvJgRxtxUYA8CAwEAAaOB5zCB5DAPBgNVHRMBAf8EBTAD -AQH/MBYGA1UdIAQPMA0wCwYJKwYBBAGzAQEBMEwGA1UdHwRFMEMwQaA/oD2GO2xkYXA6Ly8v -Y249VEVTVF9QQ0Esbz1URVNUX1BLSSxjPURFP2F1dGhvcml0eVJldm9jYXRpb25MaXN0MBEG -A1UdDgQKBAhOFXmpxh5ysDBIBgNVHSMEQTA/oTekNTAzMQswCQYDVQQGEwJERTERMA8GA1UE -ChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBggQ6jQfBMA4GA1UdDwEB/wQEAwIBBjAN -BgkqhkiG9w0BAQUFAAOCAQEAs/wp8umfNLnEQ56DyIAOdWUwgJNrLYK2hk84G+lQKhem+jD0 -BoklUd/DifJxXE6QVFMxjr9aoYjMcloCuYV2jLd0kdebDmFvFNl3O9+mR0br8wHRCXhfPMwg -dThmhdtDs9qfyfStNStLch4F0edDYJtO3XaGWlQk52ykJy3yoyxmDUIzPTIKCV3LYO7bOXfw -FVECQaoO2+HrrZef6d3h3XL7leWhGYZ2YV77yzfZuN41y8aXQKF/1J7mYvpjceUJAyMZCUMz -FLDH4Zj4YGc8OH1xpAvGgztDuPQU8JXJBXuXIL0jmUcJRAZmgbeWWOgGIhYtJ4Stoy0pnHTZ -dcn+jw== ------END CERTIFICATE----- diff --git a/tests/crl_testpki_testpca.pem b/tests/crl_testpki_testpca.pem deleted file mode 100644 index 458c48164..000000000 --- a/tests/crl_testpki_testpca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDWTCCAkECAQEwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRF -U1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQRcNMDIwMTE0MDcwMDI4WhcNMDIwMjE0MDcwMDI4 -WjCCAXIwIwIEOpzbCxcNMDEwMjI4MTQ1NTE5WjAMMAoGA1UdFQQDCgEDMCMCBDr7z9QXDTAx -MDUxNDExMTY0M1owDDAKBgNVHRUEAwoBAzAjAgQ7Cmq5Fw0wMTA1MjkxMzE1NTNaMAwwCgYD -VR0VBAMKAQMwIwIEOxOgZBcNMDEwNjI5MDcwNzMwWjAMMAoGA1UdFQQDCgEDMCMCBDs8KH4X -DTAxMDYyOTA3MTA0MVowDDAKBgNVHRUEAwoBAzAjAgQ7xr4IFw0wMTEwMzAwODIwMDdaMAww -CgYDVR0VBAMKAQAwIwIEO95jKhcNMDExMTA3MTIxNzE2WjAMMAoGA1UdFQQDCgEAMCMCBDvp -JwAXDTAxMTEwNzE0MTEwMFowDDAKBgNVHRUEAwoBAzAjAgQ8GHpuFw0wMTEyMTMxMDAzNTFa -MAwwCgYDVR0VBAMKAQMwIwIEPBh8ihcNMDExMjEzMTAxMjE3WjAMMAoGA1UdFQQDCgEDoGQw -YjALBgNVHRQEBAICAVAwSAYDVR0jBEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoU -CFRFU1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQYIEOo0HwTAJBgNVHRwEAjAAMA0GCSqGSIb3 -DQEBBQUAA4IBAQCCTBKii6N4bX7sH6d3fq6yFbn2Xr5xDbDkpjHYSvHhBnfEnFAQOjOsn9ar -qk8NDUCT4j4AWD//i/9l5YbvY+32/ER32vZ5PDtSyhZ/pHIOaYUy0haf2pwDSXf7ESZKUM5a -O8UOVBlXhniClnakZHI6z7r7Md5xIJ5C2W8JaLUswiycvyMg37eM6a+d+J+ZlFXQZNO/9cfN -ItcSCBaRgUWm4LNdTJllNeZ9HMBOJ3pgS7yta4WNQi2mNgRzCcJJuVm5qmXo/9v7hMLmL+pb -YUPnQIfyjYmJK0ea+8KsKsgIKtiU8xteqTxPQ3VJBbH7ChcO4SMUPq5yL3otGZu5zOoQ ------END CERTIFICATE----- diff --git a/tests/extrasamples/README b/tests/extrasamples/README deleted file mode 100644 index 3102eac15..000000000 --- a/tests/extrasamples/README +++ /dev/null @@ -1,5 +0,0 @@ -Extra test data where it is not clear whether we may distribute them. This -we only keep them in the CVS. - -dod-test9.p12 A file from the DoD X.509 tests suite, September 2001. - Passphrase is "password". diff --git a/tests/extrasamples/dod-test9.p12 b/tests/extrasamples/dod-test9.p12 deleted file mode 100644 index a109b1aa9..000000000 Binary files a/tests/extrasamples/dod-test9.p12 and /dev/null differ diff --git a/tests/inittests b/tests/inittests deleted file mode 100755 index 05a94eb68..000000000 --- a/tests/inittests +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh -# Copyright (C) 2002 Free Software Foundation, Inc. -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -set -e - -sample_certs=' -cert_g10code_test1.pem -cert_g10code_pete1.pem -cert_g10code_theo1.pem -' - -private_keys=' -32100C27173EF6E9C4E9A25D3D69F86D37A4F939 -' - -clean_files=' -gpgsm.conf gpg-agent.conf trustlist.txt pubring.kbx -msg msg.sig msg.unsig -' - - -[ -z "$srcdir" ] && srcdir=. -[ -z "$GPGSM" ] && GPGSM=../sm/gpgsm - -if [ -d $srcdir/samplekeys ] \ - && grep TESTS_ENVIRONMENT Makefile >/dev/null 2>&1; then - : -else - # During make distclean the Makefile has already been removed, - # so we need this extra test. - if ! grep gnupg-test-directory testdir.stamp >/dev/null 2>&1; then - echo "inittests: please cd to the tests directory first" >&2 - exit 1 - fi -fi - -if [ "$1" = "--clean" ]; then - if [ -d private-keys-v1.d ]; then - rm private-keys-v1.d/* 2>/dev/null || true - rmdir private-keys-v1.d - fi - rm ${clean_files} testdir.stamp 2>/dev/null || true - exit 0 -fi - -if [ "$GNUPGHOME" != "`pwd`" ]; then - echo "inittests: please set GNUPGHOME to the test directory" >&2 - exit 1 -fi - -if [ -n "$GPG_AGENT_INFO" ]; then - echo "inittests: please unset GPG_AGENT_INFO" >&2 - exit 1 -fi - -# A stamp file used with --clean -echo gnupg-test-directory > testdir.stamp - - -# Create the private key directy if it does not exists and copy -# the sample keys. -[ -d private-keys-v1.d ] || mkdir private-keys-v1.d -for i in ${private_keys}; do - cat ${srcdir}/samplekeys/$i.key >private-keys-v1.d/$i.key -done - -# Create the configuration scripts -# Note, die to an expired test certificate, we need to use -# the faked system time option. -cat > gpgsm.conf <<EOF -no-secmem-warning -disable-crl-checks -agent-program ../agent/gpg-agent -faked-system-time 1038835799 -EOF - -cat > gpg-agent.conf <<EOF -no-grab -pinentry-program /home/wk/work/pinentry/gtk/pinentry-gtk -EOF - -cat > trustlist.txt <<EOF -# CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE -3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E S -EOF - -# Make sure that the sample certs are available but ignore errors here -# because we are not a test script. -for i in ${sample_certs}; do - $GPGSM --import ${srcdir}/samplekeys/$i || true -done diff --git a/tests/key_g10code_pete1.pem b/tests/key_g10code_pete1.pem deleted file mode 100644 index dc26c8eda..000000000 --- a/tests/key_g10code_pete1.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,A4885DDADE65FCB5 - -6mK4tsaqaMQVILY2b0Wku2dGp0GmqJMXRb49Xl/hlDhqO6rF30ZnCbFSOWS0O74a -+QydvNhACt+0lrIYv9E1pfU8ibmlPF1ei6n2GBcXgZGT8nFd5sb/+UJ1hEB9cRny -BuWjUOWB4uFnNkkIcWJEK98Yfmiiisp8kjoW3SgWQPXW/WaZkclpgbk8SVWeZ+14 -S6GXvQsaVhiXGN1Kv5nL6Qk1LSCg8rS1jMAPsQEO/KhRCogVmjw06x2RuqM6eISz -9mAio4AFMEhcY9Dg+2Ybf+iB4NnsvTaygUIZDDZ5TZGbr3O52CDblbKjswr2fO6B -PqoBLODmhb1ZTEq0tf9kQAs0SPek8Rd7xYIQrEBmmZz7v0sU4yROyMkRU3EzEYXV -Qsue1tqVtnBXB/d/Y0GG5NR4bo1oUwjzv8oUTxzPh8uDYDTNW2+KwPBmOx0hN2LG -FkN5KzBeHmGyACvQTVZndzEBHuult+6lfdDFMkopt9dp8ePlUC0s+61x+fi3nfEs -6AZLvRNDoi8Zv1+42RAbOA5ZKC1H9zjcbF5WzOCegRgKZyhZ+1+9IIoWqoCgK841 -pn/Iaog43Ba/npyNpJE63Q7khJueSkeN0NwtV9EeYB8xSF3RMlPDrakTdTTJJIAi -wUFXCbUieMsOj5b9jw6A5H0Zls0HcUdBos/ipiE8jdAjyxOp+q2hXTaOn7eK3WaD -CadRmfnRp383pfzFM+93MhsRZHg+Mw1BTnRghM4l/flykYXgDTFR+9citxbRzQfu -sVfrcqNmHvjqdhR5054oZjZMUP0SxRm13XsUfUMhIWsB1wrqHkYa/A== ------END RSA PRIVATE KEY----- diff --git a/tests/key_g10code_theo1.pem b/tests/key_g10code_theo1.pem deleted file mode 100644 index 9722be26d..000000000 --- a/tests/key_g10code_theo1.pem +++ /dev/null @@ -1,21 +0,0 @@ - - Passphrase is "test" - ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,C1E4BE50963AE732 - -xtD0InNwYZnG0z61ydRQ+UmDoKiUiiXiwbmZQREZUG2E5Tat77WAkiA8lwjqimmC -kGPWnCUtoMpuXrBl4JC1fsvNCsOhPu9w90JcuNqlxzUltZjP9M9uj9Ic4Hut9FoR -uSKY4sz7zGlOg+1kGZu1lXEKvGgrHO7sq66Q2Y1ugaWrlvdQt+1m2mTpk01rj2vZ -fqZO2EZFYNPAgQRpfnHmfaD1zIefRLbxwjQUTUvLWTN4aOaOBBNE6AlzwSK4w0Ba -4RAJpHuk7Kk6UNvNQriMjXMBvHCZLqKIJXGn99o8acK4E/Hrsyq8CHKT3ye81FoF -JsJf1n6W9NG21BH/HuS6uDcyvhhBpgP9yJclRiHd29t0pmM2v+FQxlpycEIwMLcT -hu7BaxdVrMmZHwwZXjFW8W0paltN65U3AevAddwyh6tmMRZR7OJP5P4qws4ehzWB -M9VPgHiWHkCwgjMH1EjhCXqChj0KCW4pHHXevA3eNJP8yEuGzlHwvh6Y4b+FFqtO -gib1MfWPsSYP2kW8XPrVzb2VMMWlqepUeKdBtZSC0s7TW7+bN7sgyWJYInBtqTZT -VCTauwUaFfRflp1l+jPofypaVs5Dsom96kMjqe9Tg9b409ZvWps5A7lG1Q26Nkyk -6/GA7Elt0lArwEs7lcHy40/5cIB5Bjgj7AL5B2/1hwoxFBsNa3k69OssJC6tY6ek -qwwa2KfXHsG6gHlFgMW/gRCJENy4dqtxkaVM27d+ulRlWYP5INyXFiH0NPeSR9i0 -LUDpQoKaexXG3DSQZcGSdDGlBa16iuPfKOEQMqQiymgxjG5umSKrZQ== ------END RSA PRIVATE KEY----- diff --git a/tests/runtest b/tests/runtest deleted file mode 100755 index 8d5078647..000000000 --- a/tests/runtest +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -[ -x "$1" ] && exec $1 $2 -exec ./asschk --no-echo -DGPGSM=${GPGSM} <"$1" - diff --git a/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key b/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key deleted file mode 100644 index cf0535ff7..000000000 --- a/tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key +++ /dev/null @@ -1,18 +0,0 @@ -(private-key - (oid.1.2.840.113549.1.1.1 - (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) - (e #010001#) - (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) - (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) - (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) - (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) - ) -) - - - - - - - - diff --git a/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key b/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key deleted file mode 100644 index 2063610dc..000000000 --- a/tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key +++ /dev/null @@ -1,10 +0,0 @@ -(private-key - (rsa - (n #00DB26862FD7EAF7AC9A52BA22473E28C8DF4637B0A048230772F6D5CD96EEF905D7D650A84957CBD3CCCD720A9C941EB430FE5088E6A8DDD0D5770506A314DDB4F579A2696FB53E98E7A8750F400016A9885D1C1F5D19AC90D186186DF4B354F3BDCA978BCBFB1810DFE5AB68AFE4B2B09D1F8223265514AFECDF596628F8C58F#) - (e #010001#) - (d #674F76ECB0FE0CBA2A9A1B3333A0A2FB66FE241CB8C2A8F8C70283F202582FBEC86C38E3CC877E081FC12E24C081B723BD00F698431C924CF384C332C8C87A67080A88A0700DC36D671ECB4D7AE0EE9C645AF932B9B55BD3E16C043E9D972202399F021374C358E8B77CA37CFAC642637CFF31E6E5839A89CBD3E32B9BEF9A01#) - (p #00EB664011AD44EFEDE2B40A3F753373F7CE39E2CF4A5E7812ABF5B957AFA8C9F9FEE1EE9D8F2FF7369B553749EADD0C605A581111A4D532ECC3ED3DC46DB1A501#) - (q #00EE543E10FD86829889682BC4BECA1230924B7B4A19823566FA056C9033937B97F29665CF21F6F097F9BAB24D6F596C93EE348568FAA59BB325EA66DFBE7B9A8F#) - (u #008BD460358A993D2B442BC7DC3F1E6EF9470F17E3E3BD85A496690A50D564BB585B66A3BF841B8FF9513293EA02C784C6142008A79948020FFF03440D9591C7D7#) - ) - ) diff --git a/tests/samplekeys/README b/tests/samplekeys/README deleted file mode 100644 index 0e8877907..000000000 --- a/tests/samplekeys/README +++ /dev/null @@ -1,17 +0,0 @@ -This is a collection of keys we use with the regression tests. - -opensc-tests.p12 PKCS#12 key and certificates taken from OpenSC. - Passphrase is "password" - -ov-user.p12 Private tests keys from www.openvalidation.org. -ov-server.p12 Passphrase for both is "start" - -ossl-rentec-user.pem An OpenSSL generated user certificate using a - bunch of attributes and DC RDNs. - -webderoot.der trust.web.de Root CA certificate [2004-02-17] -webdeca.der trust.web.de CA certificate [2004-02-17] - - - - diff --git a/tests/samplekeys/cert_g10code_enconly_1.pem b/tests/samplekeys/cert_g10code_enconly_1.pem deleted file mode 100644 index ef28b6924..000000000 --- a/tests/samplekeys/cert_g10code_enconly_1.pem +++ /dev/null @@ -1,26 +0,0 @@ -Issuer ...: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de -Serial ...: 03 -Subject ..: /CN=Encrypt Only Key 1/OU=Testlab/O=g10 code/C=de - ------BEGIN CERTIFICATE----- -MIIDmDCCAwGgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBrTELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYD -VQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2to -b2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDkwMzEwMzg1NloXDTEyMDgzMTEwMzg1Nlow -TzELMAkGA1UEBhMCZGUxETAPBgNVBAoTCGcxMCBjb2RlMRAwDgYDVQQLEwdUZXN0 -bGFiMRswGQYDVQQDExJFbmNyeXB0IE9ubHkgS2V5IDEwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBANsmhi/X6vesmlK6Ikc+KMjfRjewoEgjB3L21c2W7vkF19ZQ -qElXy9PMzXIKnJQetDD+UIjmqN3Q1XcFBqMU3bT1eaJpb7U+mOeodQ9AABapiF0c -H10ZrJDRhhht9LNU873Kl4vL+xgQ3+WraK/ksrCdH4IjJlUUr+zfWWYo+MWPAgMB -AAGjggEjMIIBHzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFIDAdBgNVHQ4EFgQUxWTi -IXcx29tl0D0TYl9sQ4z4foIwgdoGA1UdIwSB0jCBz4AUilgNzsWIc4O+ang1CsXu -Xu1NypOhgbOkgbAwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNV -BAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsT -FVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSww -KgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZYIBADAJ -BgNVHREEAjAAMA0GCSqGSIb3DQEBBQUAA4GBAGPwl3GN6TxYlwnN7Za2H4lJthUk -Bdxrjoh7D7z4kxpo0JGgcBbDEpGPDNtwNg73ukwruGOiOJPGk6qZI1TtI+7joScH -f1dtGUTcfFW+qpGkImJDrY1IV+ud6qhL2LxY4FLAuEv2iPNSbM9N3X8nB0ofWoPe -fISRwikYCdR83m+t ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_pete1.pem b/tests/samplekeys/cert_g10code_pete1.pem deleted file mode 100644 index c6f778a56..000000000 --- a/tests/samplekeys/cert_g10code_pete1.pem +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID7jCCA1egAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsTELMAkGA1UEBhMCREUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBUZXN0bGFiMRYwFAYDVQQD -Ew1QZXRlciBQYW50aGVyMTIwMAYJKoZIhvcNAQkBFiNwZXRlci5wYW50aGVyQGtl -cmNraG9mZnMuZzEwY29kZS5kZTAeFw0wMjA0MTIxNjU4MzFaFw0wMzA0MTIxNjU4 -MzFaMIGxMQswCQYDVQQGEwJERTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNz -ZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRswGQYDVQQLExJLZXJja2hv -ZmZzIFRlc3RsYWIxFjAUBgNVBAMTDVBldGVyIFBhbnRoZXIxMjAwBgkqhkiG9w0B -CQEWI3BldGVyLnBhbnRoZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlMIGfMA0GCSqG -SIb3DQEBAQUAA4GNADCBiQKBgQC/UYKEu+IZgvoUwbBaKT96SDsgnsOLkC7TWuP+ -td9qyjF+tQCSUdTqRDYyP44hLH24v4h9KsVxwl5iuncJCdNmpTHL4ika+3v7arGU -DmGEHZOC3mHMzD+/dfqotse7C37AEMWSXguh4x2vmSESG9wnAxCgLl78j+RIuKUE -RVK55wIDAQABo4IBEjCCAQ4wHQYDVR0OBBYEFDhJ93SfqHOecsryvYN01++o7qh/ -MIHeBgNVHSMEgdYwgdOAFDhJ93SfqHOecsryvYN01++o7qh/oYG3pIG0MIGxMQsw -CQYDVQQGEwJERTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYw -FAYDVQQKEw1nMTAgQ29kZSBHbWJIMRswGQYDVQQLExJLZXJja2hvZmZzIFRlc3Rs -YWIxFjAUBgNVBAMTDVBldGVyIFBhbnRoZXIxMjAwBgkqhkiG9w0BCQEWI3BldGVy -LnBhbnRoZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQEEBQADgYEADoBAUnaZIjp+T60s1at/tLa03TfYT8DdTQz+p/UF -MFGPz9CTqsoN7NLFoXyq+RN9FipsGEKLMif7e/buRqlcir+ntxqQFdy6EYfxfu4n -Dys8JxnhjcEqXSz+uPUE8jiGho5Tkveo+hurDKZ54CVTeJtvKrWpA6YkuhmL/zRz -T7Y= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_test1.pem b/tests/samplekeys/cert_g10code_test1.pem deleted file mode 100644 index 61d1f9813..000000000 --- a/tests/samplekeys/cert_g10code_test1.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDFTCCAn6gAwIBAgIBADANBgkqhkiG9w0BAQQFADBrMQswCQYDVQQGEwJERTET -MBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcG -A1UECxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDEwHhcN -MDExMjAzMDkzNjM4WhcNMDIxMjAzMDkzNjM4WjBrMQswCQYDVQQGEwJERTETMBEG -A1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEZMBcGA1UE -CxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBjZXJ0IDEwgZ8wDQYJ -KoZIhvcNAQEBBQADgY0AMIGJAoGBAODOlvkLbJ4C85Ir6tqT/lCoderGvMGLuanP -LoSWXKotH/laf1QkZcbAwZ0nbkUmzgSIaKepFP00PMOofddCkf/FZVBtW7sly6xq -Di3R+LyqsNSinC83yVDzY0hL8mn3iRRARkuveYJ+A6NucLgUk47r3GPpZCR7513F -iwFLfqJRAgMBAAGjgcgwgcUwHQYDVR0OBBYEFDM3jRKRwFRxgzhfCGW/qUv5jjTz -MIGVBgNVHSMEgY0wgYqAFDM3jRKRwFRxgzhfCGW/qUv5jjTzoW+kbTBrMQswCQYD -VQQGEwJERTETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUg -R21iSDEZMBcGA1UECxMQQWVneXB0ZW4gUHJvamVjdDEUMBIGA1UEAxMLdGVzdCBj -ZXJ0IDGCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBshwQeijio -2hsXZxZEIFoNldDpdxcbWUws5utNJ7hqxQr74fn2cL9rH7AycNWtZnyCTAk7Uqwc -bH3z6CNoJH6U/k//ITk7w8PtM6nw6JhlXLD+C65Bifip6id2JtRQwl4kJ/tPpx+/ -42Muki3yVFN+BEGFPpI6hdJmh1Hz81k8GQ== ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_test_ca.pem b/tests/samplekeys/cert_g10code_test_ca.pem deleted file mode 100644 index d65a84c52..000000000 --- a/tests/samplekeys/cert_g10code_test_ca.pem +++ /dev/null @@ -1,27 +0,0 @@ -Issuer ...: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de -Serial ...: 00 -Subject ..: /CN=Root-Test-CA/OU=Test CA on Kerckhoffs/O=g10 Code GmbH/L=Düsseldorf/ST=NRW/C=de/EMail=test-ca@kerckhoffs.g10code.de - ------BEGIN CERTIFICATE----- -MIID4jCCA0ugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBrTELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYD -VQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2to -b2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDMxMTA5MjUwMVoXDTAzMDMxMTA5MjUwMVow -ga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRv -cmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24g -S2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkB -Fh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZTCBnzANBgkqhkiG9w0BAQEF -AAOBjQAwgYkCgYEAyyMceR+2i6B111NZDqVzCWjB+vcymaKoNxM58+4nNjr08afx -3M2duMX6oOapbxvpgdZOZhV9lbDMFsZ9Sc/8r8nPwKuTW93cS2qceTI12fOPd1am -td53adxR9/7HdnG+2EUWcEO6bNtXSxHcWhGGFjSspKQekrszFZFabdTwGR0CAwEA -AaOCAQ4wggEKMB0GA1UdDgQWBBSKWA3OxYhzg75qeDUKxe5e7U3KkzCB2gYDVR0j -BIHSMIHPgBSKWA3OxYhzg75qeDUKxe5e7U3Kk6GBs6SBsDCBrTELMAkGA1UEBhMC -ZGUxDDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMN -ZzEwIENvZGUgR21iSDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUw -EwYDVQQDEwxSb290LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2Vy -Y2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEE -BQADgYEAkYHZYROou2z2MavOVFOdY5nUPqgqTHlD5z2ADotCekdiRQ7YsJHHqDaE -wRdGxVxNvFPa31iA+VeZu4YTaOiAW0lFZ7SYYwjRvKjs+CDQxkPVBWxyB7JNeIOj -tWyK4FTrzcu3aNgfIJxMuzYU8EUwuwwPr+GxYP5GUFSVhP+VOsw= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cert_g10code_theo1.pem b/tests/samplekeys/cert_g10code_theo1.pem deleted file mode 100644 index a7685c415..000000000 --- a/tests/samplekeys/cert_g10code_theo1.pem +++ /dev/null @@ -1,40 +0,0 @@ - - <GnupgKeyblock> - <mainkey> - <keyid></keyid> - <fpr>E76B5D4BA2CF0B05BBBE425CDBF4E9DC4904941D</fpr> - <algo>0</algo> - <len>1024</len> - <created>1017250241</created> - <expire>1048786241</expire> - </mainkey> - <userid> - <raw>1.2.840.113549.1.9.1=#7468656F62616C642E7469676572406B6572636B686F6666732E673130636F64652E6465,CN=Theobald Tiger,OU=Kerckhoffs Testlab,O=g10 Code GmbH,L=Düsseldorf,ST=NRW,C=de</raw> - </userid> - </GnupgKeyblock> - - ------BEGIN CERTIFICATE----- -MIID9DCCA12gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBszELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBUZXN0bGFiMRcwFQYDVQQD -Ew5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYkdGhlb2JhbGQudGlnZXJA -a2VyY2tob2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDMyNzE3MzA0MVoXDTAzMDMyNzE3 -MzA0MVowgbMxCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8 -c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGzAZBgNVBAsTEktlcmNr -aG9mZnMgVGVzdGxhYjEXMBUGA1UEAxMOVGhlb2JhbGQgVGlnZXIxMzAxBgkqhkiG -9w0BCQEWJHRoZW9iYWxkLnRpZ2VyQGtlcmNraG9mZnMuZzEwY29kZS5kZTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2N+6T7awrnWhg1g+HIE8TGn3e8OOkqmE -v2k7uazL2aGUIk2Omg+2Jjq2dovotiSAjoVQFtJ+Ahk4aiGFA4Zdp34ZzijpXhD+ -+xbFt1Vz/zBWlExpN9A5m2XPAbcW5rTMcl9O6jXKgu4sLDXOGOVCSOIpaQGwB3g3 -ti/p7J4lvFcCAwEAAaOCARQwggEQMB0GA1UdDgQWBBQTVJsLsvwdrA5XJMZyCECy -gFdHGzCB4AYDVR0jBIHYMIHVgBQTVJsLsvwdrA5XJMZyCECygFdHG6GBuaSBtjCB -szELMAkGA1UEBhMCZGUxDDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9y -ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBU -ZXN0bGFiMRcwFQYDVQQDEw5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYk -dGhlb2JhbGQudGlnZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQEEBQADgYEASILHzi6O8Gf4Xd98FFtln3FGLhlHlxKV -xuO4Qn+qcBN7dFfQE3B/WKRR5jC8NTZHgGzAzcVv/ha2AAVs/zbSxE6lU04OOSJv -qm9lo6lsm5P+C/NH/hSdlUfSoKbmt5ZAPYpOhHvmPQpLi4Iv4hjeFqoCN5OVXOXN -OSgvBzegSSA= ------END CERTIFICATE----- diff --git a/tests/samplekeys/cryptlib-key.p12 b/tests/samplekeys/cryptlib-key.p12 deleted file mode 100644 index 5c23e95a7..000000000 Binary files a/tests/samplekeys/cryptlib-key.p12 and /dev/null differ diff --git a/tests/samplekeys/opensc-test.p12 b/tests/samplekeys/opensc-test.p12 deleted file mode 100644 index 990b1279a..000000000 Binary files a/tests/samplekeys/opensc-test.p12 and /dev/null differ diff --git a/tests/samplekeys/ossl-rentec-user.pem b/tests/samplekeys/ossl-rentec-user.pem deleted file mode 100644 index 290b0ef0d..000000000 --- a/tests/samplekeys/ossl-rentec-user.pem +++ /dev/null @@ -1,44 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIHnTCCBYWgAwIBAgIBATANBgkqhkiG9w0BAQQFADBGMRMwEQYKCZImiZPyLGQB -GRYDY29tMRYwFAYKCZImiZPyLGQBGRYGcmVudGVjMRcwFQYDVQQDDA5SZW5haXNz -YW5jZSBDQTAeFw0wNDAxMTAwNDE1NDZaFw0wNjAxMDkwNDE1NDZaMFcxEzARBgoJ -kiaJk/IsZAEZFgNjb20xFjAUBgoJkiaJk/IsZAEZFgZyZW50ZWMxDzANBgNVBAsM -BlBlb3BsZTEXMBUGA1UEAwwOS2Fyc3RlbiBLw7xubmUwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDBoZHGO+Ikq/Uhb9a4nUBuKayowUVga0wPQCiWhoLV -u2tDVWf7U9uzFrz/6JMIIBT3MIe5hBgQrYWq80/na3WO+H7vd4nR3gUfPBrfDPCm -HPm9nRMV1BsnFeg+2O0N+mfci2e/PLu7Ph9Arrr4+C0IVKQWxdNiqYj/gA0mSYvw -aThuBe8px3PZPAosZ9oGuhKmT+J9JtGe3qcyGPoW6yPEVpAUff0EFBGFI+wvaRV/ -vlK2omekQ2GkirzMqywTYiBPMuQ0abIjWZJn6ThR4FspIFLDAFnppwbZHMozrBYm -vS7pkoTK+DGVzk6kdbRxugWr61q0CQfL8b6VdfB6SGqxAgMBAAGjggODMIIDfzAJ -BgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAOBgNVHQ8BAf8EBAMCBeAwHQYD -VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMFAGCWCGSAGG+EIBDQRDFkFPcGVu -U1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZSwgaXNzdWVkIGJ5IFJlbmFpc3NhbmNl -IFRlY2huLiBDb3JwLjAdBgNVHQ4EFgQUh6HtcbLmbeEAQSpU73jYI7Ap0HUwbgYD -VR0jBGcwZYAUXqKKaiAqs5Gz38Yq0UGucAGbLd+hSqRIMEYxEzARBgoJkiaJk/Is -ZAEZFgNjb20xFjAUBgoJkiaJk/IsZAEZFgZyZW50ZWMxFzAVBgNVBAMMDlJlbmFp -c3NhbmNlIENBggEAMDgGA1UdEgQxMC+BDWNhQHJlbnRlYy5jb22GHmh0dHBzOi8v -d3d3LnJlbnRlYy5jb206ODQ0NC9jYTA9BgNVHR8ENjA0MDKgMKAuhixodHRwczov -L3d3dy5yZW50ZWMuY29tOjg0NDQvY2EvcmVudGVjX2NhLmNybDA6BggrBgEFBQcB -AQQuMCwwKgYIKwYBBQUHMAGGHmh0dHA6Ly9jb3VnYXIucmVudGVjLmNvbTo4MDgy -LzAuBglghkgBhvhCAQIEIRYfaHR0cHM6Ly93d3cucmVudGVjLmNvbTo4NDQ0L2Nh -LzAcBglghkgBhvhCAQgEDxYNY2Fwb2xpY3kuaHRtbDAlBglghkgBhvhCAQMEGBYW -Y2dpLWJpbi9jaGVjay1yZXYuY2dpPzCCAQUGA1UdIASB/TCB+jCB9wYKKwYBBAHD -SAMBATCB6DA4BggrBgEFBQcCARYsaHR0cHM6Ly93d3cucmVudGVjLmNvbTo4NDQ0 -L2NhL2NhcG9saWN5Lmh0bWwwgasGCCsGAQUFBwICMIGeGoGbT3BlblNTTCBHZW5l -cmF0ZWQgQ2VydGlmaWNhdGUsIGlzc3VlZCBieSBSZW5haXNzYW5jZSBUZWNobi4g -Q29ycC4sIFRoaXMgY2VydGlmaWNhdGUgaXMgdmFsaWQgb25seSBmb3IgU1NMIENs -aWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEUtTWFpbCAoUy9NSU1FKS4w -HAYDVR0RBBUwE4ERa3Vlbm5lQHJlbnRlYy5jb20wDQYJKoZIhvcNAQEEBQADggIB -AGgYIKrR5nQKICNuXl1OwWFwk+CgnbDrVIrIoFiwRlSqaNsedXMXIDYHdyE/LYwR -VaiHFimV5WywIPeoBKiws67ZcWVfGGvxF2CZuCcnuQpAyKn+J0PDAaTi3z/uoi4n -YPUVMpfU/7TPXVo4pjFfUmm9XJ6dduC6SlAN+1/xDRR1dy2WqNLcN1dpyoUTtEWp -Xvp7I66oLfWahKs0d4fOXIrZmyLqKN3H8CLrZPz8b4Skw+wWxEUIqJEkRKez5adK -Ry1VK21nIwUUWHfLvrqw4CgZvpMQVEZRhsiOPqlHEH+epDV4hD5/OCG5oK+8RoKA -Yw1xjs3gOCCf6GDVrftBBLsYQufL7E4BOD4RKDYQCo6HD7cHXfy+RttdIcKzlq4u -6QbzFgIkc3KF0/U5FpvKxQHyfQwoD8AORWF6myjGtM13ij8yXg4Mx1sgKOY9IK1/ -muLauYAamNdCSkD5+0ecmYJ98G7022zUTBE8LR6FFHAG+3F8mzP+oI2eOwJYzMFW -Zw3MNUCarArIyxts/+izpOEIfkf0ztx1TckCTGd/F7WAkQcDHZHsf8Vb+eaLTltk -rEM6mnpov+YCO8qb/vmr2018fNS5haTJvECjLbYRy6RV2v6wRPNbYRHN3og87h/8 -2HUYfYCVebbJdzSwkQGApPty9mx2wr3EwB7KTT+IjXkp ------END CERTIFICATE----- - diff --git a/tests/samplekeys/ov-server.p12 b/tests/samplekeys/ov-server.p12 deleted file mode 100644 index 52f2d558d..000000000 Binary files a/tests/samplekeys/ov-server.p12 and /dev/null differ diff --git a/tests/samplekeys/ov-user.p12 b/tests/samplekeys/ov-user.p12 deleted file mode 100644 index bb53a3d1a..000000000 Binary files a/tests/samplekeys/ov-user.p12 and /dev/null differ diff --git a/tests/samplekeys/webdeca.der b/tests/samplekeys/webdeca.der deleted file mode 100644 index 9532e3fa5..000000000 Binary files a/tests/samplekeys/webdeca.der and /dev/null differ diff --git a/tests/samplekeys/webderoot.der b/tests/samplekeys/webderoot.der deleted file mode 100644 index 3fedd9cd0..000000000 Binary files a/tests/samplekeys/webderoot.der and /dev/null differ diff --git a/tests/samplemsgs/webde-buenemann-signed.cms b/tests/samplemsgs/webde-buenemann-signed.cms deleted file mode 100644 index 9ed2dc1c4..000000000 Binary files a/tests/samplemsgs/webde-buenemann-signed.cms and /dev/null differ diff --git a/tests/skey_g10code_test1.pem b/tests/skey_g10code_test1.pem deleted file mode 100644 index 9f2db8e68..000000000 --- a/tests/skey_g10code_test1.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,CFA7DAB8D1EEDCFF - -KTLOYLEGXYFQ63WnUsqFp/vM5HWsJq758AQ5RaYp7jbtCoZdrSp5GovmLUBTPfR+ -hjfcJgGlyWIPDhPAcOObz2XnnpzcKEfmPKR/W+Ou7DFX/6WUh1xwzHq+ddPnCMHJ -vfhx2iMf0e4Y9ZMATBPcU0YIE/Rp9F4wmMKmEAGtAPOSMNdvH17KHlNLXsX+VlXf -scGi9Hr0KFcC/5ehA3J40vBlAg6oZeXwNuERX1PXOpAIlcGY0RklJhTvTBonCfaV -7+CrfggFed3/b7QuqsNTlRdmW3ctf2rqNoFFIhRB5OVQsLG4CrzIQMdzxMqlZrGd -Eks+0HLOMGO41ioaenz6015ClHORpAf3VXN8NUUrrDAvJL2HVlqFgDBCi9qi9Dp2 -TuVePAkJlpBYodgIdwvLN//dav6ZJ+FOOk3A5AnKOtNyTGO4I2Bz8nAS3JpVudk9 -ca8CEIIj52dEric6YMiBFokoiIEgMOI/6wjatDL1Yldev+kjH/el+FZT4jZm2lvQ -l1xbg4sqmPNSyIKSv8V95gO2W5E5V9kO/MBiad2GdX4qrVT1c/LwFC96t+tZKFxr -rHdN31CzZE3bHnXxvss3ai+k9IO1NZHfeeb9uqSmGd3AxbmBwWA50bxCsee+HP0R -ihU2BE5NKdlw1faBk+DPVT569uScO4PDc6Jd4fh7g7oBzLhhhcCqNnLEZh8lqa3L -rsb880baq8dm72cz8IXj//x5AppfCz8M8od/UkaQ0/pN2GGTpe4qSPPK0YJ/4MfR -f9jdMbZA6O8si3t7I4jOF2z1UHkFGaseax54ILTsTVE= ------END RSA PRIVATE KEY----- - diff --git a/tests/sm-sign+verify b/tests/sm-sign+verify deleted file mode 100644 index 1c3ae7dbd..000000000 --- a/tests/sm-sign+verify +++ /dev/null @@ -1,73 +0,0 @@ -# sm-sign+verify -# -# Creating a signature and verifying it -# Requirements: a plain file "text-1.txt" - -srcdir = getenv srcdir -plaintext = let $srcdir/text-1.txt - -in = openfile $plaintext -out = createfile msg.sig -in2 = openfile msg.sig -out2 = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -send SIGN -expect-ok - -send RESET -expect-ok -send INPUT FD=$in2 -expect-ok -send OUTPUT FD=$out2 -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Unset variables so that the files get closed. -in = -out = -in2 = -out2= - -cmpfiles $plaintext msg.unsig -fail-if !$? - -# Lets check it again with a new server instance, this time we keep -# the server running to check whether the entire message has been -# output after the VERIFY. -in = openfile msg.sig -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted - -cmpfiles $plaintext msg.unsig -fail-if !$? - -send BYE -expect-ok - - -quit - diff --git a/tests/sm-verify b/tests/sm-verify deleted file mode 100644 index b06dc16a4..000000000 --- a/tests/sm-verify +++ /dev/null @@ -1,114 +0,0 @@ -# sm-verify -# -# Verify a few distributed signatures. -# Requirements: -# - -srcdir = getenv srcdir - -# Check an opaque signature -sig = openfile $srcdir/text-1.osig.pem -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -sig = -out = -cmpfiles $srcdir/text-1.txt msg.unsig -fail-if !$? - -# Check a detached signature. -sig = openfile $srcdir/text-1.dsig.pem -plain = openfile $srcdir/text-1.txt -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send MESSAGE FD=$plain -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Check a tampered opaque message -sig = openfile $srcdir/text-1.osig-bad.pem -out = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - -# Check another opaque signature but without asking for the output. -sig = openfile $srcdir/text-2.osig.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# We als have tampered version. -sig = openfile $srcdir/text-2.osig-bad.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - - -quit - - diff --git a/tests/text-1.dsig.pem b/tests/text-1.dsig.pem deleted file mode 100644 index a031ec259..000000000 --- a/tests/text-1.dsig.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA -oIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAx -MB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzB -i7mpzy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7 -Jcusag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQk -e+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL -+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazEL -MAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBD -b2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcE -Hoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJ -O1KsHGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7 -T6cfv+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJ -BgNVBAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29k -ZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0 -IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIy -NTRaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG -9w0BAQEEgYAZpBbucgorq56kl2rokCV1EAZcKgylfpEkqSz4RU6qNid+0NtjSAxi -5164wjMLG71U9qSBX4XDdDQPHpH+PPF/8021kne2kPfeP68NiXK8CagdIqlnuJEj -K934mVre7AIjrXqoob1ipUtCWeK+2uHXsUjtUn3u1Y3eWVZ6+1hDTAAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-bad.pem b/tests/text-1.osig-bad.pem deleted file mode 100644 index 0b5f4a439..000000000 --- a/tests/text-1.osig-bad.pem +++ /dev/null @@ -1,45 +0,0 @@ -The text in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggPh -SGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2VzIG5pbmUgdGhyb3Vn -aCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNhaW50IEF0dGlsYSByYWlzZWQg -dGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhpZ2gKCXNheWluZywgIk9oIExvcmQsIEJs -ZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdyZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIg -ZW5lbWllcyB0byB0aW55IGJpdHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhl -CglwZW9wbGUgZGlkIGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jh -bmd1dGFucywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIHNpc3Rlci4gCkJyby4gTWF5bmFyZDoJQW5kIHRoZW4gdGhl -IExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRha2UKCW91dCB0aGUg -aG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8gdGhyZWUuICBObyBtb3JlLCBu -byBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUgbnVtYmVyIG9mIHRoZSBjb3VudGluZywg -YW5kIHRoZSBudW1iZXIgb2YgdGhlCgljb3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3Vy -KiBzaGFsdCB0aG91IG5vdCBjb3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBl -eGNlcHRpbmcgdGhhdCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglS -SUdIVCBPVVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQgR3JlbmFk -ZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4gbXkgc2lnaHQsIHNo -YWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0tIE1vbnR5IFB5dGhvbiwgIlRo -ZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZI -hvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6EllyqLR/5Wn9U -JGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwvN8lQ82NI -S/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1Ud -DgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhl -v6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNV -BAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMT -C3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1KsHGx98+gj -aCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt8lRTfgRB -hT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYDVQQHFApE -/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQ -cm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJ -BTEPFw0wMjA4MDgxMjIyNDZaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4X -LjALBgkqhkiG9w0BAQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RP -BDhOqaaACVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-badusage.pem b/tests/text-1.osig-badusage.pem deleted file mode 100644 index 027f23ead..000000000 --- a/tests/text-1.osig-badusage.pem +++ /dev/null @@ -1,75 +0,0 @@ -This message was created by violating the keyUsage: keyEncipherment. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIH -gjCCA+IwggNLoAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwga0xCzAJBgNVBAYTAmRl -MQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcx -MCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMG -A1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNr -aG9mZnMuZzEwY29kZS5kZTAeFw0wMjAzMTEwOTI1MDFaFw0wMzAzMTEwOTI1MDFa -MIGtMQswCQYDVQQGEwJkZTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNzZWxk -b3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMR4wHAYDVQQLExVUZXN0IENBIG9u -IEtlcmNraG9mZnMxFTATBgNVBAMTDFJvb3QtVGVzdC1DQTEsMCoGCSqGSIb3DQEJ -ARYddGVzdC1jYUBrZXJja2hvZmZzLmcxMGNvZGUuZGUwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBAMsjHHkftougdddTWQ6lcwlowfr3MpmiqDcTOfPuJzY69PGn -8dzNnbjF+qDmqW8b6YHWTmYVfZWwzBbGfUnP/K/Jz8Crk1vd3EtqnHkyNdnzj3dW -prXed2ncUff+x3ZxvthFFnBDumzbV0sR3FoRhhY0rKSkHpK7MxWRWm3U8BkdAgMB -AAGjggEOMIIBCjAdBgNVHQ4EFgQUilgNzsWIc4O+ang1CsXuXu1NypMwgdoGA1Ud -IwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOkgbAwga0xCzAJBgNVBAYT -AmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEV -MBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtl -cmNraG9mZnMuZzEwY29kZS5kZYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB -BAUAA4GBAJGB2WETqLts9jGrzlRTnWOZ1D6oKkx5Q+c9gA6LQnpHYkUO2LCRx6g2 -hMEXRsVcTbxT2t9YgPlXmbuGE2jogFtJRWe0mGMI0byo7Pgg0MZD1QVscgeyTXiD -o7VsiuBU683Lt2jYHyCcTLs2FPBFMLsMD6/hsWD+RlBUlYT/lTrMMIIDmDCCAwGg -AwIBAgIBAzANBgkqhkiG9w0BAQUFADCBrTELMAkGA1UEBhMCZGUxDDAKBgNVBAgT -A05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21i -SDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYDVQQDEwxSb290 -LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2tob2Zmcy5nMTBj -b2RlLmRlMB4XDTAyMDkwMzEwMzg1NloXDTEyMDgzMTEwMzg1NlowTzELMAkGA1UE -BhMCZGUxETAPBgNVBAoTCGcxMCBjb2RlMRAwDgYDVQQLEwdUZXN0bGFiMRswGQYD -VQQDExJFbmNyeXB0IE9ubHkgS2V5IDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBANsmhi/X6vesmlK6Ikc+KMjfRjewoEgjB3L21c2W7vkF19ZQqElXy9PMzXIK -nJQetDD+UIjmqN3Q1XcFBqMU3bT1eaJpb7U+mOeodQ9AABapiF0cH10ZrJDRhhht -9LNU873Kl4vL+xgQ3+WraK/ksrCdH4IjJlUUr+zfWWYo+MWPAgMBAAGjggEjMIIB -HzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFIDAdBgNVHQ4EFgQUxWTiIXcx29tl0D0T -Yl9sQ4z4foIwgdoGA1UdIwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOk -gbAwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3Nl -bGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Eg -b24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcN -AQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZYIBADAJBgNVHREEAjAA -MA0GCSqGSIb3DQEBBQUAA4GBAGPwl3GN6TxYlwnN7Za2H4lJthUkBdxrjoh7D7z4 -kxpo0JGgcBbDEpGPDNtwNg73ukwruGOiOJPGk6qZI1TtI+7joScHf1dtGUTcfFW+ -qpGkImJDrY1IV+ud6qhL2LxY4FLAuEv2iPNSbM9N3X8nB0ofWoPefISRwikYCdR8 -3m+tMYIBmzCCAZcCAQEwgbMwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAc -BgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0 -LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5k -ZQIBAzAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA5MDMxMTA0MzBaMCMG -CSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0BAQEE -gYB0gCqSUCIvw+26dmMFDUz/s3MG9nusAvYJpig8DLIsAGwmAw6Pg0XsI3Wkufb6 -KMTkmyjZLAsNUYWpQgcWkUvIR68iYtI1hd610+YbZubK+IppGkxUrXtFuaMK0xQs -tC0yMxlbcDBteiJYAZTDxn7cypmz106o6k4Utf0CPmd2LQAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig.pem b/tests/text-1.osig.pem deleted file mode 100644 index 7317350ec..000000000 --- a/tests/text-1.osig.pem +++ /dev/null @@ -1,48 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIyNDZa -MCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0B -AQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RPBDhOqaaA -CVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.txt b/tests/text-1.txt deleted file mode 100644 index b14c1a27c..000000000 --- a/tests/text-1.txt +++ /dev/null @@ -1,17 +0,0 @@ -High Priest: Armaments Chapter One, verses nine through twenty-seven: -Bro. Maynard: And Saint Attila raised the Holy Hand Grenade up on high - saying, "Oh Lord, Bless us this Holy Hand Grenade, and with it - smash our enemies to tiny bits." And the Lord did grin, and the - people did feast upon the lambs, and stoats, and orangutans, and - breakfast cereals, and lima bean- -High Priest: Skip a bit, brother. -Bro. Maynard: And then the Lord spake, saying: "First, shalt thou take - out the holy pin. Then shalt thou count to three. No more, no less. - *Three* shall be the number of the counting, and the number of the - counting shall be three. *Four* shalt thou not count, and neither - count thou two, excepting that thou then goest on to three. Five is - RIGHT OUT. Once the number three, being the third number be reached, - then lobbest thou thy Holy Hand Grenade towards thy foe, who, being - naughty in my sight, shall snuff it. Amen. -All: Amen. - -- Monty Python, "The Holy Hand Grenade" diff --git a/tests/text-2.osig-bad.pem b/tests/text-2.osig-bad.pem deleted file mode 100644 index 555844844..000000000 --- a/tests/text-2.osig-bad.pem +++ /dev/null @@ -1,28 +0,0 @@ -The signature time in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEU01p -bGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4gdGVybXMuCiAgICAg -ICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAw -DQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAU -BgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNV -BAMTC3Rlc3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6Ellyq -LR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwv -N8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHF -MB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBU -cYM4Xwhlv6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYx -FjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDAS -BgNVBAMTC3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA -bIcEHoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt -8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYD -VQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5 -cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqG -SIb3DQEJBTEPFw0wMjA4MDcxMjM4MjJaMCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLu -lJP7p1PCezALBgkqhkiG9w0BAQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPP -WALFPzEa6YKzftA5e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiY -EarezxGXjuPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.osig.pem b/tests/text-2.osig.pem deleted file mode 100644 index 57b5da9b2..000000000 --- a/tests/text-2.osig.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEU01pbGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4g -dGVybXMuCiAgICAgICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjM4MjJa -MCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLulJP7p1PCezALBgkqhkiG9w0B -AQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPPWALFPzEa6YKzftA5 -e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiYEarezxGX -juPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.txt b/tests/text-2.txt deleted file mode 100644 index 314c7a4e8..000000000 --- a/tests/text-2.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military intelligence is a contradiction in terms. - -- Groucho Marx diff --git a/tests/text-3.txt b/tests/text-3.txt deleted file mode 100644 index 9345b550f..000000000 --- a/tests/text-3.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military justice is to justice what military music is to music. - -- Groucho Marx diff --git a/tools/ChangeLog b/tools/ChangeLog deleted file mode 100644 index a81a2d301..000000000 --- a/tools/ChangeLog +++ /dev/null @@ -1,252 +0,0 @@ -2004-06-14 Werner Koch <wk@gnupg.org> - - * no-libgcrypt.c (gcry_realloc, gcry_xmalloc, gcry_xcalloc): New. - - * gpgconf-comp.c (retrieve_options_from_program) - (retrieve_options_from_file, change_options_file) - (change_options_program, gc_component_change_options): Replaced - getline by read_line and test for allocation failure. - -2004-05-21 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_dirmngr): Remove CRL group, put its - only option "max-replies" into LDAP group. - (gc_component): Change description of dirmngr to "Directory - Manager". - - * gpgconf-comp.c (gc_component_change_options): Move the - per-process backup file into a standard location. - -2004-05-03 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Add --allow-mark-trusted for the gpg-agent. - -2004-04-30 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Added more runtime flags for the gpg-agent - backend. - -2004-04-29 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (change_options_program): Turn on utf8-strings in - the gpgconf specific part of the config file for the GnuPG - backend. - -2004-04-28 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Add --ocsp-signer for the dirmngr backend. - -2004-04-20 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_gpg_agent): Change type of - ignore-cache-for-signing option to GC_ARG_TYPE_NONE. - -2004-04-07 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (my_dgettext): Switch the codeset once to utf-8. - Allow building with out NLS. - -2004-03-23 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_options_dirmngr): Set GC_OPT_FLAG_ARG_OPT for - "LDAP Server". - (change_options_file): Remove assertion that tests that this flag - is not present. Handle an empty string in OPTION->new_value. - - * gpgconf.c (main): Remove obsolete warning. - -2004-03-23 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (gc_options_gpg): New. - (gc_component_t, gc_component): Add GC_BACKEND_GPG. - (gc_options_dirmngr): Add allow-ocsp. - -2004-03-23 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_flag): Add missing flags. - - * gpgconf-comp.c: Include <signal.h>. - (gc_backend): Add new member runtime_change. - (gpg_agent_runtime_change): New function. - (gc_component_change_options): New variable runtime. Initialize - it. If an option is changed that has the GC_OPT_FLAG_RUNTIME bit - set, also set the corresponding runtime variable. Finally, call - the runtime_change callback of the backend if needed. - -2004-03-16 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c (gc_options_gpg_agent): Implemented. - (gc_options_gpgsm, gc_options_scdaemon): Implemented. - (gc_backend_t): Add GC_BACKEND_SCDAEMON. - -2004-03-12 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_change_options): Set the filenames - of the option's backend, not of the component. - Also use GC_BACKEND_NR, not GC_COMPONENT_NR. - -2004-03-09 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c [_riscos_]: Removed special code for RISC OS; we - don't want to clutter our code with system dependent stuff. - -2004-03-08 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (retrieve_options_from_file): Quote each string - in the list, not only the first. - -2004-02-26 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_list_options): Do not print empty - groups. - - * gpgconf-comp.c (option_check_validity): Check if option is - active. - (change_options_file): Implement. - - * gpgconf-comp.c (retrieve_options_from_program): Remove broken - string handling. - - * gpgconf-comp.c (change_options_program): Support all types of - options, including list types. - - * README.gpgconf: Fix description of arguments. - * gpgconf-comp.c (option_check_validity): Rewritten to properly - support optional arguments in lists. - - * README.gpgconf: Add info about optional arg and arg type 0. - * gpgconf-comp.c (gc_component_change_options): Parse list of - arg type 0 options. - (option_check_validity): Add new argument NEW_VALUE_NR. Perform - rigorous validity checks. - (change_options_program): Disable an option also if we have a new - value for it. - -2004-02-25 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_component_list_options): Correct output for - lists of arg type none. - (struct gc_option): Add new member new_flags. - (option_check_validity): Check OPTION->new_flags beside - OPTION->new_value. Add new argument FLAGS. - (gc_component_change_options): Support default flag correctly. - (change_options_program): Likewise. - -2004-02-24 Marcus Brinkmann <marcus@g10code.de> - - * README.gpgconf: Revert last change. Add new flags "default", - "default desc" and "no arg desc". Add new field ARGDEF. Add new - field FLAG to backend interface. - * gpgconf-comp.c (struct gc_option): Make flags of type unsigned - long. - (gc_component_list_options): Adjust type for flags. - Add default argument field. - (retrieve_options_from_program): Use "1" as value for non-option - arguments, not "Y". - (gc_component_change_options): Read in flags from input. - -2004-02-23 Marcus Brinkmann <marcus@g10code.de> - - * README.gpgconf: Change meaning of type 0 options value if it is - the empty string or "0". - - * gpgconf.h (struct): Add member runtime. - * gpgconf.c: Add new option oRuntime. - (main): Same here. - - * gpgconf-comp.c (hextobyte): New function. - (percent_deescape): New function. - (get_config_pathname): Percent deescape pathname if taken from - option (default) value. Use default value only if it exists and - is not empty. Use empty string otherwise. Don't include leading - quote in pathname. - (change_options_program): Percent deescape string before writing - it out. - - * gpgconf-comp.c (gc_component_list_options): Do not skip groups - on output. - -2004-02-18 Werner Koch <wk@gnupg.org> - - * gpgconf-comp.c: Added empty components for gpgsm and scdaemon. - -2004-02-12 Werner Koch <wk@gnupg.org> - - * watchgnupg.c (main): Implement option "--". - (print_version): New. - - * Makefile.am: Include cmacros.am for common flags. - -2004-02-03 Werner Koch <wk@gnupg.org> - - * addgnupghome: Try to use getent, so that it also works for NIS - setups. - -2004-01-31 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c: Some bug fixes, parse only defaults from the - program, and read the current values from the configuration file - directly. - -2004-01-30 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-comp.c (gc_error): New function, use it instead of - error() throughout. - - * gpgconf-comp.c: Use xmalloc, libcommon's asctimestamp and - gnupg_get_time, fix error() invocation and use getline() - consistently. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * addgnupghome: Also set the group of copied files. - -2004-01-30 Werner Koch <wk@gnupg.org> - - * Makefile.am (sbin_SCRIPTS): New, to install addgnupghome. - (EXTRA_DIST): Added rfc822parse.c rfc822parse.h gpgparsemail.c - which might be useful for debugging. - -2004-01-29 Werner Koch <wk@gnupg.org> - - * addgnupghome: New. - -2004-01-29 Marcus Brinkmann <marcus@g10code.de> - - * gpgconf-list.c: File removed. - * README.gpgconf: New file. - * gpgconf-comp.c: New file. - * Makefile.am (gpgconf_SOURCES): Remove gpgconf-list.c, add - gpgconf-comp.c. - -2004-01-16 Werner Koch <wk@gnupg.org> - - * watchgnupg.c (main): Need to use FD_ISSET for the client - descriptors too; aiiih. Set the listening socket to non-blocking. - -2004-01-10 Werner Koch <wk@gnupg.org> - - * Makefile.am: Use GPG_ERROR_CFLAGS - -2004-01-05 Werner Koch <wk@gnupg.org> - - * Manifest: New. - * gpgconf.c, gpgconf.h, gpgconf-list.c: New. A skeleton for now. - * no-libgcrypt.c: New. - * Makefile.am: Add above. - -2003-12-23 Werner Koch <wk@gnupg.org> - - * Makefile.am: New. - * watchgnupg.c: New. - - - Copyright 2003, 2004 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/tools/Makefile.am b/tools/Makefile.am deleted file mode 100644 index 71a77356f..000000000 --- a/tools/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -# Makefile.am - Tools directory -# Copyright (C) 2003 Free Software Foundation, Inc. -# -# This file is part of GnuPG. -# -# GnuPG is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# GnuPG is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -EXTRA_DIST = Manifest watchgnupg.c \ - rfc822parse.c rfc822parse.h gpgparsemail.c \ - addgnupghome - -AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/common -include $(top_srcdir)/am/cmacros.am - -# Note, that we require GPG_ERROR_CFLAGS only because some share header files -# require that file. It is not actually used in gpgconf. -AM_CFLAGS = @GPG_ERROR_CFLAGS@ - -sbin_SCRIPTS = addgnupghome - -bin_PROGRAMS = gpgconf watchgnupg - -gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c - -gpgconf_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a @INTLLIBS@ - -watchgnupg_SOURCES = watchgnupg.c diff --git a/tools/Manifest b/tools/Manifest deleted file mode 100644 index 96423352d..000000000 --- a/tools/Manifest +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.am -watchgnupg.c -gpgconf.c -gpgconf.h -gpgconf-list.c -$names$ diff --git a/tools/README.gpgconf b/tools/README.gpgconf deleted file mode 100644 index c0d3c7c61..000000000 --- a/tools/README.gpgconf +++ /dev/null @@ -1,422 +0,0 @@ -============ - GPG Conf -============ - -CONCEPT -======= - -gpgconf provides access to the configuration of one or more components -of the GnuPG system. These components correspond more or less to the -programs that exist in the GnuPG framework, like GnuPG, GPGSM, -DirMngr, etc. But this is not a strict one-to-one relationship. Not -all configuration options are available through GPGConf. GPGConf -provides a generic and abstract method to access the most important -configuration options that can feasibly be controlled via such a -mechanism. - -GPGConf can be used to gather and change the options available in each -component, and can also provide their default values. GPGConf will -give detailed type information that can be used to restrict the user's -input without making an attempt to commit the changes. - -GPGConf provides the backend of a configuration editor. The -configuration editor would usually be a graphical user interface -program, that allows to display the current options, their default -values, and allows the user to make changes to the options. These -changes can then be made active with GPGConf again. Such a program -that uses GPGConf in this way will be called 'GUI' throughout this -document. - - -Format Conventions -================== - -Some lines in the output of GPGConf contain a list of colon-separated -fields. The following conventions apply: - -The GUI program is required to strip off trailing newline and/or carriage -return characters from the output. - -GPGConf will never leave out fields. If a certain version documents a -certain field, this field will always be present in all GPGConf -versions from that time on. - -Future versions of GPGConf might append fields to the list. New -fields will always be separated from the previously last field by a -colon separator. The GUI should be prepared to parse the last field -it knows about up until a colon or end of line. - -Not all fields are defined under all conditions. You are required to -ignore the content of undefined fields. - -Some fields contain strings that are not escaped in any way. Such -fields are described to be used "verbatim". These fields will never -contain a colon character (for obvious reasons). No de-escaping or -other formatting is required to use the field content. This is for -easy parsing of the output, when it is known that the content can -never contain any special characters. - -Some fields contain strings that are described to be -"percent-escaped". Such strings need to be de-escaped before their -content can be presented to the user. A percent-escaped string is -de-escaped by replacing all occurences of %XY by the byte that has the -hexadecimal value XY. X and Y are from the set { '0'..'9', 'a'..'f' }. - -Some fields contain strings that are described to be "localised". Such -strings are translated to the active language and formatted in the -active character set. - -Some fields contain an unsigned number. This number will always fit -into a 32-bit unsigned integer variable. The number may be followed -by a space, followed by a human readable description of that value. -You should ignore everything in the field that follows the number. - -Some fields contain a signed number. This number will always fit into -a 32-bit signed integer variable. The number may be followed by a -space, followed by a human readable description of that value. You -should ignore everything in the field that follows the number. - -Some fields contain an option argument. The format of an option -argument depends on the type of the option and on some flags: - -The simplest case is that the option does not take an argument at all -(TYPE is 0). Then the option argument is an unsigned number that -specifies how often the option occurs. If the LIST flag is not set, -then the only valid number is 1. Options that don't take an argument -never have the "default" or "optional arg" flag set. - -If the option takes a number argument (ALT-TYPE is 2 or 3), and it can -only occur once (LIST flag is not set), then the option argument is -either empty (only allowed if the argument is optional), or it is a -number. A number is a string that begins with an optional minus -character, followed by one or more digits. The number must fit into -an integer variable (unsigned or signed, depending on ALT-TYPE). - -If the option takes a number argument and it can occur more than once, -then the option argument is either empty, or it is a comma-separated -list of numbers as described above. - -If the option takes a string argument (ALT-TYPE is 1), and it can only -occur once (LIST flag is not set) then the option argument is either -empty (only allowed if the argument is optional), or it starts with a -double quote character (") followed by a percent-escaped string that -is the argument value. Note that there is only a leading double quote -character, no trailing one. The double quote character is only needed -to be able to differentiate between no value and the empty string as -value. - -If the option takes a number argument and it can occur more than once, -then the option argument is either empty, or it is a comma-separated -list of string arguments as described above. - -FIXME: Document the active language and active character set. Allow -to change it via the command line? - - -Components -========== - -A component is a set of configuration options that semantically belong -together. Furthermore, several changes to a component can be made in -an atomic way with a single operation. The GUI could for example -provide a menu with one entry for each component, or a window with one -tabulator sheet per component. - -The following interface is provided to list the available components: - -Command --list-components -------------------------- - -Outputs a list of all components available, one per line. The format -of each line is: - -NAME:DESCRIPTION - -NAME - -This field contains a name tag of the component. The name tag is used -to specify the component in all communication with GPGConf. The name -tag is to be used verbatim. It is not in any escaped format. - -DESCRIPTION - -The string in this field contains a human-readable description of the -component. It can be displayed to the user of the GUI for -informational purposes. It is percent-escaped and localized. - -Example: -$ gpgconf --list-components -gpg-agent:GPG Agent -dirmngr:CRL Manager - - -OPTIONS -======= - -Every component contains one or more options. Options may belong to a -group. The following command lists all options and the groups they -belong to: - -Command --list-options COMPONENT --------------------------------- - -Lists all options (and the groups they belong to) in the component -COMPONENT. COMPONENT is the string in the field NAME in the -output of the --list-components command. - -There is one line for each option and each group. First come all -options that are not in any group. Then comes a line describing a -group. Then come all options that belong into each group. Then comes -the next group and so on. - -The format of each line is: - -NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE - -NAME - -This field contains a name tag for the group or option. The name tag -is used to specify the group or option in all communication with -GPGConf. The name tag is to be used verbatim. It is not in any -escaped format. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 1 group If this flag is set, this is a line describing - a group and not an option. - O 2 optional arg If this flag is set, the argument is optional. - This is never set for arg type 0 (none) options. - O 4 list If this flag is set, the option can be given - multiple times. - O 8 runtime If this flag is set, the option can be changed - at runtime. - O 16 default If this flag is set, a default value is available. - O 32 default desc If this flag is set, a (runtime) default is available. - This and the 'default' flag are mutually exclusive. - O 64 no arg desc If this flag is set, and the 'optional arg' flag - is set, then the option has a special meaning if no - argument is given. - -Flags marked with a 'O' are only defined for options (ie, if the GROUP -flag is not set). - -LEVEL - -This field is defined for options and for groups. It contains an -unsigned number that specifies the expert level under which this group -or option should be displayed. The following expert levels are -defined for options (they have analogous meaning for groups): - - 0 basic This option should always be offered to the user. - 1 advanced This option may be offered to advanced users. - 2 expert This option should only be offered to expert users. - 3 invisible This option should normally never be displayed, - not even to expert users. - 4 internal This option is for internal use only. Ignore it. - -The level of a group will always be the lowest level of all options it -contains. - -DESCRIPTION - -This field is defined for options and groups. The string in this -field contains a human-readable description of the option or group. -It can be displayed to the user of the GUI for informational purposes. -It is percent-escaped and localized. - -TYPE - -This field is only defined for options. It contains an unsigned -number that specifies the type of the option's argument, if any. -The following types are defined: - - Basic types - 0 none No argument allowed. - 1 string An unformatted string. - 2 int32 A signed integer number. - 3 uint32 An unsigned integer number. - - Complex types - 32 pathname A string that describes the pathname of a file. - The file does not necessarily need to exist. - 33 ldap server A string that describes an LDAP server in the format - HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. - -More types will be added in the future. Please see the ALT-TYPE field -for information on how to cope with unknown types. - -ALT-TYPE - -This field is identical to TYPE, except that only the types 0 to 31 -are allowed. The GUI is expected to present the user the option in -the format specified by TYPE. But if the argument type TYPE is not -supported by the GUI, it can still display the option in the more -generic basic type ALT-TYPE. The GUI must support all the defined -basic types to be able to display all options. More basic types may -be added in future versions. If the GUI encounters a basic type it -doesn't support, it should report an error and abort the operation. - -ARGNAME - -This field is only defined for options with an argument type TYPE that -is not 0. In this case it may contain a percent-escaped and localised -string that gives a short name for the argument. The field may also -be empty, though, in which case a short name is not known. - -DEFAULT - -This field is defined only for options. Its format is that of an -option argument (see section Format Conventions for details). If the -default value is empty, then no default is known. Otherwise, the -value specifies the default value for this option. Note that this -field is also meaningful if the option itself does not take a real -argument. - -ARGDEF - -This field is defined only for options for which the "optional arg" -flag is set. If the "no arg desc" flag is not set, its format is that -of an option argument (see section Format Conventions for details). -If the default value is empty, then no default is known. Otherwise, -the value specifies the default value for this option. If the "no arg -desc" flag is set, the field is either empty or contains a description -of the effect of this option if no argument is given. Note that this -field is also meaningful if the option itself does not take a real -argument. - -VALUE - -This field is defined only for options. Its format is that of an -option argument. If it is empty, then the option is not explicitely -set in the current configuration, and the default applies (if any). -Otherwise, it contains the current value of the option. Note that -this field is also meaningful if the option itself does not take a -real argument. - - -CHANGING OPTIONS -================ - -To change the options for a component, you must provide them in the -following format: - -NAME:FLAGS:NEW-VALUE - -NAME - -This is the name of the option to change. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 16 default If this flag is set, the option is deleted and the - default value is used instead (if applicable). - -NEW-VALUE - -The new value for the option. This field is only defined if the -"default" flag is not set. The format is that of an option argument. -If it is empty (or the field is omitted), the default argument is used -(only allowed if the argument is optional for this option). -Otherwise, the option will be set to the specified value. - - -Example: -To set the option force, which is of basic type 0 (none). -$ echo 'force:0:1' | gpgconf --change-options dirmngr -To delete the option force: -$ echo 'force:16:' | gpgconf --change-options dirmngr - - -Option --runtime ----------------- - -If this option is set, the changes will take effect at run-time, as -far as this is possible. Otherwise, they will take effect at the next -start of the respective backend programs. - - -BACKENDS -======== - -Backends should support the following commands: - -Command --gpgconf-list ----------------------- - -List the location of the configuration file, and all default values of -all options. The location of the configuration file must be an -absolute pathname. - -The format of each line is: - -NAME:FLAGS:DEFAULT:ARGDEF - -NAME - -This field contains a name tag for the group or option. The name tag -is used to specify the group or option in all communication with -GPGConf. The name tag is to be used verbatim. It is not in any -escaped format. - -FLAGS - -The flags field contains an unsigned number. Its value is the -OR-wise combination of the following flag values: - - 16 default If this flag is set, a default value is available. - 32 default desc If this flag is set, a (runtime) default is available. - This and the "default" flag are mutually exclusive. - 64 no arg desc If this flag is set, and the "optional arg" flag - is set, then the option has a special meaning if no - argument is given. - -DEFAULT - -This field is defined only for options. Its format is that of an -option argument (see section Format Conventions for details). If the -default value is empty, then no default is known. Otherwise, the -value specifies the default value for this option. Note that this -field is also meaningful if the option itself does not take a real -argument. - -ARGDEF - -This field is defined only for options for which the "optional arg" -flag is set. If the "no arg desc" flag is not set, its format is that -of an option argument (see section Format Conventions for details). -If the default value is empty, then no default is known. Otherwise, -the value specifies the default value for this option. If the "no arg -desc" flag is set, the field is either empty or contains a description -of the effect of this option if no argument is given. Note that this -field is also meaningful if the option itself does not take a real -argument. - - -Example: -$ dirmngr --gpgconf-list -gpgconf-config-file:/mnt/marcus/.gnupg/dirmngr.conf -ldapservers-file:/mnt/marcus/.gnupg/dirmngr_ldapservers.conf -add-servers:0 -max-replies:10 - - -TODO ----- - -* Extend the backend interface to include gettext domain and -description, if available, to avoid repeating this information in -gpgconf. - -* Left out string arguments (optional) are written out exactly as -empty string arguments. Should we do quoting? - -* More string argument trouble: Special characters like newlines etc -cause trouble. Again, should we do quoting? - - diff --git a/tools/addgnupghome b/tools/addgnupghome deleted file mode 100755 index 37a427bf2..000000000 --- a/tools/addgnupghome +++ /dev/null @@ -1,122 +0,0 @@ -# !/bin/sh -*- sh -*- -# Add a new .gnupg home directory for a list of users -# -# Copyright 2004 Free Software Foundation, Inc. -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -PGM=addgnupghome -any_error=0 - - -error () { - echo "$PGM: $*" >&2 - any_error=1 -} - -info () { - echo "$PGM: $*" >&2 -} - -# Do it for one user -one_user () { - user="$1" - home=$(${cat_passwd} | awk -F: -v n="$user" '$1 == n {print $6}') - if [ -z "$home" ]; then - if ${cat_passwd} | awk -F: -v n="$user" '$1 == n {exit 1}'; then - error "no such user \`$user'" - else - error "no home directory for user \`$user'" - fi - return - fi - if [ ! -d "$home" ]; then - error "home directory \`$home' of user \`$user' does not exist" - return - fi - if [ -d "$home/.gnupg" ]; then - info "skipping user \`$user': \`.gnupg' already exists" - return - fi - info "creating home directory \`$home/.gnupg' for \`$user'" - if ! mkdir "$home/.gnupg" ; then - error "error creating \`$home/.gnupg'" - return - fi - - if ! chown $user "$home/.gnupg" ; then - error "error changing ownership of \`$home/.gnupg'" - return - fi - - group=$(id -g "$user") - [ -z "$group" ] && group="0" - - if [ "$group" -gt 0 ]; then - if ! chgrp $group "$home/.gnupg" ; then - error "error changing group of \`$home/.gnupg'" - return - fi - fi - - if ! cd "$home/.gnupg" ; then - error "error cd-ing to \`$home/.gnupg'" - return - fi - for f in $filelist; do - if [ -d /etc/skel/.gnupg/$f ]; then - mkdir $f - else - cp /etc/skel/.gnupg/$f $f - fi - if ! chown $user $f ; then - error "error changing ownership of \`$f'" - return - fi - if [ "$group" -gt 0 ]; then - if ! chgrp $group "$f" ; then - error "error changing group of \`$f'" - return - fi - fi - done - -} - -if [ -z "$1" ]; then - echo "usage: $PGM userids" - exit 1 -fi - -# Check whether we can use getent -if getent --help </dev/null >/dev/null 2>&1 ; then - cat_passwd='getent passwd' -else - cat_passwd='cat /etc/passwd' - info "please note that only users from /etc/passwd are checked" -fi - -if [ ! -d /etc/skel/.gnupg ]; then - error "skeleton directory \`/etc/skel/.gnupg' does not exist" - exit 1 -fi -cd "/etc/skel/.gnupg" || (error "error cd-ing to \`/etc/skel/.gnupg'"; exit 1) -filelist=$(find . \( -type f -or -type d \) -not -name '*~' -not -name . -print) - - -if ! umask 0077 ; then - error "error setting umask" - exit 1 -fi - -for name in $*; do - one_user $name -done - -exit $any_error diff --git a/tools/der-to-pem b/tools/der-to-pem deleted file mode 100755 index 183996654..000000000 --- a/tools/der-to-pem +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# Convert A BER or DER encoding to PEM format. -# -# Copyright 20032 Free Software Foundation, Inc. -# -# This program is Free Software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -PGM="der-to-pem" -if [ $# == 0 ]; then - input="" -elif [ $# == 1 ]; then - input="$1" -else - echo "usage: $PGM [<inputfile>]" >&2 - exit 1 -fi - -echo "-----BEGIN CERTIFICATE-----" -mimencode $input -echo "-----END CERTIFICATE-----" - diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c deleted file mode 100644 index cc0751d0c..000000000 --- a/tools/gpgconf-comp.c +++ /dev/null @@ -1,2434 +0,0 @@ -/* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2004 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GnuPG is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GnuPG; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -/* FIXME use gettext.h */ -#include <libintl.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/types.h> -#include <assert.h> -#include <errno.h> -#include <time.h> -#include <stdarg.h> -#include <signal.h> - -/* For log_logv(), asctimestamp(), gnupg_get_time (). */ -#define JNLIB_NEED_LOG_LOGV -#include "util.h" - -#include "gpgconf.h" - - -/* TODO: - Components: Add more components and their options. - Robustness: Do more validation. Call programs to do validation for us. - Don't use popen, as this will not tell us if the program had a - non-zero exit code. - Add options to change backend binary path. - Extract binary path for some backends from gpgsm/gpg config. -*/ - - -#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) -void gc_error (int status, int errnum, const char *fmt, ...) \ - __attribute__ ((format (printf, 3, 4))); -#endif - -/* Output a diagnostic message. If ERRNUM is not 0, then the output - is followed by a colon, a white space, and the error string for the - error number ERRNUM. In any case the output is finished by a - newline. The message is prepended by the program name, a colon, - and a whitespace. The output may be further formatted or - redirected by the jnlib logging facility. */ -void -gc_error (int status, int errnum, const char *fmt, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, fmt); - log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr); - va_end (arg_ptr); - - if (errnum) - log_printf (": %s\n", strerror (errnum)); - else - log_printf ("\n"); - - if (status) - { - log_printf (NULL); - log_printf ("fatal error (exit status %i)\n", status); - exit (status); - } -} - - -/* Forward declaration. */ -void gpg_agent_runtime_change (void); - -/* Backend configuration. Backends are used to decide how the default - and current value of an option can be determined, and how the - option can be changed. To every option in every component belongs - exactly one backend that controls and determines the option. Some - backends are programs from the GPG system. Others might be - implemented by GPGConf itself. If you change this enum, don't - forget to update GC_BACKEND below. */ -typedef enum - { - /* Any backend, used for find_option (). */ - GC_BACKEND_ANY, - - /* The Gnu Privacy Guard. */ - GC_BACKEND_GPG, - - /* The Gnu Privacy Guard for S/MIME. */ - GC_BACKEND_GPGSM, - - /* The GPG Agent. */ - GC_BACKEND_GPG_AGENT, - - /* The GnuPG SCDaemon. */ - GC_BACKEND_SCDAEMON, - - /* The Aegypten directory manager. */ - GC_BACKEND_DIRMNGR, - - /* The LDAP server list file for the Aegypten director manager. */ - GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST, - - /* The number of the above entries. */ - GC_BACKEND_NR - } gc_backend_t; - - -/* To be able to implement generic algorithms for the various - backends, we collect all information about them in this struct. */ -static struct -{ - /* The name of the backend. */ - const char *name; - - /* The name of the program that acts as the backend. Some backends - don't have an associated program, but are implemented directly by - GPGConf. In this case, PROGRAM is NULL. */ - char *program; - - /* The runtime change callback. */ - void (*runtime_change) (void); - - /* The option name for the configuration filename of this backend. - This must be an absolute pathname. It can be an option from a - different backend (but then ordering of the options might - matter). */ - const char *option_config_filename; - - /* If this is a file backend rather than a program backend, then - this is the name of the option associated with the file. */ - const char *option_name; -} gc_backend[GC_BACKEND_NR] = - { - { NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" }, - { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" }, - { "GPG Agent", "gpg-agent", gpg_agent_runtime_change, - "gpgconf-gpg-agent.conf" }, - { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" }, - { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" }, - { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file", - "LDAP Server" }, - }; - - -/* Option configuration. */ - -/* An option might take an argument, or not. Argument types can be - basic or complex. Basic types are generic and easy to validate. - Complex types provide more specific information about the intended - use, but can be difficult to validate. If you add to this enum, - don't forget to update GC_ARG_TYPE below. YOU MUST NOT CHANGE THE - NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL - INTERFACE. */ -typedef enum - { - /* Basic argument types. */ - - /* No argument. */ - GC_ARG_TYPE_NONE = 0, - - /* A String argument. */ - GC_ARG_TYPE_STRING = 1, - - /* A signed integer argument. */ - GC_ARG_TYPE_INT32 = 2, - - /* An unsigned integer argument. */ - GC_ARG_TYPE_UINT32 = 3, - - /* ADD NEW BASIC TYPE ENTRIES HERE. */ - - /* Complex argument types. */ - - /* A complete pathname. */ - GC_ARG_TYPE_PATHNAME = 32, - - /* An LDAP server in the format - HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */ - GC_ARG_TYPE_LDAP_SERVER = 33, - - /* A 40 character fingerprint. */ - GC_ARG_TYPE_KEY_FPR = 34, - - /* ADD NEW COMPLEX TYPE ENTRIES HERE. */ - - /* The number of the above entries. */ - GC_ARG_TYPE_NR - } gc_arg_type_t; - - -/* For every argument, we record some information about it in the - following struct. */ -static struct -{ - /* For every argument type exists a basic argument type that can be - used as a fallback for input and validation purposes. */ - gc_arg_type_t fallback; - - /* Human-readable name of the type. */ - const char *name; -} gc_arg_type[GC_ARG_TYPE_NR] = - { - /* The basic argument types have their own types as fallback. */ - { GC_ARG_TYPE_NONE, "none" }, - { GC_ARG_TYPE_STRING, "string" }, - { GC_ARG_TYPE_INT32, "int32" }, - { GC_ARG_TYPE_UINT32, "uint32" }, - - /* Reserved basic type entries for future extension. */ - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, - - /* The complex argument types have a basic type as fallback. */ - { GC_ARG_TYPE_STRING, "pathname" }, - { GC_ARG_TYPE_STRING, "ldap server" }, - { GC_ARG_TYPE_STRING, "key fpr" }, - }; - - -/* Every option has an associated expert level, than can be used to - hide advanced and expert options from beginners. If you add to - this list, don't forget to update GC_LEVEL below. YOU MUST NOT - CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE - EXTERNAL INTERFACE. */ -typedef enum - { - /* The basic options should always be displayed. */ - GC_LEVEL_BASIC, - - /* The advanced options may be hidden from beginners. */ - GC_LEVEL_ADVANCED, - - /* The expert options should only be displayed to experts. */ - GC_LEVEL_EXPERT, - - /* The invisible options should normally never be displayed. */ - GC_LEVEL_INVISIBLE, - - /* The internal options are never exported, they mark options that - are recorded for internal use only. */ - GC_LEVEL_INTERNAL, - - /* ADD NEW ENTRIES HERE. */ - - /* The number of the above entries. */ - GC_LEVEL_NR - } gc_expert_level_t; - -/* A description for each expert level. */ -static struct -{ - const char *name; -} gc_level[] = - { - { "basic" }, - { "advanced" }, - { "expert" }, - { "invisible" }, - { "internal" } - }; - - -/* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING - FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0UL -/* Some entries in the option list are not options, but mark the - beginning of a new group of options. These entries have the GROUP - flag set. */ -#define GC_OPT_FLAG_GROUP (1UL << 0) -/* The ARG_OPT flag for an option indicates that the argument is - optional. This is never set for GC_ARG_TYPE_NONE options. */ -#define GC_OPT_FLAG_ARG_OPT (1UL << 1) -/* The LIST flag for an option indicates that the option can occur - several times. A comma separated list of arguments is used as the - argument value. */ -#define GC_OPT_FLAG_LIST (1UL << 2) -/* The RUNTIME flag for an option indicates that the option can be - changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1UL << 3) - -/* The following flags are incorporated from the backend. */ -/* The DEFAULT flag for an option indicates that the option has a - default value. */ -#define GC_OPT_FLAG_DEFAULT (1UL << 4) -/* The DEF_DESC flag for an option indicates that the option has a - default, which is described by the value of the default field. */ -#define GC_OPT_FLAG_DEF_DESC (1UL << 5) -/* The NO_ARG_DESC flag for an option indicates that the argument has - a default, which is described by the value of the ARGDEF field. */ -#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - -/* A human-readable description for each flag. */ -static struct -{ - const char *name; -} gc_flag[] = - { - { "group" }, - { "optional arg" }, - { "list" }, - { "runtime" }, - { "default" }, - { "default desc" }, - { "no arg desc" } - }; - - -/* To each option, or group marker, the information in the GC_OPTION - struct is provided. If you change this, don't forget to update the - option list of each component. */ -struct gc_option -{ - /* If this is NULL, then this is a terminator in an array of unknown - length. Otherwise, if this entry is a group marker (see FLAGS), - then this is the name of the group described by this entry. - Otherwise it is the name of the option described by this - entry. The name must not contain a colon. */ - const char *name; - - /* The option flags. If the GROUP flag is set, then this entry is a - group marker, not an option, and only the fields LEVEL, - DESC_DOMAIN and DESC are valid. In all other cases, this entry - describes a new option and all fields are valid. */ - unsigned long flags; - - /* The expert level. This field is valid for options and groups. A - group has the expert level of the lowest-level option in the - group. */ - gc_expert_level_t level; - - /* A gettext domain in which the following description can be found. - If this is NULL, then DESC is not translated. Valid for groups - and options. */ - const char *desc_domain; - - /* A gettext description for this group or option. If it starts - with a '|', then the string up to the next '|' describes the - argument, and the description follows the second '|'. */ - const char *desc; - - /* The following fields are only valid for options. */ - - /* The type of the option argument. */ - gc_arg_type_t arg_type; - - /* The backend that implements this option. */ - gc_backend_t backend; - - /* The following fields are set to NULL at startup (because all - option's are declared as static variables). They are at the end - of the list so that they can be omitted from the option - declarations. */ - - /* This is true if the option is supported by this version of the - backend. */ - int active; - - /* The default value for this option. This is NULL if the option is - not present in the backend, the empty string if no default is - available, and otherwise a quoted string. */ - char *default_value; - - /* The default argument is only valid if the "optional arg" flag is - set, and specifies the default argument (value) that is used if - the argument is omitted. */ - char *default_arg; - - /* The current value of this option. */ - char *value; - - /* The new flags for this option. The only defined flag is actually - GC_OPT_FLAG_DEFAULT, and it means that the option should be - deleted. In this case, NEW_VALUE is NULL. */ - unsigned long new_flags; - - /* The new value of this option. */ - char *new_value; -}; -typedef struct gc_option gc_option_t; - -/* Use this macro to terminate an option list. */ -#define GC_OPTION_NULL { NULL } - - -/* The options of the GC_COMPONENT_GPG_AGENT component. */ -static gc_option_t gc_options_gpg_agent[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, - { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "|N|expire cached PINs after N seconds", - GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, - { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, - "gnupg", "do not use the PIN cache when signing", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "allow clients to mark keys as \"trusted\"", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, - "gnupg", "do not grab keyboard and mouse", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_SCDAEMON component. */ -static gc_option_t gc_options_scdaemon[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "|N|connect to reader at port N", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|NAME|use NAME as ct-API driver", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|NAME|use NAME as PC/SC driver", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not use the OpenSC layer", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not use the internal CCID driver", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "allow the use of admin card commands", - GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_GPG component. */ -static gc_option_t gc_options_gpg[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, -/* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */ -/* NULL, NULL, */ -/* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */ - - { "Keyserver", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration for Keyservers" }, - { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "|URL|use keyserver at URL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, - - - GC_OPTION_NULL - }; - - - -/* The options of the GC_COMPONENT_GPGSM component. */ -static gc_option_t gc_options_gpgsm[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "gnupg", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "gnupg", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM }, - - { "Security", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, - { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "never consult a CRL", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "check validity using OCSP", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "|N|number of certificates to include", - GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM }, - { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "do not check certificate policies", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "fetch missing issuer certificates", - GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, - - GC_OPTION_NULL - }; - - -/* The options of the GC_COMPONENT_DIRMNGR component. */ -static gc_option_t gc_options_dirmngr[] = - { - /* The configuration file to which we write the changes. */ - { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - - { "Monitor", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - "dirmngr", "verbose", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "be somewhat more quiet", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "Format", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the format of the output" }, - { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "sh-style command output", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "csh-style command output", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "Configuration", - GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, - { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "dirmngr", "|FILE|read options from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - - { "Debug", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "dirmngr", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "dirmngr", "|LEVEL|set the debugging level to LEVEL", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "do not detach from the console", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|FILE|write logs to FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, - NULL, NULL, - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - - { "Enforcement", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the interactivity and enforcement" }, - { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "run without asking a user", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "force loading of outdated CRLs", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - - { "LDAP", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration of LDAP servers to use" }, - { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "add new servers discovered in CRL distribution points" - " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "|N|set LDAP timeout to N seconds", - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - /* The following entry must not be removed, as it is required for - the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */ - { "ldapserverlist-file", - GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, - "dirmngr", "|FILE|read LDAP server list from FILE", - GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, - /* This entry must come after at least one entry for - GC_BACKEND_DIRMNGR in this component, so that the entry for - "ldapserverlist-file will be initialized before this one. */ - { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, - NULL, "LDAP server list", - GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST }, - { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "|N|do not return more than N items in one query", - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - - { "OCSP", - GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - NULL, "Configuration for OCSP" }, - { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "dirmngr", "allow sending OCSP requests", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|URL|use OCSP responder URL", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|FPR|OCSP response signed by FPR", - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, - - - GC_OPTION_NULL - }; - - -/* Component system. Each component is a set of options that can be - configured at the same time. If you change this, don't forget to - update GC_COMPONENT below. */ -typedef enum - { - /* The classic GPG for OpenPGP. */ - GC_COMPONENT_GPG, - - /* The GPG Agent. */ - GC_COMPONENT_GPG_AGENT, - - /* The Smardcard Daemon. */ - GC_COMPONENT_SCDAEMON, - - /* GPG for S/MIME. */ - GC_COMPONENT_GPGSM, - - /* The LDAP Directory Manager for CRLs. */ - GC_COMPONENT_DIRMNGR, - - /* The number of components. */ - GC_COMPONENT_NR - } gc_component_t; - - -/* The information associated with each component. */ -static struct -{ - /* The name of this component. Must not contain a colon (':') - character. */ - const char *name; - - /* The gettext domain for the description DESC. If this is NULL, - then the description is not translated. */ - const char *desc_domain; - - /* The description for this domain. */ - const char *desc; - - /* The list of options for this component, terminated by - GC_OPTION_NULL. */ - gc_option_t *options; -} gc_component[] = - { - { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg }, - { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, - { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, - { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, - { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } - }; - - -/* Engine specific support. */ -void -gpg_agent_runtime_change (void) -{ - char *agent = getenv ("GPG_AGENT_INFO"); - char *pid_str; - unsigned long pid_long; - char *tail; - pid_t pid; - - if (!agent) - return; - - pid_str = strchr (agent, ':'); - if (!pid_str) - return; - - pid_str++; - errno = 0; - pid_long = strtoul (pid_str, &tail, 0); - if (errno || (*tail != ':' && *tail != '\0')) - return; - - pid = (pid_t) pid_long; - - /* Check for overflow. */ - if (pid_long != (unsigned long) pid) - return; - - /* Ignore any errors here. */ - kill (pid, SIGHUP); -} - - -/* More or less Robust version of dgettext. It has the sidefeect of - switching the codeset to utf-8 becuase this is what we want to - output. In theory it is posible to keep the orginal code set and - switch back for regular disgnostic output (redefine "_(" for that) - but given the natur of this tool, being something invoked from - other pograms, it does not make much sense. */ -static const char * -my_dgettext (const char *domain, const char *msgid) -{ -#ifdef ENABLE_NLS - if (domain) - { - static int switched_codeset; - char *text; - - if (!switched_codeset) - { - bind_textdomain_codeset (PACKAGE_GT, "utf-8"); - switched_codeset = 1; - } - text = dgettext (domain, msgid); - return text ? text : msgid; - } - else -#endif - return msgid; -} - - -/* Percent-Escape special characters. The string is valid until the - next invocation of the function. */ -static char * -percent_escape (const char *src) -{ - static char *esc_str; - static int esc_str_len; - int new_len = 3 * strlen (src) + 1; - char *dst; - - if (esc_str_len < new_len) - { - char *new_esc_str = realloc (esc_str, new_len); - if (!new_esc_str) - gc_error (1, errno, "can not escape string"); - esc_str = new_esc_str; - esc_str_len = new_len; - } - - dst = esc_str; - while (*src) - { - if (*src == '%') - { - *(dst++) = '%'; - *(dst++) = '2'; - *(dst++) = '5'; - } - else if (*src == ':') - { - /* The colon is used as field separator. */ - *(dst++) = '%'; - *(dst++) = '3'; - *(dst++) = 'a'; - } - else if (*src == ',') - { - /* The comma is used as list separator. */ - *(dst++) = '%'; - *(dst++) = '2'; - *(dst++) = 'c'; - } - else - *(dst++) = *(src); - src++; - } - *dst = '\0'; - return esc_str; -} - - -/* Convert two hexadecimal digits from STR to the value they - represent. Returns -1 if one of the characters is not a - hexadecimal digit. */ -static int -hextobyte (const char *str) -{ - int val = 0; - int i; - -#define NROFHEXDIGITS 2 - for (i = 0; i < NROFHEXDIGITS; i++) - { - if (*str >= '0' && *str <= '9') - val += *str - '0'; - else if (*str >= 'A' && *str <= 'F') - val += 10 + *str - 'A'; - else if (*str >= 'a' && *str <= 'f') - val += 10 + *str - 'a'; - else - return -1; - if (i < NROFHEXDIGITS - 1) - val *= 16; - str++; - } - return val; -} - - - -/* Percent-Deescape special characters. The string is valid until the - next invocation of the function. */ -static char * -percent_deescape (const char *src) -{ - static char *str; - static int str_len; - int new_len = 3 * strlen (src) + 1; - char *dst; - - if (str_len < new_len) - { - char *new_str = realloc (str, new_len); - if (!new_str) - gc_error (1, errno, "can not deescape string"); - str = new_str; - str_len = new_len; - } - - dst = str; - while (*src) - { - if (*src == '%') - { - int val = hextobyte (src + 1); - - if (val < 0) - gc_error (1, 0, "malformed end of string %s", src); - - *(dst++) = (char) val; - src += 3; - } - else - *(dst++) = *(src++); - } - *dst = '\0'; - return str; -} - - -/* List all components that are available. */ -void -gc_component_list_components (FILE *out) -{ - gc_component_t idx; - - for (idx = 0; idx < GC_COMPONENT_NR; idx++) - { - const char *desc = gc_component[idx].desc; - desc = my_dgettext (gc_component[idx].desc_domain, desc); - fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc)); - } -} - - -/* Find the component with the name NAME. Returns -1 if not - found. */ -int -gc_component_find (const char *name) -{ - gc_component_t idx; - - for (idx = 0; idx < GC_COMPONENT_NR; idx++) - { - if (!strcmp (name, gc_component[idx].name)) - return idx; - } - return -1; -} - - -/* List the option OPTION. */ -static void -list_one_option (const gc_option_t *option, FILE *out) -{ - const char *desc = NULL; - char *arg_name = NULL; - - if (option->desc) - { - desc = my_dgettext (option->desc_domain, option->desc); - - if (*desc == '|') - { - const char *arg_tail = strchr (&desc[1], '|'); - - if (arg_tail) - { - int arg_len = arg_tail - &desc[1]; - arg_name = xmalloc (arg_len + 1); - memcpy (arg_name, &desc[1], arg_len); - arg_name[arg_len] = '\0'; - desc = arg_tail + 1; - } - } - } - - - /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS - PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY - FIELDS. */ - - /* The name field. */ - fprintf (out, "%s", option->name); - - /* The flags field. */ - fprintf (out, ":%lu", option->flags); - if (opt.verbose) - { - putc (' ', out); - - if (!option->flags) - fprintf (out, "none"); - else - { - unsigned long flags = option->flags; - unsigned long flag = 0; - unsigned long first = 1; - - while (flags) - { - if (flags & 1) - { - if (first) - first = 0; - else - putc (',', out); - fprintf (out, "%s", gc_flag[flag].name); - } - flags >>= 1; - flag++; - } - } - } - - /* The level field. */ - fprintf (out, ":%u", option->level); - if (opt.verbose) - fprintf (out, " %s", gc_level[option->level].name); - - /* The description field. */ - fprintf (out, ":%s", desc ? percent_escape (desc) : ""); - - /* The type field. */ - fprintf (out, ":%u", option->arg_type); - if (opt.verbose) - fprintf (out, " %s", gc_arg_type[option->arg_type].name); - - /* The alternate type field. */ - fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); - if (opt.verbose) - fprintf (out, " %s", - gc_arg_type[gc_arg_type[option->arg_type].fallback].name); - - /* The argument name field. */ - fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); - if (arg_name) - xfree (arg_name); - - /* The default value field. */ - fprintf (out, ":%s", option->default_value ? option->default_value : ""); - - /* The default argument field. */ - fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); - - /* The value field. */ - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE - && (option->flags & GC_OPT_FLAG_LIST) - && option->value) - /* The special format "1,1,1,1,...,1" is converted to a number - here. */ - fprintf (out, ":%u", (strlen (option->value) + 1) / 2); - else - fprintf (out, ":%s", option->value ? option->value : ""); - - /* ADD NEW FIELDS HERE. */ - - putc ('\n', out); -} - - -/* List all options of the component COMPONENT. */ -void -gc_component_list_options (int component, FILE *out) -{ - const gc_option_t *option = gc_component[component].options; - const gc_option_t *group_option = NULL; - - while (option->name) - { - /* Do not output unknown or internal options. */ - if (!(option->flags & GC_OPT_FLAG_GROUP) - && (!option->active || option->level == GC_LEVEL_INTERNAL)) - { - option++; - continue; - } - - if (option->flags & GC_OPT_FLAG_GROUP) - group_option = option; - else - { - if (group_option) - { - list_one_option (group_option, out); - group_option = NULL; - } - - list_one_option (option, out); - } - - option++; - } -} - - -/* Find the option NAME in component COMPONENT, for the backend - BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */ -static gc_option_t * -find_option (gc_component_t component, const char *name, - gc_backend_t backend) -{ - gc_option_t *option = gc_component[component].options; - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP) - && !strcmp (option->name, name) - && (backend == GC_BACKEND_ANY || option->backend == backend)) - break; - option++; - } - return option->name ? option : NULL; -} - - -/* Determine the configuration pathname for the component COMPONENT - and backend BACKEND. */ -static char * -get_config_pathname (gc_component_t component, gc_backend_t backend) -{ - char *pathname = NULL; - gc_option_t *option = find_option - (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY); - assert (option); - assert (option->arg_type == GC_ARG_TYPE_PATHNAME); - assert (!(option->flags & GC_OPT_FLAG_LIST)); - - if (!option->active || !option->default_value) - gc_error (1, 0, "Option %s, needed by backend %s, was not initialized", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); - - if (option->value && *option->value) - pathname = percent_deescape (&option->value[1]); - else if (option->default_value && *option->default_value) - pathname = percent_deescape (&option->default_value[1]); - else - pathname = ""; - - if (pathname[0] != '/') - gc_error (1, 0, "Option %s, needed by backend %s, is not absolute", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); - - return pathname; -} - - -/* Retrieve the options for the component COMPONENT from backend - BACKEND, which we already know is a program-type backend. */ -static void -retrieve_options_from_program (gc_component_t component, gc_backend_t backend) -{ - char *cmd_line; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - FILE *config; - char *config_pathname; - - cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program); - - config = popen (cmd_line, "r"); - if (!config) - gc_error (1, errno, "could not gather active options from %s", cmd_line); - - while ((length = read_line (config, &line, &line_len, NULL)) > 0) - { - gc_option_t *option; - char *linep; - unsigned long flags = 0; - char *default_value = NULL; - - /* Strip newline and carriage return, if present. */ - while (length > 0 - && (line[length - 1] == '\n' || line[length - 1] == '\r')) - line[--length] = '\0'; - - linep = strchr (line, ':'); - if (linep) - *(linep++) = '\0'; - - /* Extract additional flags. Default to none. */ - if (linep) - { - char *end; - char *tail; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - errno = 0; - flags = strtoul (linep, &tail, 0); - if (errno) - gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line); - if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) - gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line); - - linep = end; - } - - /* Extract default value, if present. Default to empty if - not. */ - if (linep) - { - char *end; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - if (flags & GC_OPT_FLAG_DEFAULT) - default_value = linep; - - linep = end; - } - - /* Look up the option in the component and install the - configuration data. */ - option = find_option (component, line, backend); - if (option) - { - if (option->active) - gc_error (1, errno, "option %s returned twice from %s", - line, cmd_line); - option->active = 1; - - option->flags |= flags; - if (default_value && *default_value) - option->default_value = xstrdup (default_value); - } - } - if (length < 0 || ferror (config)) - gc_error (1, errno, "error reading from %s", cmd_line); - if (fclose (config) && ferror (config)) - gc_error (1, errno, "error closing %s", cmd_line); - xfree (cmd_line); - - /* At this point, we can parse the configuration file. */ - config_pathname = get_config_pathname (component, backend); - - config = fopen (config_pathname, "r"); - if (!config) - gc_error (0, errno, "warning: can not open config file %s", - config_pathname); - else - { - while ((length = read_line (config, &line, &line_len, NULL)) > 0) - { - char *name; - char *value; - gc_option_t *option; - - name = line; - while (*name == ' ' || *name == '\t') - name++; - if (!*name || *name == '#' || *name == '\r' || *name == '\n') - continue; - - value = name; - while (*value && *value != ' ' && *value != '\t' - && *value != '#' && *value != '\r' && *value != '\n') - value++; - if (*value == ' ' || *value == '\t') - { - char *end; - - *(value++) = '\0'; - while (*value == ' ' || *value == '\t') - value++; - - end = value; - while (*end && *end != '#' && *end != '\r' && *end != '\n') - end++; - while (end > value && (end[-1] == ' ' || end[-1] == '\t')) - end--; - *end = '\0'; - } - else - *value = '\0'; - - /* Look up the option in the component and install the - configuration data. */ - option = find_option (component, line, backend); - if (option) - { - char *opt_value; - - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) - { - if (*value) - gc_error (0, 0, - "warning: ignoring argument %s for option %s", - value, name); - opt_value = xstrdup ("1"); - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_STRING) - opt_value = xasprintf ("\"%s", percent_escape (value)); - else - { - /* FIXME: Verify that the number is sane. */ - opt_value = xstrdup (value); - } - - /* Now enter the option into the table. */ - if (!(option->flags & GC_OPT_FLAG_LIST)) - { - if (option->value) - free (option->value); - option->value = opt_value; - } - else - { - if (!option->value) - option->value = opt_value; - else - { - char *opt_val = opt_value; - - option->value = xasprintf ("%s,%s", option->value, - opt_val); - xfree (opt_value); - } - } - } - } - - if (length < 0 || ferror (config)) - gc_error (1, errno, "error reading from %s", config_pathname); - if (fclose (config) && ferror (config)) - gc_error (1, errno, "error closing %s", config_pathname); - } - - xfree (line); -} - - -/* Retrieve the options for the component COMPONENT from backend - BACKEND, which we already know is of type file list. */ -static void -retrieve_options_from_file (gc_component_t component, gc_backend_t backend) -{ - gc_option_t *list_option; - char *list_pathname; - FILE *list_file; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - char *list = NULL; - - list_option = find_option (component, - gc_backend[backend].option_name, GC_BACKEND_ANY); - assert (list_option); - assert (!list_option->active); - - list_pathname = get_config_pathname (component, backend); - list_file = fopen (list_pathname, "r"); - if (!list_file) - gc_error (0, errno, "warning: can not open list file %s", list_pathname); - else - { - - while ((length = read_line (list_file, &line, &line_len, NULL)) > 0) - { - char *start; - char *end; - char *new_list; - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (!*start || *start == '#' || *start == '\r' || *start == '\n') - continue; - - end = start; - while (*end && *end != '#' && *end != '\r' && *end != '\n') - end++; - /* Walk back to skip trailing white spaces. Looks evil, but - works because of the conditions on START and END imposed - at this point (END is at least START + 1, and START is - not a whitespace character). */ - while (*(end - 1) == ' ' || *(end - 1) == '\t') - end--; - *end = '\0'; - /* FIXME: Oh, no! This is so lame! Should use realloc and - really append. */ - if (list) - { - new_list = xasprintf ("%s,\"%s", list, percent_escape (start)); - xfree (list); - list = new_list; - } - else - list = xasprintf ("\"%s", percent_escape (start)); - } - if (length < 0 || ferror (list_file)) - gc_error (1, errno, "can not read list file %s", list_pathname); - } - - list_option->active = 1; - list_option->value = list; - - xfree (line); -} - - -/* Retrieve the currently active options and their defaults from all - involved backends for this component. */ -void -gc_component_retrieve_options (int component) -{ - int backend_seen[GC_BACKEND_NR]; - gc_backend_t backend; - gc_option_t *option = gc_component[component].options; - - for (backend = 0; backend < GC_BACKEND_NR; backend++) - backend_seen[backend] = 0; - - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP)) - { - backend = option->backend; - - if (backend_seen[backend]) - { - option++; - continue; - } - backend_seen[backend] = 1; - - assert (backend != GC_BACKEND_ANY); - - if (gc_backend[backend].program) - retrieve_options_from_program (component, backend); - else - retrieve_options_from_file (component, backend); - } - option++; - } -} - - -/* Perform a simple validity check based on the type. Return in - NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of - type GC_ARG_TYPE_NONE. */ -static void -option_check_validity (gc_option_t *option, unsigned long flags, - char *new_value, unsigned long *new_value_nr) -{ - char *arg; - - if (!option->active) - gc_error (1, 0, "option %s not supported by backend", option->name); - - if (option->new_flags || option->new_value) - gc_error (1, 0, "option %s already changed", option->name); - - if (flags & GC_OPT_FLAG_DEFAULT) - { - if (*new_value) - gc_error (1, 0, "argument %s provided for deleted option %s", - new_value, option->name); - - return; - } - - /* GC_ARG_TYPE_NONE options have special list treatment. */ - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) - { - char *tail; - - errno = 0; - *new_value_nr = strtoul (new_value, &tail, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - if (*tail) - gc_error (1, 0, "garbage after argument for option %s", - option->name); - - if (!(option->flags & GC_OPT_FLAG_LIST)) - { - if (*new_value_nr != 1) - gc_error (1, 0, "argument for non-list option %s of type 0 " - "(none) must be 1", option->name); - } - else - { - if (*new_value_nr == 0) - gc_error (1, 0, "argument for option %s of type 0 (none) " - "must be positive", option->name); - } - - return; - } - - arg = new_value; - do - { - if (*arg == '\0' || *arg == ',') - { - if (!(option->flags & GC_OPT_FLAG_ARG_OPT)) - gc_error (1, 0, "argument required for option %s", option->name); - - if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST)) - gc_error (1, 0, "list found for non-list option %s", option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - { - if (*arg != '"') - gc_error (1, 0, "string argument for option %s must begin " - "with a quote (\") character", option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) - { - errno = 0; - (void) strtol (arg, &arg, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - - if (*arg != '\0' && *arg != ',') - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) - { - errno = 0; - (void) strtoul (arg, &arg, 0); - - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - - if (*arg != '\0' && *arg != ',') - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - arg = strchr (arg, ','); - if (arg) - arg++; - } - while (arg && *arg); -} - - -/* Create and verify the new configuration file for the specified - backend and component. Returns 0 on success and -1 on error. */ -static int -change_options_file (gc_component_t component, gc_backend_t backend, - char **src_filenamep, char **dest_filenamep, - char **orig_filenamep) -{ - static const char marker[] = "###+++--- GPGConf ---+++###"; - /* True if we are within the marker in the config file. */ - int in_marker = 0; - gc_option_t *option; - char *line = NULL; - size_t line_len; - ssize_t length; - int res; - int fd; - FILE *src_file = NULL; - FILE *dest_file = NULL; - char *src_filename; - char *dest_filename; - char *orig_filename; - char *arg; - char *cur_arg = NULL; - - option = find_option (component, - gc_backend[backend].option_name, GC_BACKEND_ANY); - assert (option); - assert (option->active); - assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE); - - /* FIXME. Throughout the function, do better error reporting. */ - /* Note that get_config_pathname() calls percent_deescape(), so we - call this before processing the arguments. */ - dest_filename = xstrdup (get_config_pathname (component, backend)); - src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); - orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); - - arg = option->new_value; - if (arg && arg[0] == '\0') - arg = NULL; - else if (arg) - { - char *end; - - arg++; - end = strchr (arg, ','); - if (end) - *end = '\0'; - - cur_arg = percent_deescape (arg); - if (end) - { - *end = ','; - arg = end + 1; - } - else - arg = NULL; - } - - res = link (dest_filename, orig_filename); - if (res < 0 && errno != ENOENT) - return -1; - if (res < 0) - { - xfree (orig_filename); - orig_filename = NULL; - } - - /* We now initialize the return strings, so the caller can do the - cleanup for us. */ - *src_filenamep = src_filename; - *dest_filenamep = dest_filename; - *orig_filenamep = orig_filename; - - /* Use open() so that we can use O_EXCL. */ - fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); - if (fd < 0) - return -1; - src_file = fdopen (fd, "w"); - res = errno; - if (!src_file) - { - errno = res; - return -1; - } - - /* Only if ORIG_FILENAME is not NULL did the configuration file - exist already. In this case, we will copy its content into the - new configuration file, changing it to our liking in the - process. */ - if (orig_filename) - { - dest_file = fopen (dest_filename, "r"); - if (!dest_file) - goto change_file_one_err; - - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - int disable = 0; - char *start; - - if (!strncmp (marker, line, sizeof (marker) - 1)) - { - if (!in_marker) - in_marker = 1; - else - break; - } - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (*start && *start != '\r' && *start != '\n' && *start != '#') - { - char *end; - char *endp; - char saved_end; - - endp = start; - end = endp; - - /* Search for the end of the line. */ - while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n') - { - endp++; - if (*endp && *endp != ' ' && *endp != '\t' - && *endp != '\r' && *endp != '\n' && *endp != '#') - end = endp + 1; - } - saved_end = *end; - *end = '\0'; - - if ((option->new_flags & GC_OPT_FLAG_DEFAULT) - || !cur_arg || strcmp (start, cur_arg)) - disable = 1; - else - { - /* Find next argument. */ - if (arg) - { - char *arg_end; - - arg++; - arg_end = strchr (arg, ','); - if (arg_end) - *arg_end = '\0'; - - cur_arg = percent_deescape (arg); - if (arg_end) - { - *arg_end = ','; - arg = arg_end + 1; - } - else - arg = NULL; - } - else - cur_arg = NULL; - } - - *end = saved_end; - } - - if (disable) - { - if (!in_marker) - { - fprintf (src_file, - "# GPGConf disabled this option here at %s\n", - asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# %s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - } - else - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - } - if (length < 0 || ferror (dest_file)) - goto change_file_one_err; - } - - if (!in_marker) - { - /* There was no marker. This is the first time we edit the - file. We add our own marker at the end of the file and - proceed. Note that we first write a newline, this guards us - against files which lack the newline at the end of the last - line, while it doesn't hurt us in all other cases. */ - fprintf (src_file, "\n%s\n", marker); - if (ferror (src_file)) - goto change_file_one_err; - } - - /* At this point, we have copied everything up to the end marker - into the new file, except for the arguments we are going to add. - Now, dump the new arguments and write the end marker, possibly - followed by the rest of the original file. */ - while (cur_arg) - { - fprintf (src_file, "%s\n", cur_arg); - - /* Find next argument. */ - if (arg) - { - char *end; - - arg++; - end = strchr (arg, ','); - if (end) - *end = '\0'; - - cur_arg = percent_deescape (arg); - if (end) - { - *end = ','; - arg = end + 1; - } - else - arg = NULL; - } - else - cur_arg = NULL; - } - - fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_file_one_err; - - if (!in_marker) - { - fprintf (src_file, "# GPGConf edited this configuration file.\n"); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# It will disable options before this marked " - "block, but it will\n"); - if (ferror (src_file)) - goto change_file_one_err; - fprintf (src_file, "# never change anything below these lines.\n"); - if (ferror (src_file)) - goto change_file_one_err; - } - if (dest_file) - { - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_file_one_err; - } - if (length < 0 || ferror (dest_file)) - goto change_file_one_err; - } - xfree (line); - line = NULL; - - res = fclose (src_file); - if (res) - { - res = errno; - close (fd); - if (dest_file) - fclose (dest_file); - errno = res; - return -1; - } - close (fd); - if (dest_file) - { - res = fclose (dest_file); - if (res) - return -1; - } - return 0; - - change_file_one_err: - xfree (line); - res = errno; - if (src_file) - { - fclose (src_file); - close (fd); - } - if (dest_file) - fclose (dest_file); - errno = res; - return -1; -} - - -/* Create and verify the new configuration file for the specified - backend and component. Returns 0 on success and -1 on error. */ -static int -change_options_program (gc_component_t component, gc_backend_t backend, - char **src_filenamep, char **dest_filenamep, - char **orig_filenamep) -{ - static const char marker[] = "###+++--- GPGConf ---+++###"; - /* True if we are within the marker in the config file. */ - int in_marker = 0; - gc_option_t *option; - char *line = NULL; - size_t line_len; - ssize_t length; - int res; - int fd; - FILE *src_file = NULL; - FILE *dest_file = NULL; - char *src_filename; - char *dest_filename; - char *orig_filename; - - /* FIXME. Throughout the function, do better error reporting. */ - dest_filename = xstrdup (get_config_pathname (component, backend)); - src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); - orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); - - res = link (dest_filename, orig_filename); - if (res < 0 && errno != ENOENT) - return -1; - if (res < 0) - { - xfree (orig_filename); - orig_filename = NULL; - } - - /* We now initialize the return strings, so the caller can do the - cleanup for us. */ - *src_filenamep = src_filename; - *dest_filenamep = dest_filename; - *orig_filenamep = orig_filename; - - /* Use open() so that we can use O_EXCL. */ - fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); - if (fd < 0) - return -1; - src_file = fdopen (fd, "w"); - res = errno; - if (!src_file) - { - errno = res; - return -1; - } - - /* Only if ORIG_FILENAME is not NULL did the configuration file - exist already. In this case, we will copy its content into the - new configuration file, changing it to our liking in the - process. */ - if (orig_filename) - { - dest_file = fopen (dest_filename, "r"); - if (!dest_file) - goto change_one_err; - - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - int disable = 0; - char *start; - - if (!strncmp (marker, line, sizeof (marker) - 1)) - { - if (!in_marker) - in_marker = 1; - else - break; - } - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (*start && *start != '\r' && *start != '\n' && *start != '#') - { - char *end; - char saved_end; - - end = start; - while (*end && *end != ' ' && *end != '\t' - && *end != '\r' && *end != '\n' && *end != '#') - end++; - saved_end = *end; - *end = '\0'; - - option = find_option (component, start, backend); - *end = saved_end; - if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT) - || option->new_value)) - disable = 1; - } - if (disable) - { - if (!in_marker) - { - fprintf (src_file, - "# GPGConf disabled this option here at %s\n", - asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# %s", line); - if (ferror (src_file)) - goto change_one_err; - } - } - else - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_one_err; - } - } - if (length < 0 || ferror (dest_file)) - goto change_one_err; - } - - if (!in_marker) - { - /* There was no marker. This is the first time we edit the - file. We add our own marker at the end of the file and - proceed. Note that we first write a newline, this guards us - against files which lack the newline at the end of the last - line, while it doesn't hurt us in all other cases. */ - fprintf (src_file, "\n%s\n", marker); - if (ferror (src_file)) - goto change_one_err; - } - /* At this point, we have copied everything up to the end marker - into the new file, except for the options we are going to change. - Now, dump the changed options (except for those we are going to - revert to their default), and write the end marker, possibly - followed by the rest of the original file. */ - - /* We have to turn on UTF8 strings for GnuPG. */ - if (backend == GC_BACKEND_GPG) - fprintf (src_file, "utf8-strings\n"); - - option = gc_component[component].options; - while (option->name) - { - if (!(option->flags & GC_OPT_FLAG_GROUP) - && option->backend == backend - && option->new_value) - { - char *arg = option->new_value; - - do - { - if (*arg == '\0' || *arg == ',') - { - fprintf (src_file, "%s\n", option->name); - if (ferror (src_file)) - goto change_one_err; - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_NONE) - { - assert (*arg == '1'); - fprintf (src_file, "%s\n", option->name); - if (ferror (src_file)) - goto change_one_err; - - arg++; - } - else if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_STRING) - { - char *end; - - assert (*arg == '"'); - arg++; - - end = strchr (arg, ','); - if (end) - *end = '\0'; - - fprintf (src_file, "%s %s\n", option->name, - percent_deescape (arg)); - if (ferror (src_file)) - goto change_one_err; - - if (end) - *end = ','; - arg = end; - } - else - { - char *end; - - end = strchr (arg, ','); - if (end) - *end = '\0'; - - fprintf (src_file, "%s %s\n", option->name, arg); - if (ferror (src_file)) - goto change_one_err; - - if (end) - *end = ','; - arg = end; - } - - assert (arg == NULL || *arg == '\0' || *arg == ','); - if (arg && *arg == ',') - arg++; - } - while (arg && *arg); - } - option++; - } - - fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_one_err; - - if (!in_marker) - { - fprintf (src_file, "# GPGConf edited this configuration file.\n"); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# It will disable options before this marked " - "block, but it will\n"); - if (ferror (src_file)) - goto change_one_err; - fprintf (src_file, "# never change anything below these lines.\n"); - if (ferror (src_file)) - goto change_one_err; - } - if (dest_file) - { - while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) - { - fprintf (src_file, "%s", line); - if (ferror (src_file)) - goto change_one_err; - } - if (length < 0 || ferror (dest_file)) - goto change_one_err; - } - xfree (line); - line = NULL; - - res = fclose (src_file); - if (res) - { - res = errno; - close (fd); - if (dest_file) - fclose (dest_file); - errno = res; - return -1; - } - close (fd); - if (dest_file) - { - res = fclose (dest_file); - if (res) - return -1; - } - return 0; - - change_one_err: - xfree (line); - res = errno; - if (src_file) - { - fclose (src_file); - close (fd); - } - if (dest_file) - fclose (dest_file); - errno = res; - return -1; -} - - -/* Read the modifications from IN and apply them. */ -void -gc_component_change_options (int component, FILE *in) -{ - int err = 0; - int runtime[GC_BACKEND_NR]; - char *src_pathname[GC_BACKEND_NR]; - char *dest_pathname[GC_BACKEND_NR]; - char *orig_pathname[GC_BACKEND_NR]; - gc_backend_t backend; - gc_option_t *option; - char *line = NULL; - size_t line_len = 0; - ssize_t length; - - for (backend = 0; backend < GC_BACKEND_NR; backend++) - { - runtime[backend] = 0; - src_pathname[backend] = NULL; - dest_pathname[backend] = NULL; - orig_pathname[backend] = NULL; - } - - while ((length = read_line (in, &line, &line_len, NULL)) > 0) - { - char *linep; - unsigned long flags = 0; - char *new_value = ""; - unsigned long new_value_nr; - - /* Strip newline and carriage return, if present. */ - while (length > 0 - && (line[length - 1] == '\n' || line[length - 1] == '\r')) - line[--length] = '\0'; - - linep = strchr (line, ':'); - if (linep) - *(linep++) = '\0'; - - /* Extract additional flags. Default to none. */ - if (linep) - { - char *end; - char *tail; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - errno = 0; - flags = strtoul (linep, &tail, 0); - if (errno) - gc_error (1, errno, "malformed flags in option %s", line); - if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) - gc_error (1, 0, "garbage after flags in option %s", line); - - linep = end; - } - - /* Extract default value, if present. Default to empty if - not. */ - if (linep) - { - char *end; - - end = strchr (linep, ':'); - if (end) - *(end++) = '\0'; - - new_value = linep; - - linep = end; - } - - option = find_option (component, line, GC_BACKEND_ANY); - if (!option) - gc_error (1, 0, "unknown option %s", line); - - option_check_validity (option, flags, new_value, &new_value_nr); - - if (option->flags & GC_OPT_FLAG_RUNTIME) - runtime[option->backend] = 1; - - option->new_flags = flags; - if (!(flags & GC_OPT_FLAG_DEFAULT)) - { - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE - && (option->flags & GC_OPT_FLAG_LIST)) - { - char *str; - - /* We convert the number to a list of 1's for - convenient list handling. */ - assert (new_value_nr > 0); - option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1); - str = option->new_value; - *(str++) = '1'; - while (--new_value_nr > 0) - { - *(str++) = ','; - *(str++) = '1'; - } - *(str++) = '\0'; - } - else - option->new_value = xstrdup (new_value); - } - } - - /* Now that we have collected and locally verified the changes, - write them out to new configuration files, verify them - externally, and then commit them. */ - option = gc_component[component].options; - while (option->name) - { - /* Go on if we have already seen this backend, or if there is - nothing to do. */ - if (src_pathname[option->backend] - || !(option->new_flags || option->new_value)) - { - option++; - continue; - } - - if (gc_backend[option->backend].program) - err = change_options_program (component, option->backend, - &src_pathname[option->backend], - &dest_pathname[option->backend], - &orig_pathname[option->backend]); - else - err = change_options_file (component, option->backend, - &src_pathname[option->backend], - &dest_pathname[option->backend], - &orig_pathname[option->backend]); - - if (err) - break; - - option++; - } - - if (!err) - { - int i; - - for (i = 0; i < GC_BACKEND_NR; i++) - { - if (src_pathname[i]) - { - /* FIXME: Make a verification here. */ - - assert (dest_pathname[i]); - - if (orig_pathname[i]) - err = rename (src_pathname[i], dest_pathname[i]); - else - { - /* This is a bit safer than rename() because we - expect DEST_PATHNAME not to be there. If it - happens to be there, this will fail. */ - err = link (src_pathname[i], dest_pathname[i]); - if (!err) - unlink (src_pathname[i]); - } - if (err) - break; - src_pathname[i] = NULL; - } - } - } - - if (err) - { - int i; - int saved_errno = errno; - - /* An error occured. */ - for (i = 0; i < GC_BACKEND_NR; i++) - { - if (src_pathname[i]) - { - /* The change was not yet committed. */ - unlink (src_pathname[i]); - if (orig_pathname[i]) - unlink (orig_pathname[i]); - } - else - { - /* The changes were already committed. FIXME: This is a - tad dangerous, as we don't know if we don't overwrite - a version of the file that is even newer than the one - we just installed. */ - if (orig_pathname[i]) - rename (orig_pathname[i], dest_pathname[i]); - else - unlink (dest_pathname[i]); - } - } - gc_error (1, saved_errno, "could not commit changes"); - } - - /* If it all worked, notify the daemons of the changes. */ - if (opt.runtime) - for (backend = 0; backend < GC_BACKEND_NR; backend++) - { - if (runtime[backend] && gc_backend[backend].runtime_change) - (*gc_backend[backend].runtime_change) (); - } - - /* Move the per-process backup file into its place. */ - for (backend = 0; backend < GC_BACKEND_NR; backend++) - if (orig_pathname[backend]) - { - char *backup_pathname; - - assert (dest_pathname[backend]); - - backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]); - rename (orig_pathname[backend], backup_pathname); - } - - xfree (line); -} diff --git a/tools/gpgconf.c b/tools/gpgconf.c deleted file mode 100644 index 7aca335fa..000000000 --- a/tools/gpgconf.c +++ /dev/null @@ -1,206 +0,0 @@ -/* gpgconf.c - Configuration utility for GnuPG - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gpgconf.h" -#include "i18n.h" - -/* Constants to identify the commands and options. */ -enum cmd_and_opt_values - { - aNull = 0, - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oVerbose = 'v', - oRuntime = 'r', - oComponent = 'c', - oNoVerbose = 500, - oHomedir, - - aListComponents, - aListOptions, - aChangeOptions, - - }; - - -/* The list of commands and options. */ -static ARGPARSE_OPTS opts[] = - { - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aListComponents, "list-components", 256, N_("list all components") }, - { aListOptions, "list-options", 256, N_("|COMPONENT|list options") }, - { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oOutput, "output", 2, N_("use as output file") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, - - /* hidden options */ - { oNoVerbose, "no-verbose", 0, "@"}, - {0} - }; - - -/* Print usage information and and provide strings for help. */ -static const char * -my_strusage( int level ) -{ - const char *p; - - switch (level) - { - case 11: p = "gpgconf (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpgconf [options] (-h for help)"); - break; - case 41: - p = _("Syntax: gpgconf [options]\n" - "Manage configuration options for tools of the GnuPG system\n"); - break; - - default: p = NULL; break; - } - return p; -} - - -/* Initialize the gettext system. */ -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file (PACKAGE_GT); -#else -# ifdef ENABLE_NLS -# ifdef HAVE_LC_MESSAGES - setlocale (LC_TIME, ""); - setlocale (LC_MESSAGES, ""); -# else - setlocale (LC_ALL, "" ); -# endif - bindtextdomain (PACKAGE_GT, LOCALEDIR); - textdomain (PACKAGE_GT); -# endif -#endif -} - - -/* gpgconf main. */ -int -main (int argc, char **argv) -{ - ARGPARSE_ARGS pargs; - const char *fname; - int no_more_options = 0; - enum cmd_and_opt_values cmd = 0; - - set_strusage (my_strusage); - log_set_prefix ("gpgconf", 1); - - i18n_init(); - - /* Parse the command line. */ - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags = 1; /* Do not remove the args. */ - while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts)) - { - switch (pargs.r_opt) - { - case oOutput: opt.outfile = pargs.r.ret_str; break; - case oQuiet: opt.quiet = 1; break; - case oDryRun: opt.dry_run = 1; break; - case oRuntime: - opt.runtime = 1; - break; - case oVerbose: opt.verbose++; break; - case oNoVerbose: opt.verbose = 0; break; - - case aListComponents: - case aListOptions: - case aChangeOptions: - cmd = pargs.r_opt; - break; - - default: pargs.err = 2; break; - } - } - - if (log_get_errorcount (0)) - exit (2); - - fname = argc ? *argv : NULL; - - switch (cmd) - { - case aListComponents: - default: - /* List all components. */ - gc_component_list_components (stdout); - break; - - case aListOptions: - case aChangeOptions: - if (!fname) - { - fputs (N_("usage: gpgconf [options] "), stderr); - fputs (N_("Need one component argument"), stderr); - putc ('\n',stderr); - exit (2); - } - else - { - int idx = gc_component_find (fname); - if (idx < 0) - { - fputs (N_("Component not found"), stderr); - putc ('\n', stderr); - exit (1); - } - gc_component_retrieve_options (idx); - if (cmd == aListOptions) - gc_component_list_options (idx, stdout); - else - gc_component_change_options (idx, stdin); - } - } - - return 0; -} - - - diff --git a/tools/gpgconf.h b/tools/gpgconf.h deleted file mode 100644 index 138380b6d..000000000 --- a/tools/gpgconf.h +++ /dev/null @@ -1,58 +0,0 @@ -/* gpgconf.h - Global definitions for gpgconf - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef GPGCONF_H -#define GPGCONF_H - -#include "../common/util.h" - -/* We keep all global options in the structure OPT. */ -struct -{ - int verbose; /* Verbosity level. */ - int quiet; /* Be extra quiet. */ - int dry_run; /* Don't change any persistent data. */ - int runtime; /* Make changes active at runtime. */ - char *outfile; /* Name of output file. */ - - int component; /* The active component. */ -} opt; - - - -/*-- gpgconf-comp.c --*/ -/* List all components that are available. */ -void gc_component_list_components (FILE *out); - -/* Find the component with the name NAME. Returns -1 if not - found. */ -int gc_component_find (const char *name); - -/* Retrieve the currently active options and their defaults from all - involved backends for this component. */ -void gc_component_retrieve_options (int component); - -/* List all options of the component COMPONENT. */ -void gc_component_list_options (int component, FILE *out); - -/* Read the modifications from IN and apply them. */ -void gc_component_change_options (int component, FILE *in); - -#endif /*GPGCONF_H*/ diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c deleted file mode 100644 index fa848c8f6..000000000 --- a/tools/gpgparsemail.c +++ /dev/null @@ -1,705 +0,0 @@ -/* gpgparsemail.c - Standalone crypto mail parser - * Copyright (C) 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* This utility prints an RFC8222, possible MIME structured, message - in an annotated format with the first column having an indicator - for the content of the line.. Several options are available to - scrutinize the message. S/MIME and OpenPGP suuport is included. */ - - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <time.h> -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/wait.h> - -#include "rfc822parse.h" - - -#define PGM "gpgparsemail" - -/* Option flags. */ -static int verbose; -static int debug; -static int opt_crypto; /* Decrypt or verify messages. */ -static int opt_no_header; /* Don't output the header lines. */ - -/* Structure used to communicate with the parser callback. */ -struct parse_info_s { - int show_header; /* Show the header lines. */ - int show_data; /* Show the data lines. */ - unsigned int skip_show; /* Temporary disable above for these - number of lines. */ - int show_data_as_note; /* The next data line should be shown - as a note. */ - int show_boundary; - int nesting_level; - - int gpgsm_mime; /* gpgsm shall be used from S/MIME. */ - char *signing_protocol; - int hashing_level; /* The nesting level we are hashing. */ - int hashing; - FILE *hash_file; - FILE *sig_file; - int verify_now; /* Falg set when all signature data is - available. */ -}; - - -/* Print diagnostic message and exit with failure. */ -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - - -/* Print diagnostic message. */ -static void -err (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); -} - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core: %s", strerror (errno)); - return p; -} - -/* static void * */ -/* xcalloc (size_t n, size_t m) */ -/* { */ -/* void *p = calloc (n, m); */ -/* if (!p) */ -/* die ("out of core: %s", strerror (errno)); */ -/* return p; */ -/* } */ - -/* static void * */ -/* xrealloc (void *old, size_t n) */ -/* { */ -/* void *p = realloc (old, n); */ -/* if (!p) */ -/* die ("out of core: %s", strerror (errno)); */ -/* return p; */ -/* } */ - -static char * -xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - die ("out of core: %s", strerror (errno)); - strcpy (p, string); - return p; -} - -static char * -stpcpy (char *a,const char *b) -{ - while (*b) - *a++ = *b++; - *a = 0; - - return (char*)a; -} - - -static int -run_gnupg (int smime, int sig_fd, int data_fd, int *close_list) -{ - int rp[2]; - pid_t pid; - int i, c, is_status; - unsigned int pos; - char status_buf[10]; - const char *cmd = smime? "gpgsm":"gpg"; - FILE *fp; - - if (pipe (rp) == -1) - die ("error creating a pipe: %s", strerror (errno)); - - pid = fork (); - if (pid == -1) - die ("error forking process: %s", strerror (errno)); - - if (!pid) - { /* Child. */ - char data_fd_buf[50]; - int fd; - - /* Connect our signature fd to stdin. */ - if (sig_fd != 0) - { - if (dup2 (sig_fd, 0) == -1) - die ("dup2 stdin failed: %s", strerror (errno)); - } - - /* Keep our data fd and format it for gpg/gpgsm use. */ - sprintf (data_fd_buf, "-&%d", data_fd); - - /* Send stdout to the bit bucket. */ - fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); - if (fd != 1) - { - if (dup2 (fd, 1) == -1) - die ("dup2 stderr failed: %s", strerror (errno)); - } - - /* Connect stderr to our pipe. */ - if (rp[1] != 2) - { - if (dup2 (rp[1], 2) == -1) - die ("dup2 stderr failed: %s", strerror (errno)); - } - - /* Close other files. */ - for (i=0; (fd=close_list[i]) != -1; i++) - if (fd > 2 && fd != data_fd) - close (fd); - errno = 0; - - execlp (cmd, cmd, - "--enable-special-filenames", - "--status-fd", "2", - "--assume-base64", - "--verify", - "--", - "-", data_fd_buf, - NULL); - - die ("failed to exec the crypto command: %s", strerror (errno)); - } - - /* Parent. */ - close (rp[1]); - - fp = fdopen (rp[0], "r"); - if (!fp) - die ("can't fdopen pipe for reading: %s", strerror (errno)); - - pos = 0; - is_status = 0; - assert (sizeof status_buf > 9); - while ((c=getc (fp)) != EOF) - { - if (pos < 9) - status_buf[pos] = c; - else - { - if (pos == 9) - { - is_status = !memcmp (status_buf, "[GNUPG:] ", 9); - if (is_status) - fputs ( "c ", stdout); - else if (verbose) - fputs ( "# ", stdout); - fwrite (status_buf, 9, 1, stdout); - } - putchar (c); - } - if (c == '\n') - { - if (verbose && pos < 9) - { - fputs ( "# ", stdout); - fwrite (status_buf, pos+1, 1, stdout); - } - pos = 0; - } - else - pos++; - } - if (pos) - { - if (verbose && pos < 9) - { - fputs ( "# ", stdout); - fwrite (status_buf, pos+1, 1, stdout); - } - putchar ('\n'); - } - fclose (fp); - - while ( (i=waitpid (pid, NULL, 0)) == -1 && errno == EINTR) - ; - if (i == -1) - die ("waiting for child failed: %s", strerror (errno)); - - return 0; -} - - - - -/* Verify the signature in the current temp files. */ -static void -verify_signature (struct parse_info_s *info) -{ - int close_list[10]; - - assert (info->hash_file); - assert (info->sig_file); - rewind (info->hash_file); - rewind (info->sig_file); - -/* printf ("# Begin hashed data\n"); */ -/* while ( (c=getc (info->hash_file)) != EOF) */ -/* putchar (c); */ -/* printf ("# End hashed data signature\n"); */ -/* printf ("# Begin signature\n"); */ -/* while ( (c=getc (info->sig_file)) != EOF) */ -/* putchar (c); */ -/* printf ("# End signature\n"); */ -/* rewind (info->hash_file); */ -/* rewind (info->sig_file); */ - - close_list[0] = -1; - run_gnupg (1, fileno (info->sig_file), fileno (info->hash_file), close_list); -} - - - - - -/* Prepare for a multipart/signed. - FIELD_CTX is the parsed context of the content-type header.*/ -static void -mime_signed_begin (struct parse_info_s *info, rfc822parse_t msg, - rfc822parse_field_t field_ctx) -{ - const char *s; - s = rfc822parse_query_parameter (field_ctx, "protocol", 1); - if (s) - { - printf ("h signed.protocol: %s\n", s); - if (!strcmp (s, "application/pkcs7-signature") - || !strcmp (s, "application/x-pkcs7-signature")) - { - if (info->gpgsm_mime) - err ("note: ignoring nested pkcs7-signature"); - else - { - info->gpgsm_mime = 1; - free (info->signing_protocol); - info->signing_protocol = xstrdup (s); - } - } - else if (verbose) - printf ("# this protocol is not supported\n"); - } -} - - -/* Prepare for a multipart/encrypted. - FIELD_CTX is the parsed context of the content-type header.*/ -static void -mime_encrypted_begin (struct parse_info_s *info, rfc822parse_t msg, - rfc822parse_field_t field_ctx) -{ - const char *s; - s = rfc822parse_query_parameter (field_ctx, "protocol", 0); - if (s) - printf ("h encrypted.protocol: %s\n", s); -} - - - -/* Print the event received by the parser for debugging as comment - line. */ -static void -show_event (rfc822parse_event_t event) -{ - const char *s; - - switch (event) - { - case RFC822PARSE_OPEN: s= "Open"; break; - case RFC822PARSE_CLOSE: s= "Close"; break; - case RFC822PARSE_CANCEL: s= "Cancel"; break; - case RFC822PARSE_T2BODY: s= "T2Body"; break; - case RFC822PARSE_FINISH: s= "Finish"; break; - case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break; - case RFC822PARSE_LEVEL_DOWN: s= "Level_Down"; break; - case RFC822PARSE_LEVEL_UP: s= "Level_Up"; break; - case RFC822PARSE_BOUNDARY: s= "Boundary"; break; - case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break; - case RFC822PARSE_BEGIN_HEADER: s= "Begin_Header"; break; - case RFC822PARSE_PREAMBLE: s= "Preamble"; break; - case RFC822PARSE_EPILOGUE: s= "Epilogue"; break; - default: s= "[unknown event]"; break; - } - printf ("# *** got RFC822 event %s\n", s); -} - -/* This function is called by the parser to communicate events. This - callback comminucates with the main program using a structure - passed in OPAQUE. Should retrun 0 or set errno and return -1. */ -static int -message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) -{ - struct parse_info_s *info = opaque; - - if (debug) - show_event (event); - if (event == RFC822PARSE_OPEN) - { - /* Initialize for a new message. */ - info->show_header = 1; - } - else if (event == RFC822PARSE_T2BODY) - { - rfc822parse_field_t ctx; - - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - { - printf ("h media: %*s%s %s\n", - info->nesting_level*2, "", s1, s2); - if (info->gpgsm_mime == 3) - { - char *buf = xmalloc (strlen (s1) + strlen (s2) + 2); - strcpy (stpcpy (stpcpy (buf, s1), "/"), s2); - assert (info->signing_protocol); - if (strcmp (buf, info->signing_protocol)) - err ("invalid S/MIME structure; expected `%s', found `%s'", - info->signing_protocol, buf); - else - { - printf ("c begin_signature\n"); - info->gpgsm_mime++; - if (opt_crypto) - { - assert (!info->sig_file); - info->sig_file = tmpfile (); - if (!info->sig_file) - die ("error creating temp file: %s", - strerror (errno)); - } - } - free (buf); - } - else if (!strcmp (s1, "multipart")) - { - if (!strcmp (s2, "signed")) - mime_signed_begin (info, msg, ctx); - else if (!strcmp (s2, "encrypted")) - mime_encrypted_begin (info, msg, ctx); - } - } - else - printf ("h media: %*s none\n", info->nesting_level*2, ""); - - rfc822parse_release_field (ctx); - } - else - printf ("h media: %*stext plain [assumed]\n", - info->nesting_level*2, ""); - info->show_header = 0; - info->show_data = 1; - info->skip_show = 1; - } - else if (event == RFC822PARSE_PREAMBLE) - info->show_data_as_note = 1; - else if (event == RFC822PARSE_LEVEL_DOWN) - { - printf ("b down\n"); - info->nesting_level++; - } - else if (event == RFC822PARSE_LEVEL_UP) - { - printf ("b up\n"); - if (info->nesting_level) - info->nesting_level--; - else - err ("invalid structure (bad nesting level)"); - } - else if (event == RFC822PARSE_BOUNDARY || event == RFC822PARSE_LAST_BOUNDARY) - { - info->show_data = 0; - info->show_boundary = 1; - if (event == RFC822PARSE_BOUNDARY) - { - info->show_header = 1; - info->skip_show = 1; - printf ("b part\n"); - } - else - printf ("b last\n"); - - if (info->gpgsm_mime == 2 && info->nesting_level == info->hashing_level) - { - printf ("c end_hash\n"); - info->gpgsm_mime++; - info->hashing = 0; - } - else if (info->gpgsm_mime == 4) - { - printf ("c end_signature\n"); - info->verify_now = 1; - } - } - else if (event == RFC822PARSE_BEGIN_HEADER) - { - if (info->gpgsm_mime == 1) - { - printf ("c begin_hash\n"); - info->hashing = 1; - info->hashing_level = info->nesting_level; - info->gpgsm_mime++; - - if (opt_crypto) - { - assert (!info->hash_file); - info->hash_file = tmpfile (); - if (!info->hash_file) - die ("failed to create temporary file: %s", strerror (errno)); - } - } - } - - return 0; -} - - -/* Read a message from FP and process it according to the global - options. */ -static void -parse_message (FILE *fp) -{ - char line[5000]; - size_t length; - rfc822parse_t msg; - unsigned int lineno = 0; - int no_cr_reported = 0; - struct parse_info_s info; - - memset (&info, 0, sizeof info); - - msg = rfc822parse_open (message_cb, &info); - if (!msg) - die ("can't open parser: %s", strerror (errno)); - - /* Fixme: We should not use fgets becuase it can't cope with - embedded nul characters. */ - while (fgets (line, sizeof (line), fp)) - { - lineno++; - if (lineno == 1 && !strncmp (line, "From ", 5)) - continue; /* We better ignore a leading From line. */ - - length = strlen (line); - if (length && line[length - 1] == '\n') - line[--length] = 0; - else - err ("line number %u too long or last line not terminated", lineno); - if (length && line[length - 1] == '\r') - line[--length] = 0; - else if (verbose && !no_cr_reported) - { - err ("non canonical ended line detected (line %u)", lineno); - no_cr_reported = 1; - } - - - if (rfc822parse_insert (msg, line, length)) - die ("parser failed: %s", strerror (errno)); - - if (info.hashing) - { - /* Delay hashing of the CR/LF because the last line ending - belongs to the next boundary. */ - if (debug) - printf ("# hashing %s`%s'\n", info.hashing==2?"CR,LF+":"", line); - if (opt_crypto) - { - if (info.hashing == 2) - fputs ("\r\n", info.hash_file); - fputs (line, info.hash_file); - if (ferror (info.hash_file)) - die ("error writing to temporary file: %s", strerror (errno)); - } - - info.hashing = 2; - } - - if (info.sig_file && opt_crypto) - { - if (info.verify_now) - { - verify_signature (&info); - fclose (info.hash_file); - info.hash_file = NULL; - fclose (info.sig_file); - info.sig_file = NULL; - info.gpgsm_mime = 0; - } - else - { - fputs (line, info.sig_file); - fputs ("\r\n", info.sig_file); - if (ferror (info.sig_file)) - die ("error writing to temporary file: %s", strerror (errno)); - } - } - - if (info.show_boundary) - { - if (!opt_no_header) - printf (":%s\n", line); - info.show_boundary = 0; - } - - if (info.skip_show) - info.skip_show--; - else if (info.show_data) - { - if (info.show_data_as_note) - { - if (verbose) - printf ("# DATA: %s\n", line); - info.show_data_as_note = 0; - } - else - printf (" %s\n", line); - } - else if (info.show_header && !opt_no_header) - printf (".%s\n", line); - - } - - rfc822parse_close (msg); -} - - -int -main (int argc, char **argv) -{ - int last_argc = -1; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--help")) - { - puts ( - "Usage: " PGM " [OPTION] [FILE]\n" - "Parse a mail message into an annotated format.\n\n" - " --crypto decrypt or verify messages\n" - " --no-header don't output the header lines\n" - " --verbose enable extra informational output\n" - " --debug enable additional debug output\n" - " --help display this help and exit\n\n" - "With no FILE, or when FILE is -, read standard input.\n\n" - "Report bugs to <bug-gnupg@gnu.org>."); - exit (0); - } - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--debug")) - { - verbose = debug = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--crypto")) - { - opt_crypto = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--no-header")) - { - opt_no_header = 1; - argc--; argv++; - } - } - - if (argc > 1) - die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n"); - - signal (SIGPIPE, SIG_IGN); - - if (argc && strcmp (*argv, "-")) - { - FILE *fp = fopen (*argv, "rb"); - if (!fp) - die ("can't open `%s': %s", *argv, strerror (errno)); - parse_message (fp); - fclose (fp); - } - else - parse_message (stdin); - - return 0; -} - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o gpgparsemail rfc822parse.c gpgparsemail.c" -End: -*/ diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c deleted file mode 100644 index 0fabec90d..000000000 --- a/tools/no-libgcrypt.c +++ /dev/null @@ -1,105 +0,0 @@ -/* no-libgcrypt.c - Replacement functions for libgcrypt. - * Copyright (C) 2003 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "../common/util.h" -#include "i18n.h" - - -/* Replace libgcrypt's malloc functions which are used by - ../jnlib/libjnlib.a . ../common/util.h defines macros to map them - to xmalloc etc. */ -static void -out_of_core (void) -{ - log_fatal (_("error allocating enough memory: %s\n"), strerror (errno)); -} - - -void * -gcry_malloc (size_t n) -{ - return malloc (n); -} - -void * -gcry_xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - out_of_core (); - return p; -} - - -void * -gcry_realloc (void *a, size_t n) -{ - return realloc (a, n); -} - -void * -gcry_xrealloc (void *a, size_t n) -{ - void *p = realloc (a, n); - if (!p) - out_of_core (); - return p; -} - - - -void * -gcry_calloc (size_t n, size_t m) -{ - return calloc (n, m); -} - -void * -gcry_xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - out_of_core (); - return p; -} - - -char * -gcry_xstrdup (const char *string) -{ - void *p = malloc (strlen (string)+1); - if (!p) - out_of_core (); - strcpy( p, string ); - return p; -} - -void -gcry_free (void *a) -{ - if (a) - free (a); -} diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c deleted file mode 100644 index be1cf4a47..000000000 --- a/tools/rfc822parse.c +++ /dev/null @@ -1,1235 +0,0 @@ -/* rfc822parse.c - Simple mail and MIME parser - * Copyright (C) 1999, 2000 Werner Koch, Duesseldorf - * Copyright (C) 2003, g10 Code GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -/* According to RFC822 binary 0 are allowed at many places. We - * do not handle this correct especially in the field parsing code. It - * should be easy to fix and the API provides a interfcaes which returns - * the length but in addition makes sure that returned strings are always - * ended by a \0. - * - * Furthermore, the case of field names is changed and thus it is not - * always a good idea to use these modified header - * lines (e.g. signatures may break). - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> - -#include "rfc822parse.h" - -enum token_type -{ - tSPACE, - tATOM, - tQUOTED, - tDOMAINLIT, - tSPECIAL -}; - -/* For now we directly use our TOKEN as the parse context */ -typedef struct rfc822parse_field_context *TOKEN; -struct rfc822parse_field_context -{ - TOKEN next; - enum token_type type; - struct { - unsigned int cont:1; - unsigned int lowered:1; - } flags; - /*TOKEN owner_pantry; */ - char data[1]; -}; - -struct hdr_line -{ - struct hdr_line *next; - int cont; /* This is a continuation of the previous line. */ - unsigned char line[1]; -}; - -typedef struct hdr_line *HDR_LINE; - - -struct part -{ - struct part *right; /* The next part. */ - struct part *down; /* A contained part. */ - HDR_LINE hdr_lines; /* Header lines os that part. */ - HDR_LINE *hdr_lines_tail; /* Helper for adding lines. */ - char *boundary; /* Only used in the first part. */ -}; -typedef struct part *part_t; - -struct rfc822parse_context -{ - rfc822parse_cb_t callback; - void *callback_value; - int callback_error; - int in_body; - int in_preamble; /* Wether we are before the first boundary. */ - part_t parts; /* The tree of parts. */ - part_t current_part; /* Whom we are processing (points into parts). */ - const char *boundary; /* Current boundary. */ -}; - -static HDR_LINE find_header (rfc822parse_t msg, const char *name, - int which, HDR_LINE * rprev); - - -static size_t -length_sans_trailing_ws (const unsigned char *line, size_t len) -{ - const unsigned char *p, *mark; - size_t n; - - for (mark=NULL, p=line, n=0; n < len; n++, p++) - { - if (strchr (" \t\r\n", *p )) - { - if( !mark ) - mark = p; - } - else - mark = NULL; - } - - if (mark) - return mark - line; - return len; -} - - -static void -lowercase_string (unsigned char *string) -{ - for (; *string; string++) - if (*string >= 'A' && *string <= 'Z') - *string = *string - 'A' + 'a'; -} - -/* Transform a header name into a standard capitalized format; i.e - "Content-Type". Conversion stops at the colon. As usual we don't - use the localized versions of ctype.h. - */ -static void -capitalize_header_name (unsigned char *name) -{ - int first = 1; - - for (; *name && *name != ':'; name++) - if (*name == '-') - first = 1; - else if (first) - { - if (*name >= 'a' && *name <= 'z') - *name = *name - 'a' + 'A'; - first = 0; - } - else if (*name >= 'A' && *name <= 'Z') - *name = *name - 'A' + 'a'; -} - - -static char * -stpcpy (char *a,const char *b) -{ - while (*b) - *a++ = *b++; - *a = 0; - - return (char*)a; -} - - -/* If a callback has been registerd, call it for the event of type - EVENT. */ -static int -do_callback (rfc822parse_t msg, rfc822parse_event_t event) -{ - int rc; - - if (!msg->callback || msg->callback_error) - return 0; - rc = msg->callback (msg->callback_value, event, msg); - if (rc) - msg->callback_error = rc; - return rc; -} - -static part_t -new_part (void) -{ - part_t part; - - part = calloc (1, sizeof *part); - if (part) - { - part->hdr_lines_tail = &part->hdr_lines; - } - return part; -} - - -static void -release_part (part_t part) -{ - part_t tmp; - HDR_LINE hdr, hdr2; - - for (; part; part = tmp) - { - tmp = part->right; - if (part->down) - release_part (part->down); - for (hdr = part->hdr_lines; hdr; hdr = hdr2) - { - hdr2 = hdr->next; - free (hdr); - } - free (part->boundary); - free (part); - } -} - - -static void -release_handle_data (rfc822parse_t msg) -{ - release_part (msg->parts); - msg->parts = NULL; - msg->current_part = NULL; - msg->boundary = NULL; -} - - -/* Create a new parsing context for an entire rfc822 message and - return it. CB and CB_VALUE may be given to callback for certain - events. NULL is returned on error with errno set appropriately. */ -rfc822parse_t -rfc822parse_open (rfc822parse_cb_t cb, void *cb_value) -{ - rfc822parse_t msg = calloc (1, sizeof *msg); - if (msg) - { - msg->parts = msg->current_part = new_part (); - if (!msg->parts) - { - free (msg); - msg = NULL; - } - else - { - msg->callback = cb; - msg->callback_value = cb_value; - if (do_callback (msg, RFC822PARSE_OPEN)) - { - release_handle_data (msg); - free (msg); - msg = NULL; - } - } - } - return msg; -} - - -void -rfc822parse_cancel (rfc822parse_t msg) -{ - if (msg) - { - do_callback (msg, RFC822PARSE_CANCEL); - release_handle_data (msg); - free (msg); - } -} - - -void -rfc822parse_close (rfc822parse_t msg) -{ - if (msg) - { - do_callback (msg, RFC822PARSE_CLOSE); - release_handle_data (msg); - free (msg); - } -} - -static part_t -find_parent (part_t tree, part_t target) -{ - part_t part; - - for (part = tree->down; part; part = part->right) - { - if (part == target) - return tree; /* Found. */ - if (part->down) - { - part_t tmp = find_parent (part, target); - if (tmp) - return tmp; - } - } - return NULL; -} - -static void -set_current_part_to_parent (rfc822parse_t msg) -{ - part_t parent; - - assert (msg->current_part); - parent = find_parent (msg->parts, msg->current_part); - if (!parent) - return; /* Already at the top. */ - -#ifndef NDEBUG - { - part_t part; - for (part = parent->down; part; part = part->right) - if (part == msg->current_part) - break; - assert (part); - } -#endif - msg->current_part = parent; - - parent = find_parent (msg->parts, parent); - msg->boundary = parent? parent->boundary: NULL; -} - - - -/**************** - * We have read in all header lines and are about to receive the body - * part. The delimiter line has already been processed. - * - * FIXME: we's better return an error in case of memory failures. - */ -static int -transition_to_body (rfc822parse_t msg) -{ - rfc822parse_field_t ctx; - int rc; - - rc = do_callback (msg, RFC822PARSE_T2BODY); - if (!rc) - { - /* Store the boundary if we have multipart type. */ - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s; - - s = rfc822parse_query_media_type (ctx, NULL); - if (s && !strcmp (s,"multipart")) - { - s = rfc822parse_query_parameter (ctx, "boundary", 0); - if (s) - { - assert (!msg->current_part->boundary); - msg->current_part->boundary = malloc (strlen (s) + 1); - if (msg->current_part->boundary) - { - part_t part; - - strcpy (msg->current_part->boundary, s); - msg->boundary = msg->current_part->boundary; - part = new_part (); - if (!part) - { - int save_errno = errno; - rfc822parse_release_field (ctx); - errno = save_errno; - return -1; - } - rc = do_callback (msg, RFC822PARSE_LEVEL_DOWN); - assert (!msg->current_part->down); - msg->current_part->down = part; - msg->current_part = part; - msg->in_preamble = 1; - } - } - } - rfc822parse_release_field (ctx); - } - } - - return rc; -} - -/* We have just passed a MIME boundary and need to prepare for new part. - headers. */ -static int -transition_to_header (rfc822parse_t msg) -{ - part_t part; - - assert (msg->current_part); - assert (!msg->current_part->right); - - part = new_part (); - if (!part) - return -1; - - msg->current_part->right = part; - msg->current_part = part; - return 0; -} - - -static int -insert_header (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - HDR_LINE hdr; - - assert (msg->current_part); - if (!length) - { - msg->in_body = 1; - return transition_to_body (msg); - } - - if (!msg->current_part->hdr_lines) - do_callback (msg, RFC822PARSE_BEGIN_HEADER); - - length = length_sans_trailing_ws (line, length); - hdr = malloc (sizeof (*hdr) + length); - if (!hdr) - return -1; - hdr->next = NULL; - hdr->cont = (*line == ' ' || *line == '\t'); - memcpy (hdr->line, line, length); - hdr->line[length] = 0; /* Make it a string. */ - - /* Transform a field name into canonical format. */ - if (!hdr->cont && strchr (line, ':')) - capitalize_header_name (hdr->line); - - *msg->current_part->hdr_lines_tail = hdr; - msg->current_part->hdr_lines_tail = &hdr->next; - - /* Lets help the caller to prevent mail loops and issue an event for - * every Received header. */ - if (length >= 9 && !memcmp (line, "Received:", 9)) - do_callback (msg, RFC822PARSE_RCVD_SEEN); - return 0; -} - - -/**************** - * Note: We handle the body transparent to allow binary zeroes in it. - */ -static int -insert_body (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - int rc = 0; - - if (length > 2 && *line == '-' && line[1] == '-' && msg->boundary) - { - size_t blen = strlen (msg->boundary); - - if (length == blen + 2 - && !memcmp (line+2, msg->boundary, blen)) - { - rc = do_callback (msg, RFC822PARSE_BOUNDARY); - msg->in_body = 0; - if (!rc && !msg->in_preamble) - rc = transition_to_header (msg); - msg->in_preamble = 0; - } - else if (length == blen + 4 - && line[length-2] =='-' && line[length-1] == '-' - && !memcmp (line+2, msg->boundary, blen)) - { - rc = do_callback (msg, RFC822PARSE_LAST_BOUNDARY); - msg->boundary = NULL; /* No current boundary anymore. */ - set_current_part_to_parent (msg); - - /* Fixme: The next should acctually be sent right before the - next boundary, so that we can mark the epilogue. */ - if (!rc) - rc = do_callback (msg, RFC822PARSE_LEVEL_UP); - } - } - if (msg->in_preamble && !rc) - rc = do_callback (msg, RFC822PARSE_PREAMBLE); - - return rc; -} - -/* Insert the next line into the parser. Return 0 on success or true - on error with errno set appropriately. */ -int -rfc822parse_insert (rfc822parse_t msg, const unsigned char *line, size_t length) -{ - return (msg->in_body - ? insert_body (msg, line, length) - : insert_header (msg, line, length)); -} - - -/* Tell the parser that we have finished the message. */ -int -rfc822parse_finish (rfc822parse_t msg) -{ - return do_callback (msg, RFC822PARSE_FINISH); -} - - - -/**************** - * Get a copy of a header line. The line is returned as one long - * string with LF to separate the continuation line. Caller must free - * the return buffer. which may be used to enumerate over all lines. - * Wildcards are allowed. This function works on the current headers; - * i.e. the regular mail headers or the MIME headers of the current - * part. - * - * WHICH gives the mode: - * -1 := Take the last occurence - * n := Take the n-th one. - * - * Returns a newly allocated buffer or NULL on error. errno is set in - * case of a memory failure or set to 0 if the requested field is not - * available. - */ -char * -rfc822parse_get_field (rfc822parse_t msg, const char *name, int which) -{ - HDR_LINE h, h2; - char *buf, *p; - size_t n; - - h = find_header (msg, name, which, NULL); - if (!h) - { - errno = 0; - return NULL; /* no such field */ - } - - n = strlen (h->line) + 1; - for (h2 = h->next; h2 && h2->cont; h2 = h2->next) - n += strlen (h2->line) + 1; - - buf = p = malloc (n); - if (buf) - { - p = stpcpy (p, h->line); - *p++ = '\n'; - for (h2 = h->next; h2 && h2->cont; h2 = h2->next) - { - p = stpcpy (p, h2->line); - *p++ = '\n'; - } - p[-1] = 0; - } - return buf; -} - - -/**************** - * Enumerate all header. Caller has to provide the address of a pointer - * which has to be initialzed to NULL, the caller should then never change this - * pointer until he has closed the enumeration by passing again the address - * of the pointer but with msg set to NULL. - * The function returns pointers to all the header lines or NULL when - * all lines have been enumerated or no headers are available. - */ -const char * -rfc822parse_enum_header_lines (rfc822parse_t msg, void **context) -{ - HDR_LINE l; - - if (!msg) /* Close. */ - return NULL; - - if (*context == msg || !msg->current_part) - return NULL; - - l = *context ? (HDR_LINE) *context : msg->current_part->hdr_lines; - - if (l) - { - *context = l->next ? (void *) (l->next) : (void *) msg; - return l->line; - } - *context = msg; /* Mark end of list. */ - return NULL; -} - - - -/**************** - * Find a header field. If the Name does end in an asterisk this is meant - * to be a wildcard. - * - * which -1 : Retrieve the last field - * >0 : Retrieve the n-th field - - * RPREV may be used to return the predecessor of the returned field; - * which may be NULL for the very first one. It has to be initialzed - * to either NULL in which case the search start at the first header line, - * or it may point to a headerline, where the search should start - */ -static HDR_LINE -find_header (rfc822parse_t msg, const char *name, int which, HDR_LINE *rprev) -{ - HDR_LINE hdr, prev = NULL, mark = NULL; - unsigned char *p; - size_t namelen, n; - int found = 0; - int glob = 0; - - if (!msg->current_part) - return NULL; - - namelen = strlen (name); - if (namelen && name[namelen - 1] == '*') - { - namelen--; - glob = 1; - } - - hdr = msg->current_part->hdr_lines; - if (rprev && *rprev) - { - /* spool forward to the requested starting place. - * we cannot simply set this as we have to return - * the previous list element too */ - for (; hdr && hdr != *rprev; prev = hdr, hdr = hdr->next) - ; - } - - for (; hdr; prev = hdr, hdr = hdr->next) - { - if (hdr->cont) - continue; - if (!(p = strchr (hdr->line, ':'))) - continue; /* invalid header, just skip it. */ - n = p - hdr->line; - if (!n) - continue; /* invalid name */ - if ((glob ? (namelen <= n) : (namelen == n)) - && !memcmp (hdr->line, name, namelen)) - { - found++; - if (which == -1) - mark = hdr; - else if (found == which) - { - if (rprev) - *rprev = prev; - return hdr; - } - } - } - if (mark && rprev) - *rprev = prev; - return mark; -} - - - -static const char * -skip_ws (const char *s) -{ - while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') - s++; - return s; -} - - -static void -release_token_list (TOKEN t) -{ - while (t) - { - TOKEN t2 = t->next; - /* fixme: If we have owner_pantry, put the token back to - * this pantry so that it can be reused later */ - free (t); - t = t2; - } -} - - -static TOKEN -new_token (enum token_type type, const char *buf, size_t length) -{ - TOKEN t; - - /* fixme: look through our pantries to find a suitable - * token for reuse */ - t = malloc (sizeof *t + length); - if (t) - { - t->next = NULL; - t->type = type; - memset (&t->flags, 0, sizeof (t->flags)); - t->data[0] = 0; - if (buf) - { - memcpy (t->data, buf, length); - t->data[length] = 0; /* Make sure it is a C string. */ - } - else - t->data[0] = 0; - } - return t; -} - -static TOKEN -append_to_token (TOKEN old, const char *buf, size_t length) -{ - size_t n = strlen (old->data); - TOKEN t; - - t = malloc (sizeof *t + n + length); - if (t) - { - t->next = old->next; - t->type = old->type; - t->flags = old->flags; - memcpy (t->data, old->data, n); - memcpy (t->data + n, buf, length); - t->data[n + length] = 0; - old->next = NULL; - release_token_list (old); - } - return t; -} - - - -/* - Parse a field into tokens as defined by rfc822. - */ -static TOKEN -parse_field (HDR_LINE hdr) -{ - static const char specials[] = "<>@.,;:\\[]\"()"; - static const char specials2[] = "<>@.,;:"; - static const char tspecials[] = "/?=<>@,;:\\[]\"()"; - static const char tspecials2[] = "/?=<>@.,;:"; - static struct - { - const unsigned char *name; - size_t namelen; - } tspecial_header[] = { - { "Content-Type", 12}, - { "Content-Transfer-Encoding", 25}, - { NULL, 0} - }; - const char *delimiters; - const char *delimiters2; - const unsigned char *line, *s, *s2; - size_t n; - int i, invalid = 0; - TOKEN t, tok, *tok_tail; - - errno = 0; - if (!hdr) - return NULL; - - tok = NULL; - tok_tail = &tok; - - line = hdr->line; - if (!(s = strchr (line, ':'))) - return NULL; /* oops */ - - n = s - line; - if (!n) - return NULL; /* oops: invalid name */ - - delimiters = specials; - delimiters2 = specials2; - for (i = 0; tspecial_header[i].name; i++) - { - if (n == tspecial_header[i].namelen - && !memcmp (line, tspecial_header[i].name, n)) - { - delimiters = tspecials; - delimiters2 = tspecials2; - break; - } - } - - s++; /* Move over the colon. */ - for (;;) - { - if (!*s) - { - if (!hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - - if (*s == '(') - { - int level = 1; - int in_quote = 0; - - invalid = 0; - for (s++;; s++) - { - if (!*s) - { - if (!hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - - if (in_quote) - { - if (*s == '\"') - in_quote = 0; - else if (*s == '\\' && s[1]) /* what about continuation? */ - s++; - } - else if (*s == ')') - { - if (!--level) - break; - } - else if (*s == '(') - level++; - else if (*s == '\"') - in_quote = 1; - } - if (!*s) - ; /* Actually this is an error, but we don't care about it. */ - else - s++; - } - else if (*s == '\"' || *s == '[') - { - /* We do not check for non-allowed nesting of domainliterals */ - int term = *s == '\"' ? '\"' : ']'; - invalid = 0; - s++; - t = NULL; - - for (;;) - { - for (s2 = s; *s2; s2++) - { - if (*s2 == term) - break; - else if (*s2 == '\\' && s2[1]) /* what about continuation? */ - s2++; - } - - t = (t - ? append_to_token (t, s, s2 - s) - : new_token (term == '\"'? tQUOTED : tDOMAINLIT, s, s2 - s)); - if (!t) - goto failure; - - if (*s2 || !hdr->next || !hdr->next->cont) - break; - hdr = hdr->next; - s = hdr->line; - } - *tok_tail = t; - tok_tail = &t->next; - s = s2; - if (*s) - s++; /* skip the delimiter */ - } - else if ((s2 = strchr (delimiters2, *s))) - { /* Special characters which are not handled above. */ - invalid = 0; - t = new_token (tSPECIAL, s, 1); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - s++; - } - else if (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') - { - invalid = 0; - s = skip_ws (s + 1); - } - else if (*s > 0x20 && !(*s & 128)) - { /* Atom. */ - invalid = 0; - for (s2 = s + 1; *s2 > 0x20 - && !(*s2 & 128) && !strchr (delimiters, *s2); s2++) - ; - t = new_token (tATOM, s, s2 - s); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - s = s2; - } - else - { /* Invalid character. */ - if (!invalid) - { /* For parsing we assume only one space. */ - t = new_token (tSPACE, NULL, 0); - if (!t) - goto failure; - *tok_tail = t; - tok_tail = &t->next; - invalid = 1; - } - s++; - } - } - - return tok; - - failure: - { - int save = errno; - release_token_list (tok); - errno = save; - } - return NULL; -} - - - - -/**************** - * Find and parse a header field. - * WHICH indicates what to do if there are multiple instance of the same - * field (like "Received"); the following value are defined: - * -1 := Take the last occurence - * 0 := Reserved - * n := Take the n-th one. - * Returns a handle for further operations on the parse context of the field - * or NULL if the field was not found. - */ -rfc822parse_field_t -rfc822parse_parse_field (rfc822parse_t msg, const char *name, int which) -{ - HDR_LINE hdr; - - if (!which) - return NULL; - - hdr = find_header (msg, name, which, NULL); - if (!hdr) - return NULL; - return parse_field (hdr); -} - -void -rfc822parse_release_field (rfc822parse_field_t ctx) -{ - if (ctx) - release_token_list (ctx); -} - - - -/**************** - * Check whether T points to a parameter. - * A parameter starts with a semicolon and it is assumed that t - * points to exactly this one. - */ -static int -is_parameter (TOKEN t) -{ - t = t->next; - if (!t || t->type != tATOM) - return 0; - t = t->next; - if (!t || !(t->type == tSPECIAL && t->data[0] == '=')) - return 0; - t = t->next; - if (!t) - return 1; /* We assume that an non existing value is an empty one. */ - return t->type == tQUOTED || t->type == tATOM; -} - -/* - Some header (Content-type) have a special syntax where attribute=value - pairs are used after a leading semicolon. The parse_field code - knows about these fields and changes the parsing to the one defined - in RFC2045. - Returns a pointer to the value which is valid as long as the - parse context is valid; NULL is returned in case that attr is not - defined in the header, a missing value is reppresented by an empty string. - - With LOWER_VALUE set to true, a matching field valuebe be - lowercased. - - Note, that ATTR should be lowercase. - */ -const char * -rfc822parse_query_parameter (rfc822parse_field_t ctx, const char *attr, - int lower_value) -{ - TOKEN t, a; - - for (t = ctx; t; t = t->next) - { - /* skip to the next semicolon */ - for (; t && !(t->type == tSPECIAL && t->data[0] == ';'); t = t->next) - ; - if (!t) - return NULL; - if (is_parameter (t)) - { /* Look closer. */ - a = t->next; /* We know that this is an atom */ - if ( !a->flags.lowered ) - { - lowercase_string (a->data); - a->flags.lowered = 1; - } - if (!strcmp (a->data, attr)) - { /* found */ - t = a->next->next; - /* Either T is now an atom, a quoted string or NULL in - * which case we return an empty string. */ - - if ( lower_value && t && !t->flags.lowered ) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - return t ? t->data : ""; - } - } - } - return NULL; -} - -/**************** - * This function may be used for the Content-Type header to figure out - * the media type and subtype. Note, that the returned strings are - * guaranteed to be lowercase as required by MIME. - * - * Returns: a pointer to the media type and if subtype is not NULL, - * a pointer to the subtype. - */ -const char * -rfc822parse_query_media_type (rfc822parse_field_t ctx, const char **subtype) -{ - TOKEN t = ctx; - const char *type; - - if (t->type != tATOM) - return NULL; - if (!t->flags.lowered) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - type = t->data; - t = t->next; - if (!t || t->type != tSPECIAL || t->data[0] != '/') - return NULL; - t = t->next; - if (!t || t->type != tATOM) - return NULL; - - if (subtype) - { - if (!t->flags.lowered) - { - lowercase_string (t->data); - t->flags.lowered = 1; - } - *subtype = t->data; - } - return type; -} - - - - - -#ifdef TESTING - -/* Internal debug function to print the structure of the message. */ -static void -dump_structure (rfc822parse_t msg, part_t part, int indent) -{ - if (!part) - { - printf ("*** Structure of this message:\n"); - part = msg->parts; - } - - for (; part; part = part->right) - { - rfc822parse_field_t ctx; - part_t save_part; /* ugly hack - we should have a function to - get part inforation. */ - const char *s; - - save_part = msg->current_part; - msg->current_part = part; - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - msg->current_part = save_part; - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - printf ("*** %*s %s/%s", indent*2, "", s1, s2); - else - printf ("*** %*s [not found]", indent*2, ""); - - s = rfc822parse_query_parameter (ctx, "boundary", 0); - if (s) - printf (" (boundary=\"%s\")", s); - rfc822parse_release_field (ctx); - } - else - printf ("*** %*s text/plain [assumed]", indent*2, ""); - putchar('\n'); - - if (part->down) - dump_structure (msg, part->down, indent + 1); - } - -} - - - -static void -show_param (rfc822parse_field_t ctx, const char *name) -{ - const char *s; - - if (!ctx) - return; - s = rfc822parse_query_parameter (ctx, name, 0); - if (s) - printf ("*** %s: `%s'\n", name, s); -} - - - -static void -show_event (rfc822parse_event_t event) -{ - const char *s; - - switch (event) - { - case RFC822PARSE_OPEN: s= "Open"; break; - case RFC822PARSE_CLOSE: s= "Close"; break; - case RFC822PARSE_CANCEL: s= "Cancel"; break; - case RFC822PARSE_T2BODY: s= "T2Body"; break; - case RFC822PARSE_FINISH: s= "Finish"; break; - case RFC822PARSE_RCVD_SEEN: s= "Rcvd_Seen"; break; - case RFC822PARSE_BOUNDARY: s= "Boundary"; break; - case RFC822PARSE_LAST_BOUNDARY: s= "Last_Boundary"; break; - default: s= "***invalid event***"; break; - } - printf ("*** got RFC822 event %s\n", s); -} - -static int -msg_cb (void *dummy_arg, rfc822parse_event_t event, rfc822parse_t msg) -{ - show_event (event); - if (event == RFC822PARSE_T2BODY) - { - rfc822parse_field_t ctx; - void *ectx; - const char *line; - - for (ectx=NULL; (line = rfc822parse_enum_header_lines (msg, &ectx)); ) - { - printf ("*** HDR: %s\n", line); - } - rfc822parse_enum_header_lines (NULL, &ectx); /* Close enumerator. */ - - ctx = rfc822parse_parse_field (msg, "Content-Type", -1); - if (ctx) - { - const char *s1, *s2; - s1 = rfc822parse_query_media_type (ctx, &s2); - if (s1) - printf ("*** media: `%s/%s'\n", s1, s2); - else - printf ("*** media: [not found]\n"); - show_param (ctx, "boundary"); - show_param (ctx, "protocol"); - rfc822parse_release_field (ctx); - } - else - printf ("*** media: text/plain [assumed]\n"); - - } - - - return 0; -} - - - -int -main (int argc, char **argv) -{ - char line[5000]; - size_t length; - rfc822parse_t msg; - - msg = rfc822parse_open (msg_cb, NULL); - if (!msg) - abort (); - - while (fgets (line, sizeof (line), stdin)) - { - length = strlen (line); - if (length && line[length - 1] == '\n') - line[--length] = 0; - if (length && line[length - 1] == '\r') - line[--length] = 0; - if (rfc822parse_insert (msg, line, length)) - abort (); - } - - dump_structure (msg, NULL, 0); - - rfc822parse_close (msg); - return 0; -} -#endif - -/* -Local Variables: -compile-command: "gcc -Wall -g -DTESTING -o rfc822parse rfc822parse.c" -End: -*/ diff --git a/tools/rfc822parse.h b/tools/rfc822parse.h deleted file mode 100644 index 1293117ac..000000000 --- a/tools/rfc822parse.h +++ /dev/null @@ -1,79 +0,0 @@ -/* rfc822parse.h - Simple mail and MIME parser - * Copyright (C) 1999 Werner Koch, Duesseldorf - * Copyright (C) 2003, g10 Code GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef RFC822PARSE_H -#define RFC822PARSE_H - -struct rfc822parse_context; -typedef struct rfc822parse_context *rfc822parse_t; - -typedef enum - { - RFC822PARSE_OPEN = 1, - RFC822PARSE_CLOSE, - RFC822PARSE_CANCEL, - RFC822PARSE_T2BODY, - RFC822PARSE_FINISH, - RFC822PARSE_RCVD_SEEN, - RFC822PARSE_LEVEL_DOWN, - RFC822PARSE_LEVEL_UP, - RFC822PARSE_BOUNDARY, - RFC822PARSE_LAST_BOUNDARY, - RFC822PARSE_BEGIN_HEADER, - RFC822PARSE_PREAMBLE, - RFC822PARSE_EPILOGUE - } -rfc822parse_event_t; - -struct rfc822parse_field_context; -typedef struct rfc822parse_field_context *rfc822parse_field_t; - - -typedef int (*rfc822parse_cb_t) (void *opaque, - rfc822parse_event_t event, - rfc822parse_t msg); - - -rfc822parse_t rfc822parse_open (rfc822parse_cb_t cb, void *opaque_value); - -void rfc822parse_close (rfc822parse_t msg); - -void rfc822parse_cancel (rfc822parse_t msg); -int rfc822parse_finish (rfc822parse_t msg); - -int rfc822parse_insert (rfc822parse_t msg, - const unsigned char *line, size_t length); - -char *rfc822parse_get_field (rfc822parse_t msg, const char *name, int which); - -const char *rfc822parse_enum_header_lines (rfc822parse_t msg, void **context); - -rfc822parse_field_t rfc822parse_parse_field (rfc822parse_t msg, - const char *name, - int which); - -void rfc822parse_release_field (rfc822parse_field_t field); - -const char *rfc822parse_query_parameter (rfc822parse_field_t ctx, - const char *attr, int lower_value); - -const char *rfc822parse_query_media_type (rfc822parse_field_t ctx, - const char **subtype); - -#endif /*RFC822PARSE_H */ diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c deleted file mode 100644 index 7f79f2f18..000000000 --- a/tools/watchgnupg.c +++ /dev/null @@ -1,389 +0,0 @@ -/* watchgnupg.c - Socket server for GnuPG logs - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <errno.h> -#include <stdarg.h> -#include <assert.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <fcntl.h> -#include <time.h> - -#define PGM "watchgnupg" - -/* Allow for a standalone build. */ -#ifdef VERSION -#define MYVERSION_LINE PGM " (GnuPG) " VERSION -#define BUGREPORT_LINE "\nReport bugs to <bug-gnupg@gnu.org>.\n" -#else -#define MYVERSION_LINE PGM -#define BUGREPORT_LINE "" -#endif - -static int verbose; - - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - - -/* static void */ -/* err (const char *format, ...) */ -/* { */ -/* va_list arg_ptr; */ - -/* fflush (stdout); */ -/* fprintf (stderr, "%s: ", PGM); */ - -/* va_start (arg_ptr, format); */ -/* vfprintf (stderr, format, arg_ptr); */ -/* va_end (arg_ptr); */ -/* putc ('\n', stderr); */ -/* } */ - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core"); - return p; -} - -static void * -xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - die ("out of core"); - return p; -} - -static void * -xrealloc (void *old, size_t n) -{ - void *p = realloc (old, n); - if (!p) - die ("out of core"); - return p; -} - - -struct client_s { - struct client_s *next; - int fd; - size_t size; /* Allocated size of buffer. */ - size_t len; /* Current length of buffer. */ - unsigned char *buffer; /* Buffer to with data already read. */ - -}; -typedef struct client_s *client_t; - - - -static void -print_fd_and_time (int fd) -{ - struct tm *tp; - time_t atime = time (NULL); - - tp = localtime (&atime); - printf ("%3d - %04d-%02d-%02d %02d:%02d:%02d ", - fd, - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec ); -} - - -/* Print LINE for the client identified by C. Calling this function - witgh LINE set to NULL, will flush the internal buffer. */ -static void -print_line (client_t c, const char *line) -{ - const char *s; - size_t n; - - if (!line) - { - if (c->buffer && c->len) - { - print_fd_and_time (c->fd); - fwrite (c->buffer, c->len, 1, stdout); - putc ('\n', stdout); - c->len = 0; - } - return; - } - - while ((s = strchr (line, '\n'))) - { - print_fd_and_time (c->fd); - if (c->buffer && c->len) - { - fwrite (c->buffer, c->len, 1, stdout); - c->len = 0; - } - fwrite (line, s - line + 1, 1, stdout); - line = s + 1; - } - n = strlen (line); - if (n) - { - if (c->len + n >= c->size) - { - c->size += ((n + 255) & ~255); - c->buffer = (c->buffer - ? xrealloc (c->buffer, c->size) - : xmalloc (c->size)); - } - memcpy (c->buffer + c->len, line, n); - c->len += n; - } -} - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2004 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] SOCKETNAME\n" - "Open the local socket SOCKETNAME and display log messages\n" - "\n" - " --force delete an already existing socket file\n" - " --verbose enable extra informational output\n" - " --version print version of the program and exit\n" - " --help display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - -int -main (int argc, char **argv) -{ - int last_argc = -1; - int force = 0; - - struct sockaddr_un srvr_addr; - int addrlen; - int server; - int flags; - client_t client_list = NULL; - - if (argc) - { - argc--; argv++; - } - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--force")) - { - force = 1; - argc--; argv++; - } - } - - if (argc != 1) - { - fprintf (stderr, "usage: " PGM " socketname\n"); - exit (1); - } - - - if (verbose) - fprintf (stderr, "opening socket `%s'\n", *argv); - - setvbuf (stdout, NULL, _IOLBF, 0); - - server = socket (PF_LOCAL, SOCK_STREAM, 0); - if (server == -1) - die ("socket() failed: %s\n", strerror (errno)); - - /* We better set the listening socket to non-blocking so that we - don't get bitten by race conditions in accept. The should not - happen for Unix Domain sockets but well, shit happens. */ - flags = fcntl (server, F_GETFL, 0); - if (flags == -1) - die ("fcntl (F_GETFL) failed: %s\n", strerror (errno)); - if ( fcntl (server, F_SETFL, (flags | O_NONBLOCK)) == -1) - die ("fcntl (F_SETFL) failed: %s\n", strerror (errno)); - - - memset (&srvr_addr, 0, sizeof srvr_addr); - srvr_addr.sun_family = AF_LOCAL; - strncpy (srvr_addr.sun_path, *argv, sizeof (srvr_addr.sun_path) - 1); - srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr.sun_path) + 1); - - - again: - if (bind (server, (struct sockaddr *) &srvr_addr, addrlen)) - { - if (errno == EADDRINUSE && force) - { - force = 0; - remove (srvr_addr.sun_path); - goto again; - } - die ("bind to `%s' failed: %s\n", *argv, strerror (errno)); - } - - if (listen (server, 5)) - die ("listen failed: %s\n", strerror (errno)); - - for (;;) - { - fd_set rfds; - int max_fd; - client_t client; - - /* Usually we don't have that many connections, thus it is okay - to set them allways from scratch and don't maintain an active - fd_set. */ - FD_ZERO (&rfds); - FD_SET (server, &rfds); - max_fd = server; - for (client = client_list; client; client = client->next) - if (client->fd != -1) - { - FD_SET (client->fd, &rfds); - if (client->fd > max_fd) - max_fd = client->fd; - } - - if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0) - continue; /* Ignore any errors. */ - - if (FD_ISSET (server, &rfds)) /* New connection. */ - { - struct sockaddr_un clnt_addr; - int fd; - - addrlen = sizeof clnt_addr; - fd = accept (server, (struct sockaddr *) &clnt_addr, &addrlen); - if (fd == -1) - { - printf ("[accepting connection failed: %s]\n", strerror (errno)); - } - else if (fd >= FD_SETSIZE) - { - close (fd); - printf ("[connection request denied: too many connections]\n"); - } - else - { - for (client = client_list; client && client->fd != -1; - client = client->next) - ; - if (!client) - { - client = xcalloc (1, sizeof *client); - client->next = client_list; - client_list = client; - } - client->fd = fd; - printf ("[client at fd %d connected]\n", client->fd); - } - } - for (client = client_list; client; client = client->next) - if (client->fd != -1 && FD_ISSET (client->fd, &rfds)) - { - char line[256]; - int n; - - n = read (client->fd, line, sizeof line - 1); - if (n == 1) - { - int save_errno = errno; - print_line (client, NULL); /* flush */ - printf ("[client at fd %d read error: %s]\n", - client->fd, strerror (save_errno)); - close (client->fd); - client->fd = -1; - } - else if (!n) - { - print_line (client, NULL); /* flush */ - close (client->fd); - printf ("[client at fd %d disconnected]\n", client->fd); - client->fd = -1; - } - else - { - line[n] = 0; - print_line (client, line); - } - } - } - - return 0; -} - - -/* -Local Variables: -compile-command: "gcc -Wall -g -o watchgnupg watchgnupg.c" -End: -*/