* crypto: support --decrypt in mu view

This commit is contained in:
djcb
2012-07-22 19:39:37 +03:00
parent 5a92c8b58a
commit 8e6376ad06
3 changed files with 100 additions and 17 deletions

View File

@ -48,7 +48,7 @@
static gboolean static gboolean
view_msg_sexp (MuMsg *msg) view_msg_sexp (MuMsg *msg, MuConfig *opts)
{ {
char *sexp; char *sexp;
@ -111,40 +111,121 @@ print_field (const char* field, const char *val, gboolean color)
fputs ("\n", stdout); fputs ("\n", stdout);
} }
static char*
get_password (const char *user_id, const char *prompt_ctx,
gboolean reprompt, gpointer user_data)
{
char *pass, *prompt;
if (reprompt)
g_printerr ("Incorrect password. Please try again\n");
/* else */
/* g_print ("mu: %s\n", prompt_ctx); *\/ */
prompt = g_strdup_printf ("mu: password for %s: ", user_id);
pass = getpass (prompt);
g_free (prompt);
return pass;
}
struct _DData {
GString *gstr;
GError *err;
};
typedef struct _DData DData;
static void
each_decrypted_part (MuMsgDecryptedPart *dpart, DData *ddata)
{
gchar *str;
if (ddata->err)
return;
str = mu_msg_decrypted_part_to_string (dpart,
&ddata->err);
ddata->gstr = g_string_append (ddata->gstr,
str ? str : "");
g_free (str);
}
static gchar*
try_decrypt_body (MuMsg *msg, MuConfig *opts)
{
DData ddata;
GError *err;
err = NULL;
ddata.gstr = g_string_sized_new (mu_msg_get_size(msg));
ddata.err = NULL;
if (!mu_msg_part_decrypt_foreach
(msg,(MuMsgPartDecryptForeachFunc)each_decrypted_part,
(MuMsgPartPasswordFunc)get_password,
&ddata, MU_MSG_OPTION_USE_AGENT, &err))
goto errexit;
if (ddata.err)
goto errexit;
return g_string_free (ddata.gstr, FALSE);
errexit:
g_warning ("decryption failed: %s",
err ? err->message : "something went wrong");
g_clear_error (&err);
return NULL;
}
/* a summary_len of 0 mean 'don't show summary, show body */ /* a summary_len of 0 mean 'don't show summary, show body */
static void static void
body_or_summary (MuMsg *msg, unsigned summary_len, gboolean color) body_or_summary (MuMsg *msg, MuConfig *opts)
{ {
const char* field; const char *str;
const char *body;
char *decrypted;
gboolean color;
field = mu_msg_get_body_text (msg); color = !opts->nocolor;
if (!field)
str = mu_msg_get_body_text (msg);
decrypted = NULL;
if (!str && opts->decrypt)
decrypted = try_decrypt_body (msg, opts);
if (!str && !decrypted)
return; /* no body -- nothing more to do */ return; /* no body -- nothing more to do */
body = str ? str : decrypted;
if (summary_len != 0) { if (opts->summary_len != 0) {
gchar *summ; gchar *summ;
summ = mu_str_summarize (field, summary_len); summ = mu_str_summarize (body, opts->summary_len);
print_field ("Summary", summ, color); print_field ("Summary", summ, color);
g_free (summ); g_free (summ);
} else { } else {
color_maybe (MU_COLOR_YELLOW); color_maybe (MU_COLOR_YELLOW);
mu_util_print_encoded ("\n%s\n", field); mu_util_print_encoded ("\n%s\n", body);
color_maybe (MU_COLOR_DEFAULT); color_maybe (MU_COLOR_DEFAULT);
} }
g_free (decrypted);
} }
/* we ignore fields for now */ /* we ignore fields for now */
/* summary_len == 0 means "no summary */ /* summary_len == 0 means "no summary */
static gboolean static gboolean
view_msg_plain (MuMsg *msg, const gchar *fields, unsigned summary_len, view_msg_plain (MuMsg *msg, MuConfig *opts)
gboolean color)
{ {
gchar *attachs; gchar *attachs;
time_t date; time_t date;
const GSList *lst; const GSList *lst;
gboolean color;
color = !opts->nocolor;
print_field ("From", mu_msg_get_from (msg), color); print_field ("From", mu_msg_get_from (msg), color);
print_field ("To", mu_msg_get_to (msg), color); print_field ("To", mu_msg_get_to (msg), color);
print_field ("Cc", mu_msg_get_cc (msg), color); print_field ("Cc", mu_msg_get_cc (msg), color);
@ -167,7 +248,7 @@ view_msg_plain (MuMsg *msg, const gchar *fields, unsigned summary_len,
g_free (attachs); g_free (attachs);
} }
body_or_summary (msg, summary_len, color); body_or_summary (msg, opts);
return TRUE; return TRUE;
} }
@ -186,13 +267,10 @@ handle_msg (const char *fname, MuConfig *opts, GError **err)
switch (opts->format) { switch (opts->format) {
case MU_CONFIG_FORMAT_PLAIN: case MU_CONFIG_FORMAT_PLAIN:
rv = view_msg_plain rv = view_msg_plain (msg, opts);
(msg, NULL,
opts->summary ? opts->summary_len : 0,
!opts->nocolor);
break; break;
case MU_CONFIG_FORMAT_SEXP: case MU_CONFIG_FORMAT_SEXP:
rv = view_msg_sexp (msg); rv = view_msg_sexp (msg, opts);
break; break;
default: default:
g_critical ("bug: should not be reached"); g_critical ("bug: should not be reached");

View File

@ -302,6 +302,9 @@ config_options_group_view (void)
"terminate messages with ascii-0x07 (\\f, form-feed)", NULL}, "terminate messages with ascii-0x07 (\\f, form-feed)", NULL},
{"format", 'o', 0, G_OPTION_ARG_STRING, &MU_CONFIG.formatstr, {"format", 'o', 0, G_OPTION_ARG_STRING, &MU_CONFIG.formatstr,
"output format ('plain'(*), 'sexp')", NULL}, "output format ('plain'(*), 'sexp')", NULL},
{"decrypt", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.decrypt,
"attempt to decrypt the message body, if it is encrypted", NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL} {NULL, 0, 0, 0, NULL, NULL, NULL}
}; };

View File

@ -89,7 +89,6 @@ struct _MuConfig {
* MU_CONFIG_CMD_NONE */ * MU_CONFIG_CMD_NONE */
const char *cmdstr; /* cmd string, for user const char *cmdstr; /* cmd string, for user
* info */ * info */
/* general options */ /* general options */
gboolean quiet; /* don't give any output */ gboolean quiet; /* don't give any output */
gboolean debug; /* spew out debug info */ gboolean debug; /* spew out debug info */
@ -146,6 +145,9 @@ struct _MuConfig {
gboolean terminator; /* add separator \f between gboolean terminator; /* add separator \f between
* multiple messages in mu * multiple messages in mu
* view */ * view */
gboolean decrypt; /* try to decrypt the
* message body, if any */
/* options for cfind (and 'find' --> "after") */ /* options for cfind (and 'find' --> "after") */
gboolean personal; /* only show 'personal' addresses */ gboolean personal; /* only show 'personal' addresses */
/* also 'after' --> see above */ /* also 'after' --> see above */