mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Some changes to suport g13.
This commit is contained in:
parent
c11c23b6ac
commit
27c1b4bef8
@ -1,3 +1,15 @@
|
|||||||
|
2009-09-29 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* exechelp.c (create_inheritable_pipe): Rename to
|
||||||
|
create_inheritable_pipe_w.
|
||||||
|
(create_inheritable_pipe_r): New.
|
||||||
|
(gnupg_create_outbound_pipe): New.
|
||||||
|
|
||||||
|
* iobuf.h: Include "sysutils.h"
|
||||||
|
|
||||||
|
* iobuf.c (iobuf_open_fd_or_name): New.
|
||||||
|
(iobuf_get_fname_nonnull): New.
|
||||||
|
|
||||||
2009-09-23 Marcus Brinkmann <marcus@g10code.de>
|
2009-09-23 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* asshelp.c (start_new_gpg_agent): Allocate assuan context before
|
* asshelp.c (start_new_gpg_agent): Allocate assuan context before
|
||||||
|
@ -62,6 +62,15 @@ typedef enum
|
|||||||
operations the Dirmngr is not required and thus no such event
|
operations the Dirmngr is not required and thus no such event
|
||||||
will be logged. */
|
will be logged. */
|
||||||
|
|
||||||
|
AUDIT_GPG_READY, /* err */
|
||||||
|
/* Indicates whether the Gpg engine is available. */
|
||||||
|
|
||||||
|
AUDIT_GPGSM_READY, /* err */
|
||||||
|
/* Indicates whether the Gpgsm engine is available. */
|
||||||
|
|
||||||
|
AUDIT_G13_READY, /* err */
|
||||||
|
/* Indicates whether the G13 engine is available. */
|
||||||
|
|
||||||
AUDIT_GOT_DATA,
|
AUDIT_GOT_DATA,
|
||||||
/* Data to be processed has been seen. */
|
/* Data to be processed has been seen. */
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ build_w32_commandline (const char *pgmname, const char * const *argv,
|
|||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
/* Create pipe where the write end is inheritable. */
|
/* Create pipe where the write end is inheritable. */
|
||||||
static int
|
static int
|
||||||
create_inheritable_pipe (int filedes[2])
|
create_inheritable_pipe_w (int filedes[2])
|
||||||
{
|
{
|
||||||
HANDLE r, w, h;
|
HANDLE r, w, h;
|
||||||
SECURITY_ATTRIBUTES sec_attr;
|
SECURITY_ATTRIBUTES sec_attr;
|
||||||
@ -332,6 +332,37 @@ create_inheritable_pipe (int filedes[2])
|
|||||||
filedes[1] = handle_to_fd (w);
|
filedes[1] = handle_to_fd (w);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create pipe where the read end is inheritable. */
|
||||||
|
static int
|
||||||
|
create_inheritable_pipe_r (int filedes[2])
|
||||||
|
{
|
||||||
|
HANDLE r, w, h;
|
||||||
|
SECURITY_ATTRIBUTES sec_attr;
|
||||||
|
|
||||||
|
memset (&sec_attr, 0, sizeof sec_attr );
|
||||||
|
sec_attr.nLength = sizeof sec_attr;
|
||||||
|
sec_attr.bInheritHandle = FALSE;
|
||||||
|
|
||||||
|
if (!CreatePipe (&r, &w, &sec_attr, 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!DuplicateHandle (GetCurrentProcess(), r,
|
||||||
|
GetCurrentProcess(), &h, 0,
|
||||||
|
TRUE, DUPLICATE_SAME_ACCESS ))
|
||||||
|
{
|
||||||
|
log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
|
||||||
|
CloseHandle (r);
|
||||||
|
CloseHandle (w);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CloseHandle (r);
|
||||||
|
r = h;
|
||||||
|
|
||||||
|
filedes[0] = handle_to_fd (r);
|
||||||
|
filedes[1] = handle_to_fd (w);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
@ -425,7 +456,51 @@ gnupg_create_inbound_pipe (int filedes[2])
|
|||||||
|
|
||||||
filedes[0] = filedes[1] = -1;
|
filedes[0] = filedes[1] = -1;
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
err = gpg_error (GPG_ERR_GENERAL);
|
||||||
if (!create_inheritable_pipe (fds))
|
if (!create_inheritable_pipe_w (fds))
|
||||||
|
{
|
||||||
|
filedes[0] = _open_osfhandle (fds[0], 0);
|
||||||
|
if (filedes[0] == -1)
|
||||||
|
{
|
||||||
|
log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
|
||||||
|
CloseHandle (fd_to_handle (fds[1]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filedes[1] = _open_osfhandle (fds[1], 1);
|
||||||
|
if (filedes[1] == -1)
|
||||||
|
{
|
||||||
|
log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
|
||||||
|
close (filedes[0]);
|
||||||
|
filedes[0] = -1;
|
||||||
|
CloseHandle (fd_to_handle (fds[1]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (pipe (filedes) == -1)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
filedes[0] = filedes[1] = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Portable function to create a pipe. Under Windows the read end is
|
||||||
|
inheritable. */
|
||||||
|
gpg_error_t
|
||||||
|
gnupg_create_outbound_pipe (int filedes[2])
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
#if HAVE_W32_SYSTEM
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
filedes[0] = filedes[1] = -1;
|
||||||
|
err = gpg_error (GPG_ERR_GENERAL);
|
||||||
|
if (!create_inheritable_pipe_r (fds))
|
||||||
{
|
{
|
||||||
filedes[0] = _open_osfhandle (fds[0], 0);
|
filedes[0] = _open_osfhandle (fds[0], 0);
|
||||||
if (filedes[0] == -1)
|
if (filedes[0] == -1)
|
||||||
@ -522,7 +597,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* Create a pipe. */
|
/* Create a pipe. */
|
||||||
if (create_inheritable_pipe (rp))
|
if (create_inheritable_pipe_w (rp))
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
err = gpg_error (GPG_ERR_GENERAL);
|
||||||
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
||||||
|
@ -44,6 +44,10 @@ int *get_all_open_fds (void);
|
|||||||
inheritable. */
|
inheritable. */
|
||||||
gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
|
gpg_error_t gnupg_create_inbound_pipe (int filedes[2]);
|
||||||
|
|
||||||
|
/* Portable function to create a pipe. Under Windows the read end is
|
||||||
|
inheritable. */
|
||||||
|
gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
|
||||||
|
|
||||||
|
|
||||||
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||||
stdin, write the output to OUTFILE, return a new stream in
|
stdin, write the output to OUTFILE, return a new stream in
|
||||||
|
@ -1260,6 +1260,32 @@ iobuf_is_pipe_filename (const char *fname)
|
|||||||
return check_special_filename (fname) != -1;
|
return check_special_filename (fname) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Either open the file specified by the file descriptor FD or - if FD
|
||||||
|
is GNUPG_INVALID_FD - the file with name FNAME. As of now MODE is
|
||||||
|
assumed to be "rb" if FNAME is used. In contrast to iobuf_fdopen
|
||||||
|
the fiel descriptor FD will not be closed during an iobuf_close. */
|
||||||
|
iobuf_t
|
||||||
|
iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode)
|
||||||
|
{
|
||||||
|
iobuf_t a;
|
||||||
|
|
||||||
|
if (fd == GNUPG_INVALID_FD)
|
||||||
|
a = iobuf_open (fname);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gnupg_fd_t fd2;
|
||||||
|
|
||||||
|
fd2 = dup (fd);
|
||||||
|
if (fd2 == GNUPG_INVALID_FD)
|
||||||
|
a = NULL;
|
||||||
|
else
|
||||||
|
a = iobuf_fdopen (fd2, mode);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Create a head iobuf for reading from a file
|
* Create a head iobuf for reading from a file
|
||||||
* returns: NULL if an error occures and sets errno
|
* returns: NULL if an error occures and sets errno
|
||||||
@ -1306,8 +1332,8 @@ iobuf_open (const char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Create a head iobuf for reading from a file
|
* Create a head iobuf for reading or writing from/to a file
|
||||||
* returns: NULL if an error occures and sets errno
|
* Returns: NULL if an error occures and sets ERRNO.
|
||||||
*/
|
*/
|
||||||
iobuf_t
|
iobuf_t
|
||||||
iobuf_fdopen (int fd, const char *mode)
|
iobuf_fdopen (int fd, const char *mode)
|
||||||
@ -2355,7 +2381,9 @@ iobuf_seek (iobuf_t a, off_t newpos)
|
|||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Retrieve the real filename
|
* Retrieve the real filename. This is the filename actually used on
|
||||||
|
* disk and not a made up one. Returns NULL if no real filename is
|
||||||
|
* available.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
iobuf_get_real_fname (iobuf_t a)
|
iobuf_get_real_fname (iobuf_t a)
|
||||||
@ -2376,7 +2404,7 @@ iobuf_get_real_fname (iobuf_t a)
|
|||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Retrieve the filename
|
* Retrieve the filename. This name should only be used in diagnostics.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
iobuf_get_fname (iobuf_t a)
|
iobuf_get_fname (iobuf_t a)
|
||||||
@ -2390,6 +2418,16 @@ iobuf_get_fname (iobuf_t a)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Same as iobuf_get_fname but never returns NULL. */
|
||||||
|
const char *
|
||||||
|
iobuf_get_fname_nonnull (iobuf_t a)
|
||||||
|
{
|
||||||
|
const char *fname;
|
||||||
|
|
||||||
|
fname = iobuf_get_fname (a);
|
||||||
|
return fname? fname : "[?]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* enable partial block mode as described in the OpenPGP draft.
|
* enable partial block mode as described in the OpenPGP draft.
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#define GNUPG_COMMON_IOBUF_H
|
#define GNUPG_COMMON_IOBUF_H
|
||||||
|
|
||||||
#include "../include/types.h" /* fixme: should be moved elsewhere. */
|
#include "../include/types.h" /* fixme: should be moved elsewhere. */
|
||||||
|
#include "../common/sysutils.h"
|
||||||
|
|
||||||
#define DBG_IOBUF iobuf_debug_mode
|
#define DBG_IOBUF iobuf_debug_mode
|
||||||
|
|
||||||
@ -85,6 +85,8 @@ int iobuf_is_pipe_filename (const char *fname);
|
|||||||
iobuf_t iobuf_alloc (int use, size_t bufsize);
|
iobuf_t iobuf_alloc (int use, size_t bufsize);
|
||||||
iobuf_t iobuf_temp (void);
|
iobuf_t iobuf_temp (void);
|
||||||
iobuf_t iobuf_temp_with_content (const char *buffer, size_t length);
|
iobuf_t iobuf_temp_with_content (const char *buffer, size_t length);
|
||||||
|
iobuf_t iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname,
|
||||||
|
const char *mode);
|
||||||
iobuf_t iobuf_open (const char *fname);
|
iobuf_t iobuf_open (const char *fname);
|
||||||
iobuf_t iobuf_fdopen (int fd, const char *mode);
|
iobuf_t iobuf_fdopen (int fd, const char *mode);
|
||||||
iobuf_t iobuf_sockopen (int fd, const char *mode);
|
iobuf_t iobuf_sockopen (int fd, const char *mode);
|
||||||
@ -131,6 +133,7 @@ off_t iobuf_get_filelength (iobuf_t a, int *overflow);
|
|||||||
int iobuf_get_fd (iobuf_t a);
|
int iobuf_get_fd (iobuf_t a);
|
||||||
const char *iobuf_get_real_fname (iobuf_t a);
|
const char *iobuf_get_real_fname (iobuf_t a);
|
||||||
const char *iobuf_get_fname (iobuf_t a);
|
const char *iobuf_get_fname (iobuf_t a);
|
||||||
|
const char *iobuf_get_fname_nonnull (iobuf_t a);
|
||||||
|
|
||||||
void iobuf_set_partial_block_mode (iobuf_t a, size_t len);
|
void iobuf_set_partial_block_mode (iobuf_t a, size_t len);
|
||||||
|
|
||||||
|
@ -1,5 +1,33 @@
|
|||||||
|
2009-09-30 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* parse-packet.c (skip_packet, parse_gpg_control) <ist_mode>: Take
|
||||||
|
care of premature EOFs.
|
||||||
|
|
||||||
|
* gpg.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
|
||||||
|
|
||||||
|
2009-09-29 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* openfile.c (open_outfile): Re-indent. Use xstrconcat.
|
||||||
|
(NAME_OF_DEV_NULL): New.
|
||||||
|
(open_outfile): Use it.
|
||||||
|
(overwrite_filep): Use it. Also use case insensitive compare
|
||||||
|
when needed. Re-indent.
|
||||||
|
(open_outfile): Add arg INP_FD. Change all callers.
|
||||||
|
|
||||||
|
* encrypt.c (encrypt_crypt): Add new args FILEFD, OUTPUTFD and
|
||||||
|
PROVIDED_KEYS. Change all callers.
|
||||||
|
|
||||||
2009-09-28 Werner Koch <wk@g10code.com>
|
2009-09-28 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* server.c (skip_options, has_option): New.
|
||||||
|
(cmd_recipient): Implement.
|
||||||
|
|
||||||
|
* keydb.h (pk_list_t): New.
|
||||||
|
|
||||||
|
* pkclist.c (send_status_inv_recp): New. Replace direct calls.
|
||||||
|
(build_pk_list): Factor some code out to ...
|
||||||
|
(find_and_check_key): ... new.
|
||||||
|
|
||||||
* encode.c: Rename to encrypt.c. Re-indent all.
|
* encode.c: Rename to encrypt.c. Re-indent all.
|
||||||
* encrypt.c (encode_symmetric, encode_store, encode_seskey)
|
* encrypt.c (encode_symmetric, encode_store, encode_seskey)
|
||||||
(encode_simple, encode_crypt, encode_filter)
|
(encode_simple, encode_crypt, encode_filter)
|
||||||
|
@ -245,6 +245,9 @@ compress_filter( void *opaque, int control,
|
|||||||
memset( &cd, 0, sizeof cd );
|
memset( &cd, 0, sizeof cd );
|
||||||
cd.len = 0;
|
cd.len = 0;
|
||||||
cd.algorithm = zfx->algo;
|
cd.algorithm = zfx->algo;
|
||||||
|
/* Fixme: We should force a new CTB here:
|
||||||
|
cd.new_ctb = zfx->new_ctb;
|
||||||
|
*/
|
||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
pkt.pkttype = PKT_COMPRESSED;
|
pkt.pkttype = PKT_COMPRESSED;
|
||||||
pkt.pkt.compressed = &cd;
|
pkt.pkt.compressed = &cd;
|
||||||
|
@ -64,7 +64,7 @@ dearmor_file( const char *fname )
|
|||||||
|
|
||||||
push_armor_filter ( afx, inp );
|
push_armor_filter ( afx, inp );
|
||||||
|
|
||||||
if( (rc = open_outfile( fname, 0, &out )) )
|
if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 0, &out )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
while( (c = iobuf_get(inp)) != -1 )
|
while( (c = iobuf_get(inp)) != -1 )
|
||||||
@ -110,7 +110,7 @@ enarmor_file( const char *fname )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( (rc = open_outfile( fname, 1, &out )) )
|
if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 1, &out )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
afx->what = 4;
|
afx->what = 4;
|
||||||
|
@ -264,7 +264,8 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
do_compress = 0;
|
do_compress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )))
|
if ( rc || (rc = open_outfile (GNUPG_INVALID_FD, filename,
|
||||||
|
opt.armor? 1:0, &out )))
|
||||||
{
|
{
|
||||||
iobuf_cancel (inp);
|
iobuf_cancel (inp);
|
||||||
xfree (cfx.dek);
|
xfree (cfx.dek);
|
||||||
@ -455,11 +456,15 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encrypt the file with the given userids (or ask if none
|
* Encrypt the file with the given userids (or ask if none is
|
||||||
* is supplied).
|
* supplied). Either FILENAME or FILEFD must be given, but not both.
|
||||||
|
* The caller may provide a checked list of public keys in
|
||||||
|
* PROVIDED_PKS; if not the function builds a list of keys on its own.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
encrypt_crypt (gnupg_fd_t filefd, const char *filename,
|
||||||
|
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||||
|
gnupg_fd_t outputfd)
|
||||||
{
|
{
|
||||||
iobuf_t inp = NULL;
|
iobuf_t inp = NULL;
|
||||||
iobuf_t out = NULL;
|
iobuf_t out = NULL;
|
||||||
@ -477,6 +482,9 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
PK_LIST pk_list, work_list;
|
PK_LIST pk_list, work_list;
|
||||||
int do_compress;
|
int do_compress;
|
||||||
|
|
||||||
|
if (filefd != GNUPG_INVALID_FD && filename)
|
||||||
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
do_compress = opt.compress_algo && !RFC1991;
|
do_compress = opt.compress_algo && !RFC1991;
|
||||||
|
|
||||||
pfx = new_progress_context ();
|
pfx = new_progress_context ();
|
||||||
@ -492,10 +500,15 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC)))
|
if (provided_keys)
|
||||||
|
pk_list = provided_keys;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
release_progress_context (pfx);
|
if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC)))
|
||||||
return rc;
|
{
|
||||||
|
release_progress_context (pfx);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PGP2)
|
if(PGP2)
|
||||||
@ -512,7 +525,7 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare iobufs. */
|
/* Prepare iobufs. */
|
||||||
inp = iobuf_open(filename);
|
inp = iobuf_open_fd_or_name (filefd, filename, "rb");
|
||||||
if (inp)
|
if (inp)
|
||||||
iobuf_ioctl (inp, 3, 1, NULL); /* Disable fd caching. */
|
iobuf_ioctl (inp, 3, 1, NULL); /* Disable fd caching. */
|
||||||
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
if (inp && is_secured_file (iobuf_get_fd (inp)))
|
||||||
@ -523,20 +536,30 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
}
|
}
|
||||||
if (!inp)
|
if (!inp)
|
||||||
{
|
{
|
||||||
|
char xname[64];
|
||||||
|
|
||||||
rc = gpg_error_from_syserror ();
|
rc = gpg_error_from_syserror ();
|
||||||
|
if (filefd != GNUPG_INVALID_FD)
|
||||||
|
snprintf (xname, sizeof xname, "[fd %d]", filefd);
|
||||||
|
else if (!filename)
|
||||||
|
strcpy (xname, "[stdin]");
|
||||||
|
else
|
||||||
|
*xname = 0;
|
||||||
log_error (_("can't open `%s': %s\n"),
|
log_error (_("can't open `%s': %s\n"),
|
||||||
filename? filename: "[stdin]", gpg_strerror (rc) );
|
*xname? xname : filename, gpg_strerror (rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
else if (opt.verbose)
|
|
||||||
log_info (_("reading from `%s'\n"), filename? filename: "[stdin]");
|
if (opt.verbose)
|
||||||
|
log_info (_("reading from `%s'\n"), iobuf_get_fname_nonnull (inp));
|
||||||
|
|
||||||
handle_progress (pfx, inp, filename);
|
handle_progress (pfx, inp, filename);
|
||||||
|
|
||||||
if (opt.textmode)
|
if (opt.textmode)
|
||||||
iobuf_push_filter (inp, text_filter, &tfx);
|
iobuf_push_filter (inp, text_filter, &tfx);
|
||||||
|
|
||||||
if ((rc = open_outfile( filename, opt.armor? 1:0, &out )))
|
rc = open_outfile (outputfd, filename, opt.armor? 1:0, &out);
|
||||||
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (opt.armor)
|
if (opt.armor)
|
||||||
@ -629,7 +652,8 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
pt = setup_plaintext_name (filename, inp);
|
pt = setup_plaintext_name (filename, inp);
|
||||||
|
|
||||||
if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
if (filefd != GNUPG_INVALID_FD
|
||||||
|
&& !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
||||||
{
|
{
|
||||||
off_t tmpsize;
|
off_t tmpsize;
|
||||||
int overflow;
|
int overflow;
|
||||||
@ -709,13 +733,16 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
plain data. */
|
plain data. */
|
||||||
byte copy_buffer[4096];
|
byte copy_buffer[4096];
|
||||||
int bytes_copied;
|
int bytes_copied;
|
||||||
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
|
while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
|
||||||
if ((rc=iobuf_write(out, copy_buffer, bytes_copied)))
|
{
|
||||||
{
|
rc = iobuf_write (out, copy_buffer, bytes_copied);
|
||||||
log_error ("copying input to output failed: %s\n",
|
if (rc)
|
||||||
gpg_strerror (rc));
|
{
|
||||||
break;
|
log_error ("copying input to output failed: %s\n",
|
||||||
}
|
gpg_strerror (rc));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
wipememory (copy_buffer, 4096); /* Burn the buffer. */
|
wipememory (copy_buffer, 4096); /* Burn the buffer. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,7 +762,8 @@ encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey)
|
|||||||
xfree (cfx.dek);
|
xfree (cfx.dek);
|
||||||
xfree (symkey_dek);
|
xfree (symkey_dek);
|
||||||
xfree (symkey_s2k);
|
xfree (symkey_s2k);
|
||||||
release_pk_list (pk_list);
|
if (!provided_keys)
|
||||||
|
release_pk_list (pk_list);
|
||||||
release_armor_context (afx);
|
release_armor_context (afx);
|
||||||
release_progress_context (pfx);
|
release_progress_context (pfx);
|
||||||
return rc;
|
return rc;
|
||||||
@ -936,9 +964,11 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
|||||||
}
|
}
|
||||||
line[strlen(line)-1] = '\0';
|
line[strlen(line)-1] = '\0';
|
||||||
print_file_status(STATUS_FILE_START, line, 2);
|
print_file_status(STATUS_FILE_START, line, 2);
|
||||||
if ( (rc = encrypt_crypt(line, remusr, 0)) )
|
rc = encrypt_crypt (GNUPG_INVALID_FD, line, remusr, 0,
|
||||||
log_error("encryption of `%s' failed: %s\n",
|
NULL, GNUPG_INVALID_FD);
|
||||||
print_fname_stdin(line), g10_errstr(rc) );
|
if (rc)
|
||||||
|
log_error ("encryption of `%s' failed: %s\n",
|
||||||
|
print_fname_stdin(line), g10_errstr(rc) );
|
||||||
write_status( STATUS_FILE_DONE );
|
write_status( STATUS_FILE_DONE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,7 +977,8 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
|
|||||||
while (nfiles--)
|
while (nfiles--)
|
||||||
{
|
{
|
||||||
print_file_status(STATUS_FILE_START, *files, 2);
|
print_file_status(STATUS_FILE_START, *files, 2);
|
||||||
if ( (rc = encrypt_crypt(*files, remusr, 0)) )
|
if ( (rc = encrypt_crypt (GNUPG_INVALID_FD, *files, remusr, 0,
|
||||||
|
NULL, GNUPG_INVALID_FD)) )
|
||||||
log_error("encryption of `%s' failed: %s\n",
|
log_error("encryption of `%s' failed: %s\n",
|
||||||
print_fname_stdin(*files), g10_errstr(rc) );
|
print_fname_stdin(*files), g10_errstr(rc) );
|
||||||
write_status( STATUS_FILE_DONE );
|
write_status( STATUS_FILE_DONE );
|
||||||
|
@ -140,7 +140,7 @@ do_export( strlist_t users, int secret, unsigned int options )
|
|||||||
|
|
||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
|
|
||||||
rc = open_outfile( NULL, 0, &out );
|
rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out );
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -1920,9 +1920,6 @@ main (int argc, char **argv)
|
|||||||
gnupg_rl_initialize ();
|
gnupg_rl_initialize ();
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
/* We don't need any locking in libgcrypt unless we use any kind of
|
|
||||||
threading. */
|
|
||||||
gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
|
|
||||||
log_set_prefix ("gpg", 1);
|
log_set_prefix ("gpg", 1);
|
||||||
|
|
||||||
/* Make sure that our subsystems are ready. */
|
/* Make sure that our subsystems are ready. */
|
||||||
@ -3437,7 +3434,8 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
wrong_args(_("--encrypt [filename]"));
|
wrong_args(_("--encrypt [filename]"));
|
||||||
if( (rc = encrypt_crypt(fname,remusr,0)) )
|
if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
|
||||||
|
remusr, 0, NULL, GNUPG_INVALID_FD)) )
|
||||||
log_error("%s: encryption failed: %s\n",
|
log_error("%s: encryption failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
@ -3458,7 +3456,8 @@ main (int argc, char **argv)
|
|||||||
" while in %s mode\n"),compliance_option_string());
|
" while in %s mode\n"),compliance_option_string());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( (rc = encrypt_crypt(fname,remusr,1)) )
|
if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
|
||||||
|
remusr, 1, NULL, GNUPG_INVALID_FD)) )
|
||||||
log_error("%s: encryption failed: %s\n",
|
log_error("%s: encryption failed: %s\n",
|
||||||
print_fname_stdin(fname), g10_errstr(rc) );
|
print_fname_stdin(fname), g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
|
22
g10/keydb.h
22
g10/keydb.h
@ -83,12 +83,14 @@ struct keyblock_pos_struct {
|
|||||||
};
|
};
|
||||||
typedef struct keyblock_pos_struct KBPOS;
|
typedef struct keyblock_pos_struct KBPOS;
|
||||||
|
|
||||||
/* structure to hold a couple of public key certificates */
|
/* Structure to hold a couple of public key certificates. */
|
||||||
typedef struct pk_list *PK_LIST;
|
typedef struct pk_list *PK_LIST; /* Deprecated. */
|
||||||
struct pk_list {
|
typedef struct pk_list *pk_list_t;
|
||||||
PK_LIST next;
|
struct pk_list
|
||||||
PKT_public_key *pk;
|
{
|
||||||
int flags; /* flag bit 1==throw_keyid */
|
PK_LIST next;
|
||||||
|
PKT_public_key *pk;
|
||||||
|
int flags; /* flag bit 1==throw_keyid */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* structure to hold a couple of secret key certificates */
|
/* structure to hold a couple of secret key certificates */
|
||||||
@ -179,8 +181,12 @@ int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
|
|||||||
/*-- pkclist.c --*/
|
/*-- pkclist.c --*/
|
||||||
void show_revocation_reason( PKT_public_key *pk, int mode );
|
void show_revocation_reason( PKT_public_key *pk, int mode );
|
||||||
int check_signatures_trust( PKT_signature *sig );
|
int check_signatures_trust( PKT_signature *sig );
|
||||||
void release_pk_list( PK_LIST pk_list );
|
|
||||||
int build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use );
|
void release_pk_list (PK_LIST pk_list);
|
||||||
|
int build_pk_list (strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
|
||||||
|
gpg_error_t find_and_check_key (const char *name, unsigned int use,
|
||||||
|
int mark_hidden, pk_list_t *pk_list_addr);
|
||||||
|
|
||||||
int algo_available( preftype_t preftype, int algo,
|
int algo_available( preftype_t preftype, int algo,
|
||||||
const union pref_hint *hint );
|
const union pref_hint *hint );
|
||||||
int select_algo_from_prefs( PK_LIST pk_list, int preftype,
|
int select_algo_from_prefs( PK_LIST pk_list, int preftype,
|
||||||
|
@ -185,7 +185,9 @@ void display_online_help( const char *keyword );
|
|||||||
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||||
int encrypt_symmetric (const char *filename );
|
int encrypt_symmetric (const char *filename );
|
||||||
int encrypt_store (const char *filename );
|
int encrypt_store (const char *filename );
|
||||||
int encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey );
|
int encrypt_crypt (gnupg_fd_t filefd, const char *filename,
|
||||||
|
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
|
||||||
|
gnupg_fd_t outputfd);
|
||||||
void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr);
|
void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr);
|
||||||
int encrypt_filter (void *opaque, int control,
|
int encrypt_filter (void *opaque, int control,
|
||||||
iobuf_t a, byte *buf, size_t *ret_len);
|
iobuf_t a, byte *buf, size_t *ret_len);
|
||||||
@ -243,7 +245,7 @@ int save_unprotected_key_to_card (PKT_secret_key *sk, int keyno);
|
|||||||
int overwrite_filep( const char *fname );
|
int overwrite_filep( const char *fname );
|
||||||
char *make_outfile_name( const char *iname );
|
char *make_outfile_name( const char *iname );
|
||||||
char *ask_outfile_name( const char *name, size_t namelen );
|
char *ask_outfile_name( const char *name, size_t namelen );
|
||||||
int open_outfile( const char *iname, int mode, iobuf_t *a );
|
int open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a);
|
||||||
iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
|
iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
|
||||||
void try_make_homedir( const char *fname );
|
void try_make_homedir( const char *fname );
|
||||||
|
|
||||||
|
256
g10/openfile.c
256
g10/openfile.c
@ -1,6 +1,6 @@
|
|||||||
/* openfile.c
|
/* openfile.c
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
* 2005 Free Software Foundation, Inc.
|
* 2005, 2009 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -43,6 +43,13 @@
|
|||||||
#define SKELEXT EXTSEP_S "skel"
|
#define SKELEXT EXTSEP_S "skel"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
#define NAME_OF_DEV_NULL "nul"
|
||||||
|
#else
|
||||||
|
#define NAME_OF_DEV_NULL "/dev/null"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
|
#if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
|
||||||
#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
|
#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
|
||||||
#else
|
#else
|
||||||
@ -65,34 +72,27 @@
|
|||||||
int
|
int
|
||||||
overwrite_filep( const char *fname )
|
overwrite_filep( const char *fname )
|
||||||
{
|
{
|
||||||
if( iobuf_is_pipe_filename (fname) )
|
if ( iobuf_is_pipe_filename (fname) )
|
||||||
return 1; /* Writing to stdout is always okay */
|
return 1; /* Writing to stdout is always okay. */
|
||||||
|
|
||||||
|
if ( access( fname, F_OK ) )
|
||||||
|
return 1; /* Does not exist. */
|
||||||
|
|
||||||
|
if ( !compare_filenames (fname, NAME_OF_DEV_NULL) )
|
||||||
|
return 1; /* Does not do any harm. */
|
||||||
|
|
||||||
if( access( fname, F_OK ) )
|
if (opt.answer_yes)
|
||||||
return 1; /* does not exist */
|
return 1;
|
||||||
|
if (opt.answer_no || opt.batch)
|
||||||
|
return 0; /* Do not overwrite. */
|
||||||
|
|
||||||
#ifndef HAVE_DOSISH_SYSTEM
|
tty_printf (_("File `%s' exists. "), fname);
|
||||||
if ( !strcmp ( fname, "/dev/null" ) )
|
if (cpr_enabled ())
|
||||||
return 1; /* does not do any harm */
|
tty_printf ("\n");
|
||||||
#endif
|
if (cpr_get_answer_is_yes ("openfile.overwrite.okay",
|
||||||
#ifdef HAVE_W32_SYSTEM
|
_("Overwrite? (y/N) ")) )
|
||||||
if ( !strcmp ( fname, "nul" ) )
|
return 1;
|
||||||
return 1;
|
return 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* fixme: add some backup stuff in case of overwrite */
|
|
||||||
if( opt.answer_yes )
|
|
||||||
return 1;
|
|
||||||
if( opt.answer_no || opt.batch )
|
|
||||||
return 0; /* do not overwrite */
|
|
||||||
|
|
||||||
tty_printf(_("File `%s' exists. "), fname);
|
|
||||||
if( cpr_enabled () )
|
|
||||||
tty_printf ("\n");
|
|
||||||
if( cpr_get_answer_is_yes("openfile.overwrite.okay",
|
|
||||||
_("Overwrite? (y/N) ")) )
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,110 +178,134 @@ ask_outfile_name( const char *name, size_t namelen )
|
|||||||
* Mode 0 = use ".gpg"
|
* Mode 0 = use ".gpg"
|
||||||
* 1 = use ".asc"
|
* 1 = use ".asc"
|
||||||
* 2 = use ".sig"
|
* 2 = use ".sig"
|
||||||
|
|
||||||
|
* If INP_FD is not GNUPG_INVALID_FD the function will simply create
|
||||||
|
* an IOBUF for that file descriptor and ignore a INAME and MODE.
|
||||||
|
* Note that INP_FD won't be closed if the returned IOBUF is closed.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
open_outfile( const char *iname, int mode, IOBUF *a )
|
open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
*a = NULL;
|
*a = NULL;
|
||||||
if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
|
if (inp_fd != GNUPG_INVALID_FD)
|
||||||
*a = iobuf_create(NULL);
|
{
|
||||||
if( !*a ) {
|
char xname[64];
|
||||||
rc = gpg_error_from_syserror ();
|
gnupg_fd_t fd2;
|
||||||
log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
|
|
||||||
|
fd2 = INT2FD (dup (FD2INT (inp_fd)));
|
||||||
|
if (fd2 == GNUPG_INVALID_FD)
|
||||||
|
*a = NULL;
|
||||||
|
else
|
||||||
|
*a = iobuf_fdopen (fd2, "wb");
|
||||||
|
if (!*a)
|
||||||
|
{
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
|
||||||
|
log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (rc));
|
||||||
|
}
|
||||||
|
else if (opt.verbose)
|
||||||
|
{
|
||||||
|
snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
|
||||||
|
log_info (_("writing to `%s'\n"), xname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( opt.verbose )
|
else if (iobuf_is_pipe_filename (iname) && !opt.outfile)
|
||||||
log_info(_("writing to stdout\n"));
|
{
|
||||||
}
|
*a = iobuf_create(NULL);
|
||||||
else {
|
if ( !*a )
|
||||||
char *buf = NULL;
|
{
|
||||||
const char *name;
|
rc = gpg_error_from_syserror ();
|
||||||
|
log_error (_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
|
||||||
|
}
|
||||||
|
else if ( opt.verbose )
|
||||||
|
log_info (_("writing to stdout\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
if ( opt.dry_run )
|
if (opt.dry_run)
|
||||||
{
|
name = NAME_OF_DEV_NULL;
|
||||||
#ifdef HAVE_W32_SYSTEM
|
else if (opt.outfile)
|
||||||
name = "nul";
|
name = opt.outfile;
|
||||||
#else
|
else
|
||||||
name = "/dev/null";
|
{
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if( opt.outfile )
|
|
||||||
name = opt.outfile;
|
|
||||||
else {
|
|
||||||
#ifdef USE_ONLY_8DOT3
|
#ifdef USE_ONLY_8DOT3
|
||||||
if (opt.mangle_dos_filenames)
|
if (opt.mangle_dos_filenames)
|
||||||
{
|
|
||||||
/* It is quite common DOS system to have only one dot in a
|
|
||||||
* a filename So if we have something like this, we simple
|
|
||||||
* replace the suffix execpt in cases where the suffix is
|
|
||||||
* larger than 3 characters and not the same as.
|
|
||||||
* We should really map the filenames to 8.3 but this tends to
|
|
||||||
* be more complicated and is probaly a duty of the filesystem
|
|
||||||
*/
|
|
||||||
char *dot;
|
|
||||||
const char *newsfx = mode==1 ? ".asc" :
|
|
||||||
mode==2 ? ".sig" : ".gpg";
|
|
||||||
|
|
||||||
buf = xmalloc(strlen(iname)+4+1);
|
|
||||||
strcpy(buf,iname);
|
|
||||||
dot = strchr(buf, '.' );
|
|
||||||
if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
|
|
||||||
&& CMP_FILENAME(newsfx, dot) )
|
|
||||||
{
|
{
|
||||||
strcpy(dot, newsfx );
|
/* It is quite common for DOS systems to have only one
|
||||||
|
dot in a filename. If we have something like this,
|
||||||
|
we simple replace the suffix except in cases where
|
||||||
|
the suffix is larger than 3 characters and not the
|
||||||
|
same as the new one. We don't map the filenames to
|
||||||
|
8.3 because this is a duty of the file system. */
|
||||||
|
char *dot;
|
||||||
|
const char *newsfx;
|
||||||
|
|
||||||
|
newsfx = (mode==1 ? ".asc" :
|
||||||
|
mode==2 ? ".sig" : ".gpg");
|
||||||
|
|
||||||
|
buf = xmalloc (strlen(iname)+4+1);
|
||||||
|
strcpy (buf, iname);
|
||||||
|
dot = strchr (buf, '.' );
|
||||||
|
if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
|
||||||
|
&& CMP_FILENAME (newsfx, dot) )
|
||||||
|
strcpy (dot, newsfx);
|
||||||
|
else if (dot && !dot[1]) /* Do not duplicate a dot. */
|
||||||
|
strcpy (dot, newsfx+1);
|
||||||
|
else
|
||||||
|
strcat (buf, newsfx);
|
||||||
}
|
}
|
||||||
else if ( dot && !dot[1] ) /* don't duplicate a dot */
|
if (!buf)
|
||||||
strcpy( dot, newsfx+1 );
|
|
||||||
else
|
|
||||||
strcat ( buf, newsfx );
|
|
||||||
}
|
|
||||||
if (!buf)
|
|
||||||
#endif /* USE_ONLY_8DOT3 */
|
#endif /* USE_ONLY_8DOT3 */
|
||||||
{
|
{
|
||||||
buf = xmalloc(strlen(iname)+4+1);
|
buf = xstrconcat (iname,
|
||||||
strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
|
(mode==1 ? EXTSEP_S "asc" :
|
||||||
mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
|
mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg"),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
while ( !overwrite_filep (name) )
|
||||||
|
{
|
||||||
|
char *tmp = ask_outfile_name (NULL, 0);
|
||||||
|
if ( !tmp || !*tmp )
|
||||||
|
{
|
||||||
|
xfree (tmp);
|
||||||
|
rc = gpg_error (GPG_ERR_EEXIST);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xfree (buf);
|
||||||
|
name = buf = tmp;
|
||||||
}
|
}
|
||||||
name = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = 0;
|
|
||||||
while( !overwrite_filep (name) )
|
|
||||||
{
|
|
||||||
char *tmp = ask_outfile_name (NULL, 0);
|
|
||||||
if ( !tmp || !*tmp )
|
|
||||||
{
|
|
||||||
xfree (tmp);
|
|
||||||
rc = gpg_error (GPG_ERR_EEXIST);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
xfree (buf);
|
|
||||||
name = buf = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !rc )
|
if ( !rc )
|
||||||
{
|
{
|
||||||
if (is_secured_filename (name) )
|
if (is_secured_filename (name) )
|
||||||
{
|
{
|
||||||
*a = NULL;
|
*a = NULL;
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*a = iobuf_create( name );
|
*a = iobuf_create (name);
|
||||||
if( !*a )
|
if (!*a)
|
||||||
{
|
{
|
||||||
rc = gpg_error_from_syserror ();
|
rc = gpg_error_from_syserror ();
|
||||||
log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
|
log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
|
||||||
}
|
}
|
||||||
else if( opt.verbose )
|
else if( opt.verbose )
|
||||||
log_info(_("writing to `%s'\n"), name );
|
log_info (_("writing to `%s'\n"), name );
|
||||||
}
|
}
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*a)
|
if (*a)
|
||||||
iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
|
iobuf_ioctl (*a, 3, 1, NULL); /* Disable fd caching. */
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -682,7 +682,11 @@ skip_packet( IOBUF inp, int pkttype, unsigned long pktlen, int partial )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( ; pktlen; pktlen-- )
|
for( ; pktlen; pktlen-- )
|
||||||
dump_hex_line(iobuf_get(inp), &i);
|
{
|
||||||
|
dump_hex_line( (c=iobuf_get(inp)), &i);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
putc ('\n', listfp);
|
putc ('\n', listfp);
|
||||||
return;
|
return;
|
||||||
@ -2529,7 +2533,11 @@ parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for( ; pktlen; pktlen-- )
|
for( ; pktlen; pktlen-- )
|
||||||
dump_hex_line(iobuf_get(inp), &i);
|
{
|
||||||
|
dump_hex_line ((c=iobuf_get (inp)), &i);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
putc ('\n', listfp);
|
putc ('\n', listfp);
|
||||||
}
|
}
|
||||||
|
211
g10/pkclist.c
211
g10/pkclist.c
@ -1,6 +1,6 @@
|
|||||||
/* pkclist.c - create a list of public keys
|
/* pkclist.c - create a list of public keys
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||||
* 2008 Free Software Foundation, Inc.
|
* 2008, 2009 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -40,6 +40,18 @@
|
|||||||
|
|
||||||
#define CONTROL_D ('D' - 'A' + 1)
|
#define CONTROL_D ('D' - 'A' + 1)
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_status_inv_recp (int reason, const char *name)
|
||||||
|
{
|
||||||
|
char buf[40];
|
||||||
|
|
||||||
|
snprintf (buf, sizeof buf, "%d ", reason);
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, buf,
|
||||||
|
name, strlen (name),
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Show the revocation reason as it is stored with the given signature
|
* Show the revocation reason as it is stored with the given signature
|
||||||
*/
|
*/
|
||||||
@ -656,14 +668,15 @@ check_signatures_trust( PKT_signature *sig )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
release_pk_list( PK_LIST pk_list )
|
release_pk_list (pk_list_t pk_list)
|
||||||
{
|
{
|
||||||
PK_LIST pk_rover;
|
PK_LIST pk_rover;
|
||||||
|
|
||||||
for( ; pk_list; pk_list = pk_rover ) {
|
for ( ; pk_list; pk_list = pk_rover)
|
||||||
pk_rover = pk_list->next;
|
{
|
||||||
free_public_key( pk_list->pk );
|
pk_rover = pk_list->next;
|
||||||
xfree( pk_list );
|
free_public_key ( pk_list->pk );
|
||||||
|
xfree ( pk_list );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,7 +693,7 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
|
|||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Return a malloced string with a default reciepient if there is any
|
* Return a malloced string with a default recipient if there is any
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
default_recipient(void)
|
default_recipient(void)
|
||||||
@ -760,6 +773,96 @@ expand_group(strlist_t input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for build_pk_list to find and check one key. This helper is
|
||||||
|
also used directly in server mode by the RECIPIENTS command. On
|
||||||
|
success the new key is added to PK_LIST_ADDR. NAME is the user id
|
||||||
|
of the key. USE the requested usage and a set MARK_HIDDEN will mark
|
||||||
|
the key in the updated list as a hidden recipient. */
|
||||||
|
gpg_error_t
|
||||||
|
find_and_check_key (const char *name, unsigned int use,
|
||||||
|
int mark_hidden, pk_list_t *pk_list_addr)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
PKT_public_key *pk;
|
||||||
|
int trustlevel;
|
||||||
|
|
||||||
|
if (!name || !*name)
|
||||||
|
return gpg_error (GPG_ERR_INV_NAME);
|
||||||
|
|
||||||
|
pk = xtrycalloc (1, sizeof *pk);
|
||||||
|
if (!pk)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
pk->req_usage = use;
|
||||||
|
|
||||||
|
rc = get_pubkey_byname (NULL, pk, name, NULL, NULL, 0, 0);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
/* Key not found or other error. */
|
||||||
|
log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
|
||||||
|
send_status_inv_recp (0, name);
|
||||||
|
free_public_key (pk);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = openpgp_pk_test_algo2 (pk->pubkey_algo, use);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
/* Key found but not usable for us (e.g. sign-only key). */
|
||||||
|
send_status_inv_recp (0, name);
|
||||||
|
log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
|
||||||
|
free_public_key (pk);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Key found and usable. Check validity. */
|
||||||
|
trustlevel = get_validity (pk, pk->user_id);
|
||||||
|
if ( (trustlevel & TRUST_FLAG_DISABLED) )
|
||||||
|
{
|
||||||
|
/* Key has been disabled. */
|
||||||
|
send_status_inv_recp (0, name);
|
||||||
|
log_info (_("%s: skipped: public key is disabled\n"), name);
|
||||||
|
free_public_key (pk);
|
||||||
|
return G10ERR_UNU_PUBKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !do_we_trust_pre (pk, trustlevel) )
|
||||||
|
{
|
||||||
|
/* We don't trust this key. */
|
||||||
|
send_status_inv_recp (10, name);
|
||||||
|
free_public_key (pk);
|
||||||
|
return G10ERR_UNU_PUBKEY;
|
||||||
|
}
|
||||||
|
/* Note: do_we_trust may have changed the trustlevel. */
|
||||||
|
|
||||||
|
/* Skip the actual key if the key is already present in the
|
||||||
|
list. */
|
||||||
|
if (!key_present_in_pk_list (*pk_list_addr, pk))
|
||||||
|
{
|
||||||
|
log_info (_("%s: skipped: public key already present\n"), name);
|
||||||
|
free_public_key (pk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pk_list_t r;
|
||||||
|
|
||||||
|
r = xtrymalloc (sizeof *r);
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
free_public_key (pk);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
r->pk = pk;
|
||||||
|
r->next = *pk_list_addr;
|
||||||
|
r->flags = mark_hidden? 1:0;
|
||||||
|
*pk_list_addr = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This is the central function to collect the keys for recipients.
|
/* This is the central function to collect the keys for recipients.
|
||||||
It is thus used to prepare a public key encryption. encrypt-to
|
It is thus used to prepare a public key encryption. encrypt-to
|
||||||
keys, default keys and the keys for the actual recipients are all
|
keys, default keys and the keys for the actual recipients are all
|
||||||
@ -831,8 +934,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
|||||||
{
|
{
|
||||||
free_public_key ( pk ); pk = NULL;
|
free_public_key ( pk ); pk = NULL;
|
||||||
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
send_status_inv_recp (0, rov->d);
|
||||||
rov->d, strlen (rov->d), -1);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
|
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
|
||||||
@ -873,8 +975,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
|||||||
available. */
|
available. */
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
send_status_inv_recp (0, rov->d);
|
||||||
rov->d, strlen (rov->d), -1);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1078,85 +1179,11 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
|
|||||||
if ( (remusr->flags & 1) )
|
if ( (remusr->flags & 1) )
|
||||||
continue; /* encrypt-to keys are already handled. */
|
continue; /* encrypt-to keys are already handled. */
|
||||||
|
|
||||||
pk = xmalloc_clear( sizeof *pk );
|
rc = find_and_check_key (remusr->d, use, !!(remusr->flags&2),
|
||||||
pk->req_usage = use;
|
&pk_list);
|
||||||
if ((rc = get_pubkey_byname (NULL, pk, remusr->d, NULL, NULL, 0, 0)))
|
if (rc)
|
||||||
{
|
goto fail;
|
||||||
/* Key not found or other error. */
|
any_recipients = 1;
|
||||||
free_public_key( pk ); pk = NULL;
|
|
||||||
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
|
||||||
remusr->d, strlen (remusr->d),
|
|
||||||
-1);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) )
|
|
||||||
{
|
|
||||||
/* Key found and usable. Check validity. */
|
|
||||||
int trustlevel;
|
|
||||||
|
|
||||||
trustlevel = get_validity (pk, pk->user_id);
|
|
||||||
if ( (trustlevel & TRUST_FLAG_DISABLED) )
|
|
||||||
{
|
|
||||||
/*Key has been disabled. */
|
|
||||||
free_public_key(pk); pk = NULL;
|
|
||||||
log_info(_("%s: skipped: public key is disabled\n"),
|
|
||||||
remusr->d);
|
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
|
||||||
remusr->d,
|
|
||||||
strlen (remusr->d),
|
|
||||||
-1);
|
|
||||||
rc=G10ERR_UNU_PUBKEY;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
else if ( do_we_trust_pre( pk, trustlevel ) )
|
|
||||||
{
|
|
||||||
/* Note: do_we_trust may have changed the trustlevel */
|
|
||||||
|
|
||||||
/* We have at least one valid recipient. It doesn't
|
|
||||||
* matters if this recipient is already present. */
|
|
||||||
any_recipients = 1;
|
|
||||||
|
|
||||||
/* Skip the actual key if the key is already present
|
|
||||||
* in the list */
|
|
||||||
if (!key_present_in_pk_list(pk_list, pk))
|
|
||||||
{
|
|
||||||
free_public_key(pk); pk = NULL;
|
|
||||||
log_info(_("%s: skipped: public key already present\n"),
|
|
||||||
remusr->d);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PK_LIST r;
|
|
||||||
r = xmalloc( sizeof *r );
|
|
||||||
r->pk = pk; pk = NULL;
|
|
||||||
r->next = pk_list;
|
|
||||||
r->flags = (remusr->flags&2)?1:0;
|
|
||||||
pk_list = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* We don't trust this key. */
|
|
||||||
free_public_key( pk ); pk = NULL;
|
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "10 ",
|
|
||||||
remusr->d,
|
|
||||||
strlen (remusr->d),
|
|
||||||
-1);
|
|
||||||
rc=G10ERR_UNU_PUBKEY;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Key found but not usable for us (e.g. sign-only key). */
|
|
||||||
free_public_key( pk ); pk = NULL;
|
|
||||||
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
|
||||||
remusr->d,
|
|
||||||
strlen (remusr->d),
|
|
||||||
-1);
|
|
||||||
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
|||||||
if( !opt.armor )
|
if( !opt.armor )
|
||||||
tty_printf(_("ASCII armored output forced.\n"));
|
tty_printf(_("ASCII armored output forced.\n"));
|
||||||
|
|
||||||
if( (rc = open_outfile( NULL, 0, &out )) )
|
if( (rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
afx->what = 1;
|
afx->what = 1;
|
||||||
@ -550,7 +550,7 @@ gen_revoke( const char *uname )
|
|||||||
if( !opt.armor )
|
if( !opt.armor )
|
||||||
tty_printf(_("ASCII armored output forced.\n"));
|
tty_printf(_("ASCII armored output forced.\n"));
|
||||||
|
|
||||||
if( (rc = open_outfile( NULL, 0, &out )) )
|
if( (rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
afx->what = 1;
|
afx->what = 1;
|
||||||
|
165
g10/server.c
165
g10/server.c
@ -33,6 +33,7 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "../common/sysutils.h"
|
#include "../common/sysutils.h"
|
||||||
|
#include "status.h"
|
||||||
|
|
||||||
|
|
||||||
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
|
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
|
||||||
@ -45,6 +46,10 @@ struct server_local_s
|
|||||||
assuan_context_t assuan_ctx;
|
assuan_context_t assuan_ctx;
|
||||||
/* File descriptor as set by the MESSAGE command. */
|
/* File descriptor as set by the MESSAGE command. */
|
||||||
gnupg_fd_t message_fd;
|
gnupg_fd_t message_fd;
|
||||||
|
|
||||||
|
/* List of prepared recipients. */
|
||||||
|
pk_list_t recplist;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -61,6 +66,39 @@ close_message_fd (ctrl_t ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Skip over options. Blanks after the options are also removed. */
|
||||||
|
static char *
|
||||||
|
skip_options (const char *line)
|
||||||
|
{
|
||||||
|
while (spacep (line))
|
||||||
|
line++;
|
||||||
|
while ( *line == '-' && line[1] == '-' )
|
||||||
|
{
|
||||||
|
while (*line && !spacep (line))
|
||||||
|
line++;
|
||||||
|
while (spacep (line))
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
return (char*)line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether the option NAME appears in LINE. */
|
||||||
|
static int
|
||||||
|
has_option (const char *line, const char *name)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n = strlen (name);
|
||||||
|
|
||||||
|
s = strstr (line, name);
|
||||||
|
if (s && s >= skip_options (line))
|
||||||
|
return 0;
|
||||||
|
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Called by libassuan for Assuan options. See the Assuan manual for
|
/* Called by libassuan for Assuan options. See the Assuan manual for
|
||||||
details. */
|
details. */
|
||||||
@ -111,6 +149,9 @@ reset_notify (assuan_context_t ctx)
|
|||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
|
release_pk_list (ctrl->server_local->recplist);
|
||||||
|
ctrl->server_local->recplist = NULL;
|
||||||
|
|
||||||
close_message_fd (ctrl);
|
close_message_fd (ctrl);
|
||||||
assuan_close_input_fd (ctx);
|
assuan_close_input_fd (ctx);
|
||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
@ -157,7 +198,7 @@ output_notify (assuan_context_t ctx, const char *line)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* RECIPIENT <userID>
|
/* RECIPIENT [--hidden] <userID>
|
||||||
|
|
||||||
Set the recipient for the encryption. <userID> should be the
|
Set the recipient for the encryption. <userID> should be the
|
||||||
internal representation of the key; the server may accept any other
|
internal representation of the key; the server may accept any other
|
||||||
@ -171,9 +212,26 @@ output_notify (assuan_context_t ctx, const char *line)
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_recipient (assuan_context_t ctx, char *line)
|
cmd_recipient (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
(void)ctx;
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
(void)line;
|
gpg_error_t err;
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
int hidden;
|
||||||
|
|
||||||
|
hidden = has_option (line,"--hidden");
|
||||||
|
line = skip_options (line);
|
||||||
|
|
||||||
|
/* FIXME: Expand groups
|
||||||
|
if (opt.grouplist)
|
||||||
|
remusr = expand_group (rcpts);
|
||||||
|
else
|
||||||
|
remusr = rcpts;
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = find_and_check_key (line, PUBKEY_USAGE_ENC, hidden,
|
||||||
|
&ctrl->server_local->recplist);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
log_error ("command '%s' failed: %s\n", "RECIPIENT", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -206,22 +264,81 @@ cmd_signer (assuan_context_t ctx, char *line)
|
|||||||
/* ENCRYPT
|
/* ENCRYPT
|
||||||
|
|
||||||
Do the actual encryption process. Takes the plaintext from the
|
Do the actual encryption process. Takes the plaintext from the
|
||||||
INPUT command, writes to the ciphertext to the file descriptor set
|
INPUT command, writes the ciphertext to the file descriptor set
|
||||||
with the OUTPUT command, take the recipients form all the
|
with the OUTPUT command, take the recipients from all the
|
||||||
recipients set so far. If this command fails the clients should
|
recipients set so far with RECIPIENTS.
|
||||||
try to delete all output currently done or otherwise mark it as
|
|
||||||
invalid. GPG does ensure that there won't be any security problem
|
|
||||||
with leftover data on the output in this case.
|
|
||||||
|
|
||||||
This command should in general not fail, as all necessary checks
|
If this command fails the clients should try to delete all output
|
||||||
have been done while setting the recipients. The input and output
|
currently done or otherwise mark it as invalid. GPG does ensure
|
||||||
pipes are closed. */
|
that there won't be any security problem with leftover data on the
|
||||||
|
output in this case.
|
||||||
|
|
||||||
|
In most cases this command won't fail because most necessary checks
|
||||||
|
have been done while setting the recipients. However some checks
|
||||||
|
can only be done right here and thus error may occur anyway (for
|
||||||
|
example, no recipients at all).
|
||||||
|
|
||||||
|
The input, output and message pipes are closed after this
|
||||||
|
command. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_encrypt (assuan_context_t ctx, char *line)
|
cmd_encrypt (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
(void)ctx;
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
(void)line;
|
gpg_error_t err;
|
||||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
int inp_fd, out_fd;
|
||||||
|
|
||||||
|
(void)line; /* LINE is not used. */
|
||||||
|
|
||||||
|
if ( !ctrl->server_local->recplist )
|
||||||
|
{
|
||||||
|
write_status_text (STATUS_NO_RECP, "0");
|
||||||
|
err = gpg_error (GPG_ERR_NO_USER_ID);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0);
|
||||||
|
if (inp_fd == -1)
|
||||||
|
{
|
||||||
|
err = set_error (GPG_ERR_ASS_NO_INPUT, NULL);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
|
||||||
|
if (out_fd == -1)
|
||||||
|
{
|
||||||
|
err = set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixme: Check that we are using real files and not pipes if in
|
||||||
|
PGP-2 mode. Do all the other checks we do in gpg.c for aEncr.
|
||||||
|
Maybe we should drop the PGP2 compatibility. */
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: GPGSM does this here: Add all encrypt-to marked recipients
|
||||||
|
from the default list. */
|
||||||
|
|
||||||
|
/* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/
|
||||||
|
|
||||||
|
err = encrypt_crypt (inp_fd, NULL, NULL, 0,
|
||||||
|
ctrl->server_local->recplist,
|
||||||
|
out_fd);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
/* Release the recipient list on success. */
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
release_pk_list (ctrl->server_local->recplist);
|
||||||
|
ctrl->server_local->recplist = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close and reset the fds. */
|
||||||
|
close_message_fd (ctrl);
|
||||||
|
assuan_close_input_fd (ctx);
|
||||||
|
assuan_close_output_fd (ctx);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
log_error ("command '%s' failed: %s\n", "ENCRYPT", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -258,6 +375,9 @@ cmd_verify (assuan_context_t ctx, char *line)
|
|||||||
gnupg_fd_t out_fd = assuan_get_output_fd (ctx);
|
gnupg_fd_t out_fd = assuan_get_output_fd (ctx);
|
||||||
FILE *out_fp = NULL;
|
FILE *out_fp = NULL;
|
||||||
|
|
||||||
|
/* FIXME: Revamp this code it is nearly to 3 years old and was only
|
||||||
|
intended as a quick test. */
|
||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
if (fd == GNUPG_INVALID_FD)
|
if (fd == GNUPG_INVALID_FD)
|
||||||
@ -270,8 +390,8 @@ cmd_verify (assuan_context_t ctx, char *line)
|
|||||||
return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
|
return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug ("WARNING: The server mode work "
|
log_debug ("WARNING: The server mode is WORK "
|
||||||
"in progress and not ready for use\n");
|
"iN PROGRESS and not ready for use\n");
|
||||||
|
|
||||||
/* Need to dup it because it might get closed and libassuan won't
|
/* Need to dup it because it might get closed and libassuan won't
|
||||||
know about it then. */
|
know about it then. */
|
||||||
@ -596,8 +716,13 @@ gpg_server (ctrl_t ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
xfree (ctrl->server_local);
|
if (ctrl->server_local)
|
||||||
ctrl->server_local = NULL;
|
{
|
||||||
|
release_pk_list (ctrl->server_local->recplist);
|
||||||
|
|
||||||
|
xfree (ctrl->server_local);
|
||||||
|
ctrl->server_local = NULL;
|
||||||
|
}
|
||||||
assuan_release (ctx);
|
assuan_release (ctx);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
|
|||||||
else if( opt.verbose )
|
else if( opt.verbose )
|
||||||
log_info(_("writing to `%s'\n"), outfile );
|
log_info(_("writing to `%s'\n"), outfile );
|
||||||
}
|
}
|
||||||
else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out )))
|
else if( (rc = open_outfile (GNUPG_INVALID_FD, fname,
|
||||||
|
opt.armor? 1: detached? 2:0, &out )))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* prepare to calculate the MD over the input */
|
/* prepare to calculate the MD over the input */
|
||||||
@ -1110,7 +1111,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
|
|||||||
else if( opt.verbose )
|
else if( opt.verbose )
|
||||||
log_info(_("writing to `%s'\n"), outfile );
|
log_info(_("writing to `%s'\n"), outfile );
|
||||||
}
|
}
|
||||||
else if( (rc = open_outfile( fname, 1, &out )) )
|
else if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 1, &out )) )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
|
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
|
||||||
@ -1275,7 +1276,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
|
|||||||
cfx.dek->use_mdc=1;
|
cfx.dek->use_mdc=1;
|
||||||
|
|
||||||
/* now create the outfile */
|
/* now create the outfile */
|
||||||
rc = open_outfile (fname, opt.armor? 1:0, &out);
|
rc = open_outfile (GNUPG_INVALID_FD, fname, opt.armor? 1:0, &out);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -24,12 +24,19 @@ AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
|
|||||||
|
|
||||||
include $(top_srcdir)/am/cmacros.am
|
include $(top_srcdir)/am/cmacros.am
|
||||||
|
|
||||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS)
|
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS)
|
||||||
|
|
||||||
g13_SOURCES = \
|
g13_SOURCES = \
|
||||||
g13.c g13.h
|
g13.c g13.h \
|
||||||
|
keyblob.h \
|
||||||
|
utils.c utils.h \
|
||||||
|
create.c create.h \
|
||||||
|
call-gpg.c call-gpg.h \
|
||||||
|
backend.c backend.h \
|
||||||
|
be-encfs.c be-encfs.h \
|
||||||
|
be-truecrypt.c be-truecrypt.h
|
||||||
|
|
||||||
g13_LDADD = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a \
|
g13_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \
|
||||||
$(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
|
$(LIBGCRYPT_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \
|
||||||
$(LIBINTL)
|
$(GPG_ERROR_LIBS) $(LIBINTL)
|
||||||
|
|
||||||
|
83
g13/backend.c
Normal file
83
g13/backend.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* backend.c - Dispatcher to the various backends.
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "keyblob.h"
|
||||||
|
#include "backend.h"
|
||||||
|
#include "be-encfs.h"
|
||||||
|
#include "be-truecrypt.h"
|
||||||
|
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
no_such_backend (int conttype)
|
||||||
|
{
|
||||||
|
log_error ("invalid backend %d given - this is most likely a bug\n",
|
||||||
|
conttype);
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If the backend requires a separate file or directory for the
|
||||||
|
container, return its name by computing it from FNAME which gives
|
||||||
|
the g13 filename. The new file name is allocated and stored at
|
||||||
|
R_NAME, if this is expected to be a directory true is stored at
|
||||||
|
R_ISDIR. If no detached name is expected or an error occurs NULL
|
||||||
|
is stored at R_NAME. The function returns 0 on success or an error
|
||||||
|
code. */
|
||||||
|
gpg_error_t
|
||||||
|
be_get_detached_name (int conttype, const char *fname,
|
||||||
|
char **r_name, int *r_isdir)
|
||||||
|
{
|
||||||
|
*r_name = NULL;
|
||||||
|
*r_isdir = 0;
|
||||||
|
switch (conttype)
|
||||||
|
{
|
||||||
|
case CONTTYPE_ENCFS:
|
||||||
|
return be_encfs_get_detached_name (fname, r_name, r_isdir);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return no_such_backend (conttype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gpg_error_t
|
||||||
|
be_create_new_keys (int conttype, membuf_t *mb)
|
||||||
|
{
|
||||||
|
switch (conttype)
|
||||||
|
{
|
||||||
|
case CONTTYPE_ENCFS:
|
||||||
|
return be_encfs_create_new_keys (mb);
|
||||||
|
|
||||||
|
case CONTTYPE_TRUECRYPT:
|
||||||
|
return be_truecrypt_create_new_keys (mb);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return no_such_backend (conttype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
32
g13/backend.h
Normal file
32
g13/backend.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* backend.h - Defs for the dispatcher to the various backends.
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_BACKEND_H
|
||||||
|
#define G13_BACKEND_H
|
||||||
|
|
||||||
|
#include "../common/membuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
gpg_error_t be_get_detached_name (int conttype, const char *fname,
|
||||||
|
char **r_name, int *r_isdir);
|
||||||
|
gpg_error_t be_create_new_keys (int conttype, membuf_t *mb);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_BACKEND_H*/
|
||||||
|
|
58
g13/be-encfs.c
Normal file
58
g13/be-encfs.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* be-encfs.c - The EncFS based backend
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "keyblob.h"
|
||||||
|
#include "be-encfs.h"
|
||||||
|
|
||||||
|
/* See be_get_detached_name for a description. Note that the
|
||||||
|
dispatcher code makes sure that NULL is stored at R_NAME before
|
||||||
|
calling us. */
|
||||||
|
gpg_error_t
|
||||||
|
be_encfs_get_detached_name (const char *fname, char **r_name, int *r_isdir)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if (!fname || !*fname)
|
||||||
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
|
result = strconcat (fname, ".d", NULL);
|
||||||
|
if (!result)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
*r_name = result;
|
||||||
|
*r_isdir = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gpg_error_t
|
||||||
|
be_encfs_create_new_keys (membuf_t *mb)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
31
g13/be-encfs.h
Normal file
31
g13/be-encfs.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* be-encfs.h - Public defs for the EncFS based backend
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_BE_ENCFS_H
|
||||||
|
#define G13_BE_ENCFS_H
|
||||||
|
|
||||||
|
#include "backend.h"
|
||||||
|
|
||||||
|
gpg_error_t be_encfs_get_detached_name (const char *fname,
|
||||||
|
char **r_name, int *r_isdir);
|
||||||
|
gpg_error_t be_encfs_create_new_keys (membuf_t *mb);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_BE_ENCFS_H*/
|
||||||
|
|
39
g13/be-truecrypt.c
Normal file
39
g13/be-truecrypt.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* be-truecrypt.c - The Truecrypt based backend
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "be-truecrypt.h"
|
||||||
|
|
||||||
|
|
||||||
|
gpg_error_t
|
||||||
|
be_truecrypt_create_new_keys (membuf_t *mb)
|
||||||
|
{
|
||||||
|
(void)mb;
|
||||||
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
29
g13/be-truecrypt.h
Normal file
29
g13/be-truecrypt.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* be-truecrypt.h - Public defs for the Truecrypt based backend
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_BE_TRUECRYPT_H
|
||||||
|
#define G13_BE_TRUECRYPT_H
|
||||||
|
|
||||||
|
#include "backend.h"
|
||||||
|
|
||||||
|
gpg_error_t be_truecrypt_create_new_keys (membuf_t *mb);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_BE_TRUECRYPT_H*/
|
||||||
|
|
466
g13/call-gpg.c
Normal file
466
g13/call-gpg.c
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
/* call-gpg.c - Communication with the GPG
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <pth.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include <assuan.h>
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "call-gpg.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "../common/exechelp.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Fire up a new GPG. Handle the server's initial greeting. Returns
|
||||||
|
0 on success and stores the assuan context at R_CTX. */
|
||||||
|
static gpg_error_t
|
||||||
|
start_gpg (ctrl_t ctrl, int input_fd, int output_fd, assuan_context_t *r_ctx)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
assuan_context_t ctx = NULL;
|
||||||
|
const char *pgmname;
|
||||||
|
const char *argv[6];
|
||||||
|
int no_close_list[5];
|
||||||
|
int i;
|
||||||
|
char line[ASSUAN_LINELENGTH];
|
||||||
|
|
||||||
|
(void)ctrl;
|
||||||
|
|
||||||
|
*r_ctx = NULL;
|
||||||
|
|
||||||
|
err = assuan_new (&ctx);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("can't allocate assuan context: %s\n", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The first time we are used, intialize the gpg_program variable. */
|
||||||
|
if ( !opt.gpg_program || !*opt.gpg_program )
|
||||||
|
opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
|
||||||
|
|
||||||
|
if (opt.verbose)
|
||||||
|
log_info (_("no running gpg - starting `%s'\n"), opt.gpg_program);
|
||||||
|
|
||||||
|
/* Compute argv[0]. */
|
||||||
|
if ( !(pgmname = strrchr (opt.gpg_program, '/')))
|
||||||
|
pgmname = opt.gpg_program;
|
||||||
|
else
|
||||||
|
pgmname++;
|
||||||
|
|
||||||
|
if (fflush (NULL))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error flushing pending output: %s\n", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
argv[i++] = pgmname;
|
||||||
|
argv[i++] = "--server";
|
||||||
|
if ((opt.debug & 1024))
|
||||||
|
argv[i++] = "--debug=1024";
|
||||||
|
argv[i++] = "-z";
|
||||||
|
argv[i++] = "0";
|
||||||
|
argv[i++] = NULL;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
if (log_get_fd () != -1)
|
||||||
|
no_close_list[i++] = log_get_fd ();
|
||||||
|
no_close_list[i++] = fileno (stderr);
|
||||||
|
if (input_fd != -1)
|
||||||
|
no_close_list[i++] = input_fd;
|
||||||
|
if (output_fd != -1)
|
||||||
|
no_close_list[i++] = output_fd;
|
||||||
|
no_close_list[i] = -1;
|
||||||
|
|
||||||
|
/* Connect to GPG and perform initial handshaking. */
|
||||||
|
err = assuan_pipe_connect (ctx, opt.gpg_program, argv, no_close_list);
|
||||||
|
|
||||||
|
/* if (!err) */
|
||||||
|
/* err = assuan_transact (ctx, "OPTION audit-events=1", */
|
||||||
|
/* NULL, NULL, NULL, NULL, NULL, NULL); */
|
||||||
|
/* audit_log_ok (ctrl->audit, AUDIT_GPG_READY, err); */
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
assuan_release (ctx);
|
||||||
|
log_error ("can't connect to GPG: %s\n", gpg_strerror (err));
|
||||||
|
return gpg_error (GPG_ERR_NO_ENGINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_fd != -1)
|
||||||
|
{
|
||||||
|
snprintf (line, sizeof line, "INPUT FD=%d", input_fd);
|
||||||
|
err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
assuan_release (ctx);
|
||||||
|
log_error ("error sending INPUT command: %s\n", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output_fd != -1)
|
||||||
|
{
|
||||||
|
snprintf (line, sizeof line, "OUTPUT FD=%d", output_fd);
|
||||||
|
err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
assuan_release (ctx);
|
||||||
|
log_error ("error sending OUTPUT command: %s\n", gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_ctx = ctx;
|
||||||
|
|
||||||
|
if (DBG_ASSUAN)
|
||||||
|
log_debug ("connection to GPG established\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Release the assuan context created by start_gpg. */
|
||||||
|
static void
|
||||||
|
release_gpg (assuan_context_t ctx)
|
||||||
|
{
|
||||||
|
assuan_release (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The data passed to the writer_thread. */
|
||||||
|
struct writer_thread_parms
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
const void *data;
|
||||||
|
size_t datalen;
|
||||||
|
gpg_error_t *err_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* The thread started by start_writer. */
|
||||||
|
static void *
|
||||||
|
writer_thread (void *arg)
|
||||||
|
{
|
||||||
|
struct writer_thread_parms *parm = arg;
|
||||||
|
const char *buffer = parm->data;
|
||||||
|
size_t length = parm->datalen;
|
||||||
|
|
||||||
|
while (length)
|
||||||
|
{
|
||||||
|
ssize_t nwritten;
|
||||||
|
|
||||||
|
nwritten = pth_write (parm->fd, buffer, length < 4096? length:4096);
|
||||||
|
if (nwritten < 0)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
*parm->err_addr = gpg_error_from_syserror ();
|
||||||
|
break; /* Write error. */
|
||||||
|
}
|
||||||
|
length -= nwritten;
|
||||||
|
buffer += nwritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close (parm->fd))
|
||||||
|
log_error ("closing writer fd %d failed: %s\n", parm->fd, strerror (errno));
|
||||||
|
xfree (parm);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fire up a thread to send (DATA,DATALEN) to the file descriptor FD.
|
||||||
|
On success the thread receives the ownership over FD. The thread
|
||||||
|
ID is stored at R_TID. WRITER_ERR is the address of an gpg_error_t
|
||||||
|
variable to receive a possible write error after the thread has
|
||||||
|
finished. */
|
||||||
|
static gpg_error_t
|
||||||
|
start_writer (int fd, const void *data, size_t datalen,
|
||||||
|
pth_t *r_tid, gpg_error_t *err_addr)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
struct writer_thread_parms *parm;
|
||||||
|
pth_attr_t tattr;
|
||||||
|
pth_t tid;
|
||||||
|
|
||||||
|
*r_tid = NULL;
|
||||||
|
*err_addr = 0;
|
||||||
|
|
||||||
|
parm = xtrymalloc (sizeof *parm);
|
||||||
|
if (!parm)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
parm->fd = fd;
|
||||||
|
parm->data = data;
|
||||||
|
parm->datalen = datalen;
|
||||||
|
parm->err_addr = err_addr;
|
||||||
|
|
||||||
|
tattr = pth_attr_new ();
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_NAME, "fd-writer");
|
||||||
|
|
||||||
|
tid = pth_spawn (tattr, writer_thread, parm);
|
||||||
|
if (!tid)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error spawning writer thread: %s\n", gpg_strerror (err));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
*r_tid = tid;
|
||||||
|
}
|
||||||
|
pth_attr_destroy (tattr);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The data passed to the reader_thread. */
|
||||||
|
struct reader_thread_parms
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
membuf_t *mb;
|
||||||
|
gpg_error_t *err_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* The thread started by start_reader. */
|
||||||
|
static void *
|
||||||
|
reader_thread (void *arg)
|
||||||
|
{
|
||||||
|
struct reader_thread_parms *parm = arg;
|
||||||
|
char buffer[4096];
|
||||||
|
int nread;
|
||||||
|
|
||||||
|
while ( (nread = pth_read (parm->fd, buffer, sizeof buffer)) )
|
||||||
|
{
|
||||||
|
if (nread < 0)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
*parm->err_addr = gpg_error_from_syserror ();
|
||||||
|
break; /* Read error. */
|
||||||
|
}
|
||||||
|
|
||||||
|
put_membuf (parm->mb, buffer, nread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close (parm->fd))
|
||||||
|
log_error ("closing reader fd %d failed: %s\n", parm->fd, strerror (errno));
|
||||||
|
xfree (parm);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fire up a thread to receive data from the file descriptor FD. On
|
||||||
|
success the thread receives the ownership over FD. The thread ID
|
||||||
|
is stored at R_TID. After the thread has finished an error from
|
||||||
|
the thread will be stored at ERR_ADDR. */
|
||||||
|
static gpg_error_t
|
||||||
|
start_reader (int fd, membuf_t *mb, pth_t *r_tid, gpg_error_t *err_addr)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
struct reader_thread_parms *parm;
|
||||||
|
pth_attr_t tattr;
|
||||||
|
pth_t tid;
|
||||||
|
|
||||||
|
*r_tid = NULL;
|
||||||
|
*err_addr = 0;
|
||||||
|
|
||||||
|
parm = xtrymalloc (sizeof *parm);
|
||||||
|
if (!parm)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
parm->fd = fd;
|
||||||
|
parm->mb = mb;
|
||||||
|
parm->err_addr = err_addr;
|
||||||
|
|
||||||
|
tattr = pth_attr_new ();
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
|
||||||
|
pth_attr_set (tattr, PTH_ATTR_NAME, "fd-reader");
|
||||||
|
|
||||||
|
tid = pth_spawn (tattr, reader_thread, parm);
|
||||||
|
if (!tid)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error spawning reader thread: %s\n", gpg_strerror (err));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
*r_tid = tid;
|
||||||
|
}
|
||||||
|
pth_attr_destroy (tattr);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Call GPG to encrypt a block of data.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
gpg_error_t
|
||||||
|
gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen,
|
||||||
|
void **r_ciph, size_t *r_ciphlen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
assuan_context_t ctx;
|
||||||
|
int outbound_fds[2] = { -1, -1 };
|
||||||
|
int inbound_fds[2] = { -1, -1 };
|
||||||
|
pth_t writer_tid = NULL;
|
||||||
|
pth_t reader_tid = NULL;
|
||||||
|
gpg_error_t writer_err, reader_err;
|
||||||
|
membuf_t reader_mb;
|
||||||
|
|
||||||
|
*r_ciph = NULL;
|
||||||
|
*r_ciphlen = 0;
|
||||||
|
|
||||||
|
/* Init the memory buffer to receive the encrypted stuff. */
|
||||||
|
init_membuf (&reader_mb, 4096);
|
||||||
|
|
||||||
|
/* Create two pipes. */
|
||||||
|
err = gnupg_create_outbound_pipe (outbound_fds);
|
||||||
|
if (!err)
|
||||||
|
err = gnupg_create_inbound_pipe (inbound_fds);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start GPG and send the INPUT and OUTPUT commands. */
|
||||||
|
err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
close (outbound_fds[0]); outbound_fds[0] = -1;
|
||||||
|
close (inbound_fds[1]); inbound_fds[1] = -1;
|
||||||
|
|
||||||
|
/* Start a writer thread to feed the INPUT command of the server. */
|
||||||
|
err = start_writer (outbound_fds[1], plain, plainlen,
|
||||||
|
&writer_tid, &writer_err);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
outbound_fds[1] = -1; /* The thread owns the FD now. */
|
||||||
|
|
||||||
|
/* Start a reader thread to eat from the OUTPUT command of the
|
||||||
|
server. */
|
||||||
|
err = start_reader (inbound_fds[0], &reader_mb,
|
||||||
|
&reader_tid, &reader_err);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
outbound_fds[0] = -1; /* The thread owns the FD now. */
|
||||||
|
|
||||||
|
/* Run the encryption. */
|
||||||
|
err = assuan_transact (ctx, "RECIPIENT alpha@example.net",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("the engine's RECIPIENT command failed: %s <%s>\n",
|
||||||
|
gpg_strerror (err), gpg_strsource (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("the engine's ENCRYPT command failed: %s <%s>\n",
|
||||||
|
gpg_strerror (err), gpg_strsource (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for reader and return the data. */
|
||||||
|
if (!pth_join (reader_tid, NULL))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
reader_tid = NULL;
|
||||||
|
if (reader_err)
|
||||||
|
{
|
||||||
|
err = reader_err;
|
||||||
|
log_error ("read error in reader thread: %s\n", gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the writer to catch a writer error. */
|
||||||
|
if (!pth_join (writer_tid, NULL))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
writer_tid = NULL;
|
||||||
|
if (writer_err)
|
||||||
|
{
|
||||||
|
err = writer_err;
|
||||||
|
log_error ("write error in writer thread: %s\n", gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the data. */
|
||||||
|
*r_ciph = get_membuf (&reader_mb, r_ciphlen);
|
||||||
|
if (!*r_ciph)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error while storing the data in the reader thread: %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (reader_tid)
|
||||||
|
{
|
||||||
|
pth_cancel (reader_tid);
|
||||||
|
pth_join (reader_tid, NULL);
|
||||||
|
}
|
||||||
|
if (writer_tid)
|
||||||
|
{
|
||||||
|
pth_cancel (writer_tid);
|
||||||
|
pth_join (writer_tid, NULL);
|
||||||
|
}
|
||||||
|
if (outbound_fds[0] != -1)
|
||||||
|
close (outbound_fds[0]);
|
||||||
|
if (outbound_fds[1] != -1)
|
||||||
|
close (outbound_fds[1]);
|
||||||
|
if (inbound_fds[0] != -1)
|
||||||
|
close (inbound_fds[0]);
|
||||||
|
if (inbound_fds[1] != -1)
|
||||||
|
close (inbound_fds[1]);
|
||||||
|
release_gpg (ctx);
|
||||||
|
xfree (get_membuf (&reader_mb, NULL));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
29
g13/call-gpg.h
Normal file
29
g13/call-gpg.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* call-gpg.h - Defs for the communication with GPG
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_CALL_GPG_H
|
||||||
|
#define G13_CALL_GPG_H
|
||||||
|
|
||||||
|
gpg_error_t gpg_encrypt_blob (ctrl_t ctrl,
|
||||||
|
const void *plain, size_t plainlen,
|
||||||
|
void **r_ciph, size_t *r_ciphlen);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_CALL_GPG_H*/
|
306
g13/create.c
Normal file
306
g13/create.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/* create.c - Create a new crypto container
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
#include "create.h"
|
||||||
|
|
||||||
|
#include "keyblob.h"
|
||||||
|
#include "backend.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "call-gpg.h"
|
||||||
|
#include "estream.h"
|
||||||
|
|
||||||
|
/* Create a new blob with all the session keys and other meta
|
||||||
|
information which are to be stored encrypted in the crypto
|
||||||
|
container header. On success the malloced blob is stored at R_BLOB
|
||||||
|
and its length at R_BLOBLEN. On error en error ocde is returned
|
||||||
|
and (R_BLOB,R_BLOBLEN) are set to (NULL,0).
|
||||||
|
|
||||||
|
The format of this blob is a sequence of tag-length-value tuples.
|
||||||
|
All tuples have this format:
|
||||||
|
|
||||||
|
2 byte TAG Big endian unsigned integer (0..65535)
|
||||||
|
described by the KEYBLOB_TAG_ constants.
|
||||||
|
2 byte LENGTH Big endian unsigned integer (0..65535)
|
||||||
|
giving the length of the value.
|
||||||
|
length bytes VALUE The value described by the tag.
|
||||||
|
|
||||||
|
The first tag in a keyblob must be a BLOBVERSION. The other tags
|
||||||
|
depend on the type of the container as described by the CONTTYPE
|
||||||
|
tag. See keyblob.h for details. */
|
||||||
|
static gpg_error_t
|
||||||
|
create_new_keyblob (ctrl_t ctrl, int is_detached,
|
||||||
|
void **r_blob, size_t *r_bloblen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
unsigned char twobyte[2];
|
||||||
|
membuf_t mb;
|
||||||
|
|
||||||
|
*r_blob = NULL;
|
||||||
|
*r_bloblen = 0;
|
||||||
|
|
||||||
|
init_membuf_secure (&mb, 512);
|
||||||
|
|
||||||
|
append_tuple (&mb, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
|
||||||
|
|
||||||
|
twobyte[0] = (ctrl->conttype >> 8);
|
||||||
|
twobyte[1] = (ctrl->conttype);
|
||||||
|
append_tuple (&mb, KEYBLOB_TAG_CONTTYPE, twobyte, 2);
|
||||||
|
if (is_detached)
|
||||||
|
append_tuple (&mb, KEYBLOB_TAG_DETACHED, NULL, 0);
|
||||||
|
|
||||||
|
err = be_create_new_keys (ctrl->conttype, &mb);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
append_tuple (&mb, KEYBLOB_TAG_FILLER, "filler", 6);
|
||||||
|
|
||||||
|
|
||||||
|
*r_blob = get_membuf (&mb, r_bloblen);
|
||||||
|
if (!*r_blob)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
*r_bloblen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log_debug ("used keyblob size is %zu\n", *r_bloblen);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (get_membuf (&mb, NULL));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Encrypt the keyblob (KEYBLOB,KEYBLOBLEN) and store the result at
|
||||||
|
(R_ENCBLOB, R_ENCBLOBLEN). Returns 0 on success or an error code.
|
||||||
|
On error R_EKYBLOB is set to NULL. Depending on the keys set in
|
||||||
|
CTRL the result is a single OpenPGP binary message, a single
|
||||||
|
special OpenPGP packet encapsulating a CMS message or a
|
||||||
|
concatenation of both with the CMS packet being the last. */
|
||||||
|
static gpg_error_t
|
||||||
|
encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen,
|
||||||
|
void **r_encblob, size_t *r_encbloblen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
/* FIXME: For now we only implement OpenPGP. */
|
||||||
|
err = gpg_encrypt_blob (ctrl, keyblob, keybloblen,
|
||||||
|
r_encblob, r_encbloblen);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a new file under the name FILENAME with the keyblob and an
|
||||||
|
appropriate header. This fucntion is called with a lock file in
|
||||||
|
place and after checking that the filename does not exists. */
|
||||||
|
static gpg_error_t
|
||||||
|
write_keyblob (ctrl_t ctrl, const char *filename,
|
||||||
|
const void *keyblob, size_t keybloblen)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
estream_t fp;
|
||||||
|
unsigned char packet[32];
|
||||||
|
size_t headerlen, paddinglen;
|
||||||
|
|
||||||
|
fp = es_fopen (filename, "wbx");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error creating new container `%s': %s\n",
|
||||||
|
filename, gpg_strerror (err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow for an least 8 times larger keyblob to accommodate for
|
||||||
|
future key changes. Round it up to 4096 byte. */
|
||||||
|
headerlen = ((32 + 8 * keybloblen + 16) + 4095) / 4096 * 4096;
|
||||||
|
paddinglen = headerlen - 32 - keybloblen;
|
||||||
|
assert (paddinglen >= 16);
|
||||||
|
|
||||||
|
packet[0] = (0xc0|61); /* CTB for the private packet type 0x61. */
|
||||||
|
packet[1] = 0xff; /* 5 byte length packet, value 20. */
|
||||||
|
packet[2] = 0;
|
||||||
|
packet[3] = 0;
|
||||||
|
packet[4] = 0;
|
||||||
|
packet[5] = 26;
|
||||||
|
memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype. */
|
||||||
|
packet[16] = 1; /* G13 packet format. */
|
||||||
|
packet[17] = 0; /* Reserved. */
|
||||||
|
packet[18] = 0; /* Reserved. */
|
||||||
|
packet[19] = 0; /* OS Flag. */
|
||||||
|
packet[20] = (headerlen >> 24); /* Total length of header. */
|
||||||
|
packet[21] = (headerlen >> 16);
|
||||||
|
packet[22] = (headerlen >> 8);
|
||||||
|
packet[23] = (headerlen);
|
||||||
|
packet[24] = 1; /* Number of header copies. */
|
||||||
|
packet[25] = 0; /* Number of header copies at the end. */
|
||||||
|
packet[26] = 0; /* Reserved. */
|
||||||
|
packet[27] = 0; /* Reserved. */
|
||||||
|
packet[28] = 0; /* Reserved. */
|
||||||
|
packet[29] = 0; /* Reserved. */
|
||||||
|
packet[30] = 0; /* Reserved. */
|
||||||
|
packet[31] = 0; /* Reserved. */
|
||||||
|
|
||||||
|
if (es_fwrite (packet, 32, 1, fp) != 1)
|
||||||
|
goto writeerr;
|
||||||
|
|
||||||
|
if (es_fwrite (keyblob, keybloblen, 1, fp) != 1)
|
||||||
|
goto writeerr;
|
||||||
|
|
||||||
|
/* Write the padding. */
|
||||||
|
packet[0] = (0xc0|61); /* CTB for Private packet type 0x61. */
|
||||||
|
packet[1] = 0xff; /* 5 byte length packet, value 20. */
|
||||||
|
packet[2] = (paddinglen-6) >> 24;
|
||||||
|
packet[3] = (paddinglen-6) >> 16;
|
||||||
|
packet[4] = (paddinglen-6) >> 8;
|
||||||
|
packet[5] = (paddinglen-6);
|
||||||
|
memcpy (packet+6, "GnuPG/PAD", 10); /* Packet subtype. */
|
||||||
|
if (es_fwrite (packet, 16, 1, fp) != 1)
|
||||||
|
goto writeerr;
|
||||||
|
memset (packet, 0, 32);
|
||||||
|
for (paddinglen-=16; paddinglen >= 32; paddinglen -= 32)
|
||||||
|
if (es_fwrite (packet, 32, 1, fp) != 1)
|
||||||
|
goto writeerr;
|
||||||
|
if (paddinglen)
|
||||||
|
if (es_fwrite (packet, paddinglen, 1, fp) != 1)
|
||||||
|
goto writeerr;
|
||||||
|
|
||||||
|
if (es_fclose (fp))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error closing `%s': %s\n",
|
||||||
|
filename, gpg_strerror (err));
|
||||||
|
remove (filename);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
|
||||||
|
|
||||||
|
writeerr:
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error writing header to `%s': %s\n",
|
||||||
|
filename, gpg_strerror (err));
|
||||||
|
es_fclose (fp);
|
||||||
|
remove (filename);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a new container under the name FILENAME and intialize it
|
||||||
|
using the current settings. If the file already exists an error is
|
||||||
|
returned. */
|
||||||
|
gpg_error_t
|
||||||
|
create_new_container (ctrl_t ctrl, const char *filename)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
dotlock_t lock;
|
||||||
|
void *keyblob = NULL;
|
||||||
|
size_t keybloblen;
|
||||||
|
void *enckeyblob = NULL;
|
||||||
|
size_t enckeybloblen;
|
||||||
|
char *detachedname = NULL;
|
||||||
|
int detachedisdir;
|
||||||
|
|
||||||
|
/* A quick check to see that no container with that name already
|
||||||
|
exists. */
|
||||||
|
if (!access (filename, F_OK))
|
||||||
|
return gpg_error (GPG_ERR_EEXIST);
|
||||||
|
|
||||||
|
/* Take a lock and proceed with the creation. If there is a lock we
|
||||||
|
immediately return an error because for creation it does not make
|
||||||
|
sense to wait. */
|
||||||
|
lock = create_dotlock (filename);
|
||||||
|
if (!lock)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
if (make_dotlock (lock, 0))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
/* Check again that the file does not exist. */
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (!stat (filename, &sb))
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_EEXIST);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* And a possible detached file or directory may not exist either. */
|
||||||
|
err = be_get_detached_name (ctrl->conttype, filename,
|
||||||
|
&detachedname, &detachedisdir);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
if (detachedname)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (!stat (detachedname, &sb))
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_EEXIST);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new keyblob. */
|
||||||
|
err = create_new_keyblob (ctrl, !!detachedname, &keyblob, &keybloblen);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
/* Encrypt that keyblob. */
|
||||||
|
err = encrypt_keyblob (ctrl, keyblob, keybloblen,
|
||||||
|
&enckeyblob, &enckeybloblen);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
/* Write out the header, the encrypted keyblob and some padding. */
|
||||||
|
err = write_keyblob (ctrl, filename, enckeyblob, enckeybloblen);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
/* Create and append the container. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (detachedname);
|
||||||
|
xfree (enckeyblob);
|
||||||
|
xfree (keyblob);
|
||||||
|
destroy_dotlock (lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
103
g13/g13.c
103
g13/g13.c
@ -25,14 +25,18 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <pth.h>
|
||||||
|
|
||||||
#include "g13.h"
|
#include "g13.h"
|
||||||
|
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
#include <assuan.h>
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "sysutils.h"
|
#include "sysutils.h"
|
||||||
#include "gc-opt-flags.h"
|
#include "gc-opt-flags.h"
|
||||||
|
#include "create.h"
|
||||||
|
#include "keyblob.h"
|
||||||
|
|
||||||
|
|
||||||
enum cmd_and_opt_values {
|
enum cmd_and_opt_values {
|
||||||
@ -60,6 +64,8 @@ enum cmd_and_opt_values {
|
|||||||
oOutput,
|
oOutput,
|
||||||
|
|
||||||
oAgentProgram,
|
oAgentProgram,
|
||||||
|
oGpgProgram,
|
||||||
|
|
||||||
oDisplay,
|
oDisplay,
|
||||||
oTTYname,
|
oTTYname,
|
||||||
oTTYtype,
|
oTTYtype,
|
||||||
@ -141,6 +147,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_n (oNoOptions, "no-options", "@"),
|
ARGPARSE_s_n (oNoOptions, "no-options", "@"),
|
||||||
ARGPARSE_s_s (oHomedir, "homedir", "@"),
|
ARGPARSE_s_s (oHomedir, "homedir", "@"),
|
||||||
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
|
ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
|
||||||
|
ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"),
|
||||||
ARGPARSE_s_s (oDisplay, "display", "@"),
|
ARGPARSE_s_s (oDisplay, "display", "@"),
|
||||||
ARGPARSE_s_s (oTTYname, "ttyname", "@"),
|
ARGPARSE_s_s (oTTYname, "ttyname", "@"),
|
||||||
ARGPARSE_s_s (oTTYtype, "ttytype", "@"),
|
ARGPARSE_s_s (oTTYtype, "ttytype", "@"),
|
||||||
@ -172,6 +179,14 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd,
|
|||||||
|
|
||||||
static void emergency_cleanup (void);
|
static void emergency_cleanup (void);
|
||||||
|
|
||||||
|
/* Begin Pth wrapper functions. */
|
||||||
|
GCRY_THREAD_OPTION_PTH_IMPL;
|
||||||
|
static int fixed_gcry_pth_init (void)
|
||||||
|
{
|
||||||
|
return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
|
||||||
|
}
|
||||||
|
/* End Pth wrapper functions. */
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
my_strusage( int level )
|
my_strusage( int level )
|
||||||
@ -299,6 +314,7 @@ main ( int argc, char **argv)
|
|||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
int orig_argc;
|
int orig_argc;
|
||||||
char **orig_argv;
|
char **orig_argv;
|
||||||
|
gpg_error_t err;
|
||||||
const char *fname;
|
const char *fname;
|
||||||
int may_coredump;
|
int may_coredump;
|
||||||
FILE *configfp = NULL;
|
FILE *configfp = NULL;
|
||||||
@ -324,14 +340,23 @@ main ( int argc, char **argv)
|
|||||||
gnupg_reopen_std ("g13");
|
gnupg_reopen_std ("g13");
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
|
|
||||||
|
|
||||||
log_set_prefix ("g13", 1);
|
log_set_prefix ("g13", 1);
|
||||||
|
|
||||||
/* Make sure that our subsystems are ready. */
|
/* Make sure that our subsystems are ready. */
|
||||||
i18n_init();
|
i18n_init ();
|
||||||
init_common_subsystems ();
|
init_common_subsystems ();
|
||||||
|
|
||||||
|
/* Libgcrypt requires us to register the threading model first.
|
||||||
|
Note that this will also do the pth_init. */
|
||||||
|
gcry_threads_pth.init = fixed_gcry_pth_init;
|
||||||
|
err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
|
||||||
|
gpg_strerror (err));
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that the Libgcrypt is suitable. */
|
/* Check that the Libgcrypt is suitable. */
|
||||||
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
|
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
|
||||||
log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
|
log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
|
||||||
@ -378,6 +403,20 @@ main ( int argc, char **argv)
|
|||||||
Now we are now working under our real uid
|
Now we are now working under our real uid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Setup malloc hooks. */
|
||||||
|
{
|
||||||
|
struct assuan_malloc_hooks malloc_hooks;
|
||||||
|
|
||||||
|
malloc_hooks.malloc = gcry_malloc;
|
||||||
|
malloc_hooks.realloc = gcry_realloc;
|
||||||
|
malloc_hooks.free = gcry_free;
|
||||||
|
assuan_set_malloc_hooks (&malloc_hooks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare libassuan. */
|
||||||
|
assuan_set_assuan_log_prefix (log_get_prefix (NULL));
|
||||||
|
assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
/* Setup a default control structure for command line mode. */
|
/* Setup a default control structure for command line mode. */
|
||||||
memset (&ctrl, 0, sizeof ctrl);
|
memset (&ctrl, 0, sizeof ctrl);
|
||||||
@ -394,29 +433,31 @@ main ( int argc, char **argv)
|
|||||||
pargs.flags = 1; /* Do not remove the args. */
|
pargs.flags = 1; /* Do not remove the args. */
|
||||||
|
|
||||||
next_pass:
|
next_pass:
|
||||||
if (configname) {
|
if (configname)
|
||||||
configlineno = 0;
|
{
|
||||||
configfp = fopen (configname, "r");
|
configlineno = 0;
|
||||||
if (!configfp)
|
configfp = fopen (configname, "r");
|
||||||
{
|
if (!configfp)
|
||||||
if (default_config)
|
{
|
||||||
{
|
if (default_config)
|
||||||
if (parse_debug)
|
{
|
||||||
log_info (_("NOTE: no default option file `%s'\n"), configname);
|
if (parse_debug)
|
||||||
}
|
log_info (_("NOTE: no default option file `%s'\n"), configname);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
log_error (_("option file `%s': %s\n"), configname, strerror(errno));
|
{
|
||||||
g13_exit(2);
|
log_error (_("option file `%s': %s\n"),
|
||||||
}
|
configname, strerror(errno));
|
||||||
xfree (configname);
|
g13_exit(2);
|
||||||
configname = NULL;
|
}
|
||||||
}
|
xfree (configname);
|
||||||
if (parse_debug && configname)
|
configname = NULL;
|
||||||
log_info (_("reading options from `%s'\n"), configname);
|
}
|
||||||
default_config = 0;
|
if (parse_debug && configname)
|
||||||
}
|
log_info (_("reading options from `%s'\n"), configname);
|
||||||
|
default_config = 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (!no_more_options
|
while (!no_more_options
|
||||||
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts))
|
&& optfile_parse (configfp, configname, &configlineno, &pargs, opts))
|
||||||
{
|
{
|
||||||
@ -484,6 +525,7 @@ main ( int argc, char **argv)
|
|||||||
case oHomedir: opt.homedir = pargs.r.ret_str; break;
|
case oHomedir: opt.homedir = pargs.r.ret_str; break;
|
||||||
|
|
||||||
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
|
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
|
||||||
|
case oGpgProgram: opt.gpg_program = pargs.r.ret_str; break;
|
||||||
case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
|
case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
|
||||||
case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
|
case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
|
||||||
case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
|
case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
|
||||||
@ -635,7 +677,10 @@ main ( int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
wrong_args ("--create filename");
|
wrong_args ("--create filename");
|
||||||
|
err = create_new_container (&ctrl, argv[0]);
|
||||||
|
if (err)
|
||||||
|
log_error ("error creating a new container: %s <%s>\n",
|
||||||
|
gpg_strerror (err), gpg_strsource (err));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -647,8 +692,8 @@ main ( int argc, char **argv)
|
|||||||
/* Print the audit result if needed. */
|
/* Print the audit result if needed. */
|
||||||
if (auditlog && auditfp)
|
if (auditlog && auditfp)
|
||||||
{
|
{
|
||||||
audit_print_result (ctrl.audit, auditfp, 0);
|
/* audit_print_result (ctrl.audit, auditfp, 0); */
|
||||||
audit_release (ctrl.audit);
|
/* audit_release (ctrl.audit); */
|
||||||
ctrl.audit = NULL;
|
ctrl.audit = NULL;
|
||||||
es_fclose (auditfp);
|
es_fclose (auditfp);
|
||||||
}
|
}
|
||||||
@ -686,7 +731,7 @@ g13_exit (int rc)
|
|||||||
void
|
void
|
||||||
g13_init_default_ctrl (struct server_control_s *ctrl)
|
g13_init_default_ctrl (struct server_control_s *ctrl)
|
||||||
{
|
{
|
||||||
(void)ctrl;
|
ctrl->conttype = CONTTYPE_ENCFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
17
g13/g13.h
17
g13/g13.h
@ -41,7 +41,16 @@ struct
|
|||||||
|
|
||||||
const char *homedir; /* Configuration directory name. */
|
const char *homedir; /* Configuration directory name. */
|
||||||
const char *config_filename; /* Name of the used config file. */
|
const char *config_filename; /* Name of the used config file. */
|
||||||
|
|
||||||
|
/* Filename of the AGENT program. */
|
||||||
const char *agent_program;
|
const char *agent_program;
|
||||||
|
|
||||||
|
/* Filename of the GPG program. Unless set via an program option it
|
||||||
|
is initialzed at the first engine startup to the standard gpg
|
||||||
|
filename. */
|
||||||
|
const char *gpg_program;
|
||||||
|
|
||||||
|
/* Environment variables passed along to the engine. */
|
||||||
char *display;
|
char *display;
|
||||||
char *ttyname;
|
char *ttyname;
|
||||||
char *ttytype;
|
char *ttytype;
|
||||||
@ -50,7 +59,9 @@ struct
|
|||||||
char *xauthority;
|
char *xauthority;
|
||||||
char *pinentry_user_data;
|
char *pinentry_user_data;
|
||||||
|
|
||||||
char *outfile; /* Name of the output file. */
|
/* Name of the output file - FIXME: what is this? */
|
||||||
|
const char *outfile;
|
||||||
|
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +94,10 @@ struct server_control_s
|
|||||||
accessed. */
|
accessed. */
|
||||||
|
|
||||||
int with_colons; /* Use column delimited output format */
|
int with_colons; /* Use column delimited output format */
|
||||||
|
|
||||||
|
/* Type of the current container. See the CONTTYPE_ constants. */
|
||||||
|
int conttype;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
126
g13/keyblob.h
Normal file
126
g13/keyblob.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/* keyblob.h - Defs to describe a keyblob
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_KEYBLOB_H
|
||||||
|
#define G13_KEYBLOB_H
|
||||||
|
|
||||||
|
/* The header block is the actual core of G13. Here is the format:
|
||||||
|
|
||||||
|
u8 Packet type. Value is 61 (0x3d).
|
||||||
|
u8 Constant value 255 (0xff).
|
||||||
|
u32 Length of the following structure
|
||||||
|
b10 Value: "GnuPG/G13\x00".
|
||||||
|
u8 Version. Value is 1.
|
||||||
|
u8 reserved
|
||||||
|
u8 reserved
|
||||||
|
u8 OS Flag: reserved, should be 0.
|
||||||
|
u32 Length of the entire header. This includes all bytes
|
||||||
|
starting at the packet type and ending with the last
|
||||||
|
padding byte of the header.
|
||||||
|
u8 Number of copies of this header (1..255).
|
||||||
|
u8 Number of copies of this header at the end of the
|
||||||
|
container (usually 0).
|
||||||
|
b6 reserved
|
||||||
|
n bytes: OpenPGP encrypted and optionally signed message.
|
||||||
|
n bytes: CMS encrypted and optionally signed packet. Such a CMS
|
||||||
|
packet will be enclosed in a a private flagged OpenPGP
|
||||||
|
packet. Either the OpenPGP encrypted packet as described
|
||||||
|
above, the CMS encrypted or both packets must exist. The
|
||||||
|
encapsulation packet has this structure:
|
||||||
|
u8 Packet type. Value is 61 (0x3d).
|
||||||
|
u8 Constant value 255 (0xff).
|
||||||
|
u32 Length of the following structure
|
||||||
|
b10 Value: "GnuPG/CMS\x00".
|
||||||
|
b(n) Regular CMS structure.
|
||||||
|
n bytes: Padding. The structure resembles an OpenPGP packet.
|
||||||
|
u8 Packet type. Value is 61 (0x3d).
|
||||||
|
u8 Constant value 255 (0xff).
|
||||||
|
u32 Length of the following structure
|
||||||
|
b10 Value: "GnuPG/PAD\x00".
|
||||||
|
b(n) Padding stuff.
|
||||||
|
Given this structure the minimum padding is 16 bytes.
|
||||||
|
|
||||||
|
n bytes: File system container.
|
||||||
|
(optionally followed by copies on the header).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_BLOBVERSION 0
|
||||||
|
/* This tag is used to describe the version of the keyblob. It must
|
||||||
|
be the first tag in a keyblob. Its value is a single byte giving
|
||||||
|
the blob version. The current version is 1. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_CONTTYPE 1
|
||||||
|
/* This tag gives the type of the container. The value is a two byte
|
||||||
|
big endian integer giving the type of the container as described by
|
||||||
|
the CONTTYPE_ constants. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_DETACHED 2
|
||||||
|
/* Indicates that the actual storage is not in the same file as the
|
||||||
|
keyblob. If a value is given it is expected to be the GUID of the
|
||||||
|
partition. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_KEYNO 16
|
||||||
|
/* This tag indicates a new key. The value is a 4 byte big endian
|
||||||
|
integer giving the key number. If the container type does only
|
||||||
|
need one key this key number should be 0. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_ENCALGO 17
|
||||||
|
/* Describes the algorithm of the key. It must follow a KEYNO tag.
|
||||||
|
The value is a 2 byte big endian algorithm number. The algorithm
|
||||||
|
numbers used are those from Libgcrypt (e.g. AES 128 is described by
|
||||||
|
the value 7). This tag is optional. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_ENCKEY 18
|
||||||
|
/* This tag gives the actual encryption key. It must follow a KEYNO
|
||||||
|
tag. The value is the plain key. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_MACALGO 19
|
||||||
|
/* Describes the MAC algorithm. It must follow a KEYNO tag. The
|
||||||
|
value is a 2 byte big endian algorithm number describing the MAC
|
||||||
|
algorithm with a value of 1 indicating HMAC. It is followed by
|
||||||
|
data specific to the MAC algorithm. In case of HMAC this data is a
|
||||||
|
2 byte big endian integer with the Libgcrypt algorithm id of the
|
||||||
|
hash algorithm. */
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_MACKEY 20
|
||||||
|
/* This tag gives the actual MACing key. It must follow a KEYNO tag.
|
||||||
|
The value is the key used for MACing. */
|
||||||
|
|
||||||
|
|
||||||
|
#define KEYBLOB_TAG_FILLER 0xffff
|
||||||
|
/* This tag may be used for alignment and padding porposes. The value
|
||||||
|
has no meaning. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define CONTTYPE_ENCFS 1
|
||||||
|
/* A EncFS based backend. This requires a whole directory which
|
||||||
|
includes the encrypted files. Metadata is not encrypted. */
|
||||||
|
|
||||||
|
|
||||||
|
#define CONTTYPE_TRUECRYPT 21571
|
||||||
|
/* A Truecrypt (www.truecrypt.org) based container. Due to the design
|
||||||
|
of truecrypt this requires a second datafile because it is not
|
||||||
|
possible to to prepend a truecrypt container with our keyblob. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_KEYBLOB_H*/
|
51
g13/utils.c
Normal file
51
g13/utils.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* utils.c - Utility functions
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "g13.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Append the TAG and the VALUE to the MEMBUF. There is no error
|
||||||
|
checking here; this is instead done while getting the value back
|
||||||
|
from the membuf. */
|
||||||
|
void
|
||||||
|
append_tuple (membuf_t *membuf, int tag, const void *value, size_t length)
|
||||||
|
{
|
||||||
|
unsigned char buf[2];
|
||||||
|
|
||||||
|
assert (tag >= 0 && tag <= 0xffff);
|
||||||
|
assert (length <= 0xffff);
|
||||||
|
|
||||||
|
buf[0] = tag >> 8;
|
||||||
|
buf[1] = tag;
|
||||||
|
put_membuf (membuf, buf, 2);
|
||||||
|
buf[0] = length >> 8;
|
||||||
|
buf[1] = length;
|
||||||
|
put_membuf (membuf, buf, 2);
|
||||||
|
if (length)
|
||||||
|
put_membuf (membuf, value, length);
|
||||||
|
}
|
||||||
|
|
32
g13/utils.h
Normal file
32
g13/utils.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* utils.h - Defs for utility fucthe dispatcher to the various backends.ntions
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef G13_UTILS_H
|
||||||
|
#define G13_UTILS_H
|
||||||
|
|
||||||
|
#include "../common/membuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
void append_tuple (membuf_t *membuf,
|
||||||
|
int tag, const void *value, size_t length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*G13_UTILS_H*/
|
||||||
|
|
@ -1,3 +1,7 @@
|
|||||||
|
2009-09-30 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpgsm.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
|
||||||
|
|
||||||
2009-09-23 Marcus Brinkmann <marcus@g10code.de>
|
2009-09-23 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpgsm.c (main): Update to new assuan API.
|
* gpgsm.c (main): Update to new assuan API.
|
||||||
|
@ -862,9 +862,6 @@ main ( int argc, char **argv)
|
|||||||
gnupg_rl_initialize ();
|
gnupg_rl_initialize ();
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
/* We don't need any locking in libgcrypt unless we use any kind of
|
|
||||||
threading. */
|
|
||||||
gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
|
|
||||||
|
|
||||||
/* Please note that we may running SUID(ROOT), so be very CAREFUL
|
/* Please note that we may running SUID(ROOT), so be very CAREFUL
|
||||||
when adding any stuff between here and the call to secmem_init()
|
when adding any stuff between here and the call to secmem_init()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user