summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2009-10-02 16:57:55 +0200
committerWerner Koch <wk@gnupg.org>2009-10-02 16:57:55 +0200
commit71625f56fd98ab37bc05f1806b4b49a2e418ac37 (patch)
tree24d54f73a41c21241f7b99c3eee15374b1185df6 /g10
parentFixed EOF detection for encrypted packets. (diff)
downloadgnupg2-71625f56fd98ab37bc05f1806b4b49a2e418ac37.tar.xz
gnupg2-71625f56fd98ab37bc05f1806b4b49a2e418ac37.zip
Implement the server comamnd DECRYPT.
Use int instead of gnupg_fd_t in the server. Comment fixes. Rename encr-data.c -> decrypt-data.c
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog10
-rw-r--r--g10/Makefile.am4
-rw-r--r--g10/decrypt-data.c (renamed from g10/encr-data.c)2
-rw-r--r--g10/decrypt.c67
-rw-r--r--g10/encrypt.c19
-rw-r--r--g10/gpg.c6
-rw-r--r--g10/main.h7
-rw-r--r--g10/openfile.c18
-rw-r--r--g10/options.h1
-rw-r--r--g10/packet.h4
-rw-r--r--g10/plaintext.c32
-rw-r--r--g10/server.c2
12 files changed, 131 insertions, 41 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 5d9646067..11e13fb0c 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,5 +1,15 @@
2009-10-02 Werner Koch <wk@g10code.com>
+ * server.c (cmd_encrypt, cmd_decrypt): Implement.
+ * decrypt.c (decrypt_message_fd): New.
+ * options.h (struct opt): Add field OUTFP.
+ * plaintext.c (handle_plaintext): Support opt.outfp.
+
+ * encr-data.c: Rename to decrypt-data.c to reflect the action and
+ not the processed packet type.
+
+2009-10-02 Werner Koch <wk@g10code.com>
+
* encr-data.c (decode_filter_context_s): Add fields PARTIAL and
LENGTH.
(decrypt_data): Set them. Simplify premature EOF detection.
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 8b505e7a5..3a0529293 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -79,13 +79,13 @@ gpg2_SOURCES = gpg.c \
pubkey-enc.c \
passphrase.c \
seckey-cert.c \
- encr-data.c \
+ decrypt.c \
+ decrypt-data.c \
cipher.c \
encrypt.c \
sign.c \
verify.c \
revoke.c \
- decrypt.c \
keyedit.c \
dearmor.c \
import.c \
diff --git a/g10/encr-data.c b/g10/decrypt-data.c
index de26d0a4b..c9da9be97 100644
--- a/g10/encr-data.c
+++ b/g10/decrypt-data.c
@@ -1,4 +1,4 @@
-/* encr-data.c - process an encrypted data packet
+/* decrypt-data.c - Decrypt an encrypted data packet
* Copyright (C) 1998, 1999, 2000, 2001, 2005,
* 2006, 2009 Free Software Foundation, Inc.
*
diff --git a/g10/decrypt.c b/g10/decrypt.c
index c76c295c8..68b668864 100644
--- a/g10/decrypt.c
+++ b/g10/decrypt.c
@@ -97,6 +97,73 @@ decrypt_message (const char *filename)
}
+/* Same as decrypt_message but takes a file descriptor for input and
+ output. */
+gpg_error_t
+decrypt_message_fd (int input_fd, int output_fd)
+{
+ gpg_error_t err;
+ IOBUF fp;
+ armor_filter_context_t *afx = NULL;
+ progress_filter_context_t *pfx;
+
+ if (opt.outfp)
+ return gpg_error (GPG_ERR_BUG);
+
+ pfx = new_progress_context ();
+
+ /* Open the message file. */
+ fp = iobuf_open_fd_or_name (input_fd, NULL, "rb");
+ if (fp && is_secured_file (iobuf_get_fd (fp)))
+ {
+ iobuf_close (fp);
+ fp = NULL;
+ errno = EPERM;
+ }
+ if (!fp)
+ {
+ char xname[64];
+
+ err = gpg_error_from_syserror ();
+ snprintf (xname, sizeof xname, "[fd %d]", input_fd);
+ log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err));
+ release_progress_context (pfx);
+ return err;
+ }
+
+ opt.outfp = fdopen (dup (output_fd), "wb");
+ if (!opt.outfp)
+ {
+ char xname[64];
+
+ err = gpg_error_from_syserror ();
+ snprintf (xname, sizeof xname, "[fd %d]", output_fd);
+ log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err));
+ iobuf_close (fp);
+ release_progress_context (pfx);
+ return err;
+ }
+
+ if (!opt.no_armor)
+ {
+ if (use_armor_filter (fp))
+ {
+ afx = new_armor_context ();
+ push_armor_filter ( afx, fp );
+ }
+ }
+
+ err = proc_encryption_packets ( NULL, fp );
+
+ iobuf_close (fp);
+ fclose (opt.outfp);
+ opt.outfp = NULL;
+ release_armor_context (afx);
+ release_progress_context (pfx);
+ return err;
+}
+
+
void
decrypt_messages (int nfiles, char *files[])
{
diff --git a/g10/encrypt.c b/g10/encrypt.c
index bb3f2432a..649ea337f 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -264,8 +264,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
do_compress = 0;
}
- if ( rc || (rc = open_outfile (GNUPG_INVALID_FD, filename,
- opt.armor? 1:0, &out )))
+ if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out )))
{
iobuf_cancel (inp);
xfree (cfx.dek);
@@ -462,9 +461,9 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
* PROVIDED_PKS; if not the function builds a list of keys on its own.
*/
int
-encrypt_crypt (gnupg_fd_t filefd, const char *filename,
+encrypt_crypt (int filefd, const char *filename,
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
- gnupg_fd_t outputfd)
+ int outputfd)
{
iobuf_t inp = NULL;
iobuf_t out = NULL;
@@ -482,7 +481,7 @@ encrypt_crypt (gnupg_fd_t filefd, const char *filename,
PK_LIST pk_list, work_list;
int do_compress;
- if (filefd != GNUPG_INVALID_FD && filename)
+ if (filefd != -1 && filename)
return gpg_error (GPG_ERR_INV_ARG);
do_compress = opt.compress_algo && !RFC1991;
@@ -539,7 +538,7 @@ encrypt_crypt (gnupg_fd_t filefd, const char *filename,
char xname[64];
rc = gpg_error_from_syserror ();
- if (filefd != GNUPG_INVALID_FD)
+ if (filefd != -1)
snprintf (xname, sizeof xname, "[fd %d]", filefd);
else if (!filename)
strcpy (xname, "[stdin]");
@@ -652,7 +651,7 @@ encrypt_crypt (gnupg_fd_t filefd, const char *filename,
if (!opt.no_literal)
pt = setup_plaintext_name (filename, inp);
- if (filefd != GNUPG_INVALID_FD
+ if (filefd != -1
&& !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
{
off_t tmpsize;
@@ -964,8 +963,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
}
line[strlen(line)-1] = '\0';
print_file_status(STATUS_FILE_START, line, 2);
- rc = encrypt_crypt (GNUPG_INVALID_FD, line, remusr, 0,
- NULL, GNUPG_INVALID_FD);
+ rc = encrypt_crypt (-1, line, remusr, 0, NULL, -1);
if (rc)
log_error ("encryption of `%s' failed: %s\n",
print_fname_stdin(line), g10_errstr(rc) );
@@ -977,8 +975,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr)
while (nfiles--)
{
print_file_status(STATUS_FILE_START, *files, 2);
- if ( (rc = encrypt_crypt (GNUPG_INVALID_FD, *files, remusr, 0,
- NULL, GNUPG_INVALID_FD)) )
+ if ( (rc = encrypt_crypt (-1, *files, remusr, 0, NULL, -1)) )
log_error("encryption of `%s' failed: %s\n",
print_fname_stdin(*files), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
diff --git a/g10/gpg.c b/g10/gpg.c
index 55ba2cd9d..5b70e4fc3 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -3434,8 +3434,7 @@ main (int argc, char **argv)
{
if( argc > 1 )
wrong_args(_("--encrypt [filename]"));
- if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
- remusr, 0, NULL, GNUPG_INVALID_FD)) )
+ if( (rc = encrypt_crypt (-1, fname, remusr, 0, NULL, -1)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
}
@@ -3456,8 +3455,7 @@ main (int argc, char **argv)
" while in %s mode\n"),compliance_option_string());
else
{
- if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
- remusr, 1, NULL, GNUPG_INVALID_FD)) )
+ if( (rc = encrypt_crypt (-1, fname, remusr, 1, NULL, -1)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
}
diff --git a/g10/main.h b/g10/main.h
index 4971154f9..9dfeed378 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -185,9 +185,9 @@ void display_online_help( const char *keyword );
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
int encrypt_symmetric (const char *filename );
int encrypt_store (const char *filename );
-int encrypt_crypt (gnupg_fd_t filefd, const char *filename,
+int encrypt_crypt (int filefd, const char *filename,
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
- gnupg_fd_t outputfd);
+ int 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);
@@ -245,7 +245,7 @@ int save_unprotected_key_to_card (PKT_secret_key *sk, int keyno);
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 (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a);
+int open_outfile (int 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 );
@@ -319,6 +319,7 @@ int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, FILE *out_fp);
/*-- decrypt.c --*/
int decrypt_message( const char *filename );
+gpg_error_t decrypt_message_fd (int input_fd, int output_fd);
void decrypt_messages(int nfiles, char *files[]);
/*-- plaintext.c --*/
diff --git a/g10/openfile.c b/g10/openfile.c
index 5908b2e8f..9f41273e0 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -178,24 +178,24 @@ ask_outfile_name( const char *name, size_t namelen )
* 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.
+ *
+ * If INP_FD is not -1 the function simply creates an IOBUF for that
+ * file descriptor and ignorea INAME and MODE. Note that INP_FD won't
+ * be closed if the returned IOBUF is closed.
*/
int
-open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a)
+open_outfile (int inp_fd, const char *iname, int mode, iobuf_t *a)
{
int rc = 0;
*a = NULL;
- if (inp_fd != GNUPG_INVALID_FD)
+ if (inp_fd != -1)
{
char xname[64];
- gnupg_fd_t fd2;
+ int fd2;
- fd2 = INT2FD (dup (FD2INT (inp_fd)));
- if (fd2 == GNUPG_INVALID_FD)
+ fd2 = dup (inp_fd);
+ if (fd2 == -1)
*a = NULL;
else
*a = iobuf_fdopen (fd2, "wb");
diff --git a/g10/options.h b/g10/options.h
index a99ca22e8..3a2a68e61 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -43,6 +43,7 @@ struct
unsigned debug;
int armor;
char *outfile;
+ FILE *outfp; /* Hack, sometimes used in place of outfile. */
off_t max_output;
int dry_run;
int list_only;
diff --git a/g10/packet.h b/g10/packet.h
index cb2f0c9f1..395e70ab9 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -289,8 +289,8 @@ typedef struct {
} PKT_compressed;
typedef struct {
- u32 len; /* length of encrypted data */
- int extralen; /* this is (blocksize+2) */
+ u32 len; /* Remaining length of encrypted data. */
+ int extralen; /* This is (blocksize+2). Used by build_packet. */
byte new_ctb; /* uses a new CTB */
byte is_partial; /* partial length encoded */
byte mdc_method; /* > 0: integrity protected encrypted data packet */
diff --git a/g10/plaintext.c b/g10/plaintext.c
index 7679626f0..d1ab92381 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -86,10 +86,13 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
/* Create the filename as C string. */
if (nooutput)
;
+ else if (opt.outfp)
+ {
+ fname = xstrdup ("[FP]");
+ }
else if (opt.outfile)
{
- fname = xmalloc (strlen (opt.outfile) + 1);
- strcpy (fname, opt.outfile);
+ fname = xstrdup (opt.outfile);
}
else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
{
@@ -112,6 +115,13 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
if (nooutput)
;
+ else if (opt.outfp)
+ {
+ fp = opt.outfp;
+#ifdef HAVE_DOSISH_SYSTEM
+ setmode (fileno (fp), O_BINARY);
+#endif
+ }
else if (iobuf_is_pipe_filename (fname) || !*fname)
{
/* No filename or "-" given; write to stdout. */
@@ -138,7 +148,13 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
}
#ifndef __riscos__
- if (fp || nooutput)
+ if (opt.outfp && is_secured_file (fileno (opt.outfp)))
+ {
+ rc = gpg_error (GPG_ERR_EPERM);
+ log_error (_("error creating `%s': %s\n"), fname, gpg_strerror (rc));
+ goto leave;
+ }
+ else if (fp || nooutput)
;
else if (is_secured_filename (fname))
{
@@ -154,9 +170,9 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
goto leave;
}
#else /* __riscos__ */
- /* If no output filename was given, i.e. we constructed it,
- convert all '.' in fname to '/' but not vice versa as
- we don't create directories! */
+ /* If no output filename was given, i.e. we constructed it, convert
+ all '.' in fname to '/' but not vice versa as we don't create
+ directories! */
if (!opt.outfile)
for (c = 0; fname[c]; ++c)
if (fname[c] == '.')
@@ -418,7 +434,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
pt->buf = NULL;
}
- if (fp && fp != stdout && fclose (fp))
+ if (fp && fp != stdout && fp != opt.outfp && fclose (fp))
{
rc = (errno ? gpg_error_from_syserror ()
: gpg_error (GPG_ERR_INTERNAL));
@@ -434,7 +450,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
before checking the signature. */
fflush (stdout);
- if (fp && fp != stdout)
+ if (fp && fp != stdout && fp != opt.outfp)
fclose (fp);
xfree (fname);
return rc;
diff --git a/g10/server.c b/g10/server.c
index 33f9bb6ed..478c0ec28 100644
--- a/g10/server.c
+++ b/g10/server.c
@@ -362,7 +362,7 @@ cmd_decrypt (assuan_context_t ctx, char *line)
if (out_fd == -1)
return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ err = decrypt_message_fd (inp_fd, out_fd);
/* Close and reset the fds. */
close_message_fd (ctrl);