Exemple #1
0
static int pgp_readkeyring(BUFFER *keys, char *filename)
{
  FILE *keyfile;
  BUFFER *armored, *line, *tmp;
  int err = -1;

  if ((keyfile = mix_openfile(filename, "rb")) == NULL)
    return (err);

  armored = buf_new();
  buf_read(armored, keyfile);
  fclose(keyfile);
  if (pgp_ispacket(armored)) {
    err = 0;
    buf_move(keys, armored);
  } else {
    line = buf_new();
    tmp = buf_new();

    while (1) {
      do
	if (buf_getline(armored, line) == -1) {
	  goto end_greedy_dearmor;
	}
      while (!bufleft(line, begin_pgp)) ;
      buf_clear(tmp);
      buf_cat(tmp, line);
      buf_appends(tmp, "\n");
      do {
	if (buf_getline(armored, line) == -1) {
	  goto end_greedy_dearmor;
	}
      	buf_cat(tmp, line);
      	buf_appends(tmp, "\n");
      } while (!bufleft(line, end_pgp)) ;

      if (pgp_dearmor(tmp, tmp) == 0) {
	err = ARMORED;
	buf_cat(keys, tmp);
      }
    }
end_greedy_dearmor:
    buf_free(line);
    buf_free(tmp);

  }
  buf_free(armored);
  return (err);
}
Exemple #2
0
void clienterr(BUFFER *msgbuf, char *err)
{
  if (msgbuf) {
    buf_sets(msgbuf, "Error: ");
    buf_appends(msgbuf, err);
  } else
    errlog(ERRORMSG, "%s\n", err);
}
Exemple #3
0
int pgp_latestkeys(BUFFER* outtxt, int algo)
/* returns our latest key from pgpkey.txt in the buffer outtxt
 * with pgp key header, ascii armored
 *
 * Can probably be extended to do this for all keys if we pass
 * the keyring file and the userid
 *
 * IN:  algo: PGP_ANY, PGP_ES_RSA, PGP_E_ELG, PGP_S_DSA
 * OUT: outtxt
 */
{
  int err = -1;
  long expires_found = 0, expires;
  BUFFER *key, *userid, *tmptxt;
  KEYRING *keys;

  key = buf_new();
  userid = buf_new();
  buf_sets(userid, REMAILERNAME);
  tmptxt = buf_new();

  keys = pgpdb_open(PGPKEY, NULL, 0, PGP_TYPE_PUBLIC);
  if (keys != NULL) {
    while (pgpdb_getnext(keys, key, NULL, userid) != -1) {
      buf_clear(tmptxt);
      if (pgp_makekeyheader(PGP_PUBKEY, key, tmptxt, NULL, algo) == 0) {
	buf_rewind(key);
	pgp_getkey(PK_VERIFY, algo, NULL, NULL, &expires, key, NULL, NULL, NULL, NULL);
	if (expires == 0 || (expires_found <= expires)) {
	  err = 0;
	  buf_clear(outtxt);
	  buf_appends(outtxt, "Type Bits/KeyID     Date       User ID\n");
	  buf_cat(outtxt, tmptxt);
	  buf_nl(outtxt);
	  pgp_armor(key, PGP_ARMOR_KEY);
	  buf_cat(outtxt, key);
	  buf_nl(outtxt);
	  expires_found = expires;
	}
      }
    }
    pgpdb_close(keys);
  }

  buf_free(key);
  buf_free(userid);
  buf_free(tmptxt);

  return (err);
}
Exemple #4
0
void errlog(int type, char *fmt,...)
{
  va_list args;
  BUFFER *msg;
  FILE *e = NULL;
  time_t t;
  struct tm *tc;
  char line[LINELEN];
  int p;
  char err[6][8] =
  {"", "Error", "Warning", "Notice", "Info", "Info"};

  if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
      || (type == DEBUGINFO && VERBOSE < 3))
    return;

  t = time(NULL);
  tc = localtime(&t);
  strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);

  msg = buf_new();
  buf_appends(msg, line);
  p = msg->length;
  buf_appendf(msg, "%s: [%d] ", err[type], getpid());
  va_start(args, fmt);
  buf_vappendf(msg, fmt, args);
  va_end(args);

  if (streq(ERRLOG, "stdout"))
    e = stdout;
  else if (streq(ERRLOG, "stderr"))
    e = stderr;

  if (e == NULL && (ERRLOG[0] == '\0' ||
		    (e = mix_openfile(ERRLOG, "a")) == NULL))
    mix_status("%s", msg->data + p);
  else {
    buf_write(msg, e);
    if (e != stderr && e != stdout) {
      fclose(e);
      /* duplicate the error message on screen */
      mix_status("%s", msg->data + p);
    }
  }
  buf_free(msg);
}
int menu_getuserpass(BUFFER *b, int mode)
{
#ifdef USE_NCURSES
  char p[LINELEN];

  if (menu_initialized) {
    cl(LINES - 1, 10);
    if (mode == 0)
      printw("enter passphrase: ");
    else
      printw("re-enter passphrase: ");
    wgetnstr(stdscr, p, LINELEN);
    cl(LINES - 1, 10);
    refresh();
    if (mode == 0)
      buf_appends(b, p);
    else
      return (bufeq(b, p));
    return (0);
  }
#endif /* USE_NCURSES */
  return (-1);
}
Exemple #6
0
int chain_select(int hop[], char *chainstr, int maxrem, REMAILER *remailer,
		 int type, BUFFER *feedback)
{
/* hop[] is returned containing the chain as integers (0 means random like *)
 * chainstr is the input desired chain such as *,*,*,*
 * remailer is an input list of remailer details (see mix2_rlist())
 */
  int len = 0;
  int i, j, k;
  BUFFER *chain, *selected, *addr;
  chain = buf_new();
  selected = buf_new();
  addr = buf_new();

  if (chainstr == NULL || chainstr[0] == '\0')
    buf_sets(chain, CHAIN);
  else
    buf_sets(chain, chainstr);

  /* put the chain backwards: final hop is in hop[0] */

  for (i = chain->length; i >= 0; i--)
    if (i == 0 || chain->data[i - 1] == ','
	|| chain->data[i - 1] == ';' || chain->data[i - 1] == ':') {
      for (j = i; isspace(chain->data[j]);)	/* ignore whitespace */
	j++;
      if (chain->data[j] == '\0')
	break;

      if (chain->data[j] == '*')
	k = 0;
#if 0
      else if (isdigit(chain->data[j]))
	k = atoi(chain->data + j);
#endif /* 0 */
      else {
	buf_sets(selected, chain->data + j);
	rfc822_addr(selected, addr);
	buf_clear(selected);
	buf_getline(addr, selected);
	if (!selected->length)
	  buf_sets(selected, chain->data + j);

	for (k = 0; k < maxrem; k++)
	  if (((remailer[k].flags.mix && type == 0) ||
	       (remailer[k].flags.cpunk && type == 1) ||
	       (remailer[k].flags.newnym && type == 2)) &&
	      (streq(remailer[k].name, selected->data) ||
	       strieq(remailer[k].addr, selected->data) ||
	       (selected->data[0] == '@' && strifind(remailer[k].addr,
					    selected->data))))
	    break;
      }
      if (k < 0 || k >= maxrem) {
	if (feedback != NULL) {
		buf_appendf(feedback, "No such remailer: %b", selected);
		buf_nl(feedback);
	}
#if 0
	k = 0;
#else /* end of 0 */
	len = -1;
	goto end;
#endif /* else not 0 */
      }
      hop[len++] = k;
      if (len >= 20) {          /* array passed in is has length 20 */
	if (feedback != NULL) {
		buf_appends(feedback, "Chain too long.\n");
	}
	break;
      }
      if (i > 0)
	chain->data[i - 1] = '\0';
    }
end:
  buf_free(chain);
  buf_free(selected);
  buf_free(addr);
  return len;
}
Exemple #7
0
static enum rules_token
lex_include_string(struct scanner *s, struct xkb_compose_table *table,
                   union lvalue *val_out)
{
    while (is_space(peek(s)))
        if (next(s) == '\n')
            return TOK_END_OF_LINE;

    s->token_line = s->line;
    s->token_column = s->column;
    s->buf_pos = 0;

    if (!chr(s, '\"')) {
        scanner_err(s, "include statement must be followed by a path");
        return TOK_ERROR;
    }

    while (!eof(s) && !eol(s) && peek(s) != '\"') {
        if (chr(s, '%')) {
            if (chr(s, '%')) {
                buf_append(s, '%');
            }
            else if (chr(s, 'H')) {
                const char *home = secure_getenv("HOME");
                if (!home) {
                    scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set");
                    return TOK_ERROR;
                }
                if (!buf_appends(s, home)) {
                    scanner_err(s, "include path after expanding %%H is too long");
                    return TOK_ERROR;
                }
            }
            else if (chr(s, 'L')) {
                char *path = get_locale_compose_file_path(table->locale);
                if (!path) {
                    scanner_err(s, "failed to expand %%L to the locale Compose file");
                    return TOK_ERROR;
                }
                if (!buf_appends(s, path)) {
                    free(path);
                    scanner_err(s, "include path after expanding %%L is too long");
                    return TOK_ERROR;
                }
                free(path);
            }
            else if (chr(s, 'S')) {
                const char *xlocaledir = get_xlocaledir_path();
                if (!buf_appends(s, xlocaledir)) {
                    scanner_err(s, "include path after expanding %%S is too long");
                    return TOK_ERROR;
                }
            }
            else {
                scanner_err(s, "unknown %% format (%c) in include statement", peek(s));
                return TOK_ERROR;
            }
        } else {
            buf_append(s, next(s));
        }
    }
    if (!chr(s, '\"')) {
        scanner_err(s, "unterminated include statement");
        return TOK_ERROR;
    }
    if (!buf_append(s, '\0')) {
        scanner_err(s, "include path is too long");
        return TOK_ERROR;
    }
    val_out->string.str = s->buf;
    val_out->string.len = s->buf_pos;
    return TOK_INCLUDE_STRING;
}
Exemple #8
0
int v2body(BUFFER *body)
{
  int i, n;
  BUFFER *to, *newsgroups;
  BUFFER *temp, *out;
  BUFFER *line;
  int type = MSG_MAIL;
  int subject = 0;

  line = buf_new();
  to = buf_new();
  newsgroups = buf_new();
  temp = buf_new();
  out = buf_new();

  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "null:"))
      goto end;
    if (bufileft(line, "post:")) {
      type = MSG_POST;
      if (line->length > 5) {
	int j = 5;

	while (j < line->length && isspace(line->data[j]))
	  j++;
	if (newsgroups->length > 0)
	  buf_appends(newsgroups, ",");
	buf_append(newsgroups, line->data + j, line->length - j);
      }
    } else {
      if (to->length > 0)
	buf_appends(to, ",");
      buf_cat(to, line);
    }
  }
  if (to->length > 0) {
    buf_appends(out, "To: ");
    buf_cat(out, to);
    buf_nl(out);
  }
  if (newsgroups->length > 0) {
    buf_appends(out, "Newsgroups: ");
    buf_cat(out, newsgroups);
    buf_nl(out);
  }
  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "Subject:"))
      subject = 1;
    buf_cat(out, line);
    buf_nl(out);
  }

  buf_rest(temp, body);
  buf_uncompress(temp);
  buf_set(body, temp);
  buf_reset(temp);

  if (buf_lookahead(body, line) == 0 && isline(line, HASHMARK)) {
    buf_getline(body, line);
    while (buf_getline(body, line) == 0) {
      if (bufileft(line, "subject:"))
	subject = 1;
      buf_cat(out, line);
      buf_nl(out);
    }
  }
  if (type == MSG_POST && !subject)
    buf_appends(out, "Subject: (no subject)\n");

  buf_nl(out);
  buf_rest(out, body);
  buf_reset(body);
  mix_pool(out, type, -1);

end:
  buf_free(line);
  buf_free(to);
  buf_free(newsgroups);
  buf_free(temp);
  buf_free(out);
  return (0);
}
Exemple #9
0
void menu_nym(char *nnym)
{
  char nym[maxnym][LINELEN];
  char pending[maxnym][LINELEN];
  int c, i, num = 0, numpending = 0, select = -1;
  int edit = 0;
  BUFFER *nymlist;
  int s;
  int pass = 0;
  char reliability[9]; /* When printing information about a chain,
			  this variable stores the reliability. */

  nymlist = buf_new();

  strcpy(nym[0], NONANON);
  strcatn(nym[0], " (", sizeof(nym[0]));
  strcatn(nym[0], NAME, sizeof(nym[0]));
  strcatn(nym[0], ")", sizeof(nym[0]));

  strcpy(nym[1], ANON);
  num = 2;
  if (nymlist_read(nymlist) == -1) {
    user_delpass();
    mix_status("");
  } else
    pass = 1;
  while (nymlist_get(nymlist, nym[num], NULL, NULL, NULL, NULL, NULL, &s) >= 0) {
    if (s == NYM_OK) {
      if (num < maxnym)
	num++;
    } else if (s == NYM_WAITING) {
      if (numpending < maxnym)
	strncpy(pending[numpending++], nym[num], LINELEN);
    }
  }
  buf_free(nymlist);

nymselect:
  clear();
  standout();
  printw("Select nym:\n\n");
  standend();
#ifdef USE_PGP
  if (pass)
    printw("c)reate new nym\ne)dit nym\nd)elete nym\n\n");
  else
    printw("[nym passphrase is invalid]\n\n");
#endif /* USE_PGP */
  for (i = 0; i < num; i++)
    printw("%d) %s\n", i, nym[i]);
  if (numpending > 0) {
    printw("\n\nWaiting for confirmation: ");
    for (i = 0; i < numpending; i++)
      printw("%s ", pending[i]);
    printw("\n");
  }
select:
  if (select != -1)
    printw("\r%d", select);
  else
    printw("\r          \r");
  refresh();
  c = getch();
  if (c == erasechar())
    c = KEY_BACKSPACE;
  if (c >= '0' && c <= '9') {
    if (select == -1)
      select = c - '0';
    else
      select = 10 * select + c - '0';
    if (edit ? select == 0 || select >= num + numpending - 1 : select >= num) {
      beep();
      select = -1;
    }
    refresh();
    goto select;
  } else
    switch (c) {
    case KEY_BACKSPACE:
      select /= 10;
      if (select < 1)
	select = -1;
      goto select;
    case 'q':
      if (edit) {
	edit = 0;
	select = -1;
	goto nymselect;
      }
      break;
#ifdef USE_PGP
    case 'e':
      if (pass) {
	if (edit || num + numpending < 3) {
	  edit = 0;
	  select = -1;
	  goto nymselect;
	} else {
	  clear();
	  standout();
	  printw("Edit nym:\n\n");
	  standend();
	  for (i = 2; i < num + numpending; i++)
	    printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]);
	  printw("\n");
	  select = -1;
	  edit = NYM_MODIFY;
	  goto select;
	}
      }
      break;
    case 'd':
      if (pass) {
	if (edit || num + numpending < 3) {
	  edit = 0;
	  select = -1;
	  goto nymselect;
	} else {
	  clear();
	  standout();
	  printw("Delete nym:\n\n");
	  standend();
	  for (i = 2; i < num + numpending; i++)
	    printw("%d) %s\n", i - 1, i < num ? nym[i] : pending[i - num]);
	  printw("\n");
	  select = -1;
	  edit = NYM_DELETE;
	  goto select;
	}
      }
      break;
    case '\r':
    case '\n':
      if (select == -1 || (edit && select == 0)) {
	beep();
	edit = 0;
	select = -1;
	goto nymselect;
      }
      if (!edit) {
	strncpy(nnym, nym[select], LINELEN);
	return;
      }
      /* fallthru */
    case 'c':
      if (pass) {
	char nymserv[LINELEN] = "*";
	char replyblock[5][CHAINMAX], dest[10][LINELEN];
	int latent[5], desttype[5];
	char mdest[LINELEN], pdest[LINELEN] = "alt.anonymous.messages",
	psub[LINELEN] = "";
	int deflatent = 0, defdesttype = MSG_MAIL;
	char alias[LINELEN] = "";
	BUFFER *name, *opt;
	char sendchain[CHAINMAX];
	int sendnumcopies = 1, rnum = 1;
	int i;
	char line[LINELEN];
	int acksend = 0, signsend = 0, fixedsize = 0, disable = 0,
	    fingerkey = 1;

	name = buf_new();
	opt = buf_new();
	strncpy(sendchain, CHAIN, CHAINMAX);
	strncpy(mdest, ADDRESS, LINELEN);
	if (edit)
	  strncpy(alias, select + 1 < num ? nym[select + 1] :
		  pending[select + 1 - num], LINELEN);
	if (edit == NYM_MODIFY) {
	  nymlist_getnym(alias, NULL, NULL, opt, name, NULL);
	  acksend = bufifind(opt, "+acksend");
	  signsend = bufifind(opt, "+signsend");
	  fixedsize = bufifind(opt, "+fixedsize");
	  disable = bufifind(opt, "+disable");
	  fingerkey = bufifind(opt, "+fingerkey");
	  rnum = -1;
	}
      newnym:
	if (!edit) {
	  clear();
	  standout();
	  printw("Create a nym:");
	  standend();

	  mvprintw(3, 0, "Alias address: ");
	  echo();
	  wgetnstr(stdscr, alias, LINELEN);
	  noecho();
	  if (alias[0] == '\0')
	    goto end;
	  for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ;
	  alias[i] = '\0';
	  if (i == 0)
	    goto newnym;
	  mvprintw(4, 0, "Pseudonym: ");
	  echo();
	  wgetnstr(stdscr, line, LINELEN);
	  noecho();
	  buf_sets(name, line);
	  menu_chain(nymserv, 2, 0);
	}
	if (edit != NYM_DELETE) {
	  for (i = 0; i < 5; i++) {
	    desttype[i] = defdesttype;
	    latent[i] = deflatent;
	    dest[i][0] = '\0';
	    strcpy(replyblock[i], "*,*,*,*");
	  }
	  if (rnum != -1) {
	    menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub,
			    replyblock[0]);
	    desttype[0] = defdesttype;
	    latent[0] = deflatent;
	    strncpy(dest[0], desttype[0] == MSG_POST ? pdest : mdest,
		    LINELEN);
	  }
	}
      redraw:
	clear();
	standout();
	switch (edit) {
	case NYM_DELETE:
	  printw("Delete nym:");
	  break;
	case NYM_MODIFY:
	  printw("Edit nym:");
	  break;
	default:
	  printw("Create a nym:");
	  break;
	}
	standend();
      loop:
	{
	  if (!edit) {
	    cl(2, 0);
	    printw("Nym: a)lias address: %s", alias);
	    cl(3, 0);
	    printw("     nym s)erver: %s", nymserv);
	  }
	  if (edit != NYM_DELETE) {
	    cl(4, 0);
	    printw("     p)seudonym: %s", name->data);
	    if (edit)
	      mvprintw(6, 0, "Nym modification:");
	    else
	      mvprintw(6, 0, "Nym creation:");
	  }
	  cl(7, 0);
	  chain_reliability(sendchain, 0, reliability); /* chaintype 0=mix */
	  printw("     c)hain to nym server: %-30s (reliability: %s)", sendchain, reliability);
	  cl(8, 0);
	  printw("     n)umber of redundant copies: %d", sendnumcopies);
	  if (edit != NYM_DELETE) {
	    mvprintw(10, 0, "Configuration:\n");
	    printw("     A)cknowledge sending: %s\n", acksend ? "yes" : "no");
	    printw("     S)erver signatures: %s\n", signsend ? "yes" : "no");
	    printw("     F)ixed size replies: %s\n", fixedsize ? "yes" :
		   "no");
	    printw("     D)isable: %s\n", disable ? "yes" : "no");
	    printw("     Finger K)ey: %s\n", fingerkey ? "yes" : "no");
	    mvprintw(17, 0, "Reply chains:");
	    cl(18, 0);
	    if (rnum == -1)
	      printw("     create new r)eply block");
	    else {
 	      printw("     number of r)eply chains: %2d                                     reliability", rnum);
	      for (i = 0; i < rnum; i++) {
		cl(i + 19, 0);
 		chain_reliability(replyblock[i], 1, reliability); /* 1=ek */
 		printw("     %d) %30s %-31s [%s]", i + 1,
  		       desttype[i] == MSG_NULL ?
 		       "(cover traffic)" : dest[i], replyblock[i],
 		       reliability);
	      }
	    }
	  }
	  move(LINES - 1, COLS - 1);
	  refresh();
	  c = getch();
	  if (edit != NYM_DELETE && c >= '1' && c <= '9' && c - '1' < rnum) {
	    menu_replychain(&defdesttype, &deflatent, mdest, pdest, psub,
			    replyblock[c - '1']);
	    desttype[c - '1'] = defdesttype;
	    latent[c - '1'] = deflatent;
	    strncpy(dest[c - '1'],
		    desttype[c - '1'] == MSG_POST ? pdest : mdest, LINELEN);
	    goto redraw;
	  }
	  switch (c) {
	  case 'A':
	    acksend = !acksend;
	    goto redraw;
	  case 'S':
	    signsend = !signsend;
	    goto redraw;
	  case 'F':
	    fixedsize = !fixedsize;
	    goto redraw;
	  case 'D':
	    disable = !disable;
	    goto redraw;
	  case 'K':
	    fingerkey = !fingerkey;
	    goto redraw;
	  case 'q':
	    edit = 0;
	    select = -1;
	    goto nymselect;
	  case '\014':
	    goto redraw;
	  case 'a':
	    cl(2, 0);
	    printw("Nym: a)lias address: ");
	    echo();
	    wgetnstr(stdscr, alias, LINELEN);
	    noecho();
	    for (i = 0; alias[i] > ' ' && alias[i] != '@'; i++) ;
	    alias[i] = '\0';
	    if (i == 0)
	      goto nymselect;
	    goto redraw;
	  case 'p':
	    cl(4, 0);
	    printw("     p)seudonym: ");
	    echo();
	    wgetnstr(stdscr, line, LINELEN);
	    noecho();
	    if (line[0] != '\0')
	      buf_sets(name, line);
	    goto redraw;
	  case 'c':
	    menu_chain(sendchain, 0, 0);
	    goto redraw;
	  case 'n':
	    cl(8, 0);
	    printw("     n)umber of redundant copies: ");
	    echo();
	    wgetnstr(stdscr, line, LINELEN);
	    noecho();
	    sendnumcopies = strtol(line, NULL, 10);
	    if (sendnumcopies < 1 || sendnumcopies > 10)
	      sendnumcopies = 1;
	    goto redraw;
	  case 'r':
	    cl(18, 0);
	    printw("     number of r)eply chains: ");
	    echo();
	    wgetnstr(stdscr, line, LINELEN);
	    noecho();
	    i = rnum;
	    rnum = strtol(line, NULL, 10);
	    if (rnum < 1)
	      rnum = 1;
	    if (rnum > 5)
	      rnum = 5;
	    for (; i < rnum; i++)
	      if (dest[i][0] == '\0') {
		desttype[i] = defdesttype;
		latent[i] = deflatent;
		strncpy(dest[i], defdesttype == MSG_POST ? pdest :
			mdest, LINELEN);
	      }
	    goto redraw;
	  case 's':
	    menu_chain(nymserv, 2, 0);
	    goto redraw;
	  case '\n':
	  case '\r':
	    {
	      BUFFER *chains;
	      int err;

	      if (rnum == -1)
		chains = NULL;
	      else {
		chains = buf_new();
		for (i = 0; i < rnum; i++)
		  if (replyblock[i][0] != '\0') {
		    if (desttype[i] == MSG_POST)
		      buf_appendf(chains, "Subject: %s\n", psub);
		    if (desttype[i] == MSG_MAIL)
		      buf_appends(chains, "To: ");
		    else if (desttype[i] == MSG_POST)
		      buf_appends(chains, "Newsgroups: ");
		    else
		      buf_appends(chains, "Null:");
		    buf_appendf(chains, "%s\n", dest[i]);
		    buf_appendf(chains, "Chain: %s\n", replyblock[i]);
		    buf_appendf(chains, "Latency: %d\n\n", latent[i]);
		  }
	      }
	    create:
	      clear();
	      buf_setf(opt,
		       " %cacksend %csignsend +cryptrecv %cfixedsize %cdisable %cfingerkey",
		       acksend ? '+' : '-',
		       signsend ? '+' : '-',
		       fixedsize ? '+' : '-',
		       disable ? '+' : '-',
		       fingerkey ? '+' : '-');
	      if (edit) {
		mix_status("Preparing nymserver configuration message...");
		err = nym_config(edit, alias, NULL,
				 name, sendchain, sendnumcopies,
				 chains, opt);
	      } else {
		mix_status("Preparing nym creation request...");
		err = nym_config(edit, alias, nymserv, name,
				 sendchain, sendnumcopies, chains,
				 opt);
	      }
	      if (err == -3) {
		beep();
		mix_status("Bad passphrase!");
		getch();
		goto create;
	      }
	      if (err != 0) {
		mix_genericerror();
		beep();
		refresh();
	      } else {
		if (edit)
		  mix_status("Nymserver configuration message completed.");
		else
		  mix_status("Nym creation request completed.");
	      }
	      if (chains)
		buf_free(chains);
	      goto end;
	    }
	  default:
	    beep();
	    goto loop;
	  }
	}
      end:
	buf_free(name);
	buf_free(opt);
	return;
      }
#endif /* USE_PGP */
    default:
      beep();
      goto select;
    }
}
Exemple #10
0
int pgp_keymgt(int force)
{
  FILE *f = NULL;
  BUFFER *key, *keybak, *userid, *out, *outkey, *outtxt, *pass, *secout;
  KEYRING *keys;
  int err = 0, res, recreate_pubring = 0, dsa_ok = 0;
#ifdef USE_IDEA
  int rsa_ok = 0;
#endif /* USE_IDEA */
  long expires;
  LOCK *seclock;

  key = buf_new();
  out = buf_new();
  keybak = buf_new();
  secout = buf_new();

  userid = buf_new();
  buf_sets(userid, REMAILERNAME);
  pass = buf_new();
  buf_sets(pass, PASSPHRASE);
  outtxt = buf_new();
  outkey = buf_new();

  /* We only want to build RSA keys if we also can do IDEA
   * This is to not lose any mail should users try our RSA key
   * with IDEA.
   */
#ifdef USE_IDEA
  /* FIXME: pgpdb_getky returns the expiration date from the last key in the keyring
   *        which probably works most of the time if the keys are in the correct order
   *        it doesn't return the latest expiration date (or 0) if the key in question
   *        is before another matching key in the keyring tho
   */
  res = pgpdb_getkey(PK_DECRYPT, PGP_ES_RSA, NULL, NULL, &expires, NULL, NULL,
				  NULL, NULL, NULL, pass);
  if (force == 2 || res < 0 || (expires > 0 && expires - KEYOVERLAPPERIOD < time(NULL))) {
    rsa_ok = -1;
    pgp_keygen(PGP_ES_RSA, 0, userid, pass, PGPKEY, PGPREMSECRING, 0);
  };

  if (force == 0 && (pgpdb_getkey(PK_ENCRYPT, PGP_ES_RSA, NULL, NULL, NULL, NULL, NULL,
				  NULL, NULL, PGPKEY, NULL) < 0) && rsa_ok == 0)
    rsa_ok = 1;
#endif /* USE_IDEA */
  /* FIXME: pgpdb_getky returns the expiration date from the last key in the keyring
   *        which probably works most of the time if the keys are in the correct order
   *        it doesn't return the latest expiration date (or 0) if the key in question
   *        is before another matching key in the keyring tho
   */
  res = pgpdb_getkey(PK_DECRYPT, PGP_E_ELG, NULL, NULL, &expires, NULL, NULL,
				  NULL, NULL, NULL, pass);
  if (force == 2 || res < 0 || (expires > 0 && expires - KEYOVERLAPPERIOD < time(NULL))) {
    dsa_ok = -1;
    pgp_keygen(PGP_E_ELG, 0, userid, pass, PGPKEY, PGPREMSECRING, 0);
  }

  if (force == 0 && (pgpdb_getkey(PK_ENCRYPT, PGP_E_ELG, NULL, NULL, NULL, NULL, NULL,
				  NULL, NULL, PGPKEY, NULL) > 0) && dsa_ok == 0)
    dsa_ok = 1;

  /* No need to rewrite the files - we didn't change a thing */
  if (
#ifdef USE_IDEA
      rsa_ok == 1 &&
#endif /* USE_IDEA */
      dsa_ok == 1)
    goto end;

  /* write keys one key per armor to make hand editing easy and old PGP
   * versions happy */
  err = -1;
  keys = pgpdb_open(PGPKEY, NULL, 0, PGP_TYPE_PUBLIC);
  if (keys == NULL)
    recreate_pubring = 1;
  else {
    while (pgpdb_getnext(keys, key, NULL, userid) != -1) {
      buf_clear(outtxt);
      if (pgp_makekeyheader(PGP_PUBKEY, key, outtxt, NULL, PGP_ANY) == 0) {
	err = 0;
	buf_appends(out, "Type Bits/KeyID     Date       User ID\n");
	buf_cat(out, outtxt);
	buf_nl(out);
	pgp_armor(key, PGP_ARMOR_KEY);
	buf_cat(out, key);
	buf_nl(out);
      }
    }
    pgpdb_close(keys);
  }
  if (err != 0)
    recreate_pubring = 1;
  err = -1;

  keys = pgpdb_open(PGPREMSECRING, NULL, 0, PGP_TYPE_PRIVATE);
  if (keys == NULL)
    goto end;
  while (pgpdb_getnext(keys, key, NULL, userid) != -1) {
    buf_clear(outtxt);
    buf_clear(outkey);
    buf_clear(keybak);
    buf_cat(keybak, key);
    if (pgp_makekeyheader(PGP_SECKEY, key, outtxt, pass, PGP_ANY) == 0) {
      err = 0;
      buf_appends(secout, "Type Bits/KeyID     Date       User ID\n");
      buf_cat(secout, outtxt);
      buf_nl(secout);
      pgp_armor(key, PGP_ARMOR_SECKEY);
      buf_cat(secout, key);
      buf_nl(secout);
    }
    buf_clear(outtxt);
    if (recreate_pubring &&
	pgp_makepubkey(keybak, outtxt, outkey, pass, PGP_ANY) == 0) {
      buf_appends(out, "Type Bits/KeyID     Date       User ID\n");
      buf_cat(out, outtxt);
      buf_nl(out);
      pgp_armor(outkey, PGP_ARMOR_KEY);
      buf_cat(out, outkey);
      buf_nl(out);
    }
  }
  pgpdb_close(keys);

  seclock = lockfile(PGPREMSECRING);
  if (err == 0 && (f = mix_openfile(PGPREMSECRING, "w")) != NULL) {
    buf_write(secout, f);
    fclose(f);
  } else
    err = -1;
  unlockfile(seclock);
  if (err == 0 && (f = mix_openfile(PGPKEY, "w")) != NULL) {
    buf_write(out, f);
    fclose(f);
  } else
    err = -1;
end:
  buf_free(key);
  buf_free(keybak);
  buf_free(out);
  buf_free(userid);
  buf_free(pass);
  buf_free(outtxt);
  buf_free(outkey);
  buf_free(secout);
  return (err);
}
Exemple #11
0
int t1_encrypt(int type, BUFFER *message, char *chainstr, int latency,
	       BUFFER *ek, BUFFER *feedback)
{
  BUFFER *b, *rem, *dest, *line, *field, *content;
  REMAILER remailer[MAXREM];
  int badchains[MAXREM][MAXREM];
  int maxrem, chainlen = 0;
  int chain[20];
  int hop;
  int hashmark = 0;
  int err = 0;

  b = buf_new();
  rem = buf_new();
  dest = buf_new();
  line = buf_new();
  field = buf_new();
  content = buf_new();

  maxrem = t1_rlist(remailer, badchains);
  if (maxrem < 1) {
    clienterr(feedback, "No remailer list!");
    err = -1;
    goto end;
  }
  chainlen = chain_select(chain, chainstr, maxrem, remailer, 1, line);
  if (chainlen < 1) {
    if (line->length)
      clienterr(feedback, line->data);
    else
      clienterr(feedback, "Invalid remailer chain!");
    err = -1;
    goto end;
  }
  if (chain[0] == 0)
    chain[0] = chain_randfinal(type, remailer, badchains, maxrem, 1, chain, chainlen, 0);

  if (chain[0] == -1) {
    clienterr(feedback, "Invalid remailer chain!");
    err = -1;
    goto end;
  }
  if (chain_rand(remailer, badchains, maxrem, chain, chainlen, 1, 0) == -1) {
    clienterr(feedback, "No reliable remailers!");
    err = -1;
    goto end;
  }
  while (buf_getheader(message, field, content) == 0) {
    hdr_encode(content, 0);
    if (type == MSG_POST && bufieq(field, "newsgroups") &&
	remailer[chain[0]].flags.post) {
      buf_appendf(dest, "Anon-Post-To: %b\n", content);
    } else if (type == MSG_MAIL && bufieq(field, "to")) {
      buf_appendf(dest, "Anon-To: %b\n", content);
    } else {
      /* paste header */
      if (type == MSG_POST && bufieq(field, "newsgroups"))
	buf_appendf(dest, "Anon-To: %s\n", MAILtoNEWS);
      if (hashmark == 0) {
	buf_appends(b, "##\n");
	hashmark = 1;
      }
      buf_appendheader(b, field, content);
    }
  }
  buf_nl(b);
  buf_rest(b, message);
  buf_move(message, b);

  if (type != MSG_NULL && dest->length == 0) {
    clienterr(feedback, "No destination address!");
    err = -1;
    goto end;
  }
  if (type == MSG_NULL) {
    buf_sets(dest, "Null:\n");
  }
  for (hop = 0; hop < chainlen; hop++) {
    if (hop == 0) {
      buf_sets(b, "::\n");
      buf_cat(b, dest);
    } else {
      buf_sets(b, "::\nAnon-To: ");
      buf_appends(b, remailer[chain[hop - 1]].addr);
      buf_nl(b);
    }
    if (remailer[chain[hop]].flags.latent && latency > 0)
      buf_appendf(b, "Latent-Time: +%d:00r\n", latency);
    if (ek && remailer[chain[hop]].flags.ek) {
      t1_ek(line, ek, hop);
      buf_appendf(b, "Encrypt-Key: %b\n", line);
    }
    buf_nl(b);
    buf_cat(b, message);
#ifdef USE_PGP
    if (remailer[chain[hop]].flags.pgp) {
      buf_clear(message);
      buf_clear(rem);
      buf_setf(rem, "<%s>", remailer[chain[hop]].addr);
      err = pgp_encrypt(PGP_ENCRYPT | PGP_REMAIL | PGP_TEXT, b, rem,
			NULL, NULL, NULL, NULL);
      if (err < 0) {
	buf_setf(line, "No PGP key for remailer %s!\n",
		 remailer[chain[hop]].name);
	clienterr(feedback, line->data);
	goto end;
      }
      buf_appends(message, "::\nEncrypted: PGP\n\n");
      buf_cat(message, b);
    } else
#endif /* USE_PGP */
    {
      if (remailer[chain[hop]].flags.pgponly) {
	buf_setf(line, "PGP encryption needed for remailer %s!\n",
		 remailer[chain[hop]].name);
	clienterr(feedback, line->data);
	goto end;
      }
      buf_move(message, b);
    }
    if (ek && remailer[chain[hop]].flags.ek)
      buf_appends(message, "\n**\n");
  }
  buf_clear(b);
  if (chainlen == 0) {
    buf_appends(b, "::\n");
    buf_cat(b, dest);
  } else {
    buf_appendf(b, "%s: %s\n", ek ? "::\nAnon-To" : "To",
		remailer[chain[chainlen - 1]].addr);
  }
  buf_nl(b);
  buf_cat(b, message);
  buf_move(message, b);
end:
  buf_free(b);
  buf_free(rem);
  buf_free(dest);
  buf_free(line);
  buf_free(field);
  buf_free(content);
  return (err);
}