mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

menunym.c (11544B)


      1 /* Mixmaster version 3.0  --  (C) 1999 - 2006 Anonymizer Inc. and others.
      2 
      3    Mixmaster may be redistributed and modified under certain conditions.
      4    This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
      5    ANY KIND, either express or implied. See the file COPYRIGHT for
      6    details.
      7 
      8    Menu-based user interface - nym management
      9    $Id: menunym.c 934 2006-06-24 13:40:39Z rabbi $ */
     10 
     11 #ifdef NYMSUPPORT
     12 
     13 #include "menu.h"
     14 #include "mix3.h"
     15 #include <string.h>
     16 #include <stdlib.h>
     17 #ifdef POSIX
     18 #include <unistd.h>
     19 #endif /* POSIX */
     20 
     21 #ifdef USE_NCURSES
     22 void menu_nym(char *nnym)
     23 {
     24   char nym[maxnym][LINELEN];
     25   char pending[maxnym][LINELEN];
     26   int c, i, num = 0, numpending = 0, select = -1;
     27   int edit = 0;
     28   BUFFER *nymlist;
     29   int s;
     30   int pass = 0;
     31   char reliability[9]; /* When printing information about a chain,
     32 			  this variable stores the reliability. */
     33 
     34   nymlist = buf_new();
     35 
     36   strcpy(nym[0], NONANON);
     37   strcatn(nym[0], " (", sizeof(nym[0]));
     38   strcatn(nym[0], NAME, sizeof(nym[0]));
     39   strcatn(nym[0], ")", sizeof(nym[0]));
     40 
     41   strcpy(nym[1], ANON);
     42   num = 2;
     43   if (nymlist_read(nymlist) == -1) {
     44     user_delpass();
     45     mix_status("");
     46   } else
     47     pass = 1;
     48   while (nymlist_get(nymlist, nym[num], NULL, NULL, NULL, NULL, NULL, &s) >= 0) {
     49     if (s == NYM_OK) {
     50       if (num < maxnym)
     51 	num++;
     52     } else if (s == NYM_WAITING) {
     53       if (numpending < maxnym)
     54 	strncpy(pending[numpending++], nym[num], LINELEN);
     55     }
     56   }
     57   buf_free(nymlist);
     58 
     59 nymselect:
     60   clear();
     61   standout();
     62   printw("Select nym:\n\n");
     63   standend();
     64 #ifdef USE_PGP
     65   if (pass)
     66     printw("c)reate new nym\ne)dit nym\nd)elete nym\n\n");
     67   else
     68     printw("[nym passphrase is invalid]\n\n");
     69 #endif /* USE_PGP */
     70   for (i = 0; i < num; i++)
     71     printw("%d) %s\n", i, nym[i]);
     72   if (numpending > 0) {
     73     printw("\n\nWaiting for confirmation: ");
     74     for (i = 0; i < numpending; i++)
     75       printw("%s ", pending[i]);
     76     printw("\n");
     77   }
     78 select:
     79   if (select != -1)
     80     printw("\r%d", select);
     81   else
     82     printw("\r          \r");
     83   refresh();
     84   c = getch();
     85   if (c == erasechar())
     86     c = KEY_BACKSPACE;
     87   if (c >= '0' && c <= '9') {
     88     if (select == -1)
     89       select = c - '0';
     90     else
     91       select = 10 * select + c - '0';
     92     if (edit ? select == 0 || select >= num + numpending - 1 : select >= num) {
     93       beep();
     94       select = -1;
     95     }
     96     refresh();
     97     goto select;
     98   } else
     99     switch (c) {
    100     case KEY_BACKSPACE:
    101       select /= 10;
    102       if (select < 1)
    103 	select = -1;
    104       goto select;
    105     case 'q':
    106       if (edit) {
    107 	edit = 0;
    108 	select = -1;
    109 	goto nymselect;
    110       }
    111       break;
    112 #ifdef USE_PGP
    113     case 'e':
    114       if (pass) {
    115 	if (edit || num + numpending < 3) {
    116 	  edit = 0;
    117 	  select = -1;
    118 	  goto nymselect;
    119 	} else {
    120 	  clear();
    121 	  standout();
    122 	  printw("Edit nym:\n\n");
    123 	  standend();
    124 	  for (i = 2; i < num + numpending; i++)
    125 	    printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]);
    126 	  printw("\n");
    127 	  select = -1;
    128 	  edit = NYM_MODIFY;
    129 	  goto select;
    130 	}
    131       }
    132       break;
    133     case 'd':
    134       if (pass) {
    135 	if (edit || num + numpending < 3) {
    136 	  edit = 0;
    137 	  select = -1;
    138 	  goto nymselect;
    139 	} else {
    140 	  clear();
    141 	  standout();
    142 	  printw("Delete nym:\n\n");
    143 	  standend();
    144 	  for (i = 2; i < num + numpending; i++)
    145 	    printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]);
    146 	  printw("\n");
    147 	  select = -1;
    148 	  edit = NYM_DELETE;
    149 	  goto select;
    150 	}
    151       }
    152       break;
    153     case '\r':
    154     case '\n':
    155       if (select == -1 || (edit && select == 0)) {
    156 	beep();
    157 	edit = 0;
    158 	select = -1;
    159 	goto nymselect;
    160       }
    161       if (!edit) {
    162 	strncpy(nnym, nym[select], LINELEN);
    163 	return;
    164       }
    165       /* fallthru */
    166     case 'c':
    167       if (pass) {
    168 	char nymserv[LINELEN] = "*";
    169 	char replyblock[5][CHAINMAX], dest[10][LINELEN];
    170 	int latent[5], desttype[5];
    171 	char mdest[LINELEN], pdest[LINELEN] = "alt.anonymous.messages",
    172 	psub[LINELEN] = "";
    173 	int deflatent = 0, defdesttype = MSG_MAIL;
    174 	char alias[LINELEN] = "";
    175 	BUFFER *name, *opt;
    176 	char sendchain[CHAINMAX];
    177 	int sendnumcopies = 1, rnum = 1;
    178 	int i;
    179 	char line[LINELEN];
    180 	int acksend = 0, signsend = 0, fixedsize = 0, disable = 0,
    181 	    fingerkey = 1;
    182 
    183 	name = buf_new();
    184 	opt = buf_new();
    185 	strncpy(sendchain, CHAIN, CHAINMAX);
    186 	strncpy(mdest, ADDRESS, LINELEN);
    187 	if (edit)
    188 	  strncpy(alias, select + 1 < num ? nym[select + 1] :
    189 		  pending[select + 1 - num], LINELEN);
    190 	if (edit == NYM_MODIFY) {
    191 	  nymlist_getnym(alias, NULL, NULL, opt, name, NULL);
    192 	  acksend = bufifind(opt, "+acksend");
    193 	  signsend = bufifind(opt, "+signsend");
    194 	  fixedsize = bufifind(opt, "+fixedsize");
    195 	  disable = bufifind(opt, "+disable");
    196 	  fingerkey = bufifind(opt, "+fingerkey");
    197 	  rnum = -1;
    198 	}
    199       newnym:
    200 	if (!edit) {
    201 	  clear();
    202 	  standout();
    203 	  printw("Create a nym:");
    204 	  standend();
    205 
    206 	  mvprintw(3, 0, "Alias address: ");
    207 	  echo();
    208 	  wgetnstr(stdscr, alias, LINELEN);
    209 	  noecho();
    210 	  if (alias[0] == '\0')
    211 	    goto end;
    212 	  for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ;
    213 	  alias[i] = '\0';
    214 	  if (i == 0)
    215 	    goto newnym;
    216 	  mvprintw(4, 0, "Pseudonym: ");
    217 	  echo();
    218 	  wgetnstr(stdscr, line, LINELEN);
    219 	  noecho();
    220 	  buf_sets(name, line);
    221 	  menu_chain(nymserv, 2, 0);
    222 	}
    223 	if (edit != NYM_DELETE) {
    224 	  for (i = 0; i < 5; i++) {
    225 	    desttype[i] = defdesttype;
    226 	    latent[i] = deflatent;
    227 	    dest[i][0] = '\0';
    228 	    strcpy(replyblock[i], "*,*,*,*");
    229 	  }
    230 	  if (rnum != -1) {
    231 	    menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub,
    232 			    replyblock[0]);
    233 	    desttype[0] = defdesttype;
    234 	    latent[0] = deflatent;
    235 	    strncpy(dest[0], desttype[0] == MSG_POST ? pdest : mdest,
    236 		    LINELEN);
    237 	  }
    238 	}
    239       redraw:
    240 	clear();
    241 	standout();
    242 	switch (edit) {
    243 	case NYM_DELETE:
    244 	  printw("Delete nym:");
    245 	  break;
    246 	case NYM_MODIFY:
    247 	  printw("Edit nym:");
    248 	  break;
    249 	default:
    250 	  printw("Create a nym:");
    251 	  break;
    252 	}
    253 	standend();
    254       loop:
    255 	{
    256 	  if (!edit) {
    257 	    cl(2, 0);
    258 	    printw("Nym: a)lias address: %s", alias);
    259 	    cl(3, 0);
    260 	    printw("     nym s)erver: %s", nymserv);
    261 	  }
    262 	  if (edit != NYM_DELETE) {
    263 	    cl(4, 0);
    264 	    printw("     p)seudonym: %s", name->data);
    265 	    if (edit)
    266 	      mvprintw(6, 0, "Nym modification:");
    267 	    else
    268 	      mvprintw(6, 0, "Nym creation:");
    269 	  }
    270 	  cl(7, 0);
    271 	  chain_reliability(sendchain, 0, reliability); /* chaintype 0=mix */
    272 	  printw("     c)hain to nym server: %-30s (reliability: %s)", sendchain, reliability);
    273 	  cl(8, 0);
    274 	  printw("     n)umber of redundant copies: %d", sendnumcopies);
    275 	  if (edit != NYM_DELETE) {
    276 	    mvprintw(10, 0, "Configuration:\n");
    277 	    printw("     A)cknowledge sending: %s\n", acksend ? "yes" : "no");
    278 	    printw("     S)erver signatures: %s\n", signsend ? "yes" : "no");
    279 	    printw("     F)ixed size replies: %s\n", fixedsize ? "yes" :
    280 		   "no");
    281 	    printw("     D)isable: %s\n", disable ? "yes" : "no");
    282 	    printw("     Finger K)ey: %s\n", fingerkey ? "yes" : "no");
    283 	    mvprintw(17, 0, "Reply chains:");
    284 	    cl(18, 0);
    285 	    if (rnum == -1)
    286 	      printw("     create new r)eply block");
    287 	    else {
    288  	      printw("     number of r)eply chains: %2d                                     reliability", rnum);
    289 	      for (i = 0; i < rnum; i++) {
    290 		cl(i + 19, 0);
    291  		chain_reliability(replyblock[i], 1, reliability); /* 1=ek */
    292  		printw("     %d) %30s %-31s [%s]", i + 1,
    293   		       desttype[i] == MSG_NULL ?
    294  		       "(cover traffic)" : dest[i], replyblock[i],
    295  		       reliability);
    296 	      }
    297 	    }
    298 	  }
    299 	  move(LINES - 1, COLS - 1);
    300 	  refresh();
    301 	  c = getch();
    302 	  if (edit != NYM_DELETE && c >= '1' && c <= '9' && c - '1' < rnum) {
    303 	    menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub,
    304 			    replyblock[c - '1']);
    305 	    desttype[c - '1'] = defdesttype;
    306 	    latent[c - '1'] = deflatent;
    307 	    strncpy(dest[c - '1'],
    308 		    desttype[c - '1'] == MSG_POST ? pdest : mdest, LINELEN);
    309 	    goto redraw;
    310 	  }
    311 	  switch (c) {
    312 	  case 'A':
    313 	    acksend = !acksend;
    314 	    goto redraw;
    315 	  case 'S':
    316 	    signsend = !signsend;
    317 	    goto redraw;
    318 	  case 'F':
    319 	    fixedsize = !fixedsize;
    320 	    goto redraw;
    321 	  case 'D':
    322 	    disable = !disable;
    323 	    goto redraw;
    324 	  case 'K':
    325 	    fingerkey = !fingerkey;
    326 	    goto redraw;
    327 	  case 'q':
    328 	    edit = 0;
    329 	    select = -1;
    330 	    goto nymselect;
    331 	  case '\014':
    332 	    goto redraw;
    333 	  case 'a':
    334 	    cl(2, 0);
    335 	    printw("Nym: a)lias address: ");
    336 	    echo();
    337 	    wgetnstr(stdscr, alias, LINELEN);
    338 	    noecho();
    339 	    for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ;
    340 	    alias[i] = '\0';
    341 	    if (i == 0)
    342 	      goto nymselect;
    343 	    goto redraw;
    344 	  case 'p':
    345 	    cl(4, 0);
    346 	    printw("     p)seudonym: ");
    347 	    echo();
    348 	    wgetnstr(stdscr, line, LINELEN);
    349 	    noecho();
    350 	    if (line[0] != '\0')
    351 	      buf_sets(name, line);
    352 	    goto redraw;
    353 	  case 'c':
    354 	    menu_chain(sendchain, 0, 0);
    355 	    goto redraw;
    356 	  case 'n':
    357 	    cl(8, 0);
    358 	    printw("     n)umber of redundant copies: ");
    359 	    echo();
    360 	    wgetnstr(stdscr, line, LINELEN);
    361 	    noecho();
    362 	    sendnumcopies = strtol(line, NULL, 10);
    363 	    if (sendnumcopies < 1 || sendnumcopies > 10)
    364 	      sendnumcopies = 1;
    365 	    goto redraw;
    366 	  case 'r':
    367 	    cl(18, 0);
    368 	    printw("     number of r)eply chains: ");
    369 	    echo();
    370 	    wgetnstr(stdscr, line, LINELEN);
    371 	    noecho();
    372 	    i = rnum;
    373 	    rnum = strtol(line, NULL, 10);
    374 	    if (rnum < 1)
    375 	      rnum = 1;
    376 	    if (rnum > 5)
    377 	      rnum = 5;
    378 	    for (; i < rnum; i++)
    379 	      if (dest[i][0] == '\0') {
    380 		desttype[i] = defdesttype;
    381 		latent[i] = deflatent;
    382 		strncpy(dest[i], defdesttype == MSG_POST ? pdest :
    383 			mdest, LINELEN);
    384 	      }
    385 	    goto redraw;
    386 	  case 's':
    387 	    menu_chain(nymserv, 2, 0);
    388 	    goto redraw;
    389 	  case '\n':
    390 	  case '\r':
    391 	    {
    392 	      BUFFER *chains;
    393 	      int err;
    394 
    395 	      if (rnum == -1)
    396 		chains = NULL;
    397 	      else {
    398 		chains = buf_new();
    399 		for (i = 0; i < rnum; i++)
    400 		  if (replyblock[i][0] != '\0') {
    401 		    if (desttype[i] == MSG_POST)
    402 		      buf_appendf(chains, "Subject: %s\n", psub);
    403 		    if (desttype[i] == MSG_MAIL)
    404 		      buf_appends(chains, "To: ");
    405 		    else if (desttype[i] == MSG_POST)
    406 		      buf_appends(chains, "Newsgroups: ");
    407 		    else
    408 		      buf_appends(chains, "Null:");
    409 		    buf_appendf(chains, "%s\n", dest[i]);
    410 		    buf_appendf(chains, "Chain: %s\n", replyblock[i]);
    411 		    buf_appendf(chains, "Latency: %d\n\n", latent[i]);
    412 		  }
    413 	      }
    414 	    create:
    415 	      clear();
    416 	      buf_setf(opt,
    417 		       " %cacksend %csignsend +cryptrecv %cfixedsize %cdisable %cfingerkey",
    418 		       acksend ? '+' : '-',
    419 		       signsend ? '+' : '-',
    420 		       fixedsize ? '+' : '-',
    421 		       disable ? '+' : '-',
    422 		       fingerkey ? '+' : '-');
    423 	      if (edit) {
    424 		mix_status("Preparing nymserver configuration message...");
    425 		err = nym_config(edit, alias, NULL,
    426 				 name, sendchain, sendnumcopies,
    427 				 chains, opt);
    428 	      } else {
    429 		mix_status("Preparing nym creation request...");
    430 		err = nym_config(edit, alias, nymserv, name,
    431 				 sendchain, sendnumcopies, chains,
    432 				 opt);
    433 	      }
    434 	      if (err == -3) {
    435 		beep();
    436 		mix_status("Bad passphrase!");
    437 		getch();
    438 		goto create;
    439 	      }
    440 	      if (err != 0) {
    441 		mix_genericerror();
    442 		beep();
    443 		refresh();
    444 	      } else {
    445 		if (edit)
    446 		  mix_status("Nymserver configuration message completed.");
    447 		else
    448 		  mix_status("Nym creation request completed.");
    449 	      }
    450 	      if (chains)
    451 		buf_free(chains);
    452 	      goto end;
    453 	    }
    454 	  default:
    455 	    beep();
    456 	    goto loop;
    457 	  }
    458 	}
    459       end:
    460 	buf_free(name);
    461 	buf_free(opt);
    462 	return;
    463       }
    464 #endif /* USE_PGP */
    465     default:
    466       beep();
    467       goto select;
    468     }
    469 }
    470 
    471 #endif /* USE_NCURSES */
    472 #endif /* NYMSUPPORT */