mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
gpg: Add support for unwrapping the outer level of encryption.
* g10/decrypt-data.c (decrypt_data): If OPT.UNWRAP_ENCRYPTION is set, copy the data to the output file instead of continuing to process it. * g10/gpg.c (enum cmd_and_opt_values): Add new value oUnwrap. (opts): Handle oUnwrap. (main): Likewise. * g10/options.h (opt): Add field unwrap_encryption. * g10/plaintext.c (handle_plaintext): Break the output file selection functionality into ... (get_output_file): ... this new function. -- Signed-off-by: Neal H. Walfield <neal@g10code.com> GnuPG-bug-id: 1060 Debian-bug-id: 282061
This commit is contained in:
parent
fd4b9e2328
commit
ec409e62ae
@ -221,7 +221,38 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
|
|||||||
else
|
else
|
||||||
iobuf_push_filter ( ed->buf, decode_filter, dfx );
|
iobuf_push_filter ( ed->buf, decode_filter, dfx );
|
||||||
|
|
||||||
proc_packets (ctrl, procctx, ed->buf );
|
if (opt.unwrap_encryption)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
estream_t fp;
|
||||||
|
rc = get_output_file ("", 0, ed->buf, &filename, &fp);
|
||||||
|
if (! rc)
|
||||||
|
{
|
||||||
|
iobuf_t output = iobuf_esopen (fp, "w", 0);
|
||||||
|
armor_filter_context_t *afx = NULL;
|
||||||
|
|
||||||
|
if (opt.armor)
|
||||||
|
{
|
||||||
|
afx = new_armor_context ();
|
||||||
|
push_armor_filter (afx, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
iobuf_copy (output, ed->buf);
|
||||||
|
if ((rc = iobuf_error (ed->buf)))
|
||||||
|
log_error (_("error reading: %s\n"),
|
||||||
|
filename, gpg_strerror (rc));
|
||||||
|
else if ((rc = iobuf_error (output)))
|
||||||
|
log_error (_("error writing output ('%s'): %s\n"),
|
||||||
|
filename, gpg_strerror (rc));
|
||||||
|
|
||||||
|
iobuf_close (output);
|
||||||
|
if (afx)
|
||||||
|
release_armor_context (afx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
proc_packets (ctrl, procctx, ed->buf );
|
||||||
|
|
||||||
ed->buf = NULL;
|
ed->buf = NULL;
|
||||||
if (dfx->eof_seen > 1 )
|
if (dfx->eof_seen > 1 )
|
||||||
rc = gpg_error (GPG_ERR_INV_PACKET);
|
rc = gpg_error (GPG_ERR_INV_PACKET);
|
||||||
|
@ -391,6 +391,7 @@ enum cmd_and_opt_values
|
|||||||
oTOFUDefaultPolicy,
|
oTOFUDefaultPolicy,
|
||||||
oTOFUDBFormat,
|
oTOFUDBFormat,
|
||||||
oWeakDigest,
|
oWeakDigest,
|
||||||
|
oUnwrap,
|
||||||
|
|
||||||
oNoop
|
oNoop
|
||||||
};
|
};
|
||||||
@ -753,6 +754,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
"personal-compress-preferences", "@"),
|
"personal-compress-preferences", "@"),
|
||||||
ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
|
ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
|
||||||
ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
|
ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
|
||||||
|
ARGPARSE_s_n (oUnwrap, "unwrap", "@"),
|
||||||
|
|
||||||
/* Aliases. I constantly mistype these, and assume other people do
|
/* Aliases. I constantly mistype these, and assume other people do
|
||||||
as well. */
|
as well. */
|
||||||
@ -3147,6 +3149,9 @@ main (int argc, char **argv)
|
|||||||
case oWeakDigest:
|
case oWeakDigest:
|
||||||
additional_weak_digest(pargs.r.ret_str);
|
additional_weak_digest(pargs.r.ret_str);
|
||||||
break;
|
break;
|
||||||
|
case oUnwrap:
|
||||||
|
opt.unwrap_encryption = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case oDisplay:
|
case oDisplay:
|
||||||
set_opt_session_env ("DISPLAY", pargs.r.ret_str);
|
set_opt_session_env ("DISPLAY", pargs.r.ret_str);
|
||||||
|
@ -262,6 +262,8 @@ struct
|
|||||||
|
|
||||||
int passphrase_repeat;
|
int passphrase_repeat;
|
||||||
int pinentry_mode;
|
int pinentry_mode;
|
||||||
|
|
||||||
|
int unwrap_encryption;
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
/* CTRL is used to keep some global variables we currently can't
|
/* CTRL is used to keep some global variables we currently can't
|
||||||
|
@ -663,6 +663,8 @@ int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
|
|||||||
int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
|
int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
|
||||||
|
|
||||||
/*-- plaintext.c --*/
|
/*-- plaintext.c --*/
|
||||||
|
gpg_error_t get_output_file (const byte *embedded_name, int embedded_namelen,
|
||||||
|
iobuf_t data, char **fnamep, estream_t *fpp);
|
||||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
|
||||||
int nooutput, int clearsig );
|
int nooutput, int clearsig );
|
||||||
int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
|
int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
|
||||||
|
136
g10/plaintext.c
136
g10/plaintext.c
@ -40,53 +40,29 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
||||||
/* Handle a plaintext packet. If MFX is not NULL, update the MDs
|
/* Get the output filename. On success, the actual filename that is
|
||||||
* Note: We should have used the filter stuff here, but we have to add
|
used is set in *FNAMEP and a filepointer is returned in *FP.
|
||||||
* some easy mimic to set a read limit, so we calculate only the bytes
|
|
||||||
* from the plaintext. */
|
EMBEDDED_NAME AND EMBEDDED_NAMELEN are normally stored in a
|
||||||
int
|
plaintext packet. EMBEDDED_NAMELEN should not include any NUL
|
||||||
handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
terminator (EMBEDDED_NAME does not need to be NUL terminated).
|
||||||
int nooutput, int clearsig)
|
|
||||||
|
DATA is the iobuf containing the input data. We just use it to get
|
||||||
|
the input file's filename.
|
||||||
|
|
||||||
|
On success, the caller is responsible for calling xfree on *FNAMEP
|
||||||
|
and calling es_close on *FPP. */
|
||||||
|
gpg_error_t
|
||||||
|
get_output_file (const byte *embedded_name, int embedded_namelen,
|
||||||
|
iobuf_t data, char **fnamep, estream_t *fpp)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
char *fname = NULL;
|
char *fname = NULL;
|
||||||
estream_t fp = NULL;
|
estream_t fp = NULL;
|
||||||
static off_t count = 0;
|
int nooutput = 0;
|
||||||
int err = 0;
|
|
||||||
int c;
|
|
||||||
int convert = (pt->mode == 't' || pt->mode == 'u');
|
|
||||||
#ifdef __riscos__
|
|
||||||
int filetype = 0xfff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Let people know what the plaintext info is. This allows the
|
|
||||||
receiving program to try and do something different based on the
|
|
||||||
format code (say, recode UTF-8 to local). */
|
|
||||||
if (!nooutput && is_status_enabled ())
|
|
||||||
{
|
|
||||||
char status[50];
|
|
||||||
|
|
||||||
/* Better make sure that stdout has been flushed in case the
|
|
||||||
output will be written to it. This is to make sure that no
|
|
||||||
not-yet-flushed stuff will be written after the plaintext
|
|
||||||
status message. */
|
|
||||||
es_fflush (es_stdout);
|
|
||||||
|
|
||||||
snprintf (status, sizeof status,
|
|
||||||
"%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
|
|
||||||
write_status_text_and_buffer (STATUS_PLAINTEXT,
|
|
||||||
status, pt->name, pt->namelen, 0);
|
|
||||||
|
|
||||||
if (!pt->is_partial)
|
|
||||||
{
|
|
||||||
snprintf (status, sizeof status, "%lu", (ulong) pt->len);
|
|
||||||
write_status_text (STATUS_PLAINTEXT_LENGTH, status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the filename as C string. */
|
/* Create the filename as C string. */
|
||||||
if (nooutput)
|
if (opt.outfp)
|
||||||
;
|
|
||||||
else if (opt.outfp)
|
|
||||||
{
|
{
|
||||||
fname = xtrystrdup ("[FP]");
|
fname = xtrystrdup ("[FP]");
|
||||||
if (!fname)
|
if (!fname)
|
||||||
@ -104,16 +80,17 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
|
else if (embedded_namelen == 8 && !memcmp (embedded_name, "_CONSOLE", 8))
|
||||||
{
|
{
|
||||||
log_info (_("data not saved; use option \"--output\" to save it\n"));
|
log_info (_("data not saved; use option \"--output\" to save it\n"));
|
||||||
nooutput = 1;
|
nooutput = 1;
|
||||||
}
|
}
|
||||||
else if (!opt.flags.use_embedded_filename)
|
else if (!opt.flags.use_embedded_filename)
|
||||||
{
|
{
|
||||||
fname = make_outfile_name (iobuf_get_real_fname (pt->buf));
|
if (data)
|
||||||
|
fname = make_outfile_name (iobuf_get_real_fname (data));
|
||||||
if (!fname)
|
if (!fname)
|
||||||
fname = ask_outfile_name (pt->name, pt->namelen);
|
fname = ask_outfile_name (embedded_name, embedded_namelen);
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */
|
err = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */
|
||||||
@ -121,7 +98,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fname = utf8_to_native (pt->name, pt->namelen, 0);
|
fname = utf8_to_native (embedded_name, embedded_namelen, 0);
|
||||||
|
|
||||||
if (nooutput)
|
if (nooutput)
|
||||||
;
|
;
|
||||||
@ -205,7 +182,8 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
|||||||
/* If there's a ,xxx extension in the embedded filename,
|
/* If there's a ,xxx extension in the embedded filename,
|
||||||
use that, else check whether the user input (in fname)
|
use that, else check whether the user input (in fname)
|
||||||
has a ,xxx appended, then use that in preference */
|
has a ,xxx appended, then use that in preference */
|
||||||
if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1)
|
if ((c = riscos_get_filetype_from_string (embedded_name,
|
||||||
|
embedded_namelen)) != -1)
|
||||||
filetype = c;
|
filetype = c;
|
||||||
if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
|
if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
|
||||||
filetype = c;
|
filetype = c;
|
||||||
@ -213,6 +191,70 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
|||||||
}
|
}
|
||||||
#endif /* __riscos__ */
|
#endif /* __riscos__ */
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (fp && fp != es_stdout && fp != opt.outfp)
|
||||||
|
es_fclose (fp);
|
||||||
|
xfree (fname);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*fnamep = fname;
|
||||||
|
*fpp = fp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle a plaintext packet. If MFX is not NULL, update the MDs
|
||||||
|
* Note: We should have used the filter stuff here, but we have to add
|
||||||
|
* some easy mimic to set a read limit, so we calculate only the bytes
|
||||||
|
* from the plaintext. */
|
||||||
|
int
|
||||||
|
handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
|
||||||
|
int nooutput, int clearsig)
|
||||||
|
{
|
||||||
|
char *fname = NULL;
|
||||||
|
estream_t fp = NULL;
|
||||||
|
static off_t count = 0;
|
||||||
|
int err = 0;
|
||||||
|
int c;
|
||||||
|
int convert = (pt->mode == 't' || pt->mode == 'u');
|
||||||
|
#ifdef __riscos__
|
||||||
|
int filetype = 0xfff;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Let people know what the plaintext info is. This allows the
|
||||||
|
receiving program to try and do something different based on the
|
||||||
|
format code (say, recode UTF-8 to local). */
|
||||||
|
if (!nooutput && is_status_enabled ())
|
||||||
|
{
|
||||||
|
char status[50];
|
||||||
|
|
||||||
|
/* Better make sure that stdout has been flushed in case the
|
||||||
|
output will be written to it. This is to make sure that no
|
||||||
|
not-yet-flushed stuff will be written after the plaintext
|
||||||
|
status message. */
|
||||||
|
es_fflush (es_stdout);
|
||||||
|
|
||||||
|
snprintf (status, sizeof status,
|
||||||
|
"%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
|
||||||
|
write_status_text_and_buffer (STATUS_PLAINTEXT,
|
||||||
|
status, pt->name, pt->namelen, 0);
|
||||||
|
|
||||||
|
if (!pt->is_partial)
|
||||||
|
{
|
||||||
|
snprintf (status, sizeof status, "%lu", (ulong) pt->len);
|
||||||
|
write_status_text (STATUS_PLAINTEXT_LENGTH, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! nooutput)
|
||||||
|
{
|
||||||
|
err = get_output_file (pt->name, pt->namelen, pt->buf, &fname, &fp);
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pt->is_partial)
|
if (!pt->is_partial)
|
||||||
{
|
{
|
||||||
/* We have an actual length (which might be zero). */
|
/* We have an actual length (which might be zero). */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user