setting up environmental variable?

Marcus Brinkmann Marcus.Brinkmann at
Sun Dec 23 02:21:01 CET 2001


On Sat, Dec 22, 2001 at 06:29:41PM -0600, Tie Kan wrote:
> What I am doing
> --------------
> I am trying to encrypt a file with a "user name" in a pubring.pgp file I
> specify. As a result, I am only working intensively with the sample
> program t-encrypt.c)
> The basic problem I encountered is error "No recipient" when calling
> function
> 	 Gpgme_recipients_add_name_with_validity

Well, this means of course the gpg can not find the public key for this
recipient.  You could send me the public key ring you are using and test
program you use (do not send me the secret key ring).

> -------------
> My understanding is environmental "GNUPGHOME" specifies which
> "pubring.gpg" and "secring.gpg" are used as default key-rings.

Well, as a side effect.  It specifies what gnupg should use instead
"~/.gnupg" as its configuration directory.  Of course, the default key rings
live in this directory, too (but if you had an options file in that
directory specifying other keyrings, those would be used).

> In t-encrypt.c, we have
> Gpgme_recipients_add_name_with_validity(rset, "Alpha",
> Here, the key used to for encryption is "Alpha". However, "Alpha" is not
> listed as a user name in the pubring.gpg. It is listed as "Alpha Test"
> when I run the above. There is a directory called "Alpha" and a file
> Alpha/pubring.gpg inside this directory. 

gpgme_recipients_add_name_with_validity(rset, NAME, VALIDITY)
means for the GnuPG engine that "-r NAME" is added to the gnupg command

So, this is like saying:

GNUPGHOME=/some/path gpg --armor --encrypt -r Alpha

try it.  It works for me in the test directory.  gpg will do a substrig
match on the keys.  "Alpha" is a substring of "Alpha Test..." so it will
find the key.  If it says No_Recipient for you, the problem lies elsewhere.

You can first try if gnupg and the keyrings are okay by trying to run gpg
manually with the GNUPGHOME set and "-r Alpha" used.  If that doesn't work,
you might find the problem easier.  If it does work, and gpgme doesn't, then
I am highly interested in your program and setup.

> 	How do I determine which "user name" to use in function
> gpgme_recipients_add_name_with_validity

The short answer is "the same way as you specify recipients for the engine
used.  For OpenPGP, this means the same way how you specify -r recipients"

This will be documented (most likely in the same way, by referring to the
engines documentation) in the manual (the manual is in the works).

> 2. srcdir
> ----------
> I really do not know how srcdir is used.

This is really a seperate issue.  autoconf etc support building a program in
a directory different from the source, like this:

tar xzf gpgme-0.3.0.tar.gz
mkdir gpgme-0.3.0-i386-linux-gnu
cd gpgme-0.3.0-i386-linux-gnu

In this case, "srcdir" is set by make in the makefiles so you can find the
source files.  usually, srcdir will be something like "../../gpgme/" if the
directory you are in is "gpgme" (relative to gpgme-0.3.0-i386-linux).
Because the test programs refer to files which are in the source directory,
and the source directory is not necessarily the build directory, we set the
environment variable $srcdir when running a test program.  For files in the
source dir, the test program can access $srcdir/filename instead filename.

If you do
tar xzf gpgme-0.3.0.tar.gz
cd gpgme-0.3.0

then srcdir will always be "."

> I tried to write some C code by
> using my own pubring.gpg by the following statement
> Setenv("GNUPGHOME", "/home/tkan/.gnupg", 1);
> And pick a user name, say "tkan_test", which is a user name in file
> $GNUPGHOME/pubring.gpg, and pass it to function 
> gpgme_recipients_add_name_with_validity  
> This, however, occasionally give me error "No Receipient" (sometime it
> works, sometime it does not work, most of time I am lost).

Uh-oh.  It should not behave randomly.  It should be consistent with the
steps you are taking.  Note that the call
"gpgme_recipients_add_name_with_validity" can never fail with No Recipient. 
It can only fail with "Out of core" because setting the recipients is
delayed until an operation is performed.  So you will have to clarify what
you say above.  When or where in the code do you get "No Recipient"?  

> Later in step
> Gpgme_op_encrypt
> I get "General Error", which I believe to be a direct consequence of the
> "No Recipient" error. 

Ehm, I would like to get the clarification of the above before saying
something about this.  If something fails before op_encrypt, yes, this can
return General Error.  But if the problem is that the key can not be found,
it should be op_encrypt that fails with No Recipient, and nothing else.

gpgme can not know that the recipients can't be found until it actually
asked gpg to encrypt the data.
> 3. Choose "user name" for functions gpgme_recipients_add_name*
> -------------------------------------------------------------
> I think if I set "GNUPGHOME" and "srcdir" correctly and use the correct
> pubring.gpg, I should able to add recipients successfully. But I really
> do not know how. I have been trying this for several days and still can
> not come to any conclusion. (help!)

I hope I could help you to answer your questions.  But I can not help you
solving the problem as for that you are not giving me enough data.  I need
to see the program you are running and the output you are seeing, and of
course the involved files (but not the secret key ring) and environment
settings you are making.

> Could you please help me to point out that if I set "GNUPGHOME" and
> there is a pubring.gpg file in $GNUPGHOME directory and the command
> GNUPGHOME=/my/pub/ring/directory gpg --list-keys
> Gives something similar to 
> Pub  1024D/75462AA6  2001-12-12  Test_key1 test at
> Sub  1024g/B21E925D  2001-12-12
> Which user name I need to put for 
> gpgme_recipients_add_name_*
> so that I will not get "No Recipient" error?

Test_key1 should work, but there are other solutions. Everything that makes
this key listed when doing

GNUPGHOME=/my/pub/ring/directory gpg --list-keys USERNAME

> There is another constraint in current gpgme library:
> If we do "chroot" prior to gpgme_check_engine call and the changed root
> directory is not '/', gpgme_check_engine always returns error "invalid
> engine". 
> For example, in the following code segment (from t-encrypt.c):
> ...
> chroot("/tmp");
> gpgme_check_engine();
> gpgme_new(&ctx);
> ...
> gpgme_check_engine() always return error "invalid engine".
> But this can be countered by keeping an open file descriptor which is
> located outside the chroot-jail, say old_root_directory, escaping
> chroot-jail with the open file descriptor, chdir(..) as many time as
> necessary to the real, system root directory, then chroot("."). Call
> whatever gpgme API. After all is done, chroot(old_root_directory).
> It is an ugly hack, but it works so far.

It's actually a security problem in the Unix implementation of chroot(). 
The Hurd doesn't have this problem.  However, you are asking gpgme to do
an impossible thing:  You are chrooting to a filesystem without gpg and ask
it to perform gpg operations ;)  This can not work.  gpgme works by
executing /usr/bin/gpg (or whatever the compiled-in path is), and if it can
not find the engine under this name it will not work.  In particular, gpgme
will not break a chroot environment for you ;)

Install gpg in /tmp, and it should work.


`Rhubarb is no Egyptian god.' Debian brinkmd at
Marcus Brinkmann              GNU    marcus at
Marcus.Brinkmann at

More information about the Gnupg-devel mailing list