1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-03 16:53:03 +01:00

This commit was manufactured by cvs2svn to create branch

'GNUPG-1-9-BRANCH-MO'.
This commit is contained in:
Repo Admin 2004-06-20 11:35:13 +00:00
parent 4b3427c6ce
commit 6decea8316
395 changed files with 0 additions and 155087 deletions

625
ABOUT-NLS
View File

@ -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.

View File

340
COPYING
View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <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
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.
<signature of Ty Coon>, 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.

452
ChangeLog
View File

@ -1,452 +0,0 @@
2004-06-08 Werner Koch <wk@gnupg.org>
Released 1.9.9.
2004-06-06 Werner Koch <wk@gnupg.org>
* configure.ac: Require libksba 0.9.7.
2004-04-29 Werner Koch <wk@gnupg.org>
Released 1.9.8.
2004-04-20 Werner Koch <wk@gnupg.org>
* 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 <schwinge@nic-nac-project.de>
* autogen.sh: Added ACLOCAL_FLAGS.
2004-04-06 Werner Koch <wk@gnupg.org>
Released 1.9.7.
* configure.ac: Require libgcrypt 1.1.94.
Introduce PACKAGE_GT and set it to gnupg2.
2004-03-23 Werner Koch <wk@gnupg.org>
* configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT.
2004-03-09 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7.
2004-03-06 Werner Koch <wk@gnupg.org>
Released 1.9.6.
* configure.ac: Check the Libgcrypt API.
2004-02-25 Werner Koch <wk@gnupg.org>
* configure.ac: New option --disable-threads to inhibit
unintentional builds without Pth.
2004-02-21 Werner Koch <wk@gnupg.org>
Released 1.9.5.
2004-02-20 Werner Koch <wk@gnupg.org>
* configure.ac: Fixed URLs in the notice messages.
2004-02-18 Werner Koch <wk@gnupg.org>
* acinclude.m4: Removed macros to detect gpg-error, libgcrypt,
libassuan and ksba as they are now distributed in m4/.
2004-02-13 Werner Koch <wk@gnupg.org>
* configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92.
2004-02-12 Werner Koch <wk@gnupg.org>
* autogen.sh: Removed cruft from debugging.
* am/cmacros.am: New.
2004-02-11 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
Released 1.9.4.
* configure.ac: Require libksba 0.9.3 due to another bug fix there.
2004-01-29 Werner Koch <wk@gnupg.org>
* README: Updated.
* configure.ac: Require libksba 0.9.2 due to bug fixes.
2004-01-24 Werner Koch <wk@gnupg.org>
* configure.ac: Now requires libassuan 0.6.3.
2003-12-23 Werner Koch <wk@gnupg.org>
Released 1.9.3.
* README-alpha: Removed.
* configure.ac, Makefile.am: Add the tests and tools directories.
2003-12-19 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* configure.ac: Requires now libassuan 0.6.2.
(CFLAGS): Add --Wformat-noliteral in gcc mode.
2003-12-16 Werner Koch <wk@gnupg.org>
* configure.ac: Check for funopen and fopencookie as part of the
jnlib checks.
2003-12-09 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
Release 1.9.2.
* configure.ac: Requires now libassuan 0.6.1.
2003-10-31 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed
time interface.
2003-10-21 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION.
2003-09-23 Werner Koch <wk@gnupg.org>
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 <wk@gnupg.org>
Released 1.9.1.
* configure.ac: Require newer versions of some libraries.
2003-09-02 Werner Koch <wk@gnupg.org>
* configure.ac (HAVE_LIBUSB): Added a simple test for libusb.
2003-08-19 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AM_PATH_GPG_ERROR): Add missing comma in
invocation.
2003-08-06 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
Released 1.9.0.
* configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg.
2003-07-31 Werner Koch <wk@gnupg.org>
* Makefile.am (DISTCLEANFILES): Add g10defs.h
2003-06-18 Werner Koch <wk@gnupg.org>
* configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to
.gnupg2 to avoid accidential use with production keys.
2003-06-11 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* configure.ac, Makefile.am: Enable building of gpg.
2003-04-29 Werner Koch <wk@gnupg.org>
* 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 <bug-gnu-gettext@gnu.org>
* 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 <wk@gnupg.org>
* assuan/ : Removed. We now use libassuan.
* Makefile.am (SUBDIRS): Removed assuan
* configure.ac: Check for libassuan.
2003-01-09 Werner Koch <wk@gnupg.org>
* 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 <neal@g10code.de>
* 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 <wk@gnupg.org>
* configure.ac: Bumped version number to 1.9.0-cvs.
NewPG (Aegypten project) to GnuPG merge.
2002-09-20 Werner Koch <wk@gnupg.org>
Released 0.9.2.
2002-09-05 Neal H. Walfield <neal@g10code.de>
* configure.ac: Check for makeinfo.
2002-09-03 Neal H. Walfield <neal@g10code.de>
* 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 <wk@gnupg.org>
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 <wk@gnupg.org>
Released 0.9.0.
* configure.ac: Changed the default homedir to .gnupg.
* README-alpha: Removed.
2002-08-19 Werner Koch <wk@gnupg.org>
* acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug.
2002-08-13 Werner Koch <wk@gnupg.org>
* acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New.
* configure.ac: Use them.
2002-08-10 Werner Koch <wk@gnupg.org>
Released 0.3.10.
* configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support
for gettext.
2002-07-22 Werner Koch <wk@gnupg.org>
* configure.ac: Check for ftello and provide a replacement.
2002-07-01 Werner Koch <wk@gnupg.org>
Released 0.3.9.
* README: Short note on how to export in pkcs-12 format.
2002-06-29 Werner Koch <wk@gnupg.org>
* configure.ac: Define --with options to set the default location
of the agent, scdaemon, pinentry and dirmngr.
2002-06-27 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
Released 0.3.8.
* configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8.
2002-06-12 Werner Koch <wk@gnupg.org>
* configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now.
2002-06-04 Werner Koch <wk@gnupg.org>
Released 0.3.7.
2002-05-21 Werner Koch <wk@gnupg.org>
* configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2.
2002-05-14 Werner Koch <wk@gnupg.org>
* doc/: New
* configure.ac, Makefile.am: Added doc/
2002-05-03 Werner Koch <wk@gnupg.org>
Released 0.3.6.
2002-04-25 Werner Koch <wk@gnupg.org>
* configure.ac: Check for setlocale.
2002-04-24 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Check for locale.h.
2002-04-15 Werner Koch <wk@gnupg.org>
Released 0.3.5.
* NEWS: Started to describe release notes.
* configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined
2002-04-01 Werner Koch <wk@gnupg.org>
Released 0.3.4.
2002-03-18 Werner Koch <wk@gnupg.org>
Released 0.3.3.
2002-03-08 Werner Koch <wk@gnupg.org>
* README: Add some explanation on how to specify a user ID.
2002-03-06 Werner Koch <wk@gnupg.org>
Released 0.3.2.
2002-03-04 Werner Koch <wk@gnupg.org>
Released 0.3.1.
* README: Explained some options and files.
2002-02-14 Werner Koch <wk@gnupg.org>
* configure.ac: Fixed status messages related to presence of Pth.
2002-02-13 Werner Koch <wk@gnupg.org>
* acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New.
* configure.ac: use it.
2002-02-12 Werner Koch <wk@gnupg.org>
* configure.ac: Check for PTH. Provide replacement fucntions for
apsrintf and fopencookie.
* acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New.
2002-02-07 Werner Koch <wk@gnupg.org>
Released 0.3.0.
* configure.ac: Require libgcrypt 1.1.6.
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (KSBA_CONFIG): Remove superfluous x in front of
variable.
2002-01-26 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* configure.ac (mkdtemp): See whether we have to provide a
replacement.
2001-12-18 Werner Koch <wk@gnupg.org>
Released 0.0.0.
2001-12-17 Werner Koch <wk@gnupg.org>
* acinclude.m4: Add AM_PATH_LIBGCRYPT macro.
* configure.ac: and use it here. Figure out the location of libksba
2001-12-15 Werner Koch <wk@gnupg.org>
* configure.ac (missing_dir): Bail out if asprintf and fopencookie
are not available.
2001-12-04 Werner Koch <wk@gnupg.org>
* 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.

229
INSTALL
View File

@ -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.

View File

@ -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

171
NEWS
View File

@ -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_<n>.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.

511
README
View File

@ -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 <n>
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 <filename>
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 <path_to_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 <path_to_dirmgr_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 <user_id>
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 <path_to_pinentry_program>
Specify the PINentry program. The default value is
"<prefix>/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 <libraryname>
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 <portname>
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 <heinrichh@uni-duesseldorf.de>
* Exact match on an email address.
This is indicated by enclosing the email address in the usual way
with left and right angles
Example:
<heinrichh@uni-duesseldorf.de>
* 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]

View File

@ -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.

5
THANKS
View File

@ -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

78
TODO
View File

@ -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.

View File

@ -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 <stdlib.h>
#include <sys/types.h>], [
#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 <sys/types.h>
#include <sys/param.h>], [
#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 <sys/types.h>
#include <sys/param.h>], [
#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 <sys/socket.h>],
[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 <assert.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#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 <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
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 <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_DIRECT_H
# include <direct.h>
#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)
])

View File

@ -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

View File

@ -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 <<EOF
Note that you may use alternative versions of the tools by setting
the corresponding environment variables; see README.CVS for details.
EOF
exit 1
fi
echo "Running aclocal -I m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..."
$ACLOCAL -I m4 $ACLOCAL_FLAGS
echo "Running autoheader..."
$AUTOHEADER
echo "Running automake --gnu ..."
$AUTOMAKE --gnu;
echo "Running autoconf..."
$AUTOCONF
echo "You may now run \"./configure --enable-maintainer-mode && make\"."

View File

@ -1,340 +0,0 @@
2004-06-14 Werner Koch <wk@gnupg.org>
* xreadline.c: New. Based on the iobuf_read_line function.
2004-05-12 Werner Koch <wk@gnupg.org>
* util.h (xtrycalloc_secure,xtrymalloc_secure): New.
2004-05-11 Werner Koch <wk@gnupg.org>
* sysutils.c (disable_core_dumps): Only set the current limit.
(enable_core_dumps): New.
2004-04-13 Werner Koch <wk@gnupg.org>
* simple-pwquery.c (copy_and_escape): Relaxed quoting.
2004-04-05 Werner Koch <wk@gnupg.org>
* errors.h (STATUS_NEWSIG): New.
2004-03-11 Werner Koch <wk@gnupg.org>
* dynload.h [__MINGW32__]: Define RTLD_LAZY.
2004-03-09 Werner Koch <wk@gnupg.org>
* maperror.c (map_assuan_err): Map the Locale_Problem item.
2004-03-03 Werner Koch <wk@gnupg.org>
* asshelp.c, asshelp.h: New.
(send_pinentry_environment): New. Code taken from ../sm/call-agent.c.
2004-02-19 Werner Koch <wk@gnupg.org>
* simple-pwquery.c (agent_open): Don't mangle INFOSTR.
2004-02-17 Werner Koch <wk@gnupg.org>
* simple-pwquery.c (agent_open): Ignore an empty GPG_AGENT_INFO.
* errors.h: Added STATUS_IMPORT_OK.
2004-02-10 Werner Koch <wk@gnupg.org>
* b64enc.c: New. Based on code from ../sm/base64.c.
2004-01-30 Marcus Brinkmann <marcus@g10code.de>
* 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 <wk@gnupg.org>
* sexp-parse.h: New; moved from../agent.
* util.h (xtoi_4): New.
2003-12-23 Werner Koch <wk@gnupg.org>
* maperror.c (map_assuan_err): Prepared for a new error code.
2003-12-17 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* mkdtemp.c (mkdtemp): Use gcry_create_nonce.
* cryptmiss.c: Removed.
2003-11-13 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* maperror.c (map_ksba_err, map_gcry_err, map_kbx_err): Removed.
2003-10-31 Werner Koch <wk@gnupg.org>
* util.h (gnupg_isotime_t): New.
(gnupg_copy_time): New.
* gettime.c (gnupg_get_isotime): New.
2003-09-23 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* 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 <marcus@g10code.de>
* maperror.c (map_ksba_err): Map -1. Use gpg_err_make to set
the error source.
2003-08-14 Timo Schulz <twoaday@freakmail.de>
* dynload.h. New. W32 wrapper around the dynload mechanism.
2003-07-15 Werner Koch <wk@gnupg.org>
* simple-pwquery.c, simple-pwquery.h: New; moved from ../agent.
* Makefile.am (libsimple_pwquery_a_LIBADD): New.
2003-06-25 Werner Koch <wk@gnupg.org>
* maperror.c (map_to_assuan_status): Directly map 0 to 0.
2003-06-17 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* gettime.c (make_timestamp): New.
* ttyio.c: New. Taken from gnupg 1.2.
* ttyio.h: Move from ../include.
2003-06-13 Werner Koch <wk@gnupg.org>
* util.h (seterr): Removed macro.
(xmalloc_secure,xcalloc_secure): New.
2003-06-11 Werner Koch <wk@gnupg.org>
* iobuf.c (iobuf_writebyte,iobuf_write): Return error code from
iobuf_flush.
(iobuf_writestr): Ditto.
2003-06-10 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* 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 <wk@gnupg.org>
* util.h (fopencokokie): Removed prototype and struct.
* fopencookie.c: Removed.
* maperror.c: Use system assuan.h
2002-10-31 Neal H. Walfield <neal@g10code.de>
* isascii.c: New file.
* putc_unlocked.c: Likewise.
2002-10-28 Neal H. Walfield <neal@g10code.de>
* signal.c (caught_fatal_sig): Remove superfluous zero
initializer.
(caught_sigusr1): Likewise.
2002-09-04 Neal H. Walfield <neal@g10code.de>
* 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 <wk@gnupg.org>
* errors.h: Added STATUS_IMPORT_PROBLEM.
2002-08-20 Werner Koch <wk@gnupg.org>
* vasprintf.c: Hack to handle NULL for %s.
2002-08-09 Werner Koch <wk@gnupg.org>
* signal.c: New. Taken from GnuPG 1.1.91.
2002-07-23 Werner Koch <wk@gnupg.org>
* util.h (_IO_cookie_io_functions_t): Fixed typo. Noted by
Richard Lefebvre.
2002-07-22 Werner Koch <wk@gnupg.org>
* fseeko.c, ftello.c: New.
2002-06-28 Werner Koch <wk@gnupg.org>
* maperror.c (map_to_assuan_status): Map more errorcodes to Bad
Certificate.
2002-06-26 Werner Koch <wk@gnupg.org>
* maperror.c (map_to_assuan_status): Map EOF to No_Data_Available.
2002-06-10 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* maperror.c (map_to_assuan_status): Map Bad_CA_Certificate.
2002-05-23 Werner Koch <wk@gnupg.org>
* no-pth.c, Makefile.am: Removed.
2002-05-22 Werner Koch <wk@gnupg.org>
* mkdtemp.c: Replaced byte by unsigned char because it is no longer
defined in gcrypt.h.
2002-05-21 Werner Koch <wk@gnupg.org>
* maperror.c (map_gcry_err): Add libgcrypt's new S-expression errors.
(map_ksba_err): Add a few mappings.
2002-05-14 Werner Koch <wk@gnupg.org>
* gettime.c: New.
2002-05-03 Werner Koch <wk@gnupg.org>
* errors.h: Added STARUS_EXPSIG and STATUS_EXPKEYSIG.
2002-04-15 Werner Koch <wk@gnupg.org>
* cryptmiss.c: New.
2002-02-14 Werner Koch <wk@gnupg.org>
* maperror.c: Add more assuan<->gnupg mappings.
2002-02-12 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* mkdtemp.c: Copied from gnupg-1.0.6c and changed to use libgcrypt.
2002-01-19 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* maperror.c: Add mapping for Not_Trusted.
2002-01-11 Werner Koch <wk@gnupg.org>
* maperror.c (map_assuan_err): Codes for CRL
2002-01-08 Werner Koch <wk@gnupg.org>
* util.h (spacep): New.
2002-01-02 Werner Koch <wk@gnupg.org>
* maperror.c (map_to_assuan_status): New. Merged from ../agent
and ../sm.
2001-12-20 Werner Koch <wk@gnupg.org>
* maperror.c (map_gcry_err): Add some mappings.
2001-12-18 Werner Koch <wk@gnupg.org>
* Makefile.am (AM_CPPFLAGS): Include flags for gcrypt and ksba
2001-12-14 Werner Koch <wk@gnupg.org>
* 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.

View File

@ -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@

View File

@ -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

View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#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;
}

View File

@ -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 <assuan.h>
#include <gpg-error.h>
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*/

View File

@ -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 <config.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#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;
}

View File

@ -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 <dlfcn.h>
#else
#include <windows.h>
#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*/

View File

@ -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*/

View File

@ -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 <config.h>
#endif
#include <stdio.h>
int
fseeko (FILE *stream, off_t off, int whence)
{
return fseek (stream, off, whence);
}

View File

@ -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 <config.h>
#endif
#include <stdio.h>
off_t
ftello (FILE *stream)
{
long int off;
off = ftell (stream);
if (off == -1)
return (off_t)-1;
return off;
}

View File

@ -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 <config.h>
#include <stdlib.h>
#include <time.h>
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#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;
}

View File

@ -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 <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*/
#endif /*GNUPG_COMMON_I18N_H*/

File diff suppressed because it is too large Load Diff

View File

@ -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*/

View File

@ -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 <config.h>
#endif
int
isascii (int c)
{
return (((c) & ~0x7f) == 0);
}

View File

@ -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 <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <ksba.h>
#include <assuan.h>
#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);
}

View File

@ -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 <config.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

View File

@ -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*/

View File

@ -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 <config.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

View File

@ -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 <config.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <gcrypt.h>
#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;
}

View File

@ -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 <<EOF
/* Generated automatically by mkerrors */
/* Do not edit! */
#include <config.h>
#include <stdio.h>
#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 <<EOF
default: sprintf (buf, "ec=%d", err ); s=buf; break;
}
return s;
}
EOF

View File

@ -1,67 +0,0 @@
#!/bin/sh
# mkerrtok - Create error tokens from errors.h
# and the C source for gnupg_errortoken
# 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
cat <<EOF
/* Generated automatically by mkerrtok */
/* Do not edit! */
/**
* gnupg_error_token:
* @err: Error code
*
* This function returns a textual representaion of the given
* errorcode. If this is an unknown value, a static string is returned.
* This function differs from gnupg_strerror that it yields the string
* representation of the macro which is never subject to i18n.
*
* Return value: String with the error token.
**/
const char *
gnupg_error_token (int err)
{
const char *s;
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 ;
printf "%s\"; break;\n", substr(s,7);
}
'
cat <<EOF
default: s = "Unknown_Error"; break;
}
return s;
}
EOF

View File

@ -1,31 +0,0 @@
/* putc_unlocked.c - Replacement for putc_unlocked.
* 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 <config.h>
#endif
#include <stdio.h>
int
putc_unlocked (int c, FILE *stream)
{
return putc (c, stream);
}

View File

@ -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 <gpg-error.h>
/* 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*/

View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#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);
}

View File

@ -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 <config.h>
#endif
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#define SIMPLE_PWQUERY_IMPLEMENTATION 1
#include "simple-pwquery.h"
#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING)
# undef SPWQ_USE_LOGGING
#endif
#ifndef _
#define _(a) (a)
#endif
#if !defined (hexdigitp) && !defined (xtoi_2)
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
#endif
/* 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;
}

View File

@ -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 <gcrypt.h>
#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*/

View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#ifdef HAVE_STAT
#include <sys/stat.h>
#endif
#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 "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

View File

@ -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*/

View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_TCGETATTR
#include <termios.h>
#else
#ifdef HAVE_TERMIO_H
/* simulate termios with termio */
#include <termio.h>
#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 <windows.h>
#ifdef HAVE_TCGETATTR
#error mingw32 and termios
#endif
#endif
#include <errno.h>
#include <ctype.h>
#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;
}

View File

@ -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*/

View File

@ -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 <gcrypt.h> /* We need this for the memory function protos. */
#include <time.h> /* We need time_t. */
#include <gpg-error.h> /* 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 <stdarg.h>
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*/

View File

@ -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 <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#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 */

View File

@ -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 <config.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

View File

@ -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 <config.h>
#include <stdlib.h>
#include <errno.h>
#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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
2004-06-18 Werner Koch <wk@gnupg.org>
* debugging.texi: New.
* gnupg.texi: Include it.
2004-05-11 Werner Koch <wk@gnupg.org>
* gpgsm.texi (Esoteric Options): Add --debug-allow-core-dump.
2004-05-03 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Agent Options): Add --allow-mark-trusted.
2004-02-03 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* gpgsm.texi (Certificate Options): Add --{enable,disable}-ocsp.
2003-11-17 Werner Koch <wk@gnupg.org>
* scdaemon.texi (Scdaemon Options): Added --allow-admin and
--deny-admin.
2003-10-27 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Agent GET_CONFIRMATION): New.
2002-12-04 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Agent Signals): New.
2002-12-03 Werner Koch <wk@gnupg.org>
* gpgsm.texi (Operational Commands): Add --passwd and
--call-protect-tool.
* gpg-agent.texi (Agent PASSWD): New
2002-11-13 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Invoking GPG-AGENT): Tell about GPG_TTY.
2002-11-12 Werner Koch <wk@gnupg.org>
* gpgsm.texi (Operational Commands): Add --call-dirmngr.
2002-09-25 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Agent Options): Add --keep-tty and --keep-display.
2002-09-12 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Invoking GPG-AGENT): Explained how to start only
one instance.
2002-08-28 Werner Koch <wk@gnupg.org>
* gpg-agent.texi (Agent Options): Explained more options.
* scdaemon.texi (Scdaemon Options): Ditto.
2002-08-09 Werner Koch <wk@gnupg.org>
* Makefile.am (gnupg_TEXINFOS): Include contrib.texi.
2002-08-06 Werner Koch <wk@gnupg.org>
* gpgsm.texi: Added more options.
2002-07-26 Werner Koch <wk@gnupg.org>
* assuan.texi: New.
* gpgsm.texi, scdaemon.texi, gpg-agent.texi: Documented the Assuan
protocol used.
2002-07-22 Werner Koch <wk@gnupg.org>
* 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 <wk@gnupg.org>
* gpgsm.texi (Invocation): Described the various debug flags.
2002-05-14 Werner Koch <wk@gnupg.org>
* 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.

View File

@ -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

View File

@ -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 [<arbitary debugging information>]
Request was successful.
@item ERR @var{errorcode} [<human readable error description>]
Request could not be fulfilled. The error codes are mostly application
specific except for a few common ones.
@item S @var{keyword} <status information depending on keyword>
Informational output by the server, still processing the request.
@item # <string>
Comment line issued only for debugging purposes. Totally ignored.
@item D <raw data>
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}> <parameters>
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} <parameters>
@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 <raw data>
@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

View File

@ -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.

View File

@ -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}.

View File

@ -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:

View File

@ -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

View File

@ -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 <keyGrip>
@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
(<algo>
(<param_name1> <mpi>)
...
(<param_namen> <mpi>)))
@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 <keyGrip>
@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 <hexstring>
@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 <options>
@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
(<algo>
(<param_name1> <mpi>)
...
(<param_namen> <mpi>)))
@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 <keyGrip>
S: OK key available
C: SIGKEY <keyGrip>
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 <mpi>)
(e <mpi>)))
@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 <fingerprint>
@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}.

File diff suppressed because it is too large Load Diff

View File

@ -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 <plaintext >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.

View File

@ -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.

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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*/

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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++;
}
}
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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*/

View File

@ -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;
}

3367
g10/g10.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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*/

View File

@ -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*/

View File

@ -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) {}

View File

@ -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");
}

File diff suppressed because it is too large Load Diff

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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*/

Some files were not shown because too many files have changed in this diff Show More