[svn] GnuPG - r5167 - in trunk: common g10 g13 sm
svn author wk
cvs at cvs.gnupg.org
Wed Sep 30 17:28:40 CEST 2009
Author: wk
Date: 2009-09-30 17:28:38 +0200 (Wed, 30 Sep 2009)
New Revision: 5167
Added:
trunk/g13/backend.c
trunk/g13/backend.h
trunk/g13/be-encfs.c
trunk/g13/be-encfs.h
trunk/g13/be-truecrypt.c
trunk/g13/be-truecrypt.h
trunk/g13/call-gpg.c
trunk/g13/call-gpg.h
trunk/g13/create.c
trunk/g13/keyblob.h
trunk/g13/utils.c
trunk/g13/utils.h
Modified:
trunk/common/ChangeLog
trunk/common/audit.h
trunk/common/exechelp.c
trunk/common/exechelp.h
trunk/common/iobuf.c
trunk/common/iobuf.h
trunk/g10/ChangeLog
trunk/g10/compress.c
trunk/g10/dearmor.c
trunk/g10/encrypt.c
trunk/g10/export.c
trunk/g10/gpg.c
trunk/g10/keydb.h
trunk/g10/main.h
trunk/g10/openfile.c
trunk/g10/parse-packet.c
trunk/g10/pkclist.c
trunk/g10/revoke.c
trunk/g10/server.c
trunk/g10/sign.c
trunk/g13/Makefile.am
trunk/g13/g13.c
trunk/g13/g13.h
trunk/sm/ChangeLog
trunk/sm/gpgsm.c
Log:
Some changes to suport g13.
[The diff below has been truncated]
Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/ChangeLog 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1,3 +1,15 @@
+2009-09-29 Werner Koch <wk at 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 at g10code.de>
* asshelp.c (start_new_gpg_agent): Allocate assuan context before
Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/ChangeLog 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1,5 +1,33 @@
+2009-09-30 Werner Koch <wk at 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 at 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 at 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.
* encrypt.c (encode_symmetric, encode_store, encode_seskey)
(encode_simple, encode_crypt, encode_filter)
Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/sm/ChangeLog 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1,3 +1,7 @@
+2009-09-30 Werner Koch <wk at g10code.com>
+
+ * gpgsm.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING.
+
2009-09-23 Marcus Brinkmann <marcus at g10code.de>
* gpgsm.c (main): Update to new assuan API.
Modified: trunk/common/audit.h
===================================================================
--- trunk/common/audit.h 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/audit.h 2009-09-30 15:28:38 UTC (rev 5167)
@@ -62,6 +62,15 @@
operations the Dirmngr is not required and thus no such event
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,
/* Data to be processed has been seen. */
Modified: trunk/common/exechelp.c
===================================================================
--- trunk/common/exechelp.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/exechelp.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -304,7 +304,7 @@
#ifdef HAVE_W32_SYSTEM
/* Create pipe where the write end is inheritable. */
static int
-create_inheritable_pipe (int filedes[2])
+create_inheritable_pipe_w (int filedes[2])
{
HANDLE r, w, h;
SECURITY_ATTRIBUTES sec_attr;
@@ -332,6 +332,37 @@
filedes[1] = handle_to_fd (w);
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*/
@@ -425,7 +456,7 @@
filedes[0] = filedes[1] = -1;
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)
@@ -458,6 +489,50 @@
}
+/* 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);
+ 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;
+}
+
+
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
stdin, write the output to OUTFILE, return a new stream in
STATUSFILE for stderr and the pid of the process in PID. The
@@ -522,7 +597,7 @@
return err;
/* Create a pipe. */
- if (create_inheritable_pipe (rp))
+ if (create_inheritable_pipe_w (rp))
{
err = gpg_error (GPG_ERR_GENERAL);
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
Modified: trunk/common/exechelp.h
===================================================================
--- trunk/common/exechelp.h 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/exechelp.h 2009-09-30 15:28:38 UTC (rev 5167)
@@ -44,7 +44,11 @@
inheritable. */
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
stdin, write the output to OUTFILE, return a new stream in
STATUSFILE for stderr and the pid of the process in PID. The
Modified: trunk/common/iobuf.c
===================================================================
--- trunk/common/iobuf.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/iobuf.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1260,6 +1260,32 @@
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
* returns: NULL if an error occures and sets errno
@@ -1306,8 +1332,8 @@
}
/****************
- * Create a head iobuf for reading from a file
- * returns: NULL if an error occures and sets errno
+ * Create a head iobuf for reading or writing from/to a file
+ * Returns: NULL if an error occures and sets ERRNO.
*/
iobuf_t
iobuf_fdopen (int fd, const char *mode)
@@ -2355,7 +2381,9 @@
/****************
- * 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 *
iobuf_get_real_fname (iobuf_t a)
@@ -2376,7 +2404,7 @@
/****************
- * Retrieve the filename
+ * Retrieve the filename. This name should only be used in diagnostics.
*/
const char *
iobuf_get_fname (iobuf_t a)
@@ -2390,7 +2418,17 @@
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.
* LEN is the first length byte on read, but ignored on writes.
Modified: trunk/common/iobuf.h
===================================================================
--- trunk/common/iobuf.h 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/common/iobuf.h 2009-09-30 15:28:38 UTC (rev 5167)
@@ -21,8 +21,8 @@
#define GNUPG_COMMON_IOBUF_H
#include "../include/types.h" /* fixme: should be moved elsewhere. */
+#include "../common/sysutils.h"
-
#define DBG_IOBUF iobuf_debug_mode
@@ -85,6 +85,8 @@
iobuf_t iobuf_alloc (int use, size_t bufsize);
iobuf_t iobuf_temp (void);
iobuf_t iobuf_temp_with_content (const char *buffer, size_t length);
+iobuf_t iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname,
+ const char *mode);
iobuf_t iobuf_open (const char *fname);
iobuf_t iobuf_fdopen (int fd, const char *mode);
iobuf_t iobuf_sockopen (int fd, const char *mode);
@@ -131,6 +133,7 @@
int iobuf_get_fd (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_nonnull (iobuf_t a);
void iobuf_set_partial_block_mode (iobuf_t a, size_t len);
Modified: trunk/g10/compress.c
===================================================================
--- trunk/g10/compress.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/compress.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -245,6 +245,9 @@
memset( &cd, 0, sizeof cd );
cd.len = 0;
cd.algorithm = zfx->algo;
+ /* Fixme: We should force a new CTB here:
+ cd.new_ctb = zfx->new_ctb;
+ */
init_packet( &pkt );
pkt.pkttype = PKT_COMPRESSED;
pkt.pkt.compressed = &cd;
Modified: trunk/g10/dearmor.c
===================================================================
--- trunk/g10/dearmor.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/dearmor.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -64,7 +64,7 @@
push_armor_filter ( afx, inp );
- if( (rc = open_outfile( fname, 0, &out )) )
+ if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 0, &out )) )
goto leave;
while( (c = iobuf_get(inp)) != -1 )
@@ -110,7 +110,7 @@
}
- if( (rc = open_outfile( fname, 1, &out )) )
+ if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 1, &out )) )
goto leave;
afx->what = 4;
Modified: trunk/g10/encrypt.c
===================================================================
--- trunk/g10/encrypt.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/encrypt.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -264,7 +264,8 @@
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);
xfree (cfx.dek);
@@ -455,11 +456,15 @@
/*
- * Encrypt the file with the given userids (or ask if none
- * is supplied).
+ * Encrypt the file with the given userids (or ask if none is
+ * 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
-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 out = NULL;
@@ -477,6 +482,9 @@
PK_LIST pk_list, work_list;
int do_compress;
+ if (filefd != GNUPG_INVALID_FD && filename)
+ return gpg_error (GPG_ERR_INV_ARG);
+
do_compress = opt.compress_algo && !RFC1991;
pfx = new_progress_context ();
@@ -492,10 +500,15 @@
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);
- return rc;
+ if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC)))
+ {
+ release_progress_context (pfx);
+ return rc;
+ }
}
if(PGP2)
@@ -512,7 +525,7 @@
}
/* Prepare iobufs. */
- inp = iobuf_open(filename);
+ inp = iobuf_open_fd_or_name (filefd, filename, "rb");
if (inp)
iobuf_ioctl (inp, 3, 1, NULL); /* Disable fd caching. */
if (inp && is_secured_file (iobuf_get_fd (inp)))
@@ -523,20 +536,30 @@
}
if (!inp)
{
+ char xname[64];
+
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"),
- filename? filename: "[stdin]", gpg_strerror (rc) );
+ *xname? xname : filename, gpg_strerror (rc) );
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);
if (opt.textmode)
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;
if (opt.armor)
@@ -629,7 +652,8 @@
if (!opt.no_literal)
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;
int overflow;
@@ -709,13 +733,16 @@
plain data. */
byte copy_buffer[4096];
int bytes_copied;
- while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
- if ((rc=iobuf_write(out, copy_buffer, bytes_copied)))
- {
- log_error ("copying input to output failed: %s\n",
- gpg_strerror (rc));
- break;
- }
+ while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
+ {
+ rc = iobuf_write (out, copy_buffer, bytes_copied);
+ if (rc)
+ {
+ log_error ("copying input to output failed: %s\n",
+ gpg_strerror (rc));
+ break;
+ }
+ }
wipememory (copy_buffer, 4096); /* Burn the buffer. */
}
@@ -735,7 +762,8 @@
xfree (cfx.dek);
xfree (symkey_dek);
xfree (symkey_s2k);
- release_pk_list (pk_list);
+ if (!provided_keys)
+ release_pk_list (pk_list);
release_armor_context (afx);
release_progress_context (pfx);
return rc;
@@ -936,9 +964,11 @@
}
line[strlen(line)-1] = '\0';
print_file_status(STATUS_FILE_START, line, 2);
- if ( (rc = encrypt_crypt(line, remusr, 0)) )
- log_error("encryption of `%s' failed: %s\n",
- print_fname_stdin(line), g10_errstr(rc) );
+ rc = encrypt_crypt (GNUPG_INVALID_FD, line, remusr, 0,
+ NULL, GNUPG_INVALID_FD);
+ if (rc)
+ log_error ("encryption of `%s' failed: %s\n",
+ print_fname_stdin(line), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
}
}
@@ -947,7 +977,8 @@
while (nfiles--)
{
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",
print_fname_stdin(*files), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
Modified: trunk/g10/export.c
===================================================================
--- trunk/g10/export.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/export.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -140,7 +140,7 @@
memset( &zfx, 0, sizeof zfx);
- rc = open_outfile( NULL, 0, &out );
+ rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out );
if (rc)
return rc;
Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/gpg.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1920,9 +1920,6 @@
gnupg_rl_initialize ();
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
- /* We don't need any locking in libgcrypt unless we use any kind of
- threading. */
- gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
log_set_prefix ("gpg", 1);
/* Make sure that our subsystems are ready. */
@@ -3437,7 +3434,8 @@
{
if( argc > 1 )
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",
print_fname_stdin(fname), g10_errstr(rc) );
}
@@ -3458,7 +3456,8 @@
" while in %s mode\n"),compliance_option_string());
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",
print_fname_stdin(fname), g10_errstr(rc) );
}
Modified: trunk/g10/keydb.h
===================================================================
--- trunk/g10/keydb.h 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/keydb.h 2009-09-30 15:28:38 UTC (rev 5167)
@@ -83,12 +83,14 @@
};
typedef struct keyblock_pos_struct KBPOS;
-/* structure to hold a couple of public key certificates */
-typedef struct pk_list *PK_LIST;
-struct pk_list {
- PK_LIST next;
- PKT_public_key *pk;
- int flags; /* flag bit 1==throw_keyid */
+/* Structure to hold a couple of public key certificates. */
+typedef struct pk_list *PK_LIST; /* Deprecated. */
+typedef struct pk_list *pk_list_t;
+struct pk_list
+{
+ PK_LIST next;
+ PKT_public_key *pk;
+ int flags; /* flag bit 1==throw_keyid */
};
/* structure to hold a couple of secret key certificates */
@@ -179,8 +181,12 @@
/*-- pkclist.c --*/
void show_revocation_reason( PKT_public_key *pk, int mode );
int check_signatures_trust( PKT_signature *sig );
-void release_pk_list( PK_LIST pk_list );
-int build_pk_list( strlist_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,
const union pref_hint *hint );
int select_algo_from_prefs( PK_LIST pk_list, int preftype,
Modified: trunk/g10/main.h
===================================================================
--- trunk/g10/main.h 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/main.h 2009-09-30 15:28:38 UTC (rev 5167)
@@ -185,7 +185,9 @@
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
int encrypt_symmetric (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);
int encrypt_filter (void *opaque, int control,
iobuf_t a, byte *buf, size_t *ret_len);
@@ -243,7 +245,7 @@
int overwrite_filep( const char *fname );
char *make_outfile_name( const char *iname );
char *ask_outfile_name( const char *name, size_t namelen );
-int open_outfile( const char *iname, int mode, iobuf_t *a );
+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 );
void try_make_homedir( const char *fname );
Modified: trunk/g10/openfile.c
===================================================================
--- trunk/g10/openfile.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/openfile.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1,6 +1,6 @@
/* openfile.c
* 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.
*
@@ -43,6 +43,13 @@
#define SKELEXT EXTSEP_S "skel"
#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__)
#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
#else
@@ -65,34 +72,27 @@
int
overwrite_filep( const char *fname )
{
- if( iobuf_is_pipe_filename (fname) )
- return 1; /* Writing to stdout is always okay */
+ if ( iobuf_is_pipe_filename (fname) )
+ 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 ) )
- return 1; /* does not exist */
+ if (opt.answer_yes)
+ return 1;
+ if (opt.answer_no || opt.batch)
+ return 0; /* Do not overwrite. */
-#ifndef HAVE_DOSISH_SYSTEM
- if ( !strcmp ( fname, "/dev/null" ) )
- return 1; /* does not do any harm */
-#endif
-#ifdef HAVE_W32_SYSTEM
- if ( !strcmp ( fname, "nul" ) )
- return 1;
-#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;
+ 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 @@
* Mode 0 = use ".gpg"
* 1 = use ".asc"
* 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
-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;
*a = NULL;
- if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
- *a = iobuf_create(NULL);
- if( !*a ) {
- rc = gpg_error_from_syserror ();
- log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
+ if (inp_fd != GNUPG_INVALID_FD)
+ {
+ char xname[64];
+ gnupg_fd_t fd2;
+
+ 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 )
- log_info(_("writing to stdout\n"));
- }
- else {
- char *buf = NULL;
- const char *name;
+ else if (iobuf_is_pipe_filename (iname) && !opt.outfile)
+ {
+ *a = iobuf_create(NULL);
+ if ( !*a )
+ {
+ 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 )
- {
-#ifdef HAVE_W32_SYSTEM
- name = "nul";
-#else
- name = "/dev/null";
-#endif
- }
- else if( opt.outfile )
- name = opt.outfile;
- else {
+ if (opt.dry_run)
+ name = NAME_OF_DEV_NULL;
+ else if (opt.outfile)
+ name = opt.outfile;
+ else
+ {
#ifdef USE_ONLY_8DOT3
- if (opt.mangle_dos_filenames)
- {
- /* It is quite common DOS system to have only one dot in a
- * a filename So if we have something like this, we simple
- * replace the suffix execpt in cases where the suffix is
- * larger than 3 characters and not the same as.
- * We should really map the filenames to 8.3 but this tends to
- * be more complicated and is probaly a duty of the filesystem
- */
- char *dot;
- const char *newsfx = mode==1 ? ".asc" :
- mode==2 ? ".sig" : ".gpg";
+ if (opt.mangle_dos_filenames)
+ {
+ /* 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) )
+ 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);
+ }
+ if (!buf)
+#endif /* USE_ONLY_8DOT3 */
{
- strcpy(dot, newsfx );
+ buf = xstrconcat (iname,
+ (mode==1 ? EXTSEP_S "asc" :
+ mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg"),
+ NULL);
}
- else if ( dot && !dot[1] ) /* don't duplicate a dot */
- strcpy( dot, newsfx+1 );
- else
- strcat ( buf, newsfx );
+ name = buf;
}
- if (!buf)
-#endif /* USE_ONLY_8DOT3 */
+
+ rc = 0;
+ while ( !overwrite_filep (name) )
{
- buf = xmalloc(strlen(iname)+4+1);
- strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
- mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
+ 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;
+
+ if ( !rc )
+ {
+ if (is_secured_filename (name) )
+ {
+ *a = NULL;
+ errno = EPERM;
+ }
+ else
+ *a = iobuf_create (name);
+ if (!*a)
+ {
+ rc = gpg_error_from_syserror ();
+ log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
+ }
+ else if( opt.verbose )
+ log_info (_("writing to `%s'\n"), name );
+ }
+ xfree(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 (is_secured_filename (name) )
- {
- *a = NULL;
- errno = EPERM;
- }
- else
- *a = iobuf_create( name );
- if( !*a )
- {
- rc = gpg_error_from_syserror ();
- log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
- }
- else if( opt.verbose )
- log_info(_("writing to `%s'\n"), name );
- }
- xfree(buf);
- }
-
+
if (*a)
- iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
+ iobuf_ioctl (*a, 3, 1, NULL); /* Disable fd caching. */
return rc;
}
Modified: trunk/g10/parse-packet.c
===================================================================
--- trunk/g10/parse-packet.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/parse-packet.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -682,7 +682,11 @@
else
{
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);
return;
@@ -2529,7 +2533,11 @@
}
else {
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);
}
Modified: trunk/g10/pkclist.c
===================================================================
--- trunk/g10/pkclist.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/pkclist.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -1,6 +1,6 @@
/* pkclist.c - create a list of public keys
* 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.
*
@@ -40,6 +40,18 @@
#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
*/
@@ -656,14 +668,15 @@
void
-release_pk_list( PK_LIST pk_list )
+release_pk_list (pk_list_t pk_list)
{
- PK_LIST pk_rover;
-
- for( ; pk_list; pk_list = pk_rover ) {
- pk_rover = pk_list->next;
- free_public_key( pk_list->pk );
- xfree( pk_list );
+ PK_LIST pk_rover;
+
+ for ( ; pk_list; pk_list = pk_rover)
+ {
+ pk_rover = pk_list->next;
+ free_public_key ( pk_list->pk );
+ xfree ( pk_list );
}
}
@@ -680,7 +693,7 @@
/****************
- * 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 *
default_recipient(void)
@@ -760,6 +773,96 @@
}
+/* 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.
It is thus used to prepare a public key encryption. encrypt-to
keys, default keys and the keys for the actual recipients are all
@@ -831,8 +934,7 @@
{
free_public_key ( pk ); pk = NULL;
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- rov->d, strlen (rov->d), -1);
+ send_status_inv_recp (0, rov->d);
goto fail;
}
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
@@ -873,8 +975,7 @@
available. */
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- rov->d, strlen (rov->d), -1);
+ send_status_inv_recp (0, rov->d);
goto fail;
}
}
@@ -1078,85 +1179,11 @@
if ( (remusr->flags & 1) )
continue; /* encrypt-to keys are already handled. */
- pk = xmalloc_clear( sizeof *pk );
- pk->req_usage = use;
- if ((rc = get_pubkey_byname (NULL, pk, remusr->d, NULL, NULL, 0, 0)))
- {
- /* Key not found or other error. */
- 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;
- }
+ rc = find_and_check_key (remusr->d, use, !!(remusr->flags&2),
+ &pk_list);
+ if (rc)
+ goto fail;
+ any_recipients = 1;
}
}
Modified: trunk/g10/revoke.c
===================================================================
--- trunk/g10/revoke.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/revoke.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -326,7 +326,7 @@
if( !opt.armor )
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;
afx->what = 1;
@@ -550,7 +550,7 @@
if( !opt.armor )
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;
afx->what = 1;
Modified: trunk/g10/server.c
===================================================================
--- trunk/g10/server.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/server.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -33,6 +33,7 @@
#include "i18n.h"
#include "options.h"
#include "../common/sysutils.h"
+#include "status.h"
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
@@ -45,6 +46,10 @@
assuan_context_t assuan_ctx;
/* File descriptor as set by the MESSAGE command. */
gnupg_fd_t message_fd;
+
+ /* List of prepared recipients. */
+ pk_list_t recplist;
+
};
@@ -61,6 +66,39 @@
}
+/* 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
details. */
@@ -111,6 +149,9 @@
{
ctrl_t ctrl = assuan_get_pointer (ctx);
+ release_pk_list (ctrl->server_local->recplist);
+ ctrl->server_local->recplist = NULL;
+
close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
@@ -157,7 +198,7 @@
-/* RECIPIENT <userID>
+/* RECIPIENT [--hidden] <userID>
Set the recipient for the encryption. <userID> should be the
internal representation of the key; the server may accept any other
@@ -171,9 +212,26 @@
static gpg_error_t
cmd_recipient (assuan_context_t ctx, char *line)
{
- (void)ctx;
- (void)line;
- return gpg_error (GPG_ERR_NOT_SUPPORTED);
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ 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 @@
/* ENCRYPT
Do the actual encryption process. Takes the plaintext from the
- INPUT command, writes to the ciphertext to the file descriptor set
- with the OUTPUT command, take the recipients form all the
- recipients set so far. If this command fails the clients should
- try to delete all output currently done or otherwise mark it as
- invalid. GPG does ensure that there won't be any security problem
- with leftover data on the output in this case.
+ INPUT command, writes the ciphertext to the file descriptor set
+ with the OUTPUT command, take the recipients from all the
+ recipients set so far with RECIPIENTS.
- This command should in general not fail, as all necessary checks
- have been done while setting the recipients. The input and output
- pipes are closed. */
+ If this command fails the clients should 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.
+
+ 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
cmd_encrypt (assuan_context_t ctx, char *line)
{
- (void)ctx;
- (void)line;
- return gpg_error (GPG_ERR_NOT_SUPPORTED);
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ 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 @@
gnupg_fd_t out_fd = assuan_get_output_fd (ctx);
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;
if (fd == GNUPG_INVALID_FD)
@@ -270,8 +390,8 @@
return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
}
- log_debug ("WARNING: The server mode work "
- "in progress and not ready for use\n");
+ log_debug ("WARNING: The server mode is WORK "
+ "iN PROGRESS and not ready for use\n");
/* Need to dup it because it might get closed and libassuan won't
know about it then. */
@@ -596,8 +716,13 @@
}
leave:
- xfree (ctrl->server_local);
- ctrl->server_local = NULL;
+ if (ctrl->server_local)
+ {
+ release_pk_list (ctrl->server_local->recplist);
+
+ xfree (ctrl->server_local);
+ ctrl->server_local = NULL;
+ }
assuan_release (ctx);
return rc;
}
Modified: trunk/g10/sign.c
===================================================================
--- trunk/g10/sign.c 2009-09-28 17:11:32 UTC (rev 5166)
+++ trunk/g10/sign.c 2009-09-30 15:28:38 UTC (rev 5167)
@@ -801,7 +801,8 @@
else if( opt.verbose )
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;
/* prepare to calculate the MD over the input */
@@ -1110,7 +1111,7 @@
else if( opt.verbose )
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 )) )
More information about the Gnupg-commits
mailing list