mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
See ChangeLog: Wed Feb 10 17:15:39 CET 1999 Werner Koch
This commit is contained in:
parent
a16e15282a
commit
9a4f506a18
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for freebsd 2.2
|
||||
|
||||
* configure.in: a lot of changes to allow selection of modules.
|
||||
Add support for OS/2.
|
||||
|
||||
* acinclude.m4: add some more caching
|
||||
|
||||
* README: Spelling and grammar corrections (John A. Martin)
|
||||
* INSTALL: Ditto.
|
||||
|
||||
Wed Jan 20 21:40:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* configure.in: --enable-m-guard is now default
|
||||
|
44
INSTALL
44
INSTALL
@ -13,10 +13,10 @@ Configure options for GNUPG
|
||||
--disable-nls Disable NLS support (See ABOUT-NLS)
|
||||
|
||||
--enable-m-debug Compile with the integrated malloc debugging stuff.
|
||||
This makes the program slower but is checks every
|
||||
This makes the program slower but it checks every
|
||||
free operation and can be used to create statistics
|
||||
of memory usage. If this option is used the program
|
||||
option "--debug 32" displays every call to a a malloc
|
||||
option "--debug 32" displays every call to a malloc
|
||||
function (this makes the program *really* slow), the
|
||||
option "--debug 128" displays a memory statistic after
|
||||
the program run.
|
||||
@ -55,8 +55,8 @@ Don't forget to delete "config.cache" and run "./config.status --recheck".
|
||||
The Random Device
|
||||
=================
|
||||
Random devices are available in Linux, FreeBSD and OpenBSD.
|
||||
The device files may not exist on your system, please check this
|
||||
and create them if needed.
|
||||
The random device files may not exist on your system, please check whether
|
||||
they do and create them if needed.
|
||||
|
||||
The Linux files should look like this:
|
||||
cr--r--r-- 1 root sys 1, 8 May 28 1997 /dev/random
|
||||
@ -72,23 +72,23 @@ You can create them with:
|
||||
mknod /dev/random c 2 3
|
||||
mknod /dev/urandom c 2 4
|
||||
|
||||
Unices without a random devices must use another entropy collector
|
||||
which is called rndunix and available as an extension module. You
|
||||
Unices without a random devices must use another entropy collector. One
|
||||
entropy collector called rndunix and available as an extension module. You
|
||||
should put this in your ~/.gnupg/options file:
|
||||
===8<====================
|
||||
load-extension rndunix
|
||||
===>8====================
|
||||
This collector works by running a lot of tools which yields more or
|
||||
This collector works by running a lot of commands that yield more or
|
||||
less unpredictable output and feds this as entropy into the random
|
||||
generator - It should work reliable but you should check whether
|
||||
it produces good output for your kind of Unix. There are some debug
|
||||
generator - It should work reliably but you should check whether
|
||||
it produces good output for your version of Unix. There are some debug
|
||||
options to help you (see cipher/rndunix.c).
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
gpg is not installed as suid:root; if you want to do it, do it manually.
|
||||
gpg is not installed as suid:root; if you want to do that, do it manually.
|
||||
We will use capabilities in the future.
|
||||
|
||||
The ~/.gnupg directory will be created if it does not exist. Your first
|
||||
@ -135,9 +135,9 @@ diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
The file `configure.in' is used by the program `autoconf' to create
|
||||
`configure'. You only need `configure.in' if you want to change it or
|
||||
regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
@ -147,7 +147,7 @@ The simplest way to compile this package is:
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
Running `configure' takes a while. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
@ -177,19 +177,19 @@ a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
Or, on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
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 `..'.
|
||||
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', such as GNU `make',
|
||||
that supports the `VPATH' variable. `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 supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
|
@ -10,7 +10,7 @@ all-recursive-am: g10defs.h
|
||||
g10defs.h : config.h
|
||||
@( set -e; \
|
||||
echo "/* Generated automatically by Makefile */" ; \
|
||||
echo "#ifdef __MINGW32__"; \
|
||||
echo "#ifdef HAVE_DRIVE_LETTERS"; \
|
||||
echo "#define G10_LOCALEDIR \"c:/lib/gnupg/locale\""; \
|
||||
echo "#define GNUPG_LIBDIR \"c:/lib/gnupg\""; \
|
||||
echo "#define GNUPG_DATADIR \"c:/lib/gnupg\""; \
|
||||
|
367
README
367
README
@ -1,19 +1,19 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
|
||||
GnuPG - The GNU Privacy Guard
|
||||
-------------------------------
|
||||
Version 0.9
|
||||
GnuPG - The GNU Privacy Guard
|
||||
-------------------------------
|
||||
Version 0.9
|
||||
|
||||
GnuPG is now in Beta test and you should report all bugs to the
|
||||
mailing list (see below). The 0.9.x versions are mainly released
|
||||
to fix all remaining serious bugs. As soon as version 1.0 is out,
|
||||
mailing list (see below). The 0.9.x versions are released mainly
|
||||
to fix all remaining serious bugs. As soon as version 1.0 is out,
|
||||
development will continue with a 1.1 series and bug fixes for the
|
||||
1.0 version are released as needed.
|
||||
1.0 version as needed.
|
||||
|
||||
GnuPG works best on GNU/Linux or *BSD. Other Unices are
|
||||
also supported but not as good tested as those Freenix ones.
|
||||
Please verify the tar file; there is a PGP2 and a GnuPG/PGP5
|
||||
signature available. My PGP2 key is well known and published in
|
||||
also supported but are not as well tested as the Free Unices.
|
||||
Please verify the tar file with the PGP2 or GnuPG/PGP5
|
||||
signatures provided. My PGP2 key is well known and published in
|
||||
the "Global Trust Register for 1998", ISBN 0-9532397-0-5.
|
||||
|
||||
I have included my pubring as "g10/pubring.asc", which contains
|
||||
@ -25,33 +25,33 @@
|
||||
"pub 1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>"
|
||||
"Key fingerprint = ECAF 7590 EB34 43B5 C7CF 3ACB 6C7E E1B8 621C C013"
|
||||
|
||||
You may want add it to your GnuPG pubring and use it in the future to
|
||||
verify new releases. Because you verified this README file and
|
||||
_checked_that_it_is_really_my PGP2 key 0C9857A5, you can be sure
|
||||
that the above fingerprints are correct.
|
||||
You may want add my new DSA key to your GnuPG pubring and use it in
|
||||
the future to verify new releases. Because you verified this README
|
||||
file and _checked_that_it_is_really_my PGP2 key 0C9857A5, you can be
|
||||
sure that the above fingerprints are correct.
|
||||
|
||||
Please subscribe to g10@net.lut.ac.uk by sending a mail with
|
||||
the word "subscribe" in the body to "g10-request@net.lut.ac.uk".
|
||||
This mailing list is a closed one (only subscribers are allowed
|
||||
to post) to avoid misuse by folks who don't know the Netiquette
|
||||
and trash your mailspool with commercial junk.
|
||||
This mailing list is closed (only subscribers are allowed to post)
|
||||
to avoid misuse by folks who don't know the Netiquette and trash
|
||||
your mailspool with commercial junk.
|
||||
|
||||
See the file COPYING for copyright and warranty information.
|
||||
|
||||
GnuPG is in compliance with RFC2440 (OpenPGP), see doc/OpenPGP for
|
||||
details.
|
||||
|
||||
Due to the fact that GnuPG does not use use any patented algorithm,
|
||||
it cannot be compatible with PGP2 versions; PGP 2.x does only use
|
||||
IDEA (which is patented worldwide) and RSA (which is patented in
|
||||
the United States until Sep 20, 2000).
|
||||
Because GnuPG does not use use any patented algorithm it cannot be
|
||||
compatible with PGP2 versions. PGP 2.x uses only IDEA (which is
|
||||
patented worldwide) and RSA (which is patented in the United States
|
||||
until Sep 20, 2000).
|
||||
|
||||
The default algorithms are now DSA and ElGamal. ElGamal for signing
|
||||
is still available, but due to the larger size of such signatures it
|
||||
is depreciated (Please note that the GnuPG implementation of ElGamal
|
||||
signatures is *not* insecure). Symmetric algorithms are: 3DES,
|
||||
Blowfish and CAST5 (Twofish will come soon), available digest
|
||||
algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
|
||||
is still available, but because of the larger size of such
|
||||
signatures it is deprecated (Please note that the GnuPG
|
||||
implementation of ElGamal signatures is *not* insecure). Symmetric
|
||||
algorithms are: 3DES, Blowfish, and CAST5 (Twofish will come soon).
|
||||
Digest algorithms available are MD5, RIPEMD160, SHA1, and TIGER/192.
|
||||
|
||||
|
||||
Installation
|
||||
@ -61,7 +61,7 @@
|
||||
|
||||
Here is a quick summary:
|
||||
|
||||
1) "./configure"
|
||||
1) "./configure"
|
||||
|
||||
2) "make"
|
||||
|
||||
@ -69,24 +69,25 @@
|
||||
|
||||
4) You end up with the binaries "gpg" and "gpgm" in /usr/local/bin.
|
||||
|
||||
5) Optional, but suggested: install the binary "gpg" as suid root.
|
||||
5) Optional, but suggested, install the binary "gpg" as suid root.
|
||||
|
||||
|
||||
|
||||
Intro
|
||||
-----
|
||||
This is a brief overview how to use GnuPG - it is highly suggested
|
||||
that you read the manual^H^H^H more information about the use
|
||||
of cryptography. GnuPG is only the technical tool to do it and
|
||||
the security highly depends on that YOU KNOW WHAT YOU ARE DOING.
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This is a brief overview how to use GnuPG - it is strongly suggested
|
||||
that you read the manual^H^H^H more information about the use of
|
||||
cryptography. GnuPG is only a tool, secure results require that YOU
|
||||
KNOW WHAT YOU ARE DOING.
|
||||
|
||||
If you already have a DSA key from PGP 5 (they call them DH/ElGamal)
|
||||
you can simply copy the pgp keyrings over the GnuPG keyrings after
|
||||
running gpg once, so that it can create the correct directory.
|
||||
running gpg once to create the correct directory.
|
||||
|
||||
The normal way to create a key is:
|
||||
The normal way to create a key is
|
||||
|
||||
gpg --gen-key
|
||||
gpg --gen-key
|
||||
|
||||
This asks some questions and then starts key generation. To create
|
||||
good random numbers for the key parameters, GnuPG needs to gather
|
||||
@ -98,209 +99,212 @@
|
||||
access - don't do it over the network or on a machine used also
|
||||
by others - especially if you have no access to the root account.
|
||||
|
||||
When you are asked for a passphrase; use a good one which you can easy
|
||||
remember. Don't make the passphrase too long because you have to
|
||||
type it for every decryption or signing; but - AND THIS IS VERY
|
||||
IMPORTANT - use a good one which is not easily guessable as the
|
||||
When you are asked for a passphrase use a good one which you can
|
||||
easy remember. Don't make the passphrase too long because you have
|
||||
to type it for every decryption or signing; but, - AND THIS IS VERY
|
||||
IMPORTANT - use a good one that is not easily to guess because the
|
||||
security of the whole system relies on your secret key and the
|
||||
passphrase is used to protect this secret key in case someone was
|
||||
able to get access to your secret keyring. A good way to select
|
||||
a passphrase is to figure out a short nonsense sentence which makes
|
||||
some sense for you and modify it by inserting extra spaces, non-letters
|
||||
and changing the case of some characters - this is really easy to
|
||||
remember especially if you associate some pictures with it.
|
||||
passphrase that protects it when someone gains access to your secret
|
||||
keyring. A good way to select a passphrase is to figure out a short
|
||||
nonsense sentence which makes some sense for you and modify it by
|
||||
inserting extra spaces, non-letters and changing the case of some
|
||||
characters - this is really easy to remember especially if you
|
||||
associate some pictures with it.
|
||||
|
||||
Then you should create a revocation certificate in case someone
|
||||
gets knowledge of your secret key or you forgot your passphrase:
|
||||
Next, you should create a revocation certificate in case someone
|
||||
gets knowledge of your secret key or you forgot your passphrase
|
||||
|
||||
gpg --gen-revoke your_user_id
|
||||
gpg --gen-revoke your_user_id
|
||||
|
||||
Run this command and store it away; output is always ASCII armored,
|
||||
so that you can print it and (hopefully never) re-create it if
|
||||
your electronic media fails.
|
||||
Run this command and store the revocation certificate away. The output
|
||||
is always ASCII armored, so that you can print it and (hopefully
|
||||
never) re-create it if your electronic media fails.
|
||||
|
||||
Now you can use your key to create digital signatures:
|
||||
Now you can use your key to create digital signatures
|
||||
|
||||
gpg -s file
|
||||
gpg -s file
|
||||
|
||||
This creates a file file.gpg which is compressed and has a signature
|
||||
attached.
|
||||
This creates a file "file.gpg" which is compressed and has a
|
||||
signature attached.
|
||||
|
||||
gpg -sa file
|
||||
gpg -sa file
|
||||
|
||||
Same as above, but creates the file.asc which is ascii armored and
|
||||
and ready for sending by mail. Note: It is better to use your
|
||||
Same as above, but creates a file "file.asc" which is ASCII armored
|
||||
and and ready for sending by mail. It is better to use your
|
||||
mailers features to create signatures (The mailer uses GnuPG to do
|
||||
this) because the mailer has the ability to MIME encode such
|
||||
signatures - but this is not a security issue.
|
||||
|
||||
gpg -s -o out file
|
||||
gpg -s -o out file
|
||||
|
||||
Creates a signature of file, but writes the output to the file "out".
|
||||
Creates a signature of "file", but writes the output to the file
|
||||
"out".
|
||||
|
||||
Everyone who knows your public key (you can and should publish
|
||||
your key by putting it on a key server, a web page or in your .plan
|
||||
file) is now able to check whether you really signed this text;
|
||||
file) is now able to check whether you really signed this text
|
||||
|
||||
gpg --verify file
|
||||
gpg --verify file
|
||||
|
||||
GnuPG now checks whether the signature is valid and prints an
|
||||
appropriate message. If the signature is good, you know at least
|
||||
that the person (or machine) has access to the secret key which
|
||||
corresponds to the published public key.
|
||||
|
||||
If you run gpg without an option it will verify the signature and
|
||||
create a new file which is identical to the original file. gpg
|
||||
can also run as a filter, so that you can pipe data to verify
|
||||
trough it:
|
||||
create a new file that is identical to the original. gpg can also
|
||||
run as a filter, so that you can pipe data to verify trough it
|
||||
|
||||
cat signed-file | gpg | wc -l
|
||||
cat signed-file | gpg | wc -l
|
||||
|
||||
will check the signature of signed-file and then display the
|
||||
which will check the signature of signed-file and then display the
|
||||
number of lines in the original file.
|
||||
|
||||
To send a message encrypted to someone you can use this:
|
||||
To send a message encrypted to someone you can use
|
||||
|
||||
gpg -e -r heine file
|
||||
gpg -e -r heine file
|
||||
|
||||
This encrypts file with the public key of the user "heine" and
|
||||
This encrypts "file" with the public key of the user "heine" and
|
||||
writes it to "file.gpg"
|
||||
|
||||
echo "hallo" | gpg -ea -r heine | mail heine
|
||||
echo "hello" | gpg -ea -r heine | mail heine
|
||||
|
||||
Ditto, but encrypts "hallo\n" and mails it as ascii armored message
|
||||
Ditto, but encrypts "hello\n" and mails it as ASCII armored message
|
||||
to the user with the mail address heine.
|
||||
|
||||
gpg -se -r heine file
|
||||
gpg -se -r heine file
|
||||
|
||||
This encrypts file with the public key of "heine" and writes it
|
||||
This encrypts "file" with the public key of "heine" and writes it
|
||||
to "file.gpg" after signing it with your user id.
|
||||
|
||||
gpg -se -r heine -u Suttner file
|
||||
gpg -se -r heine -u Suttner file
|
||||
|
||||
Ditto, but sign the file with your alternative user id "Suttner"
|
||||
|
||||
|
||||
GnuPG has some options to help you publish public keys; this is
|
||||
called "exporting" a key:
|
||||
GnuPG has some options to help you publish public keys. This is
|
||||
called "exporting" a key, thus
|
||||
|
||||
gpg --export >all-my-keys
|
||||
gpg --export >all-my-keys
|
||||
|
||||
exports all the keys in the keyring and writes them (in a binary format)
|
||||
to all-my-keys. You may then mail "all-my-keys" as an MIME attachment
|
||||
to someone else or put it on an FTP server. To export only some
|
||||
user IDs, you give them as arguments on the command line.
|
||||
exports all the keys in the keyring and writes them (in a binary
|
||||
format) to "all-my-keys". You may then mail "all-my-keys" as an
|
||||
MIME attachment to someone else or put it on an FTP server. To
|
||||
export only some user IDs, you give them as arguments on the command
|
||||
line.
|
||||
|
||||
To mail a public key or put it on a web page you have to create
|
||||
the key in ASCII armored format:
|
||||
the key in ASCII armored format
|
||||
|
||||
gpg --export --armor | mail panther@tiger.int
|
||||
gpg --export --armor | mail panther@tiger.int
|
||||
|
||||
This will send all your public keys to your friend panther.
|
||||
|
||||
If you have received a key from someone else you can put it
|
||||
into your public keyring; is called "importing":
|
||||
into your public keyring. This is called "importing"
|
||||
|
||||
gpg --import [filenames]
|
||||
gpg --import [filenames]
|
||||
|
||||
New keys are appended to your keyring and already existing
|
||||
keys are updated. Note that GnuPG does not allow keys which
|
||||
are not self-signed by the user.
|
||||
keys are updated. Note that GnuPG does not import keys that
|
||||
are not self-signed.
|
||||
|
||||
Because anyone can claim that the public key belongs to her
|
||||
we must have some way to check that the public key really belongs
|
||||
Because anyone can claim that a public key belongs to her
|
||||
we must have some way to check that a public key really belongs
|
||||
to the owner. This can be achieved by comparing the key during
|
||||
a phone call. Sure, it is not very easy to compare a binary file
|
||||
by reading the complete hex dump of the file - GnuPG (and nearly
|
||||
every other program used for management of cryptographic keys)
|
||||
provides other solutions:
|
||||
provides other solutions.
|
||||
|
||||
gpg --fingerprint <username>
|
||||
gpg --fingerprint <username>
|
||||
|
||||
prints the so called "fingerprint" of the given username; this
|
||||
prints the so called "fingerprint" of the given username which
|
||||
is a sequence of hex bytes (which you may have noticed in mail
|
||||
sigs or on business cards) which uniquely identify the public
|
||||
key - two different keys will always have different fingerprints.
|
||||
It is easy to compare this fingerprint by phone and I suggest
|
||||
sigs or on business cards) that uniquely identifies the public
|
||||
key - different keys will always have different fingerprints.
|
||||
It is easy to compare fingerprints by phone and I suggest
|
||||
that you print your fingerprint on the back of your business
|
||||
card.
|
||||
|
||||
If you don't know the owner of the public key you are in trouble;
|
||||
but wait: A friend of you knows someone who knows someone who
|
||||
has met the owner of the public key at some computer conference.
|
||||
So all the persons between you and the public key holder may now
|
||||
act as introducer to you; this is done by signing the keys and
|
||||
thereby certifying the other keys. If you then trust all the
|
||||
introducers to correctly sign other keys, you can be be sure that
|
||||
the other key really belongs to the one who claims so.
|
||||
If you don't know the owner of the public key you are in trouble.
|
||||
Suppose however that friend of yours knows someone who knows someone
|
||||
who has met the owner of the public key at some computer conference.
|
||||
Suppose that all the people between you and the public key holder
|
||||
may now act as introducers to you. Introducers signing keys thereby
|
||||
certify that they know the owner of the keys they sign. If you then
|
||||
trust all the introducers to have correctly signed other keys, you
|
||||
can be be sure that the other key really belongs to the one who
|
||||
claims to own it..
|
||||
|
||||
There are 2 steps to validate a target key:
|
||||
1. First check that there is a complete chain
|
||||
of signed keys from the public key you want to use
|
||||
and your key and verify each signature.
|
||||
2. Make sure that you have full trust in the certificates
|
||||
of all the introduces between the public key holder and
|
||||
you.
|
||||
There are 2 steps to validate a key:
|
||||
1. First check that there is a complete chain
|
||||
of signed keys from the public key you want to use
|
||||
and your key and verify each signature.
|
||||
2. Make sure that you have full trust in the certificates
|
||||
of all the introduces between the public key holder and
|
||||
you.
|
||||
Step 2 is the more complicated part because there is no easy way
|
||||
for a computer to decide who is trustworthy and who is not. GnuPG
|
||||
leaves this decision to you and will ask you for a trust value
|
||||
(here also referenced as the owner-trust of a key) for every key
|
||||
needed to check the chain of certificates. You may choose from:
|
||||
needed to check the chain of certificates. You may choose from:
|
||||
a) "I don't know" - then it is not possible to use any
|
||||
of the chains of certificates, in which this key is used
|
||||
as an introducer, to validate the target key. Use this if
|
||||
you don't know the introducer.
|
||||
of the chains of certificates, in which this key is used
|
||||
as an introducer, to validate the target key. Use this if
|
||||
you don't know the introducer.
|
||||
b) "I do not trust" - Use this if you know that the introducer
|
||||
does not do a good job in certifying other keys. The effect
|
||||
is the same as with a) but for a) you may later want to
|
||||
change the value because you got new information about this
|
||||
introducer.
|
||||
does not do a good job in certifying other keys. The effect
|
||||
is the same as with a) but for a) you may later want to
|
||||
change the value because you got new information about this
|
||||
introducer.
|
||||
c) "I trust marginally" - Use this if you assume that the
|
||||
introducer knows what he is doing. Together with some
|
||||
other marginally trusted keys, GnuPG validates the target
|
||||
key then as good.
|
||||
introducer knows what he is doing. Together with some
|
||||
other marginally trusted keys, GnuPG validates the target
|
||||
key then as good.
|
||||
d) "I fully trust" - Use this if you really know that this
|
||||
introducer does a good job when certifying other keys.
|
||||
If all the introducer are of this trust value, GnuPG
|
||||
normally needs only one chain of signatures to validate
|
||||
a target key okay. (But this may be adjusted with the help
|
||||
of some options).
|
||||
These information are confidential because they give your
|
||||
personal opinion on the trustworthy of someone else. Therefore
|
||||
this data is not stored in the keyring but in the "trustdb"
|
||||
introducer does a good job when certifying other keys.
|
||||
If all the introducer are of this trust value, GnuPG
|
||||
normally needs only one chain of signatures to validate
|
||||
a target key okay. (But this may be adjusted with the help
|
||||
of some options).
|
||||
This information is confidential because it gives your personal
|
||||
opinion on the trustworthiness of someone else. Therefore this data
|
||||
is not stored in the keyring but in the "trustdb"
|
||||
(~/.gnupg/trustdb.gpg). Do not assign a high trust value just
|
||||
because the introducer is a friend of you - decide how far she
|
||||
understands all the implications of key signatures and you may
|
||||
want to tell him more about public key cryptography so you
|
||||
can later change the trust value you assigned.
|
||||
because the introducer is a friend of yours - decide how well she
|
||||
understands the implications of key signatures and you may want to
|
||||
tell her more about public key cryptography so you can later change
|
||||
the trust value you assigned.
|
||||
|
||||
Okay, here is how GnuPG helps you in key management: Most stuff is
|
||||
done with the --edit-key command:
|
||||
Okay, here is how GnuPG helps you with key management. Most stuff
|
||||
is done with the --edit-key command
|
||||
|
||||
gpg --edit-key <keyid or username>
|
||||
gpg --edit-key <keyid or username>
|
||||
|
||||
GnuPG displays some information about the key and then prompts
|
||||
for a command (enter "help" to see a list of commands and see
|
||||
the man page for a more detailed explanation). To sign a key
|
||||
you select the user ID you want to sign by entering the number
|
||||
which is displayed in the leftmost column (or do nothing if the
|
||||
that is displayed in the leftmost column (or do nothing if the
|
||||
key has only one user ID) and then enter the command "sign" and
|
||||
follow all the prompts. When you are ready, give the command
|
||||
"save" (or use "quit" to cancel your actions).
|
||||
|
||||
If you want to sign the key with another user ID of yours, you
|
||||
If you want to sign the key with another of your user IDs, you
|
||||
must give an "-u" option on the command line together with the
|
||||
"--edit-key".
|
||||
|
||||
Normally you want to sign only one user ID because GnuPG
|
||||
does only use one and this keeps the public key certificate
|
||||
uses only one and this keeps the public key certificate
|
||||
small. Because such key signatures are very important you
|
||||
should make sure that the signators of your key sign a user ID
|
||||
should make sure that the signatories of your key sign a user ID
|
||||
which is very likely to stay for a long time - choose one with an
|
||||
email address you have full control of or do not enter an email
|
||||
address at all. In future GnuPG will have a way to tell which
|
||||
user ID is the one with an email address you prefer - because
|
||||
you have no signatures on this email address it is easy to change
|
||||
this address. Remember: Your signators sign your public key (the
|
||||
this address. Remember, your signatories sign your public key (the
|
||||
primary one) together with one of your user IDs - so it is not possible
|
||||
to change the user ID later without voiding all the signatures.
|
||||
|
||||
@ -310,51 +314,59 @@
|
||||
trust you assign to a key).
|
||||
|
||||
|
||||
7 Ways to Specify a User ID
|
||||
8 Ways to Specify a User ID
|
||||
--------------------------
|
||||
There are several ways to specify a user ID, here are some examples:
|
||||
There are several ways to specify a user ID, here are some examples.
|
||||
|
||||
* Only by the short keyid (prepend a zero if it begins with A..F):
|
||||
|
||||
"234567C4"
|
||||
"0F34E556E"
|
||||
"01347A56A"
|
||||
"0xAB123456
|
||||
"234567C4"
|
||||
"0F34E556E"
|
||||
"01347A56A"
|
||||
"0xAB123456
|
||||
|
||||
* By a complete keyid:
|
||||
|
||||
"234AABBCC34567C4"
|
||||
"0F323456784E56EAB"
|
||||
"01AB3FED1347A5612"
|
||||
"0x234AABBCC34567C4"
|
||||
"234AABBCC34567C4"
|
||||
"0F323456784E56EAB"
|
||||
"01AB3FED1347A5612"
|
||||
"0x234AABBCC34567C4"
|
||||
|
||||
* By a fingerprint:
|
||||
|
||||
"1234343434343434C434343434343434"
|
||||
"123434343434343C3434343434343734349A3434"
|
||||
"0E12343434343434343434EAB3484343434343434"
|
||||
"1234343434343434C434343434343434"
|
||||
"123434343434343C3434343434343734349A3434"
|
||||
"0E12343434343434343434EAB3484343434343434"
|
||||
|
||||
The first one is MD5 the others are ripemd160 or sha1.
|
||||
|
||||
* By an exact string:
|
||||
|
||||
"=Heinrich Heine <heinrichh@uni-duesseldorf.de>"
|
||||
"=Heinrich Heine <heinrichh@uni-duesseldorf.de>"
|
||||
|
||||
* By an email address:
|
||||
|
||||
"<heinrichh@uni-duesseldorf.de>"
|
||||
"<heinrichh@uni-duesseldorf.de>"
|
||||
|
||||
* By word match
|
||||
|
||||
"+Heinrich Heine duesseldorf"
|
||||
|
||||
All words must match excatly (not case sensitive) and appear in
|
||||
any order in the user ID. Words are any sequences of letters,
|
||||
digits, the underscore and characters with bit 7 set.
|
||||
|
||||
* By the Local ID (from the trust DB):
|
||||
|
||||
"#34"
|
||||
"#34"
|
||||
|
||||
This may be used by a MUA to specify an exact key after selecting
|
||||
a key from GnuPG (by the use of a special option or an extra utility)
|
||||
a key from GnuPG (by using a special option or an extra utility)
|
||||
|
||||
* Or by the usual substring:
|
||||
|
||||
"Heine"
|
||||
"*Heine"
|
||||
"Heine"
|
||||
"*Heine"
|
||||
|
||||
The '*' indicates substring search explicitly.
|
||||
|
||||
@ -363,7 +375,7 @@
|
||||
----------
|
||||
If you use the option "--batch", GnuPG runs in non-interactive mode and
|
||||
never prompts for input data. This does not even allow entering the
|
||||
passphrase; until we have a better solution (something like ssh-agent),
|
||||
passphrase. Until we have a better solution (something like ssh-agent),
|
||||
you can use the option "--passphrase-fd n", which works like PGPs
|
||||
PGPPASSFD.
|
||||
|
||||
@ -375,29 +387,29 @@
|
||||
-----------
|
||||
GnuPG returns with an exit status of 1 if in batch mode and a bad signature
|
||||
has been detected or 2 or higher for all other errors. You should parse
|
||||
stderr or better the output of the fd specified with --status-fd to get
|
||||
stderr or, better, the output of the fd specified with --status-fd to get
|
||||
detailed information about the errors.
|
||||
|
||||
|
||||
Esoteric commands
|
||||
-----------------
|
||||
|
||||
gpg --list-packets datafile
|
||||
gpg --list-packets datafile
|
||||
|
||||
Use this to list the contents of a data file. If the file is encrypted
|
||||
you are asked for the passphrase, so that GnuPG is able to look at the
|
||||
inner structure of a encrypted packet. This command should be able
|
||||
to list all kinds of rfc2440 messages.
|
||||
inner structure of a encrypted packet. This command should list all
|
||||
kinds of rfc2440 messages.
|
||||
|
||||
gpgm --list-trustdb
|
||||
gpgm --list-trustdb
|
||||
|
||||
List the contents of the trust DB in a human readable format
|
||||
|
||||
gpgm --list-trustdb <usernames>
|
||||
gpgm --list-trustdb <usernames>
|
||||
|
||||
List the tree of certificates for the given usernames
|
||||
|
||||
gpgm --list-trust-path username
|
||||
gpgm --list-trust-path username
|
||||
|
||||
List the possible trust paths for the given username. The length
|
||||
of such a trust path is limited by the option --max-cert-depth
|
||||
@ -415,22 +427,21 @@
|
||||
See http://www.gnupg.org/mirrors.html for a list of FTP mirrors
|
||||
and use them if possible.
|
||||
|
||||
Please direct bug reports to <gnupg-bugs@gnu.org> or better
|
||||
Please direct bug reports to <gnupg-bugs@gnu.org> or, better,
|
||||
post them to the mailing list <g10@net.lut.ac.uk> (this is a
|
||||
closed list - subscribe before posting, see above (~line 33)).
|
||||
Please direct questions about GnuPG to the mailing list or
|
||||
one of the pgp newsgroups; this gives me more time to improve
|
||||
one of the pgp newsgroups and give me more time to improve
|
||||
GnuPG. Commercial support for GnuPG will be available soon.
|
||||
|
||||
Have fun and remember: Echelon is looking at you kid.
|
||||
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v0.9.1 (GNU/Linux)
|
||||
Version: GnuPG v0.9.2 (GNU/Linux)
|
||||
Comment: For info see http://www.gnupg.org
|
||||
|
||||
iQB1AwUBNpyIDR0Z9MEMmFelAQGn4gL+IVlEye5I6LplxdUExsrHQpLV21H0UXFa
|
||||
/Dl1T/HjrGHj41NeW2evO4Ck2K6Z0TG5jPg9CuJdcJp0siJ8odO7BTLaF3r6gwxF
|
||||
CA4EXgqhSyE8PXRPS4m4M5I7Ru/bsZrF
|
||||
=HfE0
|
||||
iQB1AwUBNr2fPh0Z9MEMmFelAQHqNAL/e7pApR0CGUJ/zuIsjaVhNGPEgKAglcEd
|
||||
YuVdB+RCN0wq7ZfI0AHU2FdVISRACmSN3xituTTgeiOUsczM40EZ4l1XNfyRF768
|
||||
fglui6XxEeYHFY7mSQMgzzFWDG0Squx0
|
||||
=enRo
|
||||
-----END PGP SIGNATURE-----
|
||||
|
9
TODO
9
TODO
@ -8,8 +8,13 @@ Bugs
|
||||
|
||||
* clearsign bug Greg Troxel Jan 11.
|
||||
|
||||
* README does not verify okay. verify inserts an extra CR,LF
|
||||
just before "Esoteric Command" (after ~8k of text).
|
||||
|
||||
Important
|
||||
----------
|
||||
* replace gettext by a non exploitable one.
|
||||
|
||||
* Check revocation and expire stuff. PLEASE: THIS MUST BE TESTED!
|
||||
|
||||
* Check calculation of key validity. PLEASE: IT IS IMPORTED THAT
|
||||
@ -34,6 +39,8 @@ Needed
|
||||
-Wl,-export-dynamic flag from my Makefile and it linked and seems to
|
||||
be working OK so far.
|
||||
|
||||
* Use capabilities if available.
|
||||
|
||||
|
||||
Minor Bugs
|
||||
----------
|
||||
@ -56,7 +63,7 @@ Nice to have
|
||||
really make sense?
|
||||
* change the fake_data stuff to mpi_set_opaque
|
||||
* How about letting something like 'gpg --version -v', list the
|
||||
effective options.
|
||||
effective options. Too much work.
|
||||
* Stats about used random numbers.
|
||||
|
||||
|
||||
|
14
acconfig.h
14
acconfig.h
@ -32,6 +32,7 @@
|
||||
#undef VERSION
|
||||
#undef PACKAGE
|
||||
#undef PRINTABLE_OS_NAME
|
||||
#undef IS_DEVELOPMENT_VERSION
|
||||
|
||||
/* Define if your locale.h file contains LC_MESSAGES. */
|
||||
#undef HAVE_LC_MESSAGES
|
||||
@ -64,14 +65,6 @@
|
||||
|
||||
#undef HAVE_BROKEN_MLOCK
|
||||
|
||||
/* One of the following macros is defined to select which of
|
||||
* the cipher/rndxxxx.c is linked into the program */
|
||||
#undef USE_RNDLINUX
|
||||
#undef USE_RNDUNIX
|
||||
#undef USE_RNDOS2
|
||||
#undef USE_RNDATARI
|
||||
#undef USE_RNDW32
|
||||
#undef USE_RNDMVS
|
||||
/* defined if we have a /dev/random and /dev/urandom */
|
||||
#undef HAVE_DEV_RANDOM
|
||||
/* and the real names of the random devices */
|
||||
@ -92,6 +85,11 @@
|
||||
#undef USE_ONLY_8DOT3
|
||||
/* defined if we must run on a stupid file system */
|
||||
#undef HAVE_DRIVE_LETTERS
|
||||
/* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
|
||||
* with special properties like no file modes */
|
||||
#undef HAVE_DOSISH_SYSTEM
|
||||
|
||||
|
||||
|
||||
@BOTTOM@
|
||||
|
||||
|
65
acinclude.m4
65
acinclude.m4
@ -1,4 +1,4 @@
|
||||
dnl macros to configure g10
|
||||
dnl macros to configure g10 7cache_va
|
||||
|
||||
|
||||
dnl GNUPG_MSG_PRINT(STRING)
|
||||
@ -203,6 +203,9 @@ define(GNUPG_CHECK_RDYNAMIC,
|
||||
solaris*)
|
||||
CFLAGS_RDYNAMIC="-Wl,-dy"
|
||||
;;
|
||||
freebsd2*)
|
||||
CFLAGS_RDYNAMIC=""
|
||||
;;
|
||||
*)
|
||||
CFLAGS_RDYNAMIC="-Wl,-export-dynamic"
|
||||
;;
|
||||
@ -221,8 +224,9 @@ dnl
|
||||
define(GNUPG_CHECK_IPC,
|
||||
[ AC_CHECK_HEADERS(sys/ipc.h sys/shm.h)
|
||||
if test "$ac_cv_header_sys_shm_h" = "yes"; then
|
||||
AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
|
||||
AC_TRY_RUN([
|
||||
AC_MSG_CHECKING(whether IPC_RMID allowes subsequent attaches)
|
||||
AC_CACHE_VAL(gnupg_cv_ipc_rmid_deferred_release,
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
@ -245,19 +249,38 @@ define(GNUPG_CHECK_IPC,
|
||||
exit (0);
|
||||
}
|
||||
],
|
||||
AC_DEFINE(IPC_RMID_DEFERRED_RELEASE)
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no),
|
||||
AC_MSG_RESULT(assuming no))
|
||||
gnupg_cv_ipc_rmid_deferred_release="yes",
|
||||
gnupg_cv_ipc_rmid_deferred_release="no",
|
||||
gnupg_cv_ipc_rmid_deferred_release="assume-no")
|
||||
)
|
||||
if test "$gnupg_cv_ipc_rmid_deferred_release" = "yes"; then
|
||||
AC_DEFINE(IPC_RMID_DEFERRED_RELEASE)
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gnupg_cv_ipc_rmid_deferred_release" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT([assuming no])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether SHM_LOCK is available)
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
AC_CACHE_VAL(gnupg_cv_ipc_have_shm_lock,
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>],[
|
||||
int foo( int shm_id ) { shmctl(shm_id, SHM_LOCK, 0); }
|
||||
],
|
||||
gnupg_cv_ipc_have_shm_lock="yes",
|
||||
gnupg_cv_ipc_have_shm_lock="no"
|
||||
)
|
||||
)
|
||||
if test "$gnupg_cv_ipc_have_shm_lock" = "yes"; then
|
||||
AC_DEFINE(IPC_HAVE_SHM_LOCK)
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no))
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
@ -272,7 +295,8 @@ define(GNUPG_CHECK_MLOCK,
|
||||
[ AC_CHECK_FUNCS(mlock)
|
||||
if test "$ac_cv_func_mlock" = "yes"; then
|
||||
AC_MSG_CHECKING(whether mlock is broken)
|
||||
AC_TRY_RUN([
|
||||
AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
|
||||
AC_TRY_RUN([
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@ -299,10 +323,21 @@ define(GNUPG_CHECK_MLOCK,
|
||||
}
|
||||
|
||||
],
|
||||
AC_MSG_RESULT(no),
|
||||
AC_DEFINE(HAVE_BROKEN_MLOCK)
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(assuming no))
|
||||
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)
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gnupg_cv_have_broken_mlock" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(assuming no)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* Makefile.am: Modules are now figured out by configure
|
||||
* construct.c: New. Generated by configure. Changed all modules
|
||||
to work with that.
|
||||
* sha1.h: Removed.
|
||||
* md5.h: Removed.
|
||||
|
||||
* twofish.c: Changed interface to allow Twofish/256
|
||||
|
||||
* rndunix.c (start_gatherer): Die on SIGPIPE.
|
||||
|
||||
Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* rndunix.c (gather_random): Fix to avoid infinite loop.
|
||||
|
@ -1,12 +1,33 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
|
||||
noinst_LIBRARIES = libcipher.a
|
||||
|
||||
EXTRA_PROGRAMS = tiger twofish rndunix rndlinux
|
||||
# The configure script greps the module names from the following lines.
|
||||
# You must also add all these names to EXTRA_PROGRAMS some lines below
|
||||
# and EXTRA_foo_SOURCES entries.
|
||||
# Hmmm is there a more easy way to do this? (EXTRA_PROGRAMS
|
||||
# might also list programs which are not modules)
|
||||
# MODULES: rndunix rndlinux
|
||||
# MODULES: sha1 rmd160 md5 tiger
|
||||
# MODULES: twofish
|
||||
EXTRA_PROGRAMS = rndunix rndlinux \
|
||||
sha1 rmd160 md5 tiger \
|
||||
twofish
|
||||
|
||||
EXTRA_rndlinux_SOURCES = rndlinux.c
|
||||
EXTRA_rndunix_SOURCES = rndunix.c
|
||||
EXTRA_md5_SOURCES = md5.c
|
||||
EXTRA_rmd160_SOURCES = rmd160.c
|
||||
EXTRA_sha1_SOURCES = sha1.c
|
||||
EXTRA_tiger_SOURCES = tiger.c
|
||||
EXTRA_twofish_SOURCES = twofish.c
|
||||
|
||||
|
||||
if ENABLE_GNUPG_EXTENSIONS
|
||||
pkglib_PROGRAMS = @DYNAMIC_CIPHER_MODS@ @DYNAMIC_RANDOM_MODS@
|
||||
pkglib_PROGRAMS = @DYNAMIC_CIPHER_MODS@
|
||||
else
|
||||
pkglib_PROGRAMS =
|
||||
endif
|
||||
@ -27,37 +48,41 @@ libcipher_a_SOURCES = cipher.c \
|
||||
cast5.h \
|
||||
elgamal.c \
|
||||
elgamal.h \
|
||||
md5.c \
|
||||
md5.h \
|
||||
primegen.c \
|
||||
random.h \
|
||||
random.c \
|
||||
rand-internal.h \
|
||||
rmd.h \
|
||||
rmd160.c \
|
||||
sha1.h \
|
||||
sha1.c \
|
||||
dsa.h \
|
||||
dsa.c \
|
||||
g10c.c \
|
||||
smallprime.c
|
||||
smallprime.c \
|
||||
construct.c
|
||||
|
||||
# configure creates the constructor file
|
||||
BUILT_SOURCES = construct.c
|
||||
|
||||
|
||||
EXTRA_libcipher_a_SOURCES = rndlinux.c rndunix.c
|
||||
EXTRA_tiger_SOURCES = tiger.c
|
||||
EXTRA_twofish_SOURCES = twofish.c
|
||||
libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@
|
||||
libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@
|
||||
|
||||
libcipher_a_DEPENDENCIES = @STATIC_RANDOM_OBJS@ @STATIC_CIPHER_OBJS@
|
||||
libcipher_a_LIBADD = @STATIC_RANDOM_OBJS@ @STATIC_CIPHER_OBJS@
|
||||
|
||||
# If I remember it correct, automake 1.4 has a feature to set
|
||||
# fooFLAGS depending on the program. So we should check it out.
|
||||
|
||||
tiger: $(srcdir)/tiger.c
|
||||
`echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
|
||||
sed -e 's/-O[2-9]*/-O1/' `
|
||||
sed -e 's/-O[2-9]*/-O1/g' `
|
||||
|
||||
tiger.o: $(srcdir)/tiger.c
|
||||
`echo $(COMPILE) $(srcdir)/tiger.c | sed -e 's/-O[2-9]*/-O1/g' `
|
||||
|
||||
twofish: $(srcdir)/twofish.c
|
||||
`echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \
|
||||
sed -e 's/-O[0-9]*/ /' `
|
||||
sed -e 's/-O[0-9]*/ /g' `
|
||||
|
||||
twofish.o: $(srcdir)/twofish.c
|
||||
`echo $(COMPILE) $(srcdir)/twofish.c | sed -e 's/-O[0-9]*/ /g' `
|
||||
|
||||
|
||||
rndunix: $(srcdir)/rndunix.c
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "types.h"
|
||||
#include "errors.h"
|
||||
#include "blowfish.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
||||
|
||||
|
@ -18,8 +18,6 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#define DEFINES_CIPHER_HANDLE 1
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -160,6 +158,7 @@ load_cipher_modules()
|
||||
int any = 0;
|
||||
|
||||
if( !initialized ) {
|
||||
cipher_modules_constructor();
|
||||
setup_cipher_table(); /* load static modules on the first call */
|
||||
initialized = 1;
|
||||
return 1;
|
||||
|
@ -66,6 +66,7 @@ typedef struct {
|
||||
int seq1;
|
||||
int seq2;
|
||||
void *sym;
|
||||
int reqalgo;
|
||||
} ENUMCONTEXT;
|
||||
|
||||
|
||||
@ -323,6 +324,7 @@ enum_gnupgext_digests( void **enum_context,
|
||||
if( !*enum_context ) { /* init context */
|
||||
ctx = m_alloc_clear( sizeof( *ctx ) );
|
||||
ctx->r = extensions;
|
||||
ctx->reqalgo = *algo;
|
||||
*enum_context = ctx;
|
||||
}
|
||||
else if( !algo ) { /* release the context */
|
||||
@ -333,6 +335,7 @@ enum_gnupgext_digests( void **enum_context,
|
||||
else
|
||||
ctx = *enum_context;
|
||||
|
||||
/* fixme: have a look at the hint string */
|
||||
for( r = ctx->r; r; r = r->next ) {
|
||||
int class, vers;
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#ifndef G10_CIPHER_DYNLOAD_H
|
||||
#define G10_CIPHER_DYNLOAD_H
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
|
||||
void register_internal_cipher_extension( const char *module_id,
|
||||
void * (*enumfunc)(int, int*, int*, int*) );
|
||||
@ -60,4 +62,7 @@ void (*dynload_getfnc_fast_random_poll(void)
|
||||
)( void (*)(const void*, size_t, int), int );
|
||||
|
||||
|
||||
/** This function is in construct.c **/
|
||||
void cipher_modules_constructor(void);
|
||||
|
||||
#endif /*G10_CIPHER_DYNLOAD_H*/
|
||||
|
65
cipher/md.c
65
cipher/md.c
@ -18,8 +18,6 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#define DEFINES_MD_HANDLE 1
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -30,8 +28,6 @@
|
||||
#include "cipher.h"
|
||||
#include "errors.h"
|
||||
#include "dynload.h"
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "rmd.h"
|
||||
|
||||
|
||||
@ -57,7 +53,6 @@ struct md_digest_list_s {
|
||||
static struct md_digest_list_s *digest_list;
|
||||
|
||||
|
||||
|
||||
static struct md_digest_list_s *
|
||||
new_list_item( int algo,
|
||||
const char *(*get_info)( int, size_t*,byte**, int*, int*,
|
||||
@ -79,33 +74,19 @@ new_list_item( int algo,
|
||||
return r;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Put the static entries into the table.
|
||||
*/
|
||||
static void
|
||||
setup_digest_list()
|
||||
{
|
||||
struct md_digest_list_s *r;
|
||||
|
||||
r = new_list_item( DIGEST_ALGO_MD5, md5_get_info );
|
||||
if( r ) { r->next = digest_list; digest_list = r; }
|
||||
|
||||
r = new_list_item( DIGEST_ALGO_RMD160, rmd160_get_info );
|
||||
if( r ) { r->next = digest_list; digest_list = r; }
|
||||
|
||||
r = new_list_item( DIGEST_ALGO_SHA1, sha1_get_info );
|
||||
if( r ) { r->next = digest_list; digest_list = r; }
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Try to load all modules and return true if new modules are available
|
||||
* Try to load the modules with the requeste algorithm
|
||||
* and return true if new modules are available
|
||||
* If req_alog is -1 try to load all digest algorithms.
|
||||
*/
|
||||
static int
|
||||
load_digest_modules()
|
||||
load_digest_module( int req_algo )
|
||||
{
|
||||
static int done = 0;
|
||||
static int initialized = 0;
|
||||
static u32 checked_algos[256/32];
|
||||
static int checked_all = 0;
|
||||
struct md_digest_list_s *r;
|
||||
void *context = NULL;
|
||||
int algo;
|
||||
@ -116,16 +97,24 @@ load_digest_modules()
|
||||
void (**)(void*),byte *(**)(void*));
|
||||
|
||||
if( !initialized ) {
|
||||
setup_digest_list(); /* load static modules on the first call */
|
||||
cipher_modules_constructor();
|
||||
initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( done )
|
||||
return 0;
|
||||
done = 1;
|
||||
algo = req_algo;
|
||||
if( algo > 255 || !algo )
|
||||
return 0; /* algorithm number too high (does not fit into out bitmap)*/
|
||||
if( checked_all )
|
||||
return 0; /* already called with -1 */
|
||||
if( algo < 0 )
|
||||
checked_all = 1;
|
||||
else if( (checked_algos[algo/32] & (1 << (algo%32))) )
|
||||
return 0; /* already checked and not found */
|
||||
else
|
||||
checked_algos[algo/32] |= (1 << (algo%32));
|
||||
|
||||
while( enum_gnupgext_digests( &context, &algo, &get_info ) ) {
|
||||
if( req_algo != -1 && algo != req_algo )
|
||||
continue;
|
||||
for(r=digest_list; r; r = r->next )
|
||||
if( r->algo == algo )
|
||||
break;
|
||||
@ -144,6 +133,8 @@ load_digest_modules()
|
||||
r->next = digest_list;
|
||||
digest_list = r;
|
||||
any = 1;
|
||||
if( req_algo != -1 )
|
||||
break;
|
||||
}
|
||||
enum_gnupgext_digests( &context, NULL, NULL );
|
||||
return any;
|
||||
@ -163,7 +154,7 @@ string_to_digest_algo( const char *string )
|
||||
for(r = digest_list; r; r = r->next )
|
||||
if( !stricmp( r->name, string ) )
|
||||
return r->algo;
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module(-1) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -180,7 +171,7 @@ digest_algo_to_string( int algo )
|
||||
for(r = digest_list; r; r = r->next )
|
||||
if( r->algo == algo )
|
||||
return r->name;
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module( algo ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -194,7 +185,7 @@ check_digest_algo( int algo )
|
||||
for(r = digest_list; r; r = r->next )
|
||||
if( r->algo == algo )
|
||||
return 0;
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module(algo) );
|
||||
return G10ERR_DIGEST_ALGO;
|
||||
}
|
||||
|
||||
@ -241,7 +232,7 @@ md_enable( MD_HANDLE h, int algo )
|
||||
for(r = digest_list; r; r = r->next )
|
||||
if( r->algo == algo )
|
||||
break;
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module( algo ) );
|
||||
if( !r ) {
|
||||
log_error("md_enable: algorithm %d not available\n", algo );
|
||||
return;
|
||||
@ -456,7 +447,7 @@ md_digest_length( int algo )
|
||||
if( r->algo == algo )
|
||||
return r->mdlen;
|
||||
}
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module( algo ) );
|
||||
log_error("WARNING: no length for md algo %d\n", algo);
|
||||
return 0;
|
||||
}
|
||||
@ -479,7 +470,7 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
|
||||
return r->asnoid;
|
||||
}
|
||||
}
|
||||
} while( !r && load_digest_modules() );
|
||||
} while( !r && load_digest_module( algo ) );
|
||||
log_bug("no asn for md algo %d\n", algo);
|
||||
return NULL;
|
||||
}
|
||||
|
57
cipher/md5.c
57
cipher/md5.c
@ -34,8 +34,8 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "md5.h"
|
||||
#include "memory.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -338,7 +338,7 @@ md5_read( MD5_CONTEXT *hd )
|
||||
* Returns: A pointer to string describing the algorithm or NULL if
|
||||
* the ALGO is invalid.
|
||||
*/
|
||||
const char *
|
||||
static const char *
|
||||
md5_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
@ -367,5 +367,58 @@ md5_get_info( int algo, size_t *contextsize,
|
||||
}
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
const char * const gnupgext_version = "MD5 ($Revision$)";
|
||||
|
||||
static struct {
|
||||
int class;
|
||||
int version;
|
||||
int value;
|
||||
void (*func)(void);
|
||||
} func_table[] = {
|
||||
{ 10, 1, 0, (void(*)(void))md5_get_info },
|
||||
{ 11, 1, 1 },
|
||||
};
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
void *
|
||||
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
{
|
||||
void *ret;
|
||||
int i = *sequence;
|
||||
|
||||
do {
|
||||
if( i >= DIM(func_table) || i < 0 )
|
||||
return NULL;
|
||||
*class = func_table[i].class;
|
||||
*vers = func_table[i].version;
|
||||
switch( *class ) {
|
||||
case 11: case 21: case 31: ret = &func_table[i].value; break;
|
||||
default: ret = func_table[i].func; break;
|
||||
}
|
||||
i++;
|
||||
} while( what && what != *class );
|
||||
|
||||
*sequence = i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
void
|
||||
md5_constructor(void)
|
||||
{
|
||||
register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
34
cipher/md5.h
34
cipher/md5.h
@ -1,34 +0,0 @@
|
||||
/* md5.h - message digest 5
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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_MD5_H
|
||||
#define G10_MD5_H
|
||||
|
||||
|
||||
const char *
|
||||
md5_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asn_len, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
void (**r_write)( void *c, byte *buf, size_t nbytes ),
|
||||
void (**r_final)( void *c ),
|
||||
byte *(**r_read)( void *c )
|
||||
);
|
||||
|
||||
|
||||
#endif /*G10_MD5_H*/
|
@ -170,6 +170,7 @@ load_pubkey_modules()
|
||||
|
||||
|
||||
if( !initialized ) {
|
||||
cipher_modules_constructor();
|
||||
setup_pubkey_table();
|
||||
initialized = 1;
|
||||
return 1;
|
||||
|
@ -116,16 +116,7 @@ initialize()
|
||||
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
|
||||
: m_alloc_clear(POOLSIZE+BLOCKLEN);
|
||||
is_initialized = 1;
|
||||
|
||||
#if USE_RNDLINUX
|
||||
rndlinux_constructor();
|
||||
#elif USE_RNDUNIX
|
||||
rndunix_constructor();
|
||||
#elif USE_RNDW32
|
||||
#elif USE_RNDOS2
|
||||
#elif USE_RNDATARI
|
||||
#elif USE_RNDMVS
|
||||
#endif
|
||||
cipher_modules_constructor();
|
||||
}
|
||||
|
||||
void
|
||||
|
12
cipher/rmd.h
12
cipher/rmd.h
@ -32,16 +32,4 @@ typedef struct {
|
||||
void rmd160_init( RMD160_CONTEXT *hd );
|
||||
void rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer );
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
rmd160_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asn_len, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
void (**r_write)( void *c, byte *buf, size_t nbytes ),
|
||||
void (**r_final)( void *c ),
|
||||
byte *(**r_read)( void *c )
|
||||
);
|
||||
|
||||
|
||||
#endif /*G10_RMD_H*/
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "memory.h"
|
||||
#include "rmd.h"
|
||||
#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
|
||||
#include "dynload.h"
|
||||
|
||||
/*********************************
|
||||
* RIPEMD-160 is not patented, see (as of 25.10.97)
|
||||
@ -554,7 +555,7 @@ rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
|
||||
* Returns: A pointer to string describing the algorithm or NULL if
|
||||
* the ALGO is invalid.
|
||||
*/
|
||||
const char *
|
||||
static const char *
|
||||
rmd160_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
@ -582,3 +583,63 @@ rmd160_get_info( int algo, size_t *contextsize,
|
||||
return "RIPEMD160";
|
||||
}
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
const char * const gnupgext_version = "RMD160 ($Revision$)";
|
||||
|
||||
static struct {
|
||||
int class;
|
||||
int version;
|
||||
int value;
|
||||
void (*func)(void);
|
||||
} func_table[] = {
|
||||
{ 10, 1, 0, (void(*)(void))rmd160_get_info },
|
||||
{ 11, 1, 3 },
|
||||
};
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
void *
|
||||
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
{
|
||||
void *ret;
|
||||
int i = *sequence;
|
||||
|
||||
do {
|
||||
if( i >= DIM(func_table) || i < 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
*class = func_table[i].class;
|
||||
*vers = func_table[i].version;
|
||||
switch( *class ) {
|
||||
case 11:
|
||||
case 21:
|
||||
case 31:
|
||||
ret = &func_table[i].value;
|
||||
break;
|
||||
default:
|
||||
ret = func_table[i].func;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} while( what && what != *class );
|
||||
|
||||
*sequence = i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
void
|
||||
rmd160_constructor(void)
|
||||
{
|
||||
register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -642,6 +642,9 @@ start_gatherer( int pipefd )
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
continue;
|
||||
}
|
||||
if( errno == EPIPE ) /* parent has exited, so give up */
|
||||
exit(0);
|
||||
|
||||
/* we can't do very much here because stderr is closed */
|
||||
if( dbgfp )
|
||||
fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "sha1.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -331,7 +331,7 @@ sha1_read( SHA1_CONTEXT *hd )
|
||||
* Returns: A pointer to string describing the algorithm or NULL if
|
||||
* the ALGO is invalid.
|
||||
*/
|
||||
const char *
|
||||
static const char *
|
||||
sha1_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asnlen, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
@ -358,3 +358,64 @@ sha1_get_info( int algo, size_t *contextsize,
|
||||
return "SHA1";
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
const char * const gnupgext_version = "SHA1 ($Revision$)";
|
||||
|
||||
static struct {
|
||||
int class;
|
||||
int version;
|
||||
int value;
|
||||
void (*func)(void);
|
||||
} func_table[] = {
|
||||
{ 10, 1, 0, (void(*)(void))sha1_get_info },
|
||||
{ 11, 1, 2 },
|
||||
};
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
void *
|
||||
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
{
|
||||
void *ret;
|
||||
int i = *sequence;
|
||||
|
||||
do {
|
||||
if( i >= DIM(func_table) || i < 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
*class = func_table[i].class;
|
||||
*vers = func_table[i].version;
|
||||
switch( *class ) {
|
||||
case 11:
|
||||
case 21:
|
||||
case 31:
|
||||
ret = &func_table[i].value;
|
||||
break;
|
||||
default:
|
||||
ret = func_table[i].func;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} while( what && what != *class );
|
||||
|
||||
*sequence = i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
void
|
||||
sha1_constructor(void)
|
||||
{
|
||||
register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* sha1.h - SHA1 hash function
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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_SHA1_H
|
||||
#define G10_SHA1_H
|
||||
|
||||
|
||||
const char *
|
||||
sha1_get_info( int algo, size_t *contextsize,
|
||||
byte **r_asnoid, int *r_asn_len, int *r_mdlen,
|
||||
void (**r_init)( void *c ),
|
||||
void (**r_write)( void *c, byte *buf, size_t nbytes ),
|
||||
void (**r_final)( void *c ),
|
||||
byte *(**r_read)( void *c )
|
||||
);
|
||||
|
||||
#endif /*G10_SHA1_H*/
|
@ -909,6 +909,9 @@ tiger_get_info( int algo, size_t *contextsize,
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
const char * const gnupgext_version = "TIGER ($Revision$)";
|
||||
|
||||
static struct {
|
||||
@ -938,6 +941,9 @@ static struct {
|
||||
* version = interface version of the function/pointer
|
||||
* (currently this is 1 for all functions)
|
||||
*/
|
||||
#ifndef IS_MODULE
|
||||
static
|
||||
#endif
|
||||
void *
|
||||
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
{
|
||||
@ -969,5 +975,17 @@ gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef IS_MODULE
|
||||
void
|
||||
tiger_constructor(void)
|
||||
{
|
||||
register_internal_cipher_extension( gnupgext_version,
|
||||
gnupgext_enum_func );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HAVE_U64_TYPEDEF */
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "types.h" /* for byte and u32 typedefs */
|
||||
#include "util.h"
|
||||
#include "errors.h"
|
||||
#include "dynload.h"
|
||||
|
||||
|
||||
/* Prototype for the self-test function. */
|
||||
@ -462,7 +463,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
|
||||
static const char *selftest_failed=0;
|
||||
|
||||
/* Check key length. */
|
||||
if( keylen != 16 )
|
||||
if( keylen != 16 ) /* enhance this code for 256 bit keys */
|
||||
return G10ERR_WRONG_KEYLEN;
|
||||
|
||||
/* Do self-test if necessary. */
|
||||
@ -840,16 +841,18 @@ twofish_get_info (int algo, size_t *keylen,
|
||||
void (**r_decrypt) (void *c, byte *outbuf, byte *inbuf)
|
||||
)
|
||||
{
|
||||
*keylen = 128;
|
||||
*keylen = algo==10? 256 : 128;
|
||||
*blocksize = 16;
|
||||
*contextsize = sizeof (TWOFISH_context);
|
||||
*r_setkey = FNCCAST_SETKEY (twofish_setkey);
|
||||
*r_encrypt= FNCCAST_CRYPT (twofish_encrypt);
|
||||
*r_decrypt= FNCCAST_CRYPT (twofish_decrypt);
|
||||
|
||||
if( algo == 10 )
|
||||
return "TWOFISH";
|
||||
if (algo == 102) /* This algorithm number is assigned for
|
||||
* experiments, so we can use it */
|
||||
return "TWOFISH";
|
||||
return "TWOFISH128";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -863,6 +866,7 @@ static struct {
|
||||
void (*func)(void);
|
||||
} func_table[] = {
|
||||
{ 20, 1, 0, (void(*)(void))twofish_get_info },
|
||||
{ 21, 1, 10 },
|
||||
{ 21, 1, 102 },
|
||||
};
|
||||
|
||||
|
115
configure.in
115
configure.in
@ -15,11 +15,15 @@ AM_CONFIG_HEADER(config.h)
|
||||
VERSION=`cat $srcdir/VERSION`
|
||||
PACKAGE=gnupg
|
||||
ALL_LINGUAS="de es_ES fr it pl pt_BR ru"
|
||||
static_modules="sha1 md5 rmd160"
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
|
||||
|
||||
MODULES_IN_CIPHER=`awk '/# MODULES: / { for(i=3;i<=NF;i++) print $i}' \
|
||||
$srcdir/cipher/Makefile.am`
|
||||
|
||||
AC_MSG_CHECKING([whether use of /dev/random is requested])
|
||||
AC_ARG_ENABLE(dev-random,
|
||||
[ --disable-dev-random disable the use of dev random],
|
||||
@ -91,6 +95,8 @@ if test "$GCC" = yes; then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
|
||||
try_gettext=yes
|
||||
try_gdbm=yes
|
||||
case "${target}" in
|
||||
i386--mingw32)
|
||||
# special stuff for Windoze NT
|
||||
@ -99,9 +105,19 @@ case "${target}" in
|
||||
CPP="i386--mingw32-gcc -E"
|
||||
RANLIB="i386--mingw32-ranlib"
|
||||
ac_cv_have_dev_random=no
|
||||
AC_DEFINE(USE_RNDW32)
|
||||
AC_DEFINE(USE_ONLY_8DOT3)
|
||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||
try_gettext="no"
|
||||
try_gdbm="no"
|
||||
;;
|
||||
i386-emx-os2)
|
||||
# OS/2 with the EMX environment
|
||||
ac_cv_have_dev_random=no
|
||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||
try_gettext="no"
|
||||
try_gdbm="no"
|
||||
;;
|
||||
*-*-hpux*)
|
||||
if test -z "$GCC" ; then
|
||||
@ -126,6 +142,9 @@ case "${target}" in
|
||||
i386--mingw32)
|
||||
PRINTABLE_OS_NAME="MingW32"
|
||||
;;
|
||||
i386-emx-os2)
|
||||
PRINTABLE_OS_NAME="OS/2"
|
||||
;;
|
||||
*-linux*)
|
||||
PRINTABLE_OS_NAME="GNU/Linux"
|
||||
;;
|
||||
@ -154,9 +173,13 @@ AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
if test "$try_gettext" = yes; then
|
||||
AM_GNU_GETTEXT
|
||||
fi
|
||||
|
||||
if test "$try_gdbm" = yes; then
|
||||
AC_CHECK_LIB(gdbm,gdbm_firstkey)
|
||||
fi
|
||||
|
||||
|
||||
if test "$try_dynload" = yes ; then
|
||||
@ -252,7 +275,6 @@ AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
|
||||
ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
|
||||
if test "$ac_cv_have_dev_random" = yes; then
|
||||
AC_DEFINE(HAVE_DEV_RANDOM)
|
||||
AC_DEFINE(USE_RNDLINUX)
|
||||
fi
|
||||
else
|
||||
AC_MSG_CHECKING(for random device)
|
||||
@ -262,42 +284,93 @@ fi
|
||||
|
||||
|
||||
dnl
|
||||
dnl Figure how to link the random modules
|
||||
dnl Figure out the default linkage mode for cipher modules
|
||||
dnl
|
||||
dnl (We always need a static rmd160)
|
||||
static_modules="$static_modules rmd160"
|
||||
if test "$ac_cv_have_dev_random" = yes; then
|
||||
AC_DEFINE(USE_RNDLINUX)
|
||||
STATIC_RANDOM_OBJS="rndlinux.o"
|
||||
DYNAMIC_RANDOM_MODS=""
|
||||
static_modules="$static_modules rndlinux"
|
||||
else
|
||||
case "${target}" in
|
||||
i386--mingw32)
|
||||
AC_DEFINE(USE_RNDW32)
|
||||
STATIC_RANDOM_OBJS=""
|
||||
DYNAMIC_RANDOM_MODS=""
|
||||
static_modules="$static_modules rndw32"
|
||||
;;
|
||||
i386-emx-os2)
|
||||
static_modules="$static_modules rndos2"
|
||||
;;
|
||||
m68k-atari-mint)
|
||||
AC_DEFINE(USE_RNDATARI)
|
||||
STATIC_RANDOM_OBJS=""
|
||||
DYNAMIC_RANDOM_MODS=""
|
||||
static_modules="$static_modules rndatari"
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE(USE_RNDUNIX)
|
||||
STATIC_RANDOM_OBJS="rndunix.o"
|
||||
DYNAMIC_RANDOM_MODS=""
|
||||
static_modules="$static_modules rndunix"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_SUBST(STATIC_RANDOM_OBJS)
|
||||
AC_SUBST(DYNAMIC_RANDOM_MODS)
|
||||
dnl
|
||||
dnl Parse the modules list and build the list
|
||||
dnl of static and dymically linked modules
|
||||
dnl
|
||||
STATIC_CIPHER_NAMES=""
|
||||
STATIC_CIPHER_OBJS=""
|
||||
DYNAMIC_CIPHER_MODS=""
|
||||
GNUPG_MSG_PRINT([dynamically linked cipher modules:])
|
||||
for name in $MODULES_IN_CIPHER; do
|
||||
x="no"
|
||||
for i in $static_modules; do
|
||||
if test "$name" = "$i" ; then
|
||||
x="yes"
|
||||
fi
|
||||
done;
|
||||
if test $x = yes; then
|
||||
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
|
||||
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.o"
|
||||
else
|
||||
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
|
||||
GNUPG_MSG_PRINT([$name])
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT()
|
||||
AC_SUBST(STATIC_CIPHER_OBJS)
|
||||
AC_SUBST(STATIC_CIPHER_NAMES)
|
||||
AC_SUBST(DYNAMIC_CIPHER_MODS)
|
||||
|
||||
dnl
|
||||
dnl And build the constructor file
|
||||
dnl
|
||||
cat <<EOF >cipher/construct.c
|
||||
/* automatically generated by configure - do not edit */
|
||||
|
||||
EOF
|
||||
GNUPG_MSG_PRINT([statically linked cipher modules:])
|
||||
for name in $STATIC_CIPHER_NAMES; do
|
||||
echo "void ${name}_constructor(void);" >>cipher/construct.c
|
||||
GNUPG_MSG_PRINT([$name])
|
||||
done
|
||||
AC_MSG_RESULT()
|
||||
cat <<EOF >>cipher/construct.c
|
||||
|
||||
void
|
||||
cipher_modules_constructor(void)
|
||||
{
|
||||
static int done = 0;
|
||||
if( done )
|
||||
return;
|
||||
done = 1;
|
||||
|
||||
EOF
|
||||
for name in $STATIC_CIPHER_NAMES; do
|
||||
echo " ${name}_constructor();" >>cipher/construct.c
|
||||
done
|
||||
echo '}' >>cipher/construct.c
|
||||
|
||||
|
||||
|
||||
|
||||
dnl
|
||||
dnl Figure how to link the cipher modules
|
||||
dnl
|
||||
dnl (form now these are only dynamic)
|
||||
STATIC_CIPHER_OBJS=""
|
||||
DYNAMIC_CIPHER_MODS="twofish tiger"
|
||||
AC_SUBST(STATIC_CIPHER_OBJS)
|
||||
AC_SUBST(DYNAMIC_CIPHER_MODS)
|
||||
|
||||
@ -351,6 +424,10 @@ fi
|
||||
fi
|
||||
AC_SUBST(ZLIBS)
|
||||
|
||||
if echo "$VERSION" | grep '[a-zA-Z]' >/dev/null ; then
|
||||
AC_DEFINE(IS_DEVELOPMENT_VERSION)
|
||||
fi
|
||||
|
||||
GNUPG_DO_LINK_FILES
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ more arguments in future versions.
|
||||
The used key has been revoked by his owner. No arguments yet.
|
||||
|
||||
BADARMOR
|
||||
The ascii armor is corrupted. No arguments yet.
|
||||
The ASCII armor is corrupted. No arguments yet.
|
||||
|
||||
RSA_OR_IDEA
|
||||
The RSA or IDEA algorithms has been used in the data. A
|
||||
@ -175,7 +175,7 @@ Record type 2: (directory record)
|
||||
1 u32 cache record
|
||||
1 byte ownertrust
|
||||
1 byte dirflag
|
||||
1 byte validity
|
||||
1 byte validity of the key calucalted over all user ids
|
||||
19 byte reserved
|
||||
|
||||
|
||||
@ -208,7 +208,7 @@ Record type 4: (uid record)
|
||||
1 u32 pointer to preference record
|
||||
1 u32 siglist list of valid signatures
|
||||
1 byte uidflags
|
||||
1 byte reserved
|
||||
1 byte validity of the key calculated over this user id
|
||||
20 bytes ripemd160 hash of the username.
|
||||
|
||||
|
||||
@ -418,7 +418,7 @@ Usage of gdbm files for keyrings
|
||||
================================
|
||||
The key to store the keyblock is it's fingerprint, other records
|
||||
are used for secondary keys. fingerprints are always 20 bytes
|
||||
where 16 bit fingerprints are appded with zero.
|
||||
where 16 bit fingerprints are appended with zero.
|
||||
The first byte of the key gives some information on the type of the
|
||||
key.
|
||||
1 = key is a 20 bit fingerprint (16 bytes fpr are padded with zeroes)
|
||||
|
166
doc/FAQ
166
doc/FAQ
@ -23,11 +23,10 @@
|
||||
|
||||
GNUPG is also useful for signing things. Things that are encrypted with
|
||||
the secret key can be decrypted with the public key. To sign something, a
|
||||
hash is taken of the data, and then the hash is in some form encoded
|
||||
with the secret
|
||||
key. If someone has your public key, they can verify that it is from
|
||||
you and that it hasn't changed by checking the encoded form of the
|
||||
hash with the public key.
|
||||
hash is taken of the data, and then the hash is in some form encoded with
|
||||
the secret key. If someone has your public key, they can verify that it
|
||||
is from you and that it hasn't changed by checking the encoded form of
|
||||
the hash with the public key.
|
||||
|
||||
A keyring is just a large file that stores keys. You have a public keyring
|
||||
where you store yours and your friend's public keys. You have a secret
|
||||
@ -63,12 +62,12 @@
|
||||
or at a meeting of your local GNU/Linux User Group.
|
||||
|
||||
Hmm, what else. You may use the option "-o filename" to force output
|
||||
to this filename (use "-" to force output to stdout).
|
||||
"-r" just lets you specify the recipient (which public key you encrypt with)
|
||||
on the command line instead of typing it interactively.
|
||||
to this filename (use "-" to force output to stdout). "-r" just lets you
|
||||
specify the recipient (which public key you encrypt with) on the command
|
||||
line instead of typing it interactively.
|
||||
|
||||
Oh yeah, this is important. By default all data is encrypted in some weird
|
||||
binary format. If you want to have things appear in ascii text that is
|
||||
binary format. If you want to have things appear in ASCII text that is
|
||||
readable, just add the '-a' option. But the preferred method is to use
|
||||
a MIME aware mail reader (Mutt, Pine and many more).
|
||||
|
||||
@ -94,31 +93,31 @@
|
||||
a v3 packet. GNUPG is the only program which had used
|
||||
these v3 ElGamal keys - so this assumption is quite safe.
|
||||
|
||||
Q: Why is PGP 5.x not able to encrypt messages with my public key.
|
||||
Q: Why is PGP 5.x not able to encrypt messages with my public key?
|
||||
A: PGP Inc refuses to accept ElGamal keys of type 20 even for
|
||||
encryption. They only supports type 16 (which are identical
|
||||
at least for decryption). To be better interoperable, GNUPG
|
||||
at least for decryption). To be more inter-operable, GNUPG
|
||||
(starting with version 0.3.3) now also uses type 16 for the
|
||||
ElGamal subkey which is created if the default key algorithm
|
||||
is chosen. You may add an type 16 ElGamal key to your public
|
||||
key which is easy as your key signatures are still valid.
|
||||
|
||||
Q: Why is PGP 5.x not able to verify my messages.
|
||||
Q: Why is PGP 5.x not able to verify my messages?
|
||||
A: PGP 5.x does not accept V4 signatures for data material but
|
||||
OpenPGP requires generation of V3 signatures for all kind of
|
||||
data. Use the option "--force-v3-sigs" to generate V3 signatures
|
||||
for data.
|
||||
|
||||
Q: I can't delete an user id because it is already deleted on my
|
||||
public keyring.
|
||||
public keyring?
|
||||
A: Because you can only select from the public key ring, there is
|
||||
no direct way to do this. However it is not so complicated
|
||||
do to it anyway: Create a new user id with exactly the same name,
|
||||
you will notice that there are two identical user ids on the
|
||||
secret ring now. Now select this user id and delete it; both
|
||||
user ids from the secret ring will be removed.
|
||||
no direct way to do this. However it is not very complicated
|
||||
to do it anyway. Create a new user id with exactly the same name
|
||||
and you will see that there are now two identical user ids on the
|
||||
secret ring. Now select this user id and delete it. Both user
|
||||
ids will be removed from the secret ring.
|
||||
|
||||
Q: How can I encrypt a message in way pgp 2.x is able to decrypt it later?
|
||||
Q: How can I encrypt a message so that pgp 2.x is able to decrypt it?
|
||||
A: You can't do that because pgp 2.x normally uses IDEA which is not
|
||||
supported by GNUPG because it is patented, but if you have a modified
|
||||
version of PGP you can try this:
|
||||
@ -130,11 +129,11 @@
|
||||
|
||||
gpg -c --cipher-algo 3des --compress-algo 1 --no-comment myfile
|
||||
|
||||
You may replace "3des" by "cast5"; "blowfish" does not work with
|
||||
You may replace "3des" by "cast5". "blowfish" does not work with
|
||||
all versions of pgp5. You may also want to put
|
||||
no-comment
|
||||
compress-algo 1
|
||||
into your ~/.gnupg/options file - this does not affect the normal
|
||||
into your ~/.gnupg/options file - this does not affect normal
|
||||
gnupg operation.
|
||||
|
||||
|
||||
@ -142,42 +141,40 @@
|
||||
A: The problem here is that we need a lot of random bytes and for that
|
||||
we (on Linux the /dev/random device) must collect some random data.
|
||||
It is really not easy to fill the Linux internal entropy buffer; I
|
||||
talked to Ted Ts'o and he commited that the best way to fill the
|
||||
buffer is to play with your keyboard.
|
||||
Good security has it's price.
|
||||
What I do is to hit several times on the shift,control, alternate,
|
||||
capslock keys, as these keys do not produce any output to the screen.
|
||||
This way you get your keys really fast (it's the same thing pgp2 does).
|
||||
talked to Ted Ts'o and he commented that the best way to fill the buffer
|
||||
is to play with your keyboard. Good security has it's price. What I do
|
||||
is to hit several times on the shift, control, alternate, and capslock
|
||||
keys, because these keys do not produce output to the screen. This way
|
||||
you get your keys really fast (it's the same thing pgp2 does).
|
||||
|
||||
Another problem might be another program which eats up your random bytes
|
||||
(a program (look at your daemons) that reads from /dev/[u]random).
|
||||
|
||||
Q: And it really takes long when I work on a remote system. Why?
|
||||
A: Don't do this at all!
|
||||
You should never create keys or even use gnupg on a remote system because
|
||||
you normally have
|
||||
no physical control over your secret keyring (which is in most cases
|
||||
vulnerable to advanced dictionary attacks) - I strongly encourage
|
||||
everyone to only create keys on a local computer (a disconnected
|
||||
laptop is probably the best choice) and if you need it on your
|
||||
connected box (I know: We all do this) be sure to have a strong
|
||||
password for your account, your secret key and trust your Root.
|
||||
A: Don't do this at all! You should never create keys or even use gnupg
|
||||
on a remote system because you normally have no physical control over
|
||||
your secret keyring (which is in most cases vulnerable to advanced
|
||||
dictionary attacks) - I strongly encourage everyone to only create keys
|
||||
on a local computer (a disconnected laptop is probably the best choice)
|
||||
and if you need it on your connected box (I know: We all do this) be
|
||||
sure to have a strong password for your account and for your secret key
|
||||
and trust your Root.
|
||||
|
||||
When I check gnupg on a remote system via ssh (I have no Alpha here ;-)
|
||||
I have the same problem too: it takes *very* long to create the keys,
|
||||
so I use a special option --quick-random to generate insecure keys which are
|
||||
only good for some tests.
|
||||
I have the same problem. It takes a *very* long time to create the
|
||||
keys, so I use a special option, --quick-random, to generate insecure
|
||||
keys which are only good for some tests.
|
||||
|
||||
|
||||
Q: How does the whole trust thing work?
|
||||
A: It works more or less like PGP. The difference is, that the trust is
|
||||
computed at the time it is needed; this is one of the reasons for the
|
||||
A: It works more or less like PGP. The difference is that the trust is
|
||||
computed at the time it is needed. This is one of the reasons for the
|
||||
trustdb which holds a list of valid key signatures. If you are not
|
||||
running in batch mode you will be asked to assign a trust parameter
|
||||
(ownertrust) to a key. I have plans to use a cache for calculated
|
||||
trust values to speed up calculation.
|
||||
|
||||
You can see the validity (calculated trust value) using this command:
|
||||
You can see the validity (calculated trust value) using this command.
|
||||
|
||||
gpgm --list-keys --with-colons
|
||||
|
||||
@ -193,13 +190,13 @@
|
||||
is only used for keys for which
|
||||
the secret key is also available.
|
||||
|
||||
You can get a list of the assigned trust values (how far you trust
|
||||
the owner to correctly sign another one's key)
|
||||
You can get a list of the assigned trust values (how much you trust
|
||||
the owner to correctly sign another person's key)
|
||||
|
||||
gpgm --list-ownertrust
|
||||
|
||||
The first field is the fingerprint of the primary key, the second one
|
||||
the assigned value:
|
||||
The first field is the fingerprint of the primary key, the second field
|
||||
is the assigned value:
|
||||
|
||||
- = No Ownertrust value yet assigned.
|
||||
n = Never trust this keyholder to correctly verify others signatures.
|
||||
@ -207,42 +204,42 @@
|
||||
f = Assume that the key holder really knows how to sign keys.
|
||||
u = No need to trust ourself because we have the secret key.
|
||||
|
||||
Please keep these values confidential, as they express some opinions of
|
||||
you about others. PGP does store these information with the keyring, so
|
||||
it is not a good idea to publish the keyring instead of exporting the
|
||||
keyring - gnupg stores the trust in the trust-DB and therefor it is okay
|
||||
to give the keyring away (but we have a --export command too).
|
||||
Keep these values confidential because they express your opinions
|
||||
about others. PGP stores this information with the keyring thus
|
||||
it is not a good idea to publish a PGP keyring instead of exporting the
|
||||
keyring. gnupg stores the trust in the trust-DB so it is okay
|
||||
to give a gpg keyring away (but we have a --export command too).
|
||||
|
||||
|
||||
Q: What is the difference between options and commands?
|
||||
A: If you do a "gpg --help", you will get two separate lists. The first is a list
|
||||
of commands. The second is a list of options. Whenever you run GPG, you *must*
|
||||
pick exactly one command (**with one exception, see below). You *may* pick one
|
||||
or more options. The command should, just by convention, come at the end of the
|
||||
argument list, after all the options. If the command takes a file (all the
|
||||
basic ones do), the filename comes at the very end. So the basic way to
|
||||
run gpg is:
|
||||
A: If you do a "gpg --help", you will get two separate lists. The first is
|
||||
a list of commands. The second is a list of options. Whenever you run GPG,
|
||||
you *must* pick exactly one command (**with one exception, see below). You
|
||||
*may* pick one or more options. The command should, just by convention,
|
||||
come at the end of the argument list, after all the options. If the
|
||||
command takes a file (all the basic ones do), the filename comes at the
|
||||
very end. So the basic way to run gpg is:
|
||||
|
||||
gpg [--option something] [--option2] [--option3 something] --command file
|
||||
|
||||
Some options take arguments, for example the --output option (which can be
|
||||
abbreviated -o) is an option which takes a filename. The option's argument
|
||||
must follow immediately after the option itself: otherwise gpg doesn't know
|
||||
abbreviated -o) is an option that takes a filename. The option's argument
|
||||
must follow immediately after the option itself, otherwise gpg doesn't know
|
||||
which option the argument is supposed to go with. As an option, --output and
|
||||
its filename must come before the command. The --remote-user (-r) option takes
|
||||
a name or keyid to encrypt the message to, which must come right after the -r
|
||||
argument. The --encrypt (or -e) command comes after all the options, followed
|
||||
by the file you wish to encrypt. So use:
|
||||
argument. The --encrypt (or -e) command comes after all the options followed
|
||||
by the file you wish to encrypt. So use
|
||||
|
||||
gpg -r alice -o secret.txt -e test.txt
|
||||
|
||||
If you write the options out in full, it is easier to read:
|
||||
If you write the options out in full, it is easier to read
|
||||
|
||||
gpg --remote-user alice --output secret.txt --encrypt test.txt
|
||||
|
||||
If you're saving it in a file called ".txt" then you'd probably expect to see
|
||||
ascii-armored text in there, so you need to add the --armor (-a) option,
|
||||
which doesn't take any arguments:
|
||||
ASCII-armored text in there, so you need to add the --armor (-a) option,
|
||||
which doesn't take any arguments.
|
||||
|
||||
gpg --armor --remote-user alice --output secret.txt --encrypt test.txt
|
||||
|
||||
@ -251,7 +248,7 @@
|
||||
|
||||
gpg [--armor] [--remote-user alice] [--output secret.txt] --encrypt test.txt
|
||||
|
||||
The optional parts can be rearranged any way you want:
|
||||
The optional parts can be rearranged any way you want.
|
||||
|
||||
gpg --output secret.txt --remote-user alice --armor --encrypt test.txt
|
||||
|
||||
@ -268,30 +265,30 @@
|
||||
Q: What kind of output is this: "key C26EE891.298, uid 09FB: ...."?
|
||||
A: This is the internal representation of an user id in the trustdb.
|
||||
"C26EE891" is the keyid, "298" is the local id (a record number
|
||||
in the trustdb) and "09FB" are the last two bytes of a ripe-md-160
|
||||
in the trustdb) and "09FB" is the last two bytes of a ripe-md-160
|
||||
hash of the user id for this key.
|
||||
|
||||
|
||||
Q: What is trust, validity and ownertrust?
|
||||
A: "ownertrust" is used instead of "trust" to make clear that
|
||||
this is the value you have assigned to key to express, how far you
|
||||
this is the value you have assigned to key to express how much you
|
||||
trust the owner of this key to correctly sign (and so introduce)
|
||||
other keys. "validity" or calculated trust is a value which
|
||||
says, how far the gnupg thinks a key is valid (that it really belongs
|
||||
other keys. "validity", or calculated trust, is a value which
|
||||
says how much the gnupg thinks a key is valid (that it really belongs
|
||||
to the one who claims to be the owner of the key).
|
||||
For more see the chapter "The Web of Trust" in the
|
||||
Manual [gpg: Oops: Internal error: manual not found - sorry]
|
||||
|
||||
Q: How do interpret some of the informational outputs:
|
||||
A: While checking the validness of a key, GnuPG sometimes print
|
||||
some informations which are prefixed with information about
|
||||
the checked item:
|
||||
Q: How do interpret some of the informational outputs?
|
||||
A: While checking the validity of a key, GnuPG sometimes prints
|
||||
some information which is prefixed with information about
|
||||
the checked item.
|
||||
"key 12345678.3456"
|
||||
This is about the key with key ID 12345678 and the internal
|
||||
number 3456, which is the record number of the so called
|
||||
directory record in the trustdb.
|
||||
"uid 12345678.3456/ACDE"
|
||||
This is about the user ID for the same key; to identify the
|
||||
This is about the user ID for the same key. To identify the
|
||||
user ID the last two bytes of a ripe-md-160 over the user ID
|
||||
ring is printed.
|
||||
"sig 12345678.3456/ACDE/9A8B7C6D"
|
||||
@ -302,15 +299,14 @@
|
||||
|
||||
Q: How do I sign a patch file?
|
||||
A: Use "gpg --clearsign --not-dash-escaped ...".
|
||||
The problem with --clearsign is
|
||||
that all lines starting with a dash are quoted with "- "; obviously
|
||||
diff produces many of lines starting with a dash and these are
|
||||
then quoted and that is not good for patch ;-). In order to use
|
||||
a patch file without removing the cleartext signature, the special
|
||||
option --not-dash-escaped may be used to suppress generation of
|
||||
these escape sequences. You should not mail such a patch because
|
||||
spaces and line endings are also subject to the signature and a mailer
|
||||
may not preserve these. If you want to mail a file you can simply sign
|
||||
it using your MUA.
|
||||
The problem with --clearsign is that all lines starting with a dash are
|
||||
quoted with "- "; obviously diff produces many of lines starting with a
|
||||
dash and these are then quoted and that is not good for patch ;-). To
|
||||
use a patch file without removing the cleartext signature, the special
|
||||
option --not-dash-escaped may be used to suppress generation of these
|
||||
escape sequences. You should not mail such a patch because spaces and
|
||||
line endings are also subject to the signature and a mailer may not
|
||||
preserve these. If you want to mail a file you can simply sign it
|
||||
using your MUA.
|
||||
|
||||
|
||||
|
87
doc/gpg.1pod
87
doc/gpg.1pod
@ -67,7 +67,7 @@ B<-k> [I<username>] [I<keyring>]
|
||||
Kludge to be somewhat compatible with PGP.
|
||||
Without arguments, all public keyrings are listed.
|
||||
With one argument, only I<keyring> is listed.
|
||||
Special combinations are also allowed, but it may
|
||||
Special combinations are also allowed, but they may
|
||||
give strange results when combined with more options.
|
||||
B<-kv> Same as B<-k>
|
||||
B<-kvv> List the signatures with every key.
|
||||
@ -130,7 +130,7 @@ B<--edit-key> I<name>
|
||||
Remove a subkey.
|
||||
B<expire>
|
||||
Change the key expiration time. If a key is
|
||||
select, the time of this key will be changed.
|
||||
selected, the time of this key will be changed.
|
||||
With no selection the key expiration of the
|
||||
primary key is changed.
|
||||
B<passwd>
|
||||
@ -154,10 +154,10 @@ B<--edit-key> I<name>
|
||||
key rings.
|
||||
The listing shows you the key with its secondary
|
||||
keys and all user ids. Selected keys or user ids
|
||||
indicated by an asterisk. The trust value is
|
||||
displayed with the primary key: The first one is the
|
||||
assigned owner trust and the second the calculated
|
||||
trust value; letters are used for the values:
|
||||
are indicated by an asterisk. The trust value is
|
||||
displayed with the primary key: the first is the
|
||||
assigned owner trust and the second is the calculated
|
||||
trust value. Letters are used for the values:
|
||||
B<-> No ownertrust assigned / not yet calculated.
|
||||
B<e> Trust calculation has failed.
|
||||
B<q> Not enough information for calculation.
|
||||
@ -201,11 +201,11 @@ B<--export-secret-keys> [I<names>]
|
||||
|
||||
B<--import>, B<--fast-import>
|
||||
Import/merge keys. The fast version does not build
|
||||
the trustdb; this can be deon at anytime with the
|
||||
the trustdb; this can be done at any time with the
|
||||
command B<--update-trustdb>.
|
||||
|
||||
B<--export-ownertrust>
|
||||
List the assigned ownertrust values in ascii format
|
||||
List the assigned ownertrust values in ASCII format
|
||||
for backup purposes [B<gpgm> only].
|
||||
|
||||
B<--import-ownertrust> [I<filename>]
|
||||
@ -215,9 +215,9 @@ B<--import-ownertrust> [I<filename>]
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
Long options can be put in an options file (default F<~/.gnupg/options>);
|
||||
do not write the 2 dashes, but simply the name of the option and any
|
||||
arguments if required. Lines with a hash as the first non-white-space
|
||||
Long options can be put in an options file (default F<~/.gnupg/options>).
|
||||
Do not write the 2 dashes, but simply the name of the option and any
|
||||
required arguments. Lines with a hash as the first non-white-space
|
||||
character are ignored. Commands may be put in this file too, but that
|
||||
does not make sense.
|
||||
|
||||
@ -250,7 +250,7 @@ B<--trusted-key> I<keyid>
|
||||
|
||||
You may also use this option to skip the verification
|
||||
of your own secret keys which is normally done every
|
||||
time GnuPG starts up: Use for I<keyid> the one of
|
||||
time GnuPG starts up by using the I<keyid> of
|
||||
your key.
|
||||
|
||||
B<-r> I<name>, B<--recipient> I<name>
|
||||
@ -268,7 +268,7 @@ B<-q>, B<--quiet>
|
||||
B<-z> I<n>
|
||||
Set compress level to I<n>. A value of 0 for I<n>
|
||||
disables compression. Default is to use the default
|
||||
compression level of zlib (which is 6).
|
||||
compression level of zlib (normally 6).
|
||||
|
||||
B<-t>, B<--textmode>
|
||||
Use canonical text mode. If B<-t> (but not
|
||||
@ -276,17 +276,17 @@ B<-t>, B<--textmode>
|
||||
and signing, this enables clearsigned messages.
|
||||
This kludge is needed for PGP compatibility;
|
||||
normally you would use B<--sign> or B<--clearsign>
|
||||
to selected the type os signatures.
|
||||
to selected the type of the signature.
|
||||
|
||||
B<-n>, B<--dry-run>
|
||||
Don't make any changes (not yet implemented).
|
||||
|
||||
B<--batch>
|
||||
Batch mode; never ask, do not allow interactive
|
||||
Use batch mode. Never ask, do not allow interactive
|
||||
commands.
|
||||
|
||||
B<--no-batch>
|
||||
Disable batch mode; this may be used if B<batch>
|
||||
Disable batch mode. This may be used if B<batch>
|
||||
is used in the options file.
|
||||
|
||||
B<--yes>
|
||||
@ -297,7 +297,7 @@ B<--no>
|
||||
|
||||
B<--keyserver> I<name>
|
||||
Use I<name> to lookup keys which are not yet in
|
||||
your keyring; this is only done while verifying
|
||||
your keyring. This is only done while verifying
|
||||
messages with signatures. The option is also
|
||||
required for the command B<--send-keys> to
|
||||
specify the keyserver to where the keys should
|
||||
@ -374,11 +374,11 @@ B<--set-filename> I<string>
|
||||
|
||||
B<--completes-needed> I<n>
|
||||
Number of completely trusted users to introduce a new
|
||||
key signator (defaults to 1).
|
||||
key signer (defaults to 1).
|
||||
|
||||
B<--marginals-needed> I<n>
|
||||
Number of marginally trusted users to introduce a new
|
||||
key signator (defaults to 3)
|
||||
key signer (defaults to 3)
|
||||
|
||||
B<--max-cert-depth> I<n>
|
||||
Maximum depth of a certification chain (default is 5).
|
||||
@ -409,7 +409,7 @@ B<--s2k-digest-algo> I<name>
|
||||
encryption if B<--digest-algo> is not given.
|
||||
|
||||
B<--s2k-mode> I<number>
|
||||
Selects how passphrases are mangled: A number of I<0>
|
||||
Selects how passphrases are mangled. A number of I<0>
|
||||
uses the plain passphrase (which is not recommended),
|
||||
a I<1> (default) adds a salt to the passphrase and
|
||||
I<3> iterates the whole process a couple of times.
|
||||
@ -418,12 +418,12 @@ B<--s2k-mode> I<number>
|
||||
|
||||
B<--compress-algo> I<number>
|
||||
Use compress algorithm I<number>. Default is I<2> which is
|
||||
RFC1950 compression; you may use I<1> to use the old zlib
|
||||
version which is used by PGP.
|
||||
The default algorithm may give better
|
||||
results because the window size is not limited to 8K.
|
||||
If this is not used the OpenPGP behavior is used; i.e.
|
||||
the compression algorithm is selected from the preferences.
|
||||
RFC1950 compression. You may use I<1> to use the old zlib
|
||||
version which is used by PGP. The default algorithm may
|
||||
give better results because the window size is not limited
|
||||
to 8K. If this is not used the OpenPGP behavior is used,
|
||||
i.e. the compression algorithm is selected from the
|
||||
preferences.
|
||||
|
||||
B<--digest-algo> I<name>
|
||||
Use I<name> as message digest algorithm. Running the
|
||||
@ -438,21 +438,20 @@ B<--throw-keyid>
|
||||
process because all available secret keys are tried.
|
||||
|
||||
B<--not-dash-escaped>
|
||||
This option changes the behavior of cleartext signature
|
||||
This option changes the behavior of cleartext signatures
|
||||
so that they can be used for patch files. You should not
|
||||
send such an armored file via email because all spaces
|
||||
and line endings are hashed too. You can not use this
|
||||
option for data which has 5 dashes somewhere at the
|
||||
beginning of a line - patch files don't have this.
|
||||
A special armor header line tells GnuPG about this
|
||||
cleartext signature framework.
|
||||
option for data which has 5 dashes at the beginning of a
|
||||
line, patch files don't have this. A special armor header
|
||||
line tells GnuPG about this cleartext signature option.
|
||||
|
||||
B<--escape-from-lines>
|
||||
Because some mailers change lines starting with "From "
|
||||
to ">From " it is good to handle such lines in a special
|
||||
way when creating cleartext signatures; all other PGP
|
||||
versions do it this way too. Because this would violate
|
||||
rfc2440, this option is not enabled per default.
|
||||
way when creating cleartext signatures. All other PGP
|
||||
versions do it this way too. This option is not enabled
|
||||
by default because it would violate rfc2440.
|
||||
|
||||
B<--passphrase-fd> I<n>
|
||||
Read the passphrase from file descriptor I<n>. If you use
|
||||
@ -464,10 +463,10 @@ B<--rfc1991>
|
||||
Try to be more RFC1991 (PGP 2.x) compliant.
|
||||
|
||||
B<--force-v3-sigs>
|
||||
OpenPGP states that a implementation should generate
|
||||
v4 signatures but PGP 5.x does only recognize such
|
||||
signatures on key material. This options forces
|
||||
v3 signatures for signatures on data.
|
||||
OpenPGP states that an implementation should generate
|
||||
v4 signatures but PGP 5.x recognizes v4 signatures only
|
||||
on key material. This options forces v3 signatures for
|
||||
signatures on data.
|
||||
|
||||
B<--lock-once>
|
||||
Lock the file the first time a lock is requested
|
||||
@ -510,7 +509,7 @@ B<-h>, B<--help>
|
||||
=head1 RETURN VALUE
|
||||
|
||||
The Program returns 0 if everything was fine, 1 if at least
|
||||
a signature was bad and other errorcode for fatal errors.
|
||||
a signature was bad, and other error codes for fatal errors.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
@ -552,15 +551,15 @@ Use a B<good> password for your user account and a B<good> passphrase
|
||||
to protect your secret key. This passphrase is the weakest part of the
|
||||
whole system. Programs to do dictionary attacks on your secret keyring
|
||||
are very easy to write and so you should protect your B<~/.gnupg/>
|
||||
directory very good.
|
||||
directory very well.
|
||||
|
||||
Keep in mind that, if this program is used over a network (telnet), it
|
||||
is B<very> easy to spy out your passphrase!
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
On many systems this program should be installed as setuid(root); this
|
||||
is necessary to lock some pages of memory. If you get no warning message
|
||||
about insecure memory your OS kernel supports locking without being root;
|
||||
setuid is dropped as soon as this memory is allocated.
|
||||
On many systems this program should be installed as setuid(root). This
|
||||
is necessary to lock memory pages. If you get no warning message about
|
||||
insecure memory your OS kernel supports locking without being root.
|
||||
The program drops root privileges as soon as locked memory is allocated.
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* g10.c (main): check for development version now in configure
|
||||
|
||||
* tdbio.c (tdbio_write_record): Add uid.validity
|
||||
(tdbio_read_record) : Ditto.
|
||||
(tdbio_dump_record) : Ditto.
|
||||
|
||||
* keygen.c (keygen_add_std_prefs): Replaced Blowfish by Twofish,
|
||||
removed MD5 and Tiger.
|
||||
* pubkey-enc.c (get_it): Suppress warning about missing Blowfish
|
||||
in preferences in certain cases.
|
||||
|
||||
* ringedit.c (lock_rentry,unlock_rentry): New.
|
||||
|
||||
* getkey.c (key_byname): Pass ret_kb down to lookup_xx.
|
||||
|
||||
* armor.c (armor_filter): No output of of empty comment lines.
|
||||
Add option --no-version to suppress the output of the version string.
|
||||
|
||||
* getkey.c: Release the getkey context for auto context variables.
|
||||
|
||||
Sun Jan 24 18:16:26 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* getkey.c: Changed the internal design to allow simultaneous
|
||||
|
29
g10/armor.c
29
g10/armor.c
@ -876,23 +876,26 @@ armor_filter( void *opaque, int control,
|
||||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, head_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----\n");
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")\n");
|
||||
if( !opt.no_version )
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")\n");
|
||||
|
||||
if( opt.comment_string ) {
|
||||
const char *s = opt.comment_string;
|
||||
iobuf_writestr(a, "Comment: " );
|
||||
for( ; *s; s++ ) {
|
||||
if( *s == '\n' )
|
||||
iobuf_writestr(a, "\\n" );
|
||||
else if( *s == '\r' )
|
||||
iobuf_writestr(a, "\\r" );
|
||||
else if( *s == '\v' )
|
||||
iobuf_writestr(a, "\\v" );
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
if( *s ) {
|
||||
iobuf_writestr(a, "Comment: " );
|
||||
for( ; *s; s++ ) {
|
||||
if( *s == '\n' )
|
||||
iobuf_writestr(a, "\\n" );
|
||||
else if( *s == '\r' )
|
||||
iobuf_writestr(a, "\\r" );
|
||||
else if( *s == '\v' )
|
||||
iobuf_writestr(a, "\\v" );
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
iobuf_put(a, '\n' );
|
||||
}
|
||||
iobuf_put(a, '\n' );
|
||||
}
|
||||
else
|
||||
iobuf_writestr(a,
|
||||
|
12
g10/g10.c
12
g10/g10.c
@ -117,6 +117,7 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
oDebugAll,
|
||||
oStatusFD,
|
||||
oNoComment,
|
||||
oNoVersion,
|
||||
oCompletesNeeded,
|
||||
oMarginalsNeeded,
|
||||
oMaxCertDepth,
|
||||
@ -307,6 +308,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
|
||||
{ oSetFilename, "set-filename", 2, "@" },
|
||||
{ oComment, "comment", 2, "@" },
|
||||
{ oNoVersion, "no-version", 0, "@"},
|
||||
{ oNotDashEscaped, "not-dash-escaped", 0, "@" },
|
||||
{ oEscapeFrom, "escape-from-lines", 0, "@" },
|
||||
{ oLockOnce, "lock-once", 0, "@" },
|
||||
@ -716,6 +718,7 @@ main( int argc, char **argv )
|
||||
opt.verbose = 0; opt.list_sigs=0; break;
|
||||
case oQuickRandom: quick_random_gen(1); break;
|
||||
case oNoComment: opt.no_comment=1; break;
|
||||
case oNoVersion: opt.no_version=1; break;
|
||||
case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
|
||||
case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
|
||||
case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
|
||||
@ -810,6 +813,9 @@ main( int argc, char **argv )
|
||||
if( greeting ) {
|
||||
tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
|
||||
tty_printf("%s\n", strusage(15) );
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
|
||||
@ -859,12 +865,6 @@ main( int argc, char **argv )
|
||||
log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
|
||||
}
|
||||
|
||||
{ const char *p = strusage(13);
|
||||
for( ; *p && (isdigit(*p) || *p=='.'); p++ )
|
||||
;
|
||||
if( *p )
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
}
|
||||
|
||||
if( log_get_errorcount(0) )
|
||||
g10_exit(2);
|
||||
|
37
g10/getkey.c
37
g10/getkey.c
@ -38,9 +38,9 @@
|
||||
#define MAX_PK_CACHE_ENTRIES 50
|
||||
#define MAX_UID_CACHE_ENTRIES 50
|
||||
|
||||
/* Aa map of the all characters valid used for word_match()
|
||||
/* A map of the all characters valid used for word_match()
|
||||
* Valid characters are in in this table converted to uppercase.
|
||||
* becuase the upper 128 bytes have special meanin, we assume
|
||||
* because the upper 128 bytes have special meaning, we assume
|
||||
* that they are all valid.
|
||||
* Note: We must use numerical values here in case that this program
|
||||
* will be converted to those little blue HAL9000s with their strange
|
||||
@ -95,6 +95,7 @@ struct getkey_ctx_s {
|
||||
KBPOS kbpos;
|
||||
int last_rc;
|
||||
ulong count;
|
||||
int not_allocated;
|
||||
int nitems;
|
||||
getkey_item_t items[1];
|
||||
};
|
||||
@ -322,11 +323,13 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
|
||||
/* do a lookup */
|
||||
{ struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_pk( &ctx, pk, NULL );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
if( !rc )
|
||||
goto leave;
|
||||
@ -371,11 +374,13 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
|
||||
struct getkey_ctx_s ctx;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
if( !rc ) {
|
||||
/* check the secret key (this may prompt for a passprase to
|
||||
* unlock the secret key
|
||||
@ -395,14 +400,18 @@ int
|
||||
get_primary_seckey( PKT_secret_key *sk, u32 *keyid )
|
||||
{
|
||||
struct getkey_ctx_s ctx;
|
||||
int rc;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.primary = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
return lookup_sk( &ctx, sk, NULL );
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -421,11 +430,13 @@ seckey_available( u32 *keyid )
|
||||
|
||||
sk = m_alloc_clear( sizeof *sk );
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
free_secret_key( sk );
|
||||
return rc;
|
||||
}
|
||||
@ -653,9 +664,9 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
||||
/* and call the lookup function */
|
||||
ctx->primary = 1; /* we want to look for the primary key only */
|
||||
if( sk )
|
||||
rc = lookup_sk( ctx, sk, NULL );
|
||||
rc = lookup_sk( ctx, sk, ret_kb );
|
||||
else
|
||||
rc = lookup_pk( ctx, pk, NULL );
|
||||
rc = lookup_pk( ctx, pk, ret_kb );
|
||||
|
||||
if( retctx ) /* caller wants the context */
|
||||
*retctx = ctx;
|
||||
@ -733,7 +744,8 @@ get_pubkey_end( GETKEY_CTX ctx )
|
||||
enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */
|
||||
for(n=0; n < ctx->nitems; n++ )
|
||||
m_free( ctx->items[n].namebuf );
|
||||
m_free( ctx );
|
||||
if( !ctx->not_allocated )
|
||||
m_free( ctx );
|
||||
}
|
||||
}
|
||||
|
||||
@ -748,10 +760,12 @@ get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len)
|
||||
if( fprint_len == 20 || fprint_len == 16 ) {
|
||||
struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len;
|
||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
||||
rc = lookup_pk( &ctx, pk, NULL );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
else
|
||||
rc = G10ERR_GENERAL; /* Oops */
|
||||
@ -772,10 +786,12 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
|
||||
if( fprint_len == 20 || fprint_len == 16 ) {
|
||||
struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len;
|
||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
||||
rc = lookup_pk( &ctx, pk, ret_keyblock );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
else
|
||||
rc = G10ERR_GENERAL; /* Oops */
|
||||
@ -806,10 +822,12 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect )
|
||||
struct getkey_ctx_s ctx;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.primary = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 15;
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
}
|
||||
else {
|
||||
add_to_strlist( &namelist, name );
|
||||
@ -868,7 +886,8 @@ get_seckey_end( GETKEY_CTX ctx )
|
||||
enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */
|
||||
for(n=0; n < ctx->nitems; n++ )
|
||||
m_free( ctx->items[n].namebuf );
|
||||
m_free( ctx );
|
||||
if( !ctx->not_allocated )
|
||||
m_free( ctx );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1600,7 +1619,7 @@ lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
|
||||
k = find_first( ctx->keyblock, pk );
|
||||
else if( item->mode == 16 || item->mode == 20 )
|
||||
k = find_by_fpr( ctx->keyblock, pk,
|
||||
item->name, item->mode );
|
||||
item->fprint, item->mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
@ -1687,7 +1706,7 @@ lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
|
||||
k = find_first_sk( ctx->keyblock, sk );
|
||||
else if( item->mode == 16 || item->mode == 20 )
|
||||
k = find_by_fpr_sk( ctx->keyblock, sk,
|
||||
item->name, item->mode );
|
||||
item->fprint, item->mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
|
@ -83,15 +83,13 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
|
||||
|
||||
keygen_add_key_expire( sig, opaque );
|
||||
|
||||
buf[0] = CIPHER_ALGO_BLOWFISH;
|
||||
buf[0] = CIPHER_ALGO_TWOFISH;
|
||||
buf[1] = CIPHER_ALGO_CAST5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_SYM, buf, 2 );
|
||||
|
||||
buf[0] = DIGEST_ALGO_RMD160;
|
||||
buf[1] = DIGEST_ALGO_SHA1;
|
||||
buf[2] = DIGEST_ALGO_TIGER;
|
||||
buf[3] = DIGEST_ALGO_MD5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 4 );
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 2 );
|
||||
|
||||
buf[0] = 2;
|
||||
buf[1] = 1;
|
||||
|
@ -169,6 +169,7 @@ list_keyblock( KBNODE keyblock, int secret )
|
||||
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error("Oops; key lost!\n");
|
||||
dump_kbnode( keyblock );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,11 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
free_md_filter_context( &c->mfx );
|
||||
c->mfx.md = md_open( 0, 0);
|
||||
/* fixme: we may need to push the textfilter if we have sigclass 1
|
||||
* and no armoring - Not yet tested */
|
||||
* and no armoring - Not yet tested
|
||||
* Hmmm, why don't we need it at all if we have sigclass 1
|
||||
* Should we assume that plaintext in mode 't' has always sigclass 1??
|
||||
* See: Russ Allbery's mail 1999-02-09
|
||||
*/
|
||||
any = clearsig = 0;
|
||||
for(n=c->list; n; n = n->next ) {
|
||||
if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
|
@ -47,6 +47,7 @@ struct {
|
||||
int def_compress_algo;
|
||||
const char *def_secret_key;
|
||||
int no_comment;
|
||||
int no_version;
|
||||
int marginals_needed;
|
||||
int completes_needed;
|
||||
int max_cert_depth;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "trustdb.h"
|
||||
#include "cipher.h"
|
||||
#include "status.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static int get_it( PKT_pubkey_enc *k,
|
||||
@ -179,9 +180,17 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
||||
else if( !pk->local_id && query_trust_record(pk) )
|
||||
log_error("can't check algorithm against preferences\n");
|
||||
else if( dek->algo != CIPHER_ALGO_3DES
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) )
|
||||
log_info(_("NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) {
|
||||
/* Don't print a note while we are not on verbose mode,
|
||||
* the cipher is blowfish and the preferences have twofish
|
||||
* listed */
|
||||
if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
|
||||
|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM,
|
||||
CIPHER_ALGO_TWOFISH ) )
|
||||
log_info(_(
|
||||
"NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
dek->algo );
|
||||
}
|
||||
free_public_key( pk );
|
||||
rc = 0;
|
||||
}
|
||||
|
@ -72,12 +72,13 @@ struct resource_table_struct {
|
||||
GDBM_FILE dbf;
|
||||
#endif
|
||||
enum resource_type rt;
|
||||
DOTLOCK lockhd;
|
||||
int is_locked;
|
||||
};
|
||||
typedef struct resource_table_struct RESTBL;
|
||||
|
||||
#define MAX_RESOURCES 10
|
||||
static RESTBL resource_table[MAX_RESOURCES];
|
||||
static const char *keyring_lock;
|
||||
|
||||
static int search( PACKET *pkt, KBPOS *kbpos, int secret );
|
||||
|
||||
@ -117,15 +118,40 @@ fatal_gdbm_error( const char *string )
|
||||
|
||||
#endif /* HAVE_LIBGDBM */
|
||||
|
||||
|
||||
/****************
|
||||
* Hmmm, how to avoid deadlock? They should not happen if everyone
|
||||
* locks the key resources in the same order; but who knows.
|
||||
* A solution is to use only one lock file in the gnupg homedir but
|
||||
* what will happen with key resources which normally don't belong
|
||||
* to the gpg homedir?
|
||||
*/
|
||||
static void
|
||||
cleanup( void )
|
||||
lock_rentry( RESTBL *rentry )
|
||||
{
|
||||
if( keyring_lock ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
if( !rentry->lockhd ) {
|
||||
rentry->lockhd = create_dotlock( rentry->fname );
|
||||
if( !rentry->lockhd )
|
||||
log_fatal("can't allocate lock for `%s'\n", rentry->fname );
|
||||
rentry->is_locked = 0;
|
||||
}
|
||||
if( !rentry->is_locked ) {
|
||||
if( make_dotlock( rentry->lockhd, -1 ) )
|
||||
log_fatal("can't lock `%s'\n", rentry->fname );
|
||||
rentry->is_locked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unlock_rentry( RESTBL *rentry )
|
||||
{
|
||||
if( opt.lock_once )
|
||||
return;
|
||||
if( !release_dotlock( rentry->lockhd ) )
|
||||
rentry->is_locked = 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
****************** public functions ****************************
|
||||
****************************************************************/
|
||||
@ -162,7 +188,6 @@ enum_keyblock_resources( int *sequence, int secret )
|
||||
int
|
||||
add_keyblock_resource( const char *url, int force, int secret )
|
||||
{
|
||||
static int initialized = 0;
|
||||
static int any_secret, any_public;
|
||||
const char *resname = url;
|
||||
IOBUF iobuf = NULL;
|
||||
@ -171,10 +196,6 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
int rc = 0;
|
||||
enum resource_type rt = rt_UNKNOWN;
|
||||
|
||||
if( !initialized ) {
|
||||
initialized = 1;
|
||||
atexit( cleanup );
|
||||
}
|
||||
|
||||
/* Do we have an URL?
|
||||
* gnupg-gdbm:filename := this is a GDBM resource
|
||||
@ -190,7 +211,7 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
rt = rt_GDBM;
|
||||
resname += 11;
|
||||
}
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DRIVE_LETTERS
|
||||
else if( strchr( resname, ':' ) ) {
|
||||
log_error("%s: invalid URL\n", url );
|
||||
rc = G10ERR_GENERAL;
|
||||
@ -264,7 +285,7 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
if( access(filename, F_OK) ) {
|
||||
if( strlen(filename) >= 7
|
||||
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
|
||||
#if __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if( mkdir(filename) )
|
||||
#else
|
||||
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
|
||||
@ -298,10 +319,10 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
else
|
||||
log_info(_("%s: keyring created\n"), filename );
|
||||
}
|
||||
#if __MINGW32__ || 1
|
||||
/* must close it again */
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
iobuf_close( iobuf );
|
||||
iobuf = NULL;
|
||||
/* must close it again */
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1039,7 +1060,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
kbpos->rt = rt_RING;
|
||||
kbpos->valid = 0;
|
||||
|
||||
#if __MINGW32__ || 1
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
assert(!iobuf);
|
||||
iobuf = iobuf_open( fname );
|
||||
if( !iobuf ) {
|
||||
@ -1084,7 +1105,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
leave:
|
||||
free_packet(&pkt);
|
||||
set_packet_list_mode(save_mode);
|
||||
#if __MINGW32__ || 1
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
iobuf_close(iobuf);
|
||||
#endif
|
||||
return rc;
|
||||
@ -1276,10 +1297,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
if( kbpos->fp )
|
||||
BUG(); /* not allowed with such a handle */
|
||||
|
||||
if( !keyring_lock );
|
||||
keyring_lock = make_dotlock( rentry->fname, -1 );
|
||||
if( !keyring_lock )
|
||||
log_fatal("can't lock `%s'\n", rentry->fname );
|
||||
lock_rentry( rentry );
|
||||
|
||||
/* open the source file */
|
||||
fp = iobuf_open( rentry->fname );
|
||||
@ -1290,10 +1308,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
newfp = iobuf_create( rentry->fname );
|
||||
if( !newfp ) {
|
||||
log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno));
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
else
|
||||
@ -1305,28 +1320,19 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
iobuf_cancel(newfp);
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
}
|
||||
if( iobuf_close(newfp) ) {
|
||||
log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_CLOSE_FILE;
|
||||
}
|
||||
if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
|
||||
log_error("%s: chmod failed: %s\n",
|
||||
rentry->fname, strerror(errno) );
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
return 0;
|
||||
@ -1338,7 +1344,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
}
|
||||
|
||||
/* create the new file */
|
||||
#ifdef __MINGW32__
|
||||
#ifdef USE_ONLY_8DOT3
|
||||
/* Here is another Windoze bug?:
|
||||
* you cant rename("pubring.gpg.tmp", "pubring.gpg");
|
||||
* but rename("pubring.gpg.tmp", "pubring.aaa");
|
||||
@ -1451,7 +1457,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
goto leave;
|
||||
}
|
||||
/* if the new file is a secring, restrict the permissions */
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if( rentry->secret ) {
|
||||
if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) {
|
||||
log_error("%s: chmod failed: %s\n",
|
||||
@ -1464,7 +1470,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
|
||||
/* rename and make backup file */
|
||||
if( !rentry->secret ) { /* but not for secret keyrings */
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
remove( bakfname );
|
||||
#endif
|
||||
if( rename( rentry->fname, bakfname ) ) {
|
||||
@ -1474,7 +1480,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
remove( rentry->fname );
|
||||
#endif
|
||||
if( rename( tmpfname, rentry->fname ) ) {
|
||||
@ -1492,10 +1498,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
}
|
||||
|
||||
leave:
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
m_free(bakfname);
|
||||
m_free(tmpfname);
|
||||
return rc;
|
||||
|
12
g10/signal.c
12
g10/signal.c
@ -70,7 +70,7 @@ got_usr_signal( int sig )
|
||||
caught_sigusr1 = 1;
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
static void
|
||||
do_sigaction( int sig, struct sigaction *nact )
|
||||
{
|
||||
@ -85,7 +85,7 @@ do_sigaction( int sig, struct sigaction *nact )
|
||||
void
|
||||
init_signals()
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
struct sigaction nact;
|
||||
|
||||
nact.sa_handler = got_fatal_signal;
|
||||
@ -100,7 +100,7 @@ init_signals()
|
||||
nact.sa_handler = got_usr_signal;
|
||||
sigaction( SIGUSR1, &nact, NULL );
|
||||
nact.sa_handler = SIG_IGN;
|
||||
sigaction( SIGPIPE, &nact, NULL );
|
||||
sigaction( SIGPIPE, &nact, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ init_signals()
|
||||
void
|
||||
pause_on_sigusr( int which )
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
sigset_t mask, oldmask;
|
||||
|
||||
assert( which == 1 );
|
||||
@ -127,7 +127,7 @@ pause_on_sigusr( int which )
|
||||
static void
|
||||
do_block( int block )
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
static int is_blocked;
|
||||
static sigset_t oldmask;
|
||||
|
||||
@ -146,7 +146,7 @@ do_block( int block )
|
||||
sigprocmask( SIG_SETMASK, &oldmask, NULL );
|
||||
is_blocked = 0;
|
||||
}
|
||||
#endif /*__MINGW32__*/
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
}
|
||||
|
||||
|
||||
|
78
g10/tdbio.c
78
g10/tdbio.c
@ -77,7 +77,8 @@ struct cmp_sdir_struct {
|
||||
|
||||
|
||||
static char *db_name;
|
||||
static const char *lockname;
|
||||
static DOTLOCK lockhandle;
|
||||
static int is_locked;
|
||||
static int db_fd = -1;
|
||||
static int in_transaction;
|
||||
|
||||
@ -236,10 +237,12 @@ put_record_into_cache( ulong recno, const char *data )
|
||||
int n = dirty_count / 5; /* discard some dirty entries */
|
||||
if( !n )
|
||||
n = 1;
|
||||
if( !lockname )
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
}
|
||||
for( unused = NULL, r = cache_list; r; r = r->next ) {
|
||||
if( r->flags.used && r->flags.dirty ) {
|
||||
int rc = write_cache_item( r );
|
||||
@ -254,8 +257,8 @@ put_record_into_cache( ulong recno, const char *data )
|
||||
}
|
||||
}
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
assert( unused );
|
||||
r = unused;
|
||||
@ -287,17 +290,20 @@ tdbio_sync()
|
||||
CACHE_CTRL r;
|
||||
int did_lock = 0;
|
||||
|
||||
if( db_fd == -1 )
|
||||
open_db();
|
||||
if( in_transaction )
|
||||
log_bug("tdbio: syncing while in transaction\n");
|
||||
|
||||
if( !cache_is_dirty )
|
||||
return 0;
|
||||
|
||||
if( !lockname ) {
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
did_lock = 1;
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
}
|
||||
for( r = cache_list; r; r = r->next ) {
|
||||
if( r->flags.used && r->flags.dirty ) {
|
||||
@ -308,8 +314,8 @@ tdbio_sync()
|
||||
}
|
||||
cache_is_dirty = 0;
|
||||
if( did_lock && !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -344,17 +350,19 @@ tdbio_end_transaction()
|
||||
|
||||
if( !in_transaction )
|
||||
log_bug("tdbio: no active transaction\n");
|
||||
if( !lockname )
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
}
|
||||
block_all_signals();
|
||||
in_transaction = 0;
|
||||
rc = tdbio_sync();
|
||||
unblock_all_signals();
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -392,9 +400,9 @@ tdbio_cancel_transaction()
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
if( lockname ) {
|
||||
release_dotlock(lockname);
|
||||
lockname = NULL;
|
||||
if( is_locked ) {
|
||||
if( !release_dotlock(lockhandle) )
|
||||
is_locked = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,7 +436,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
if( access( fname, F_OK ) ) {
|
||||
if( strlen(fname) >= 7
|
||||
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
|
||||
#if __MINGW32__
|
||||
#if HAVE_DOSISH_SYSTEM
|
||||
if( mkdir( fname ) )
|
||||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
@ -450,7 +458,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
fclose(fp);
|
||||
m_free(db_name);
|
||||
db_name = fname;
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
db_fd = open( db_name, O_RDWR | O_BINARY );
|
||||
#else
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
@ -501,7 +509,10 @@ open_db()
|
||||
TRUSTREC rec;
|
||||
assert( db_fd == -1 );
|
||||
|
||||
#ifdef __MINGW32__
|
||||
lockhandle = create_dotlock( db_name );
|
||||
if( !lockhandle )
|
||||
log_fatal( _("%s: can't create lock\n"), db_name );
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
db_fd = open( db_name, O_RDWR | O_BINARY );
|
||||
#else
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
@ -970,6 +981,8 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
rec->r.uid.prefrec,
|
||||
rec->r.uid.siglist,
|
||||
rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
|
||||
if( rec->r.uid.uidflags & UIDF_VALVALID )
|
||||
fprintf( fp, ", v=%02x", rec->r.uid.validity );
|
||||
if( rec->r.uid.uidflags & UIDF_CHECKED ) {
|
||||
if( rec->r.uid.uidflags & UIDF_VALID )
|
||||
fputs(", valid", fp );
|
||||
@ -1155,7 +1168,18 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
rec->r.uid.prefrec = buftoulong(p); p += 4;
|
||||
rec->r.uid.siglist = buftoulong(p); p += 4;
|
||||
rec->r.uid.uidflags = *p++;
|
||||
p ++;
|
||||
rec->r.uid.validity = *p++;
|
||||
switch( rec->r.uid.validity ) {
|
||||
case 0:
|
||||
case TRUST_UNDEFINED:
|
||||
case TRUST_NEVER:
|
||||
case TRUST_MARGINAL:
|
||||
case TRUST_FULLY:
|
||||
case TRUST_ULTIMATE:
|
||||
break;
|
||||
default:
|
||||
log_info("lid %lu: invalid validity value - cleared\n", recnum);
|
||||
}
|
||||
memcpy( rec->r.uid.namehash, p, 20);
|
||||
break;
|
||||
case RECTYPE_PREF: /* preference record */
|
||||
@ -1278,7 +1302,7 @@ tdbio_write_record( TRUSTREC *rec )
|
||||
ulongtobuf(p, rec->r.uid.prefrec); p += 4;
|
||||
ulongtobuf(p, rec->r.uid.siglist); p += 4;
|
||||
*p++ = rec->r.uid.uidflags;
|
||||
p++;
|
||||
*p++ = rec->r.uid.validity;
|
||||
memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
|
||||
break;
|
||||
|
||||
|
10
g10/tdbio.h
10
g10/tdbio.h
@ -59,9 +59,10 @@
|
||||
#define KEYF_EXPIRED 4 /* this key is expired */
|
||||
#define KEYF_REVOKED 8 /* this key has been revoked */
|
||||
|
||||
#define UIDF_CHECKED 1 /* user id has been checked - other bits are valid */
|
||||
#define UIDF_VALID 2 /* this is a valid user id */
|
||||
#define UIDF_REVOKED 8 /* this user id has been revoked */
|
||||
#define UIDF_CHECKED 1 /* user id has been checked - other bits are valid */
|
||||
#define UIDF_VALID 2 /* this is a valid user id */
|
||||
#define UIDF_REVOKED 8 /* this user id has been revoked */
|
||||
#define UIDF_VALVALID 16 /* the validity field is valid */
|
||||
|
||||
#define SIGF_CHECKED 1 /* signature has been checked - bits 0..6 are valid */
|
||||
#define SIGF_VALID 2 /* the signature is valid */
|
||||
@ -98,7 +99,7 @@ struct trust_record {
|
||||
ulong cacherec; /* the cache record */
|
||||
byte ownertrust;
|
||||
byte dirflags;
|
||||
byte validity; /* calculated trustlevel */
|
||||
byte validity; /* calculated trustlevel over all uids */
|
||||
} dir;
|
||||
struct { /* primary public key record */
|
||||
ulong lid;
|
||||
@ -114,6 +115,7 @@ struct trust_record {
|
||||
ulong prefrec; /* recno of preference record */
|
||||
ulong siglist; /* list of valid signatures (w/o self-sig)*/
|
||||
byte uidflags;
|
||||
byte validity; /* calculated trustlevel of this uid */
|
||||
byte namehash[20]; /* ripemd hash of the username */
|
||||
} uid;
|
||||
struct { /* preference record */
|
||||
|
253
g10/trustdb.c
253
g10/trustdb.c
@ -104,6 +104,8 @@ static void release_lid_table( LOCAL_ID_TABLE tbl );
|
||||
static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
|
||||
static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
|
||||
|
||||
|
||||
|
||||
static void print_user_id( const char *text, u32 *keyid );
|
||||
static void sort_tsl_list( TRUST_SEG_LIST *trust_seg_list );
|
||||
static int list_sigs( ulong pubkey_id );
|
||||
@ -839,42 +841,13 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
ulong rn, uidrn;
|
||||
int marginal=0;
|
||||
int fully=0;
|
||||
LOCAL_ID_TABLE sigs_seen = NULL;
|
||||
/*LOCAL_ID_TABLE sigs_seen = NULL;*/
|
||||
|
||||
if( depth >= max_depth ) /* max cert_depth reached */
|
||||
return TRUST_UNDEFINED;
|
||||
|
||||
stack[depth].lid = drec->r.dir.lid;
|
||||
stack[depth].otrust = drec->r.dir.ownertrust;
|
||||
stack[depth].trust = 0;
|
||||
{ int i;
|
||||
|
||||
for(i=0; i < depth; i++ )
|
||||
if( stack[i].lid == drec->r.dir.lid )
|
||||
return TRUST_UNDEFINED; /* closed (we already visited this lid) */
|
||||
}
|
||||
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
|
||||
/* we are at the end of a path */
|
||||
TRUST_SEG_LIST tsl;
|
||||
int i;
|
||||
|
||||
stack[depth].trust = TRUST_ULTIMATE;
|
||||
stack[depth].otrust = TRUST_ULTIMATE;
|
||||
if( trust_seg_head ) {
|
||||
/* we can now put copy our current stack to the trust_seg_list */
|
||||
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
|
||||
for(i=0; i <= depth; i++ )
|
||||
tsl->path[i] = stack[i];
|
||||
tsl->pathlen = i;
|
||||
tsl->next = *trust_seg_head;
|
||||
*trust_seg_head = tsl;
|
||||
}
|
||||
return TRUST_ULTIMATE;
|
||||
}
|
||||
|
||||
/* loop over all user-ids */
|
||||
if( !all )
|
||||
sigs_seen = new_lid_table();
|
||||
/*if( !all ) sigs_seen = new_lid_table();*/
|
||||
for( rn = drec->r.dir.uidlist; rn; rn = uidrn ) {
|
||||
TRUSTREC rec; /* used for uids and sigs */
|
||||
ulong sigrn;
|
||||
@ -888,7 +861,36 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
if( (rec.r.uid.uidflags & UIDF_REVOKED) )
|
||||
continue; /* user id has been revoked */
|
||||
|
||||
/* loop over all signature records */
|
||||
stack[depth].lid = drec->r.dir.lid;
|
||||
stack[depth].otrust = drec->r.dir.ownertrust;
|
||||
stack[depth].trust = 0;
|
||||
{ int i;
|
||||
|
||||
for(i=0; i < depth; i++ )
|
||||
if( stack[i].lid == drec->r.dir.lid )
|
||||
return TRUST_UNDEFINED; /* closed (we already visited this lid) */
|
||||
}
|
||||
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
|
||||
/* we are at the end of a path */
|
||||
TRUST_SEG_LIST tsl;
|
||||
int i;
|
||||
|
||||
stack[depth].trust = TRUST_ULTIMATE;
|
||||
stack[depth].otrust = TRUST_ULTIMATE;
|
||||
if( trust_seg_head ) {
|
||||
/* we can now put copy our current stack to the trust_seg_list */
|
||||
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
|
||||
for(i=0; i <= depth; i++ )
|
||||
tsl->path[i] = stack[i];
|
||||
tsl->pathlen = i;
|
||||
tsl->next = *trust_seg_head;
|
||||
*trust_seg_head = tsl;
|
||||
}
|
||||
return TRUST_ULTIMATE;
|
||||
}
|
||||
|
||||
|
||||
/* loop over all signature records of this user id */
|
||||
for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
|
||||
int i;
|
||||
|
||||
@ -917,11 +919,11 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
}
|
||||
|
||||
/* visit every signer only once (a signer may have
|
||||
* signed more than one user ID) */
|
||||
if( sigs_seen && ins_lid_table_item( sigs_seen,
|
||||
rec.r.sig.sig[i].lid, 0) )
|
||||
continue; /* we already have this one */
|
||||
|
||||
* signed more than one user ID)
|
||||
* if( sigs_seen && ins_lid_table_item( sigs_seen,
|
||||
* rec.r.sig.sig[i].lid, 0) )
|
||||
* continue; we already have this one
|
||||
*/
|
||||
read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
|
||||
if( tmp.rectype != RECTYPE_DIR ) {
|
||||
if( tmp.rectype != RECTYPE_SDIR )
|
||||
@ -945,8 +947,7 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
/* we have signed this key and only in this special case
|
||||
* we assume that this one is fully trusted */
|
||||
if( !all ) {
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
|
||||
return (stack[depth].trust = TRUST_FULLY);
|
||||
}
|
||||
}
|
||||
@ -962,16 +963,14 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
if( fully >= opt.completes_needed
|
||||
|| marginal >= opt.marginals_needed ) {
|
||||
if( !all ) {
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
|
||||
return (stack[depth].trust = TRUST_FULLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen ); */
|
||||
if( all && ( fully >= opt.completes_needed
|
||||
|| marginal >= opt.marginals_needed ) ) {
|
||||
return (stack[depth].trust = TRUST_FULLY );
|
||||
@ -983,6 +982,145 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
ulong lid;
|
||||
ulong uid;
|
||||
} CERT_ITEM;
|
||||
|
||||
/* structure to hold certification chains. Item[nitems-1] is the
|
||||
* ultimateley trusted key, item[0] is the key which
|
||||
* is introduced, indices [1,(nitems-2)] are all introducers.
|
||||
*/
|
||||
typedef struct cert_chain *CERT_CHAIN;
|
||||
struct cert_chain {
|
||||
CERT_CHAIN next;
|
||||
int dups;
|
||||
int nitems;
|
||||
CERT_ITEM items[1];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Copy all items to the set SET_HEAD in a way that the requirements
|
||||
* of a CERT_CHAIN are met.
|
||||
*/
|
||||
static void
|
||||
add_cert_items_to_set( CERT_CHAIN *set_head, CERT_ITEM *items, int nitems )
|
||||
{
|
||||
CERT_CHAIN ac;
|
||||
int i;
|
||||
|
||||
ac = m_alloc_clear( sizeof *ac + (nitems-1)*sizeof(CERT_ITEM) );
|
||||
ac->nitems = nitems;
|
||||
for(i=0; i < nitems; i++ )
|
||||
ac->items[i] = items[i];
|
||||
ac->next = *set_head;
|
||||
*set_head = ac;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Find all certification paths of a given LID.
|
||||
* Limit the search to MAX_DEPTH. stack is a helper variable which
|
||||
* should have been allocated with size max_depth, stack[0] should
|
||||
* be setup to the key we are investigating, so the minimal depth
|
||||
* we should ever see in this function is 1.
|
||||
* Returns: -1 max_depth reached
|
||||
* 0 no paths found
|
||||
* 1 ultimately trusted key found
|
||||
* certchain_set must be a valid set or point to NULL; this function
|
||||
* may modifiy it.
|
||||
*/
|
||||
static int
|
||||
find_cert_chain( ulong lid, int depth, int max_depth,
|
||||
CERT_ITEM *stack, CERT_CHAIN *cert_chain_set )
|
||||
{
|
||||
TRUSTREC dirrec;
|
||||
TRUSTREC uidrec;
|
||||
ulong uidrno;
|
||||
|
||||
if( depth >= max_depth )
|
||||
return -1;
|
||||
|
||||
stack[depth].lid = lid;
|
||||
stack[depth].uid = 0;
|
||||
|
||||
if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
|
||||
/* this is an ultimately trusted key;
|
||||
* which means that we have found the end of the chain:
|
||||
* copy the chain to the set */
|
||||
add_cert_items_to_set( cert_chain_set, stack, depth+1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
read_record( lid, &dirrec, 0 );
|
||||
if( dirrec.rectype != RECTYPE_DIR ) {
|
||||
if( dirrec.rectype != RECTYPE_SDIR )
|
||||
log_debug("lid %lu, has rectype %d"
|
||||
" - skipped\n", lid, dirrec.rectype );
|
||||
return 0;
|
||||
}
|
||||
/* Performance hint: add stuff to ignore this one when the
|
||||
* assigned validity of the key is bad */
|
||||
|
||||
/* loop over all user ids */
|
||||
for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
|
||||
TRUSTREC sigrec;
|
||||
ulong sigrno;
|
||||
|
||||
stack[depth].uid = uidrno;
|
||||
read_record( uidrno, &uidrec, RECTYPE_UID );
|
||||
|
||||
if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
|
||||
continue; /* user id has not been checked */
|
||||
if( !(uidrec.r.uid.uidflags & UIDF_VALID) )
|
||||
continue; /* user id is not valid */
|
||||
if( (uidrec.r.uid.uidflags & UIDF_REVOKED) )
|
||||
continue; /* user id has been revoked */
|
||||
|
||||
/* loop over all signature records */
|
||||
for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
|
||||
int i, j;
|
||||
|
||||
read_record( sigrno, &sigrec, RECTYPE_SIG );
|
||||
|
||||
for(i=0; i < SIGS_PER_RECORD; i++ ) {
|
||||
if( !sigrec.r.sig.sig[i].lid )
|
||||
continue; /* skip deleted sigs */
|
||||
if( !(sigrec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||
continue; /* skip unchecked signatures */
|
||||
if( !(sigrec.r.sig.sig[i].flag & SIGF_VALID) )
|
||||
continue; /* skip invalid signatures */
|
||||
if( (sigrec.r.sig.sig[i].flag & SIGF_EXPIRED) )
|
||||
continue; /* skip expired signatures */
|
||||
if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
|
||||
continue; /* skip revoked signatures */
|
||||
for(j=0; j < depth; j++ ) {
|
||||
if( stack[j].lid == sigrec.r.sig.sig[i].lid )
|
||||
break;
|
||||
}
|
||||
if( j < depth )
|
||||
continue; /* avoid cycles as soon as possible */
|
||||
|
||||
if( find_cert_chain( sigrec.r.sig.sig[i].lid,
|
||||
depth+1, max_depth,
|
||||
stack, cert_chain_set ) > 0 ) {
|
||||
/* ultimately trusted key found:
|
||||
* no need to check more signatures of this uid */
|
||||
sigrec.r.sig.next = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end loop over sig recs */
|
||||
} /* end loop over user ids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Given the directory record of a key, check whether we can
|
||||
* find a path to an ultimately trusted key. We do this by
|
||||
@ -1337,6 +1475,7 @@ void
|
||||
list_trust_path( const char *username )
|
||||
{
|
||||
int rc;
|
||||
ulong lid;
|
||||
TRUSTREC rec;
|
||||
TRUST_INFO *tmppath;
|
||||
TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
|
||||
@ -1357,8 +1496,10 @@ list_trust_path( const char *username )
|
||||
assert( pk->local_id );
|
||||
}
|
||||
}
|
||||
lid = pk->local_id;
|
||||
free_public_key( pk );
|
||||
|
||||
#if 0
|
||||
/* collect the paths */
|
||||
tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
|
||||
trust_seg_list = NULL;
|
||||
@ -1378,6 +1519,26 @@ list_trust_path( const char *username )
|
||||
m_free( tsl );
|
||||
}
|
||||
trust_seg_list = NULL;
|
||||
#else /* test code */
|
||||
{
|
||||
CERT_ITEM *stack;
|
||||
CERT_CHAIN chains, r;
|
||||
int i;
|
||||
|
||||
chains = NULL;
|
||||
stack = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *stack );
|
||||
find_cert_chain( lid, 0, opt.max_cert_depth, stack, &chains);
|
||||
m_free( stack );
|
||||
/* dump chains */
|
||||
for(r=chains; r ; r = r->next ) {
|
||||
printf("chain:" );
|
||||
for(i=0; i < r->nitems; i++ )
|
||||
printf(" %4lu/%-4lu", r->items[i].lid, r->items[i].uid );
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2719,15 +2880,17 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
||||
continue; /* skip deleted sigs */
|
||||
}
|
||||
if( rec.r.sig.sig[i].lid == pk_lid ) {
|
||||
#if 0 /* must take uid into account */
|
||||
if( found_sig ) {
|
||||
log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||
(ulong)keyid[1], lid, uidhash[18],
|
||||
uidhash[19], (ulong)sig->keyid[1],
|
||||
_("Duplicated certificate - deleted") );
|
||||
_("duplicated certificate - deleted") );
|
||||
rec.r.sig.sig[i].lid = 0;
|
||||
rec.dirty = 1;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
found_sig = 1;
|
||||
}
|
||||
if( !recheck && !revoke && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||
@ -2811,7 +2974,7 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
||||
}
|
||||
}
|
||||
|
||||
if( found_sig )
|
||||
if( found_sig ) /* fixme: uid stuff */
|
||||
return;
|
||||
|
||||
/* at this point, we have verified, that the signature is not in
|
||||
|
@ -1,3 +1,8 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* cipher.h (CIPHER_ALGO_TWOFISH): Chnaged ID to 10 and renamed
|
||||
the old experimenatl algorithm to xx_OLD.
|
||||
|
||||
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* cipher.h (MD_BUFFER_SIZE): Removed.
|
||||
|
@ -33,9 +33,10 @@
|
||||
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */
|
||||
#define CIPHER_ALGO_SAFER_SK128 5
|
||||
#define CIPHER_ALGO_DES_SK 6
|
||||
#define CIPHER_ALGO_TWOFISH 10 /* twofish 256 bit */
|
||||
#define CIPHER_ALGO_BLOWFISH160 42 /* blowfish 160 bit key (not in OpenPGP)*/
|
||||
#define CIPHER_ALGO_SKIPJACK 101 /* experimental: skipjack */
|
||||
#define CIPHER_ALGO_TWOFISH 102 /* experimental: twofish 128 bit */
|
||||
#define CIPHER_ALGO_TWOFISH_OLD 102 /* experimental: twofish 128 bit */
|
||||
#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */
|
||||
|
||||
#define PUBKEY_ALGO_RSA 1
|
||||
@ -63,11 +64,9 @@ typedef struct {
|
||||
byte key[24]; /* this is the largest used keylen (3des) */
|
||||
} DEK;
|
||||
|
||||
struct cipher_handle_s;
|
||||
typedef struct cipher_handle_s *CIPHER_HANDLE;
|
||||
|
||||
#ifndef DEFINES_CIPHER_HANDLE
|
||||
struct cipher_handle_s { char does_not_matter[1]; };
|
||||
#endif
|
||||
|
||||
#define CIPHER_MODE_ECB 1
|
||||
#define CIPHER_MODE_CFB 2
|
||||
@ -75,6 +74,8 @@ struct cipher_handle_s { char does_not_matter[1]; };
|
||||
#define CIPHER_MODE_AUTO_CFB 4
|
||||
#define CIPHER_MODE_DUMMY 5 /* used with algo DUMMY for no encryption */
|
||||
|
||||
struct md_digest_list_s;
|
||||
|
||||
typedef struct {
|
||||
int secure;
|
||||
FILE *debug;
|
||||
@ -85,12 +86,6 @@ typedef struct {
|
||||
} *MD_HANDLE;
|
||||
|
||||
|
||||
#ifndef DEFINES_MD_HANDLE /* not really the handle but the algorithm list */
|
||||
struct md_digest_list_s { char does_not_matter[1]; };
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int g10c_debug_mode;
|
||||
int g10_opt_verbose;
|
||||
|
||||
|
@ -127,10 +127,12 @@ const char *strusage( int level );
|
||||
|
||||
|
||||
/*-- dotlock.c --*/
|
||||
const char *make_dotlock( const char *file_to_lock, long timeout );
|
||||
int release_dotlock( const char *lockfile );
|
||||
|
||||
struct dotlock_handle;
|
||||
typedef struct dotlock_handle *DOTLOCK;
|
||||
|
||||
DOTLOCK create_dotlock( const char *file_to_lock );
|
||||
int make_dotlock( DOTLOCK h, long timeout );
|
||||
int release_dotlock( DOTLOCK h );
|
||||
|
||||
|
||||
/*-- fileutil.c --*/
|
||||
|
@ -1,3 +1,7 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* pl.po: New version.
|
||||
|
||||
Wed Jan 20 21:40:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* es_ES.po: Import of new version.
|
||||
|
@ -1,3 +1,7 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* config.sub, config.guess: Support i386-emx-os2
|
||||
|
||||
Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* autogen.sh: Now checks for installed gettext
|
||||
|
4
scripts/config.guess
vendored
4
scripts/config.guess
vendored
@ -708,6 +708,10 @@ main ()
|
||||
printf ("i860-alliant-bsd\n"); exit (0);
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
printf ("i386-emx-os2"); exit(0);
|
||||
#endif
|
||||
|
||||
exit (1);
|
||||
}
|
||||
EOF
|
||||
|
6
scripts/config.sub
vendored
6
scripts/config.sub
vendored
@ -282,6 +282,9 @@ case $basic_machine in
|
||||
atarist)
|
||||
basic_machine=m68k-atari
|
||||
;;
|
||||
emx)
|
||||
basic_machine=i386-emx
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@ -971,6 +974,9 @@ case $os in
|
||||
-mint)
|
||||
os=-mint
|
||||
;;
|
||||
-os2)
|
||||
os=-os2
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
|
@ -18,6 +18,10 @@ fix_it () {
|
||||
|
||||
EOF
|
||||
cvs -Q checkout -p gnupg/NEWS >>$dir/NEWS
|
||||
here=`pwd`
|
||||
cd $dir
|
||||
ln -sf gnupg.html index.html
|
||||
cd $here
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
@ -67,7 +67,7 @@ main(int argc, char **argv)
|
||||
int n, size=4096;
|
||||
int algo;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
setmode( fileno(stdin), O_BINARY );
|
||||
setmode( fileno(stdout), O_BINARY );
|
||||
#endif
|
||||
|
@ -19,10 +19,10 @@
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
fprintf(stderr, "Sorry, not yet available for Windoze\n");
|
||||
fprintf(stderr, "Sorry, not yet available for DOSish systems\n");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
@ -193,4 +193,4 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
|
||||
#endif /* !__MINGW32__ */
|
||||
#endif
|
||||
|
@ -1,3 +1,10 @@
|
||||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* dotlock.c (remove_lockfiles): Add cleanup function.
|
||||
(make_dotlock): Add deadlock check.
|
||||
|
||||
* secmem.c (secmem_malloc): Changed error message.
|
||||
|
||||
Wed Jan 20 21:40:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* http.c (http_wait_response): Moved the shutdown behind the dup
|
||||
|
261
util/dotlock.c
261
util/dotlock.c
@ -35,37 +35,56 @@
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
|
||||
struct dotlock_handle {
|
||||
struct dotlock_handle *next;
|
||||
char *tname; /* name of lockfile template */
|
||||
char *lockname; /* name of the real lockfile */
|
||||
int locked; /* lock status */
|
||||
};
|
||||
|
||||
|
||||
static DOTLOCK all_lockfiles;
|
||||
|
||||
static int read_lockfile( const char *name );
|
||||
static void remove_lockfiles(void);
|
||||
|
||||
/****************
|
||||
* Create a lockfile with the given name. A TIMEOUT of 0
|
||||
* returns immediately, -1 waits forever (hopefully not), other
|
||||
* values are timeouts in milliseconds.
|
||||
* Returns: a char pointer used as handle for release lock
|
||||
* or NULL in case of an error.
|
||||
* Create a lockfile with the given name and return an object of
|
||||
* type DOTLOCK which may be used later to actually do the lock.
|
||||
* A cleanup routine gets installed to cleanup left over locks
|
||||
* or other files used together with the lockmechanism.
|
||||
* Althoug the function is called dotlock, this does not necessarily
|
||||
* mean that real lockfiles are used - the function may decide to
|
||||
* use fcntl locking. Calling the function with NULL only install
|
||||
* the atexit handler and maybe used to assure that the cleanup
|
||||
* is called after all other atexit handlers.
|
||||
*
|
||||
* Notes: This function creates a lock file in the same directory
|
||||
* as file_to_lock with the name "file_to_lock.lock"
|
||||
* A temporary file ".#lk.<hostname>.pid[.threadid] is used.
|
||||
* This function does nothing for Windoze.
|
||||
*/
|
||||
const char *
|
||||
make_dotlock( const char *file_to_lock, long timeout )
|
||||
DOTLOCK
|
||||
create_dotlock( const char *file_to_lock )
|
||||
{
|
||||
int fd=-1, pid;
|
||||
static int initialized;
|
||||
DOTLOCK h;
|
||||
int fd = -1;
|
||||
char pidstr[16];
|
||||
const char *handle = NULL;
|
||||
char *lockname = NULL;
|
||||
char *tname = NULL;
|
||||
int have_tfile = 0;
|
||||
struct utsname uts;
|
||||
const char *nodename;
|
||||
const char *dirpart;
|
||||
int dirpartlen;
|
||||
const char *maybe_dead="";
|
||||
int backoff=0;
|
||||
|
||||
if( !initialized ) {
|
||||
atexit( remove_lockfiles );
|
||||
initialized = 1;
|
||||
}
|
||||
if( !file_to_lock )
|
||||
return NULL;
|
||||
|
||||
h = m_alloc_clear( sizeof *h );
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
sprintf( pidstr, "%10d\n", getpid() );
|
||||
/* fixme: add the hostname to the second line (FQDN or IP addr?) */
|
||||
|
||||
@ -84,131 +103,180 @@ make_dotlock( const char *file_to_lock, long timeout )
|
||||
dirpart = file_to_lock;
|
||||
}
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
tname = m_alloc( dirpartlen + 6 + strlen(nodename) + 11+ 20 );
|
||||
sprintf( tname, "%.*s/.#lk.%s.%d.%p",
|
||||
dirpartlen, dirpart, nodename, getpid(), &pid );
|
||||
#else
|
||||
tname = m_alloc( dirpartlen + 6 + strlen(nodename) + 11 );
|
||||
sprintf( tname, "%.*s/.#lk.%s.%d",
|
||||
dirpartlen, dirpart, nodename, getpid() );
|
||||
#ifdef _REENTRANT
|
||||
/* fixme: aquire mutex on all_lockfiles */
|
||||
#endif
|
||||
h->next = all_lockfiles;
|
||||
all_lockfiles = h;
|
||||
|
||||
h->tname = m_alloc( dirpartlen + 6+30+ strlen(nodename) + 11 );
|
||||
sprintf( h->tname, "%.*s/.#lk%p.%s.%d",
|
||||
dirpartlen, dirpart, h, nodename, (int)getpid() );
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
fd = open( tname, O_WRONLY|O_CREAT|O_EXCL,
|
||||
fd = open( h->tname, O_WRONLY|O_CREAT|O_EXCL,
|
||||
S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
|
||||
} while( fd == -1 && errno == EINTR );
|
||||
if( fd == -1 ) {
|
||||
log_error( "failed to create temporary file `%s': %s\n",
|
||||
tname, strerror(errno));
|
||||
goto leave;
|
||||
h->tname, strerror(errno));
|
||||
m_free(h->tname);
|
||||
m_free(h);
|
||||
return NULL;
|
||||
}
|
||||
have_tfile = 1;
|
||||
if( write(fd, pidstr, 11 ) != 11 ) {
|
||||
log_fatal( "error writing to `%s': %s\n", tname, strerror(errno) );
|
||||
goto leave;
|
||||
all_lockfiles = h->next;
|
||||
#ifdef _REENTRANT
|
||||
/* release mutex */
|
||||
#endif
|
||||
log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) );
|
||||
close(fd);
|
||||
unlink(h->tname);
|
||||
m_free(h->tname);
|
||||
m_free(h);
|
||||
return NULL;
|
||||
}
|
||||
if( close(fd) ) {
|
||||
log_error( "error closing `%s': %s\n", tname, strerror(errno));
|
||||
goto leave;
|
||||
all_lockfiles = h->next;
|
||||
#ifdef _REENTRANT
|
||||
/* release mutex */
|
||||
#endif
|
||||
log_error( "error closing `%s': %s\n", h->tname, strerror(errno));
|
||||
unlink(h->tname);
|
||||
m_free(h->tname);
|
||||
m_free(h);
|
||||
return NULL;
|
||||
}
|
||||
fd = -1;
|
||||
|
||||
lockname = m_alloc( strlen(file_to_lock) + 6 );
|
||||
strcpy(stpcpy(lockname, file_to_lock), ".lock");
|
||||
#ifdef _REENTRANT
|
||||
/* release mutex */
|
||||
#endif
|
||||
#endif /* !HAVE_DOSISH_SYSTEM */
|
||||
h->lockname = m_alloc( strlen(file_to_lock) + 6 );
|
||||
strcpy(stpcpy(h->lockname, file_to_lock), ".lock");
|
||||
return h;
|
||||
}
|
||||
|
||||
retry:
|
||||
if( !link(tname, lockname) ) {/* fixme: better use stat to check the link count */
|
||||
handle = lockname;
|
||||
lockname = NULL;
|
||||
static int
|
||||
maybe_deadlock( DOTLOCK h )
|
||||
{
|
||||
DOTLOCK r;
|
||||
|
||||
for( r=all_lockfiles; r; r = r->next ) {
|
||||
if( r != h && r->locked )
|
||||
return 1;
|
||||
}
|
||||
else if( errno == EEXIST ) {
|
||||
if( (pid = read_lockfile(lockname)) == -1 ) {
|
||||
if( errno == ENOENT ) {
|
||||
log_info( "lockfile disappeared\n");
|
||||
goto retry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Do a lock on H. A TIMEOUT of 0 returns immediately,
|
||||
* -1 waits forever (hopefully not), other
|
||||
* values are timeouts in milliseconds.
|
||||
* Returns: 0 on success
|
||||
*/
|
||||
int
|
||||
make_dotlock( DOTLOCK h, long timeout )
|
||||
{
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
int pid;
|
||||
const char *maybe_dead="";
|
||||
int backoff=0;
|
||||
|
||||
if( h->locked ) {
|
||||
log_debug("oops, `%s' is already locked\n", h->lockname );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
if( !link(h->tname, h->lockname) ) {
|
||||
/* fixme: better use stat to check the link count */
|
||||
h->locked = 1;
|
||||
return 0; /* okay */
|
||||
}
|
||||
if( errno != EEXIST ) {
|
||||
log_error( "lock not made: link() failed: %s\n", strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
if( (pid = read_lockfile(h->lockname)) == -1 ) {
|
||||
if( errno != ENOENT ) {
|
||||
log_info("cannot read lockfile\n");
|
||||
return -1;
|
||||
}
|
||||
log_info("cannot read lockfile\n");
|
||||
log_info( "lockfile disappeared\n");
|
||||
continue;
|
||||
}
|
||||
else if( pid == getpid() ) {
|
||||
log_info( "Oops: lock already hold by us\n");
|
||||
handle = lockname;
|
||||
lockname = NULL;
|
||||
h->locked = 1;
|
||||
return 0; /* okay */
|
||||
}
|
||||
else if( kill(pid, 0) && errno == ESRCH ) {
|
||||
maybe_dead = " - probably dead";
|
||||
#if 0 /* we should not do this without checking the permissions */
|
||||
/* and the hostname */
|
||||
log_info( "removing stale lockfile (created by %d)", pid );
|
||||
remove( lockname );
|
||||
goto retry;
|
||||
#endif
|
||||
}
|
||||
if( timeout == -1 ) {
|
||||
struct timeval tv;
|
||||
log_info( "waiting for lock (hold by %d%s) ...\n", pid, maybe_dead );
|
||||
log_info( "waiting for lock (hold by %d%s) %s...\n",
|
||||
pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":"");
|
||||
|
||||
|
||||
/* can't use sleep, cause signals may be blocked */
|
||||
tv.tv_sec = 1 + backoff;
|
||||
tv.tv_usec = 0;
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
if( backoff < 10 )
|
||||
backoff++ ;
|
||||
goto retry;
|
||||
}
|
||||
/* fixme: implement timeouts */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
log_error( "lock not made: link() failed: %s\n", strerror(errno) );
|
||||
|
||||
leave:
|
||||
if( fd != -1 )
|
||||
close(fd);
|
||||
if( have_tfile )
|
||||
remove(tname);
|
||||
m_free(tname);
|
||||
m_free(lockname);
|
||||
return handle;
|
||||
/*not reached */
|
||||
#endif /* !HAVE_DOSISH_SYSTEM */
|
||||
}
|
||||
|
||||
/****************
|
||||
* Create a lockfile for a existing file
|
||||
* Returns: a char pointer used as handle for release lock
|
||||
* or NULL in case of an error.
|
||||
*
|
||||
* Notes: This function creates a lock file in the same directory
|
||||
* as file_to_lock with the name "lock.<inode-no>"
|
||||
*
|
||||
* int
|
||||
* make_inodelock( const char *file_to_lock )
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* release a lock
|
||||
* Returns: 0 := success
|
||||
*/
|
||||
int
|
||||
release_dotlock( const char *lockfile )
|
||||
release_dotlock( DOTLOCK h )
|
||||
{
|
||||
int pid = read_lockfile( lockfile );
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
int pid;
|
||||
|
||||
if( !h->locked ) {
|
||||
log_debug("oops, `%s' is not locked\n", h->lockname );
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = read_lockfile( h->lockname );
|
||||
if( pid == -1 ) {
|
||||
log_error( "release_dotlock: lockfile error");
|
||||
log_error( "release_dotlock: lockfile error\n");
|
||||
return -1;
|
||||
}
|
||||
if( pid != getpid() ) {
|
||||
log_error( "release_dotlock: not our lock (pid=%d)", pid);
|
||||
log_error( "release_dotlock: not our lock (pid=%d)\n", pid);
|
||||
return -1;
|
||||
}
|
||||
if( remove( lockfile ) ) {
|
||||
if( unlink( h->lockname ) ) {
|
||||
log_error( "release_dotlock: error removing lockfile `%s'",
|
||||
lockfile);
|
||||
h->lockname);
|
||||
return -1;
|
||||
}
|
||||
m_free( (char*)lockfile );
|
||||
/* fixme: check that the link count is now 1 */
|
||||
h->locked = 0;
|
||||
return 0;
|
||||
#endif /* !HAVE_DOSISH_SYSTEM */
|
||||
}
|
||||
|
||||
|
||||
@ -218,6 +286,9 @@ release_dotlock( const char *lockfile )
|
||||
static int
|
||||
read_lockfile( const char *name )
|
||||
{
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
return 0;
|
||||
#else
|
||||
int fd, pid;
|
||||
char pidstr[16];
|
||||
|
||||
@ -241,5 +312,29 @@ read_lockfile( const char *name )
|
||||
return -1;
|
||||
}
|
||||
return pid;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
remove_lockfiles()
|
||||
{
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
DOTLOCK h, h2;
|
||||
|
||||
h = all_lockfiles;
|
||||
all_lockfiles = NULL;
|
||||
|
||||
while( h ) {
|
||||
h2 = h->next;
|
||||
if( h->locked )
|
||||
unlink( h->lockname );
|
||||
unlink(h->tname);
|
||||
m_free(h->tname);
|
||||
m_free(h->lockname);
|
||||
m_free(h);
|
||||
h = h2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -38,16 +38,16 @@ char *
|
||||
make_basename(const char *filepath)
|
||||
{
|
||||
char *p;
|
||||
|
||||
|
||||
if ( !(p=strrchr(filepath, '/')) )
|
||||
#ifdef __MINGW32__
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#endif
|
||||
{
|
||||
return m_strdup(filepath);
|
||||
}
|
||||
|
||||
{
|
||||
return m_strdup(filepath);
|
||||
}
|
||||
|
||||
return m_strdup(p+1);
|
||||
}
|
||||
|
||||
@ -65,21 +65,21 @@ make_dirname(const char *filepath)
|
||||
char *dirname;
|
||||
int dirname_length;
|
||||
char *p;
|
||||
|
||||
|
||||
if ( !(p=strrchr(filepath, '/')) )
|
||||
#ifdef __MINGW32__
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#endif
|
||||
{
|
||||
return m_strdup(".");
|
||||
}
|
||||
|
||||
{
|
||||
return m_strdup(".");
|
||||
}
|
||||
|
||||
dirname_length = p-filepath;
|
||||
dirname = m_alloc(dirname_length+1);
|
||||
strncpy(dirname, filepath, dirname_length);
|
||||
dirname[dirname_length] = 0;
|
||||
|
||||
|
||||
return dirname;
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ compare_filenames( const char *a, const char *b )
|
||||
/* ? check whether this is an absolute filename and
|
||||
* resolve symlinks?
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
return stricmp(a,b);
|
||||
#else
|
||||
return strcmp(a,b);
|
||||
|
@ -126,8 +126,11 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
|
||||
*(char**)buf = "file_filter";
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
if( fp != stdin && fp != stdout )
|
||||
if( fp != stdin && fp != stdout ) {
|
||||
if( DBG_IOBUF )
|
||||
log_debug("%s: close fd %d\n", a->fname, fileno(fp) );
|
||||
fclose(fp);
|
||||
}
|
||||
fp = NULL;
|
||||
m_free(a); /* we can free our context now */
|
||||
}
|
||||
@ -545,7 +548,8 @@ iobuf_open( const char *fname )
|
||||
file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
|
||||
file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
|
||||
if( DBG_IOBUF )
|
||||
log_debug("iobuf-%d.%d: open `%s'\n", a->no, a->subno, fname );
|
||||
log_debug("iobuf-%d.%d: open `%s' fd=%d\n",
|
||||
a->no, a->subno, fname, fileno(fcx->fp) );
|
||||
|
||||
return a;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ void
|
||||
secmem_init( size_t n )
|
||||
{
|
||||
if( !n ) {
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
uid_t uid;
|
||||
|
||||
disable_secmem=1;
|
||||
@ -245,8 +245,12 @@ secmem_malloc( size_t size )
|
||||
MEMBLOCK *mb, *mb2;
|
||||
int compressed=0;
|
||||
|
||||
if( !pool_okay )
|
||||
log_bug("secmem not initialized\n");
|
||||
if( !pool_okay ) {
|
||||
log_info(
|
||||
_("operation is not possible without initialized secure memory\n"));
|
||||
log_info(_("(you may have used the wrong program for this task)\n"));
|
||||
exit(2);
|
||||
}
|
||||
if( show_warning && !suspend_warning ) {
|
||||
show_warning = 0;
|
||||
print_warn();
|
||||
|
@ -105,6 +105,8 @@ init_ttyfp()
|
||||
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 = fopen("/dev/tty", "r+");
|
||||
if( !ttyfp )
|
||||
|
Loading…
x
Reference in New Issue
Block a user