NeoMutt  2021-02-05-329-g9e03b7
Teaching an old dog new tricks
DOXYGEN
remailer.c File Reference

Support of Mixmaster anonymous remailer. More...

#include "config.h"
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "menu/lib.h"
#include "send/lib.h"
#include "format_flags.h"
#include "keymap.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "remailer.h"
+ Include dependency graph for remailer.c:

Go to the source code of this file.

Data Structures

struct  Coord
 Screen coordinates. More...
 

Functions

static MixCapFlags mix_get_caps (const char *capstr)
 Get Mixmaster Capabilities. More...
 
static void mix_add_entry (struct Remailer ***type2_list, struct Remailer *entry, size_t *slots, size_t *used)
 Add an entry to the Remailer list. More...
 
static struct Remailerremailer_new (void)
 Create a new Remailer. More...
 
static void remailer_free (struct Remailer **ptr)
 Free a Remailer. More...
 
static struct Remailer ** mix_type2_list (size_t *l)
 parse the type2.list as given by mixmaster -T More...
 
static void mix_type2_list_free (struct Remailer ***ttlp)
 Free a Remailer List. More...
 
static void mix_screen_coordinates (struct MuttWindow *win, struct Remailer **type2_list, struct Coord **coordsp, struct MixChain *chain, int i)
 Get the screen coordinates to place a chain. More...
 
static void mix_redraw_ce (struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int i, bool selected)
 Redraw the Remailer chain. More...
 
static void mix_redraw_chain (struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int cur)
 Redraw the chain on screen. More...
 
static void mix_redraw_head (struct MuttWindow *win, struct MixChain *chain)
 Redraw the Chain info. More...
 
static const char * mix_format_caps (struct Remailer *r)
 Turn flags into a MixMaster capability string. More...
 
static const char * mix_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the remailer menu - Implements format_t. More...
 
static void mix_make_entry (struct Menu *menu, char *buf, size_t buflen, int num)
 Format a menu item for the mixmaster chain list - Implements Menu::make_entry() More...
 
static int mix_chain_add (struct MixChain *chain, const char *s, struct Remailer **type2_list)
 Add a host to the chain. More...
 
static int remailer_config_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the remailer - Implements observer_t. More...
 
void dlg_select_mixmaster_chain (struct ListHead *chainhead)
 Create a Mixmaster chain. More...
 
int mix_check_message (struct Email *e)
 Safety-check the message before passing it to mixmaster. More...
 
int mix_send_message (struct ListHead *chain, const char *tempfile)
 Send an email via Mixmaster. More...
 

Variables

static const struct Mapping RemailerHelp []
 Help Bar for the Mixmaster dialog. More...
 

Detailed Description

Support of Mixmaster anonymous remailer.

Authors
  • Thomas Roessler
  • Pietro Cerutti

This program 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/.

Definition in file remailer.c.

Function Documentation

◆ mix_get_caps()

static MixCapFlags mix_get_caps ( const char *  capstr)
static

Get Mixmaster Capabilities.

Parameters
capstrCapability string to parse
Return values
numCapabilities, see MixCapFlags

Definition at line 80 of file remailer.c.

81 {
83 
84  while (*capstr)
85  {
86  switch (*capstr)
87  {
88  case 'C':
89  caps |= MIX_CAP_COMPRESS;
90  break;
91 
92  case 'M':
93  caps |= MIX_CAP_MIDDLEMAN;
94  break;
95 
96  case 'N':
97  {
98  switch (*++capstr)
99  {
100  case 'm':
101  caps |= MIX_CAP_NEWSMAIL;
102  break;
103 
104  case 'p':
105  caps |= MIX_CAP_NEWSPOST;
106  break;
107  }
108  }
109  }
110 
111  if (*capstr)
112  capstr++;
113  }
114 
115  return caps;
116 }
#define MIX_CAP_NEWSPOST
Definition: remailer.h:39
uint8_t MixCapFlags
Flags, e.g. MIX_CAP_NO_FLAGS.
Definition: remailer.h:35
#define MIX_CAP_NO_FLAGS
No flags are set.
Definition: remailer.h:36
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:40
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:38
#define MIX_CAP_COMPRESS
Definition: remailer.h:37
+ Here is the caller graph for this function:

◆ mix_add_entry()

static void mix_add_entry ( struct Remailer ***  type2_list,
struct Remailer entry,
size_t *  slots,
size_t *  used 
)
static

Add an entry to the Remailer list.

Parameters
[out]type2_listRemailer list to add to
[in]entryRemailer to add
[out]slotsTotal number of slots
[out]usedNumber of slots used

Definition at line 125 of file remailer.c.

127 {
128  if (*used == *slots)
129  {
130  *slots += 5;
131  mutt_mem_realloc(type2_list, sizeof(struct Remailer *) * (*slots));
132  }
133 
134  (*type2_list)[(*used)++] = entry;
135  if (entry)
136  entry->num = *used;
137 }
int num
Definition: remailer.h:47
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remailer_new()

static struct Remailer* remailer_new ( void  )
static

Create a new Remailer.

Return values
ptrNewly allocated Remailer

Definition at line 143 of file remailer.c.

144 {
145  return mutt_mem_calloc(1, sizeof(struct Remailer));
146 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remailer_free()

static void remailer_free ( struct Remailer **  ptr)
static

Free a Remailer.

Parameters
[out]ptrRemailer to free

Definition at line 152 of file remailer.c.

153 {
154  if (!ptr || !*ptr)
155  return;
156 
157  struct Remailer *r = *ptr;
158 
159  FREE(&r->shortname);
160  FREE(&r->addr);
161  FREE(&r->ver);
162  FREE(ptr);
163 }
char * shortname
Definition: remailer.h:48
#define FREE(x)
Definition: memory.h:40
char * addr
Definition: remailer.h:49
char * ver
Definition: remailer.h:50
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the caller graph for this function:

◆ mix_type2_list()

static struct Remailer** mix_type2_list ( size_t *  l)
static

parse the type2.list as given by mixmaster -T

Parameters
[out]lLength of list
Return values
ptrtype2.list

Definition at line 170 of file remailer.c.

171 {
172  if (!l)
173  return NULL;
174 
175  FILE *fp = NULL;
176  char line[8192];
177  char *t = NULL;
178 
179  struct Remailer **type2_list = NULL;
180  struct Remailer *p = NULL;
181  size_t slots = 0, used = 0;
182 
183  int fd_null = open("/dev/null", O_RDWR);
184  if (fd_null == -1)
185  return NULL;
186 
187  struct Buffer *cmd = mutt_buffer_pool_get();
188  const char *const c_mixmaster = cs_subset_string(NeoMutt->sub, "mixmaster");
189  mutt_buffer_printf(cmd, "%s -T", c_mixmaster);
190 
191  pid_t mm_pid =
192  filter_create_fd(mutt_buffer_string(cmd), NULL, &fp, NULL, fd_null, -1, fd_null);
193  if (mm_pid == -1)
194  {
196  close(fd_null);
197  return NULL;
198  }
199 
201 
202  /* first, generate the "random" remailer */
203 
204  p = remailer_new();
205  p->shortname = mutt_str_dup(_("<random>"));
206  mix_add_entry(&type2_list, p, &slots, &used);
207 
208  while (fgets(line, sizeof(line), fp))
209  {
210  p = remailer_new();
211 
212  t = strtok(line, " \t\n");
213  if (!t)
214  goto problem;
215 
216  p->shortname = mutt_str_dup(t);
217 
218  t = strtok(NULL, " \t\n");
219  if (!t)
220  goto problem;
221 
222  p->addr = mutt_str_dup(t);
223 
224  t = strtok(NULL, " \t\n");
225  if (!t)
226  goto problem;
227 
228  t = strtok(NULL, " \t\n");
229  if (!t)
230  goto problem;
231 
232  p->ver = mutt_str_dup(t);
233 
234  t = strtok(NULL, " \t\n");
235  if (!t)
236  goto problem;
237 
238  p->caps = mix_get_caps(t);
239 
240  mix_add_entry(&type2_list, p, &slots, &used);
241  continue;
242 
243  problem:
244  remailer_free(&p);
245  }
246 
247  *l = used;
248 
249  mix_add_entry(&type2_list, NULL, &slots, &used);
250  filter_wait(mm_pid);
251 
252  close(fd_null);
253 
254  return type2_list;
255 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
MixCapFlags caps
Definition: remailer.h:51
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
static void remailer_free(struct Remailer **ptr)
Free a Remailer.
Definition: remailer.c:152
static void mix_add_entry(struct Remailer ***type2_list, struct Remailer *entry, size_t *slots, size_t *used)
Add an entry to the Remailer list.
Definition: remailer.c:125
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
char * shortname
Definition: remailer.h:48
static MixCapFlags mix_get_caps(const char *capstr)
Get Mixmaster Capabilities.
Definition: remailer.c:80
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
static struct Remailer * remailer_new(void)
Create a new Remailer.
Definition: remailer.c:143
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
char * addr
Definition: remailer.h:49
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
char * ver
Definition: remailer.h:50
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_type2_list_free()

static void mix_type2_list_free ( struct Remailer ***  ttlp)
static

Free a Remailer List.

Parameters
[out]ttlpRemailer List to free

Definition at line 261 of file remailer.c.

262 {
263  struct Remailer **type2_list = *ttlp;
264 
265  for (int i = 0; type2_list[i]; i++)
266  remailer_free(&type2_list[i]);
267 
268  FREE(type2_list);
269 }
static void remailer_free(struct Remailer **ptr)
Free a Remailer.
Definition: remailer.c:152
#define FREE(x)
Definition: memory.h:40
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_screen_coordinates()

static void mix_screen_coordinates ( struct MuttWindow win,
struct Remailer **  type2_list,
struct Coord **  coordsp,
struct MixChain chain,
int  i 
)
static

Get the screen coordinates to place a chain.

Parameters
[in]winWindow
[out]type2_listRemailer List
[out]coordspOn screen coordinates
[in]chainChain
[in]iIndex in chain

Definition at line 279 of file remailer.c.

281 {
282  const int wrap_indent = 2;
283 
284  if (!chain->cl)
285  return;
286 
287  short c, r;
288 
289  mutt_mem_realloc(coordsp, sizeof(struct Coord) * chain->cl);
290 
291  struct Coord *coords = *coordsp;
292 
293  if (i == 0)
294  {
295  r = 0;
296  c = 0;
297  }
298  else
299  {
300  c = coords[i - 1].c + strlen(type2_list[chain->ch[i - 1]]->shortname) + 2;
301  r = coords[i - 1].r;
302  }
303 
304  for (; i < chain->cl; i++)
305  {
306  short oc = c;
307  c += strlen(type2_list[chain->ch[i]]->shortname) + 2;
308 
309  if (c >= win->state.cols)
310  {
311  oc = wrap_indent;
312  c = wrap_indent;
313  r++;
314  }
315 
316  coords[i].c = oc;
317  coords[i].r = r;
318  }
319 }
int ch[MAX_MIXES]
Definition: remailer.h:60
short r
row
Definition: remailer.c:59
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
char * shortname
Definition: remailer.h:48
size_t cl
Definition: remailer.h:59
Screen coordinates.
Definition: remailer.c:57
short c
column
Definition: remailer.c:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_redraw_ce()

static void mix_redraw_ce ( struct MuttWindow win,
struct Remailer **  type2_list,
struct Coord coords,
struct MixChain chain,
int  i,
bool  selected 
)
static

Redraw the Remailer chain.

Parameters
[in]winWindow
[out]type2_listRemailer List
[in]coordsScreen Coordinates
[in]chainChain
[in]iIndex in chain
[in]selectedtrue, if this item is selected

Definition at line 330 of file remailer.c.

332 {
333  if (!coords || !chain)
334  return;
335 
336  if (coords[i].r < win->state.rows)
337  {
338  if (selected)
340  else
342 
343  mutt_window_mvaddstr(win, coords[i].c, coords[i].r, type2_list[chain->ch[i]]->shortname);
345 
346  if (i + 1 < chain->cl)
347  mutt_window_addstr(", ");
348  }
349 }
int ch[MAX_MIXES]
Definition: remailer.h:60
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:56
short r
row
Definition: remailer.c:59
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:396
Plain text.
Definition: color.h:58
Selected item in list.
Definition: color.h:54
char * shortname
Definition: remailer.h:48
size_t cl
Definition: remailer.h:59
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:519
short c
column
Definition: remailer.c:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_redraw_chain()

static void mix_redraw_chain ( struct MuttWindow win,
struct Remailer **  type2_list,
struct Coord coords,
struct MixChain chain,
int  cur 
)
static

Redraw the chain on screen.

Parameters
[in]winWindow
[out]type2_listRemailer List
[in]coordsWhere to draw the list on screen
[in]chainChain to display
[in]curChain index of current selection

Definition at line 359 of file remailer.c.

361 {
362  for (int i = 0; i < win->state.rows; i++)
363  {
364  mutt_window_move(win, 0, i);
366  }
367 
368  for (int i = 0; i < chain->cl; i++)
369  mix_redraw_ce(win, type2_list, coords, chain, i, i == cur);
370 }
static void mix_redraw_ce(struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int i, bool selected)
Redraw the Remailer chain.
Definition: remailer.c:330
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:242
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:59
size_t cl
Definition: remailer.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_redraw_head()

static void mix_redraw_head ( struct MuttWindow win,
struct MixChain chain 
)
static

Redraw the Chain info.

Parameters
winWindow
chainChain

Definition at line 377 of file remailer.c.

378 {
379  char buf[1024];
380  snprintf(buf, sizeof(buf), "-- Remailer chain [Length: %ld]", chain ? chain->cl : 0);
381  sbar_set_title(win, buf);
382 }
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:159
size_t cl
Definition: remailer.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_format_caps()

static const char* mix_format_caps ( struct Remailer r)
static

Turn flags into a MixMaster capability string.

Parameters
rRemailer to use
Return values
ptrCapability string
Note
The string is a static buffer

Definition at line 391 of file remailer.c.

392 {
393  static char capbuf[10];
394  char *t = capbuf;
395 
396  if (r->caps & MIX_CAP_COMPRESS)
397  *t++ = 'C';
398  else
399  *t++ = ' ';
400 
401  if (r->caps & MIX_CAP_MIDDLEMAN)
402  *t++ = 'M';
403  else
404  *t++ = ' ';
405 
406  if (r->caps & MIX_CAP_NEWSPOST)
407  {
408  *t++ = 'N';
409  *t++ = 'p';
410  }
411  else
412  {
413  *t++ = ' ';
414  *t++ = ' ';
415  }
416 
417  if (r->caps & MIX_CAP_NEWSMAIL)
418  {
419  *t++ = 'N';
420  *t++ = 'm';
421  }
422  else
423  {
424  *t++ = ' ';
425  *t++ = ' ';
426  }
427 
428  *t = '\0';
429 
430  return capbuf;
431 }
#define MIX_CAP_NEWSPOST
Definition: remailer.h:39
MixCapFlags caps
Definition: remailer.h:51
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:40
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:38
#define MIX_CAP_COMPRESS
Definition: remailer.h:37
+ Here is the caller graph for this function:

◆ mix_format_str()

static const char* mix_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the remailer menu - Implements format_t.

Expando Description
%a The remailer's e-mail address
%c Remailer capabilities
%n The running number on the menu
%s The remailer's short name

Definition at line 443 of file remailer.c.

447 {
448  char fmt[128];
449  struct Remailer *remailer = (struct Remailer *) data;
450  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
451 
452  switch (op)
453  {
454  case 'a':
455  if (!optional)
456  {
457  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
458  snprintf(buf, buflen, fmt, NONULL(remailer->addr));
459  }
460  else if (!remailer->addr)
461  optional = false;
462  break;
463 
464  case 'c':
465  if (optional)
466  break;
467 
468  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
469  snprintf(buf, buflen, fmt, mix_format_caps(remailer));
470  break;
471 
472  case 'n':
473  if (optional)
474  break;
475 
476  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
477  snprintf(buf, buflen, fmt, remailer->num);
478  break;
479 
480  case 's':
481  if (!optional)
482  {
483  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
484  snprintf(buf, buflen, fmt, NONULL(remailer->shortname));
485  }
486  else if (!remailer->shortname)
487  optional = false;
488  break;
489 
490  default:
491  *buf = '\0';
492  }
493 
494  if (optional)
495  {
496  mutt_expando_format(buf, buflen, col, cols, if_str, mix_format_str, data,
498  }
499  else if (flags & MUTT_FORMAT_OPTIONAL)
500  {
501  mutt_expando_format(buf, buflen, col, cols, else_str, mix_format_str, data,
503  }
504 
505  /* We return the format string, unchanged */
506  return src;
507 }
#define NONULL(x)
Definition: string2.h:37
static const char * mix_format_caps(struct Remailer *r)
Turn flags into a MixMaster capability string.
Definition: remailer.c:391
int num
Definition: remailer.h:47
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
char * shortname
Definition: remailer.h:48
static const char * mix_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the remailer menu - Implements format_t.
Definition: remailer.c:443
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:779
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
char * addr
Definition: remailer.h:49
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_make_entry()

static void mix_make_entry ( struct Menu menu,
char *  buf,
size_t  buflen,
int  num 
)
static

Format a menu item for the mixmaster chain list - Implements Menu::make_entry()

Definition at line 512 of file remailer.c.

513 {
514  struct Remailer **type2_list = menu->mdata;
515  const char *const c_mix_entry_format =
516  cs_subset_string(NeoMutt->sub, "mix_entry_format");
517  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
518  NONULL(c_mix_entry_format), mix_format_str,
519  (intptr_t) type2_list[num], MUTT_FORMAT_ARROWCURSOR);
520 }
#define NONULL(x)
Definition: string2.h:37
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
int num
Definition: remailer.h:47
Container for Accounts, Notifications.
Definition: neomutt.h:36
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:122
void * mdata
Private data.
Definition: lib.h:129
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
static const char * mix_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the remailer menu - Implements format_t.
Definition: remailer.c:443
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:779
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct MuttWindow * win_index
Definition: lib.h:66
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_chain_add()

static int mix_chain_add ( struct MixChain chain,
const char *  s,
struct Remailer **  type2_list 
)
static

Add a host to the chain.

Parameters
[in]chainChain to add to
[in]sHostname
[out]type2_listRemailer List
Return values
0Success
-1Error

Definition at line 530 of file remailer.c.

531 {
532  int i;
533 
534  if (chain->cl >= MAX_MIXES)
535  return -1;
536 
537  if (mutt_str_equal(s, "0") || mutt_istr_equal(s, "<random>"))
538  {
539  chain->ch[chain->cl++] = 0;
540  return 0;
541  }
542 
543  for (i = 0; type2_list[i]; i++)
544  {
545  if (mutt_istr_equal(s, type2_list[i]->shortname))
546  {
547  chain->ch[chain->cl++] = i;
548  return 0;
549  }
550  }
551 
552  /* replace unknown remailers by <random> */
553 
554  if (!type2_list[i])
555  chain->ch[chain->cl++] = 0;
556 
557  return 0;
558 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
int ch[MAX_MIXES]
Definition: remailer.h:60
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
char * shortname
Definition: remailer.h:48
size_t cl
Definition: remailer.h:59
#define MAX_MIXES
Definition: remailer.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remailer_config_observer()

static int remailer_config_observer ( struct NotifyCallback nc)
static

Listen for config changes affecting the remailer - Implements observer_t.

Definition at line 563 of file remailer.c.

564 {
565  if (!nc->event_data || !nc->global_data)
566  return -1;
567  if (nc->event_type != NT_CONFIG)
568  return 0;
569 
570  struct EventConfig *ec = nc->event_data;
571  struct MuttWindow *dlg = nc->global_data;
572 
573  if (!mutt_str_equal(ec->name, "status_on_top"))
574  return 0;
575 
576  const bool c_status_on_top = cs_subset_bool(ec->sub, "status_on_top");
577  struct MuttWindow *win_move = NULL;
578  if (c_status_on_top)
579  {
580  win_move = TAILQ_LAST(&dlg->children, MuttWindowList);
581  TAILQ_REMOVE(&dlg->children, win_move, entries);
582  TAILQ_INSERT_HEAD(&dlg->children, win_move, entries);
583  }
584  else
585  {
586  win_move = TAILQ_FIRST(&dlg->children);
587  TAILQ_REMOVE(&dlg->children, win_move, entries);
588  TAILQ_INSERT_TAIL(&dlg->children, win_move, entries);
589  }
590 
591  mutt_window_reflow(dlg);
592  return 0;
593 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define TAILQ_LAST(head, headname)
Definition: queue.h:812
A config-change event.
Definition: subset.h:70
A division of the screen.
Definition: mutt_window.h:117
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:41
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:789
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:433
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:131
const struct ConfigSubset * sub
Config Subset.
Definition: subset.h:72
const char * name
Name of config item that changed.
Definition: subset.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_mixmaster_chain()

void dlg_select_mixmaster_chain ( struct ListHead *  chainhead)

Create a Mixmaster chain.

Parameters
chainheadList of chain links

Ask the user to select Mixmaster hosts to create a chain.

Definition at line 601 of file remailer.c.

602 {
603  int c_cur = 0, c_old = 0;
604  bool c_redraw = true;
605  size_t ttll = 0;
606 
607  struct Coord *coords = NULL;
608 
609  struct Menu *menu = NULL;
610  bool loop = true;
611 
612  char *t = NULL;
613 
614  struct Remailer **type2_list = mix_type2_list(&ttll);
615  if (!type2_list)
616  {
617  mutt_error(_("Can't get mixmaster's type2.list"));
618  return;
619  }
620 
621  struct MixChain *chain = mutt_mem_calloc(1, sizeof(struct MixChain));
622 
623  struct ListNode *p = NULL;
624  STAILQ_FOREACH(p, chainhead, entries)
625  {
626  mix_chain_add(chain, p->data, type2_list);
627  }
628  mutt_list_free(chainhead);
629 
630  /* safety check */
631  for (int i = 0; i < chain->cl; i++)
632  {
633  if (chain->ch[i] >= ttll)
634  chain->ch[i] = 0;
635  }
636 
637  struct MuttWindow *dlg =
640  dlg->help_menu = MENU_MIX;
641  dlg->help_data = RemailerHelp;
642 
643  struct MuttWindow *win_hosts = menu_new_window(MENU_MIX);
644  win_hosts->focus = win_hosts;
645 
646  struct MuttWindow *win_chain =
649 
650  struct MuttWindow *win_cbar = NULL;
651  struct MuttWindow *win_rbar = NULL;
652 
653  const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
654  if (c_status_on_top)
655  {
656  win_rbar = sbar_add(dlg);
657  mutt_window_add_child(dlg, win_hosts);
658  win_cbar = sbar_add(dlg);
659  mutt_window_add_child(dlg, win_chain);
660  }
661  else
662  {
663  mutt_window_add_child(dlg, win_hosts);
664  win_cbar = sbar_add(dlg);
665  mutt_window_add_child(dlg, win_chain);
666  win_rbar = sbar_add(dlg);
667  }
668  sbar_set_title(win_rbar, _("Select a remailer chain"));
669 
670  mix_screen_coordinates(dlg, type2_list, &coords, chain, 0);
671 
672  menu = win_hosts->wdata;
673  menu->max = ttll;
674  menu->make_entry = mix_make_entry;
675  menu->tag = NULL;
676  menu->mdata = type2_list;
677 
679  dialog_push(dlg);
680 
681  while (loop)
682  {
683  if (c_redraw)
684  {
685  mix_redraw_head(win_cbar, chain);
686  mix_redraw_chain(win_chain, type2_list, coords, chain, c_cur);
687  c_redraw = false;
688  }
689  else if (c_cur != c_old)
690  {
691  mix_redraw_ce(win_chain, type2_list, coords, chain, c_old, false);
692  mix_redraw_ce(win_chain, type2_list, coords, chain, c_cur, true);
693  }
694 
695  c_old = c_cur;
696 
697  window_redraw(dlg, true);
698  const int op = menu_loop(menu);
699  switch (op)
700  {
701  case OP_REDRAW:
702  {
703  mix_redraw_head(win_cbar, chain);
704  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, 0);
705  mix_redraw_chain(win_chain, type2_list, coords, chain, c_cur);
706  break;
707  }
708 
709  case OP_EXIT:
710  {
711  chain->cl = 0;
712  loop = false;
713  break;
714  }
715 
716  case OP_MIX_USE:
717  {
718  if (!chain->cl)
719  {
720  chain->cl++;
721  chain->ch[0] = menu_get_index(menu);
722  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
723  c_redraw = true;
724  }
725 
726  if (chain->cl && chain->ch[chain->cl - 1] &&
727  (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
728  {
729  mutt_error(
730  _("Error: %s can't be used as the final remailer of a chain"),
731  type2_list[chain->ch[chain->cl - 1]]->shortname);
732  }
733  else
734  {
735  loop = false;
736  }
737  break;
738  }
739 
740  case OP_GENERIC_SELECT_ENTRY:
741  case OP_MIX_APPEND:
742  {
743  if ((chain->cl < MAX_MIXES) && (c_cur < chain->cl))
744  c_cur++;
745  }
746  /* fallthrough */
747  case OP_MIX_INSERT:
748  {
749  if (chain->cl < MAX_MIXES)
750  {
751  chain->cl++;
752  for (int i = chain->cl - 1; i > c_cur; i--)
753  chain->ch[i] = chain->ch[i - 1];
754 
755  chain->ch[c_cur] = menu_get_index(menu);
756  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
757  c_redraw = true;
758  }
759  else
760  {
761  /* L10N The '%d' here hard-coded to 19 */
762  mutt_error(_("Mixmaster chains are limited to %d elements"), MAX_MIXES);
763  }
764 
765  break;
766  }
767 
768  case OP_MIX_DELETE:
769  {
770  if (chain->cl)
771  {
772  chain->cl--;
773 
774  for (int i = c_cur; i < chain->cl; i++)
775  chain->ch[i] = chain->ch[i + 1];
776 
777  if ((c_cur == chain->cl) && c_cur)
778  c_cur--;
779 
780  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
781  c_redraw = true;
782  }
783  else
784  {
785  mutt_error(_("The remailer chain is already empty"));
786  }
787  break;
788  }
789 
790  case OP_MIX_CHAIN_PREV:
791  {
792  if (c_cur)
793  c_cur--;
794  else
795  mutt_error(_("You already have the first chain element selected"));
796 
797  break;
798  }
799 
800  case OP_MIX_CHAIN_NEXT:
801  {
802  if (chain->cl && (c_cur < chain->cl - 1))
803  c_cur++;
804  else
805  mutt_error(_("You already have the last chain element selected"));
806 
807  break;
808  }
809  }
810  }
811 
812  dialog_pop();
814 
815  /* construct the remailer list */
816 
817  if (chain->cl)
818  {
819  for (int i = 0; i < chain->cl; i++)
820  {
821  const int j = chain->ch[i];
822  if (j != 0)
823  t = type2_list[j]->shortname;
824  else
825  t = "*";
826 
827  mutt_list_insert_tail(chainhead, mutt_str_dup(t));
828  }
829  }
830 
831  mix_type2_list_free(&type2_list);
832  FREE(&coords);
833  FREE(&chain);
834 }
static void mix_redraw_ce(struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int i, bool selected)
Redraw the Remailer chain.
Definition: remailer.c:330
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:71
GUI selectable list of items.
Definition: lib.h:56
A Mixmaster chain.
Definition: remailer.h:57
int ch[MAX_MIXES]
Definition: remailer.h:60
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:136
Window uses all available vertical space.
Definition: mutt_window.h:36
MixCapFlags caps
Definition: remailer.h:51
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
A division of the screen.
Definition: mutt_window.h:117
static void mix_redraw_chain(struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int cur)
Redraw the chain on screen.
Definition: remailer.c:359
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Format a item for a menu.
Definition: lib.h:91
struct MuttWindow * focus
Focussed Window.
Definition: mutt_window.h:135
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: dialog.c:65
Window with a custom drawing function.
Definition: mutt_window.h:93
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:173
Window has a fixed size.
Definition: mutt_window.h:45
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
static void mix_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
Format a menu item for the mixmaster chain list - Implements Menu::make_entry()
Definition: remailer.c:512
void * mdata
Private data.
Definition: lib.h:129
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:50
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:137
char * shortname
Definition: remailer.h:48
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:159
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: lib.h:110
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
size_t cl
Definition: remailer.h:59
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:38
int max
Number of entries in the menu.
Definition: lib.h:60
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:562
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:41
static void mix_type2_list_free(struct Remailer ***ttlp)
Free a Remailer List.
Definition: remailer.c:261
char * data
String.
Definition: list.h:36
#define mutt_error(...)
Definition: logging.h:84
void dialog_pop(void)
Hide a Window from the user.
Definition: dialog.c:97
Create/edit a Mixmaster chain.
Definition: keymap.h:91
#define FREE(x)
Definition: memory.h:40
struct MuttWindow * sbar_add(struct MuttWindow *parent)
Add the Simple Bar (status)
Definition: sbar.c:134
static void mix_redraw_head(struct MuttWindow *win, struct MixChain *chain)
Redraw the Chain info.
Definition: remailer.c:377
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:212
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:744
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
Add a host to the chain.
Definition: remailer.c:530
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:164
struct MuttWindow * win_index
Definition: lib.h:66
A List node for strings.
Definition: list.h:34
Window wants as much space as possible.
Definition: mutt_window.h:46
static void mix_screen_coordinates(struct MuttWindow *win, struct Remailer **type2_list, struct Coord **coordsp, struct MixChain *chain, int i)
Get the screen coordinates to place a chain.
Definition: remailer.c:279
void * wdata
Private data.
Definition: mutt_window.h:140
static struct Remailer ** mix_type2_list(size_t *l)
parse the type2.list as given by mixmaster -T
Definition: remailer.c:170
static int remailer_config_observer(struct NotifyCallback *nc)
Listen for config changes affecting the remailer - Implements observer_t.
Definition: remailer.c:563
#define MAX_MIXES
Definition: remailer.h:33
Screen coordinates.
Definition: remailer.c:57
static const struct Mapping RemailerHelp[]
Help Bar for the Mixmaster dialog.
Definition: remailer.c:64
Remailer Dialog, dlg_select_mixmaster_chain()
Definition: mutt_window.h:89
A Mixmaster remailer.
Definition: remailer.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_check_message()

int mix_check_message ( struct Email e)

Safety-check the message before passing it to mixmaster.

Parameters
eEmail
Return values
0Success
-1Error

Definition at line 842 of file remailer.c.

843 {
844  bool need_hostname = false;
845 
846  if (!TAILQ_EMPTY(&e->env->cc) || !TAILQ_EMPTY(&e->env->bcc))
847  {
848  mutt_error(_("Mixmaster doesn't accept Cc or Bcc headers"));
849  return -1;
850  }
851 
852  /* When using mixmaster, we MUST qualify any addresses since
853  * the message will be delivered through remote systems.
854  *
855  * use_domain won't be respected at this point, hidden_host will.
856  */
857 
858  struct Address *a = NULL;
859  TAILQ_FOREACH(a, &e->env->to, entries)
860  {
861  if (!a->group && !strchr(a->mailbox, '@'))
862  {
863  need_hostname = true;
864  break;
865  }
866  }
867 
868  if (need_hostname)
869  {
870  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
871  if (!fqdn)
872  {
873  mutt_error(_("Please set the hostname variable to a proper value when "
874  "using mixmaster"));
875  return -1;
876  }
877 
878  /* Cc and Bcc are empty at this point. */
879  mutt_addrlist_qualify(&e->env->to, fqdn);
880  mutt_addrlist_qualify(&e->env->reply_to, fqdn);
882  }
883 
884  return 0;
885 }
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:35
char * mailbox
Mailbox and host address.
Definition: address.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1187
bool group
Group mailbox?
Definition: address.h:39
#define mutt_error(...)
Definition: logging.h:84
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:714
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_send_message()

int mix_send_message ( struct ListHead *  chain,
const char *  tempfile 
)

Send an email via Mixmaster.

Parameters
chainString list of hosts
tempfileTemporary file containing email
Return values
-1Error
>=0Success (Mixmaster's return code)

Definition at line 894 of file remailer.c.

895 {
896  int i = 0;
897  struct Buffer *cmd = mutt_buffer_pool_get();
898  struct Buffer *cd_quoted = mutt_buffer_pool_get();
899 
900  const char *const c_mixmaster = cs_subset_string(NeoMutt->sub, "mixmaster");
901  mutt_buffer_printf(cmd, "cat %s | %s -m ", tempfile, c_mixmaster);
902 
903  struct ListNode *np = NULL;
904  STAILQ_FOREACH(np, chain, entries)
905  {
906  mutt_buffer_addstr(cmd, (i != 0) ? "," : " -l ");
907  mutt_buffer_quote_filename(cd_quoted, (char *) np->data, true);
908  mutt_buffer_addstr(cmd, mutt_buffer_string(cd_quoted));
909  i = 1;
910  }
911 
912  mutt_endwin();
913 
914  i = mutt_system(cmd->data);
915  if (i != 0)
916  {
917  fprintf(stderr, _("Error sending message, child exited %d\n"), i);
918  if (!OptNoCurses)
919  {
921  mutt_error(_("Error sending message"));
922  }
923  }
924 
926  mutt_buffer_pool_release(&cd_quoted);
927  unlink(tempfile);
928  return i;
929 }
void mutt_buffer_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell&#39;s quoting rules.
Definition: file.c:838
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:568
char * data
Pointer to data.
Definition: buffer.h:35
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:295
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:601
char * data
String.
Definition: list.h:36
#define mutt_error(...)
Definition: logging.h:84
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
A List node for strings.
Definition: list.h:34
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ RemailerHelp

const struct Mapping RemailerHelp[]
static
Initial value:
= {
{ N_("Append"), OP_MIX_APPEND },
{ N_("Insert"), OP_MIX_INSERT },
{ N_("Delete"), OP_MIX_DELETE },
{ N_("Abort"), OP_EXIT },
{ N_("OK"), OP_MIX_USE },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Help Bar for the Mixmaster dialog.

Definition at line 64 of file remailer.c.