Exemplo n.º 1
0
u_char
cisco_decrypt(void)
{
     u_char retval;
     time_t start, stop;

     tty_init();
     time(&start);

     /* check if the arg is a valid md5 cisco IOS password */
     if (cisco_is_ios_md5crypt(usr_opt.decryptopt.cipher))
          cipher_engine = cisco_ios_cipher;
     /* check if the arg is a valid md5 PIX password */
     else if (cisco_is_pix_md5crypt(usr_opt.decryptopt.cipher))
          cipher_engine = cisco_pix_cipher;
     else
          tty_error(ERR_USAGE,
                    "neither a Cisco IOS nor a PIX password -- `%s'",
                    usr_opt.decryptopt.cipher);

     retval = (usr_opt.action == decrypt_wl || usr_opt.action == resume_wl) ?
              wordlist() : bruteforce();
     time(&stop);

     if (usr_opt.verbose)
          tty_message("scan time: %g second(s)\n\n", difftime(stop, start));

     return retval;
}
Exemplo n.º 2
0
static void opt_check(int * opt_set)
{
/* *INDENT-OFF* */
/* error table (0 means `ok', 1 means `illegal option pair')
 */
     static const char *opt_table[] = {
          /*       csedypbwlDrLhqvV                */
          /* c */ "",                /* crypt-ios  */
          /* s */ "0",               /* salt       */
          /* e */ "01",              /* egd        */
          /* d */ "011",             /* dev-random */
          /* y */ "0111",            /* sys-rand   */
          /* p */ "11111",           /* crypt-pix  */
          /* b */ "111111",          /* bruteforce */
          /* w */ "1111111",         /* dictionary */
          /* l */ "11111100",        /* length     */
          /* D */ "111111000",       /* daemonize  */
          /* r */ "1111111110",      /* restore    */
          /* L */ "11111111111",     /* license    */
          /* h */ "111111111111",    /* help       */
          /* q */ "0000000001011",   /* quiet      */
          /* v */ "00000000010111",  /* verbose    */
          /* V */ "111111111111111"  /* version    */
     };
/* *INDENT-ON* */

     int row, col;

     for (row = 0; row < opt_last; row++) {
          /* the matrix `opt_table' is symmetric */
          for (col = 0; col < row; col++) {
               if (*(opt_table[row] + col) == '1'
                   && opt_set[row] && opt_set[col])
                    tty_error(ERR_USAGE,
                              "`%s' and `%s' belong to different contexts",
                              longopts[row].name, longopts[col].name);
          }
     }
}
Exemplo n.º 3
0
Arquivo: tty.c Projeto: fdomig/ottos
void tty_run() {

  // FIXME
  tty_cwd = malloc(sizeof(char) * MAX_PATH_LENGTH);

  tty_print_startup();

  while (TRUE) {
    // XXX: how do we ensure, we do not read more than 1025 characters?
    char line[MAX_PATH_LENGTH + 1] = { '\0' };

    char* tokens;
    char cmd[64];
    int rc;
    BOOLEAN background = FALSE;

    // print prefix
    tty_print_prefix();

    // read one line
    // TODO ([email protected]) read from serial device
    // this has to be a system call in the end since we move this to
    // a user mode application
    // rc = scanf("%1024[^\n]%*[^\n]", line);
    // rc = serial_getline(line, 1024);
    // print("command: ");
    rc = tty_getline(line, MAX_PATH_LENGTH);
    if (rc <= 1) {
      print("\r");
      continue;
    }
    print("\r\n");
//    print("your command: ");
//
//    line[MAX_PATH_LENGTH] = 0;
//    print(line);
//    print("\r\n");
    //    if (rc == EOF) {
    //      // TODO ([email protected]) line was already at EOF while trying to get
    //      // the first character
    //    } else if (rc == 0) {
    //      // TODO ([email protected]) the user entered an empty line
    //    }

    // TODO ([email protected]) getchar(), feof() and ferror() have to be
    // changed to use our serial device - I have no idea how to do that
    // in the end we need a system call to get this done since we need to
    // move the TTY to the user space
    //if (!feof(stdin) && !ferror(stdin)) getchar();

    // split input string into tokens
    tokens = strtok(line, SPLIT_CHARS);
    strcpy(cmd, tokens);
    //cmd = tokens;
    //tokens = strtok(NULL, SPLIT_CHARS);

    // XXX: built in CMDs are for test only; later each built in CMD will get
    // an own binary file

    //    // check for a built in command
    //    if (strcmp(cmd, "cd") == 0) {
    //      tty_cmd_cd(tokens);
    //
    //    } else if (strcmp(cmd, "pwd") == 0) {
    //      tty_cmd_pwd();
    //
    //    } else if (strcmp(cmd, "ls") == 0) {
    //      tty_cmd_ls(tokens);
    //
    //    } else if (strcmp(cmd, "cat") == 0) {
    //      tty_cmd_cat(tokens);
    //
    //      // finally, is there a application with the entered name?
    //    } else

    // TODO if there is a & at the end of the command, the tty_find_binary returns false
        // run a new process
        if (cmd[strlen(cmd) - 1] == START_IN_BACKGROUND_SYSMBOL) {
          background = TRUE;
          cmd[strlen(cmd) -1] = '\0';
        }

    if (!tty_find_binary(cmd)) {
      char* debug = malloc(sizeof(char) * 256);
      sprintf(debug, "%s command not found", line);
      tty_error(debug);
      free(debug);
      continue;
    }


    {
      char* tmp_cmd = NULL;
      tmp_cmd = malloc(sizeof(char) * (strlen(cmd) + strlen(BIN_DIRECTORY) + 1));
      sprintf(tmp_cmd, "%s/%s", BIN_DIRECTORY, cmd);
      tty_start_process(tmp_cmd, tokens, background);
      free(tmp_cmd);
    }
  }
}
Exemplo n.º 4
0
static u_char
bruteforce(void)
{
     u_char salt[MD5_SALT_SIZE], *plaintext;
#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
     char ch;
#endif
     char **alphabet;
     int *chposi, *vsize, i, j;
#if defined (HAVE_WORKING_FORK)
     FILE *fout;
#endif

     /* initialize data */
     strncpy((char *) salt,
             (char *) (usr_opt.decryptopt.cipher + MD5_MAGIC_SIZE),
             MD5_SALT_SIZE);

     plaintext = zmem_alloc(MAX_PLAIN_SIZE + 1);
     if (usr_opt.action != resume_bf)
          chpos = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*chpos));
     chpos_safe = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*chpos_safe));
     vsize = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*vsize));

     /* set the alphabet(s) used reading/parsing the relate argv */
     alphabet = zmem_alloc(MAX_PLAIN_SIZE * sizeof(*alphabet));

     /* option `-b' with no `regexpr' set */
     if (!usr_opt.decryptopt.regexpr)
          usr_opt.decryptopt.regexpr = str_alloc_copy(ALPHABET_FULL);

     regex_explode(alphabet, usr_opt.decryptopt.regexpr,
                   &usr_opt.decryptopt.fromlen, &usr_opt.decryptopt.tolen);

     if (usr_opt.action == resume_bf) {
          for (i = 0; i < usr_opt.decryptopt.tolen; i++) {
               vsize[i] = strlen(alphabet[i]);
               if (chpos[i] > vsize[i])
                    tty_error(ERR_INFO_RFILE,
                              "illegal `chpos' value load from restore file");
          }

          /* no errors in the restore file, so it can be safely removed here */
          if (remove(usr_opt.decryptopt.restore_file) == -1)
               tty_warning("cannot remove the file `%s'",
                            usr_opt.decryptopt.restore_file);
     } else {
          actual_len = usr_opt.decryptopt.fromlen;
          for (i = 0; i < usr_opt.decryptopt.tolen; i++) {
               chpos[i] = chpos_safe[i] = 0;
               vsize[i] = strlen(alphabet[i]);
          }
     }

     if (usr_opt.verbose) {
          /* some infos, just to let the user check the input entered */
          tty_message("trying to crack   : \"%s\"\n"
                      "method used       : bruteforce\n"
                      "password scheme   : ",
                      usr_opt.decryptopt.cipher);

          tty_message("%s %s\n", usr_opt.decryptopt.regexpr,
                      !strcmp(usr_opt.decryptopt.regexpr, ALPHABET_FULL) ?
                      "(full search)" : "");
          if (usr_opt.verbose > 2) {
               tty_message("expanded password scheme :\n");
               i = 0;
               while (i < usr_opt.decryptopt.tolen) {
                    for (j = i + 1;
                         j < usr_opt.decryptopt.tolen &&
                         alphabet[j] == alphabet[i]; j++);
                    if (j - 1 > i) {
                         tty_message("   p[%d..%d] = \"%s\"\n",
                                     i, j - 1, alphabet[i]);
                         i = j;
                    } else {
                         tty_message("   p[%d] = \"%s\"\n", i, alphabet[i]);
                         i++;
                    }
               }
          }

          tty_message("length of strings : ");
          if (usr_opt.decryptopt.fromlen !=
              usr_opt.decryptopt.tolen)
               tty_message("[%d..%d]\n",
                           usr_opt.decryptopt.fromlen,
                           usr_opt.decryptopt.tolen);
          else
               tty_message("%d\n", usr_opt.decryptopt.fromlen);

          if (usr_opt.action == resume_bf)
               tty_message("\nrestoring session stopped on %s\n",
                           usr_opt.decryptopt.saved_date);

          tty_message("\nplease wait... ");

#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
          tty_message("\n[type <ENTER> to display the current plaintext] ");
#endif
     }

     /* initialize the first plaintext to be used */
     for (i = 0; i < actual_len; i++)
          plaintext[i] = alphabet[i][chpos[i]];

     while (1) {
#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
          if (read(tty_fd, &ch, 1) > 0 && usr_opt.verbose)
               tty_message("%s", plaintext);
#endif
#if 0
          /* begin of DEBUG CODE */
          fprintf(stderr, "\n%s\n", plaintext);
          for (i = 0; i < usr_opt.decryptopt.tolen; i++)
               fprintf(stderr, "chpos[%d] = %d\n", i, chpos[i]);
          fflush(stderr);
          /* end of DEBUG CODE */
#endif

          if (!strcmp((cipher_engine == cisco_ios_cipher ?
                      cisco_ios_crypt(plaintext, salt) :
                      cisco_pix_crypt(plaintext)) + MD5_PREAMBLE_SIZE,
                      (char *) (usr_opt.decryptopt.cipher +
                                MD5_PREAMBLE_SIZE))) {
#if defined(HAVE_WORKING_FORK)
               if (usr_opt.daemonize) {
                    if ((fout = fopen(SCORE_FILE, "a"))) {
                         fprintf(fout, "** FOUND: \"%s\" (%s)\n",
                                 plaintext, usr_opt.decryptopt.cipher);
                         fclose(fout);
                    }
               }
               else
#endif
                    tty_message(usr_opt.verbose ?
                                "\n** FOUND: \"%s\"\n" : "%s\n", plaintext);
               i = 0;
               while (i < actual_len) {
                    mem_free(alphabet[i++]);
                    /* skip the duplicates alphabets */
                    while (alphabet[i] == alphabet[i - 1])
                         i++;
               }
               return SUCCESS;
          }

          /* if `++chpos[i] % vsize[i]' is zero then all the letters of
           * `alphabet[i]' has been checked, so skip to the previous
           * letter (`i--') of `plaintext'
           */
          i = 0;
          memcpy(chpos_safe, chpos, MAX_PLAIN_SIZE * sizeof(*chpos_safe));
          do {
               chposi = chpos + i;
               *chposi = ++(*chposi) % vsize[i];
               plaintext[i] = alphabet[i][*chposi];
          } while (++i != actual_len && !*chposi);

          if (i == actual_len && !chpos[actual_len - 1]) {
               if (actual_len++ == usr_opt.decryptopt.tolen) {
#if defined (HAVE_WORKING_FORK)
                    if (usr_opt.daemonize) {
                         if ((fout = fopen(SCORE_FILE, "a"))) {
                              fprintf(fout,
                                      "** FAILURE: (%s)\n"
                                      "   password scheme   : %s\n"
                                      "   length of strings : [%d..%d]\n",
                                      usr_opt.decryptopt.cipher,
                                      usr_opt.decryptopt.regexpr,
                                      usr_opt.decryptopt.fromlen,
                                      usr_opt.decryptopt.tolen);
                              fclose(fout);
                         }
                    }
                    else
#endif
                         tty_message("\n** FAILURE: the cipher string doesn't "
                                     "match the password scheme you set\n");
                    i = 0;
                    while (i < actual_len) {
                         mem_free(alphabet[i++]);
                         /* skip the duplicates alphabets */
                         while (alphabet[i] == alphabet[i - 1])
                              i++;
                    }
                    return FAILURE;
               }
               tty_message("\n** NOTE: switching to lenght `%ld', "
                           "please wait... ", actual_len);
               plaintext[actual_len - 1] = alphabet[actual_len - 1][0];
          }
     }
}
Exemplo n.º 5
0
static u_char
wordlist(void)
{
     FILE *wfile;
#if defined (HAVE_WORKING_FORK)
     FILE *fout;
#endif
     u_char salt[MD5_SALT_SIZE], len;
#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
     char ch;
#endif
     bool seekpoint_found = false;

     if ((wfile = fopen(usr_opt.decryptopt.wordlist, "rt")) == NULL)
          tty_error(ERR_IO_FILE,
                    "error opening `%s' : %s",
                    usr_opt.decryptopt.wordlist, strerror(errno));

     strncpy((char *) salt,
             (char *) (usr_opt.decryptopt.cipher + MD5_MAGIC_SIZE),
             MD5_SALT_SIZE);

     if (usr_opt.action != resume_wl) {
          if (!usr_opt.decryptopt.fromlen)   /* not set by the user */
               usr_opt.decryptopt.fromlen++;
          if (!usr_opt.decryptopt.tolen)     /* not set by the user */
               usr_opt.decryptopt.tolen = MAX_PLAIN_SIZE;
     }

     if (usr_opt.verbose) {
          /* some infos, just to let the user check the input entered */
          tty_message("trying to crack   : \"%s\"\n"
                      "method used       : dictionary\n"
                      "wordlist          : %s\n",
                      usr_opt.decryptopt.cipher,
                      usr_opt.decryptopt.wordlist);

          tty_message("length of strings : ");
          if (usr_opt.decryptopt.fromlen != usr_opt.decryptopt.tolen)
               tty_message("[%d..%d]\n",
                           usr_opt.decryptopt.fromlen,
                           usr_opt.decryptopt.tolen);
          else
               tty_message("%d\n", usr_opt.decryptopt.fromlen);

          if (usr_opt.action == resume_wl)
               tty_message("\nrestoring session stopped on %s\n",
                           usr_opt.decryptopt.saved_date);

          tty_message("\nplease wait ... ");
#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
          tty_message("\n[type <ENTER> to dispay the current plaintext used] ");
#endif
     }

     while (fgets(wbuf, FLINE_BUFSIZE, wfile) != NULL) {
          /* strip the trail character `\n' */
          if (wbuf[(len = strlen(wbuf)) - 1] == '\n')
               wbuf[--len] = '\0';

          /* switch to `seekpoint', if the action is `restore_wf' */
          if (!seekpoint_found && (usr_opt.action == resume_wl)
               && strcmp(seekpoint, wbuf))
               continue;
          else
               seekpoint_found = true;

          if (len < usr_opt.decryptopt.fromlen ||
              len > usr_opt.decryptopt.tolen)
               continue;        /* wrong range for length */

#if defined(HAVE_TERMIOS_H) && defined(HAVE_DEV_TTY)
          if (read(tty_fd, &ch, 1) > 0 && usr_opt.verbose)
               tty_message("%s", wbuf);
#endif
          if (!strcmp((cipher_engine == cisco_ios_cipher ?
                      cisco_ios_crypt((u_char *) wbuf, salt) :
                      cisco_pix_crypt((u_char *) wbuf)) + MD5_PREAMBLE_SIZE,
                      (char *) (usr_opt.decryptopt.cipher +
                                MD5_PREAMBLE_SIZE))) {

#if defined (HAVE_WORKING_FORK)
               if (usr_opt.daemonize) {
                    if ((fout = fopen(SCORE_FILE, "a"))) {
                         fprintf(fout, "** FOUND: \"%s\" (%s)\n",
                                 wbuf, usr_opt.decryptopt.cipher);
                         fclose(fout);
                    }
               }
               else
#endif
                    tty_message(usr_opt.verbose ?
                                "\n\n** FOUND: \"%s\"\n" : "%s\n", wbuf);

               return SUCCESS;
          }
     }
     fclose(wfile);

#if defined (HAVE_WORKING_FORK)
     if (usr_opt.daemonize) {
          if ((fout = fopen(SCORE_FILE, "a"))) {
               fprintf(fout,
                       "** FAILURE: (%s)\n"
                       "   dictionary used   : %s\n"
                       "   length of strings : [%d..%d]\n",
                       usr_opt.decryptopt.cipher,
                       usr_opt.decryptopt.wordlist,
                       usr_opt.decryptopt.fromlen,
                       usr_opt.decryptopt.tolen);
               fclose(fout);
          }
     }
     else
#endif
          tty_message("\n\n"
                      "** FAILURE: no match found in the dictionary selected\n"
                      "please, use another dictionary or choose the "
                      "bruteforce attack.\n");
     return FAILURE;
}
Exemplo n.º 6
0
int
main(int argc, char **argv)
{
     int i, retval = SUCCESS;
#if defined (HAVE_WORKING_FORK)
     pid_t cpid;
     FILE *fscore;
#endif

#if defined (HAVE_ASSERT_H) && defined (SHORT_PASSWORDS)
     assert(MAX_PLAIN_SIZE < 16);
#endif

     /* set the default values for `usr_opt' */
     memset(&usr_opt, 0, sizeof(usr_opt));
     usr_opt.verbose = 1;
#if defined (DEV_RANDOM_SUPPORT)
     usr_opt.cryptopt.get_entropy = get_dev_entropy;
#elif defined (EGD_SUPPORT)
     usr_opt.cryptopt.get_entropy = get_egd_entropy;
#else
     usr_opt.cryptopt.get_entropy = get_sys_entropy;
#endif

     opt_parse(argc, argv, &usr_opt);

#if defined (HAVE_UMASK)
     /* set umask for security reasons */
     umask(0077);
#endif

     switch (usr_opt.action) {
     case crypt_ios:
     case crypt_pix:
          if (argc != optind + 1)
               tty_error(ERR_USAGE, "no string to crypt");
          usr_opt.cryptopt.plain = (u_char *) str_alloc_copy(argv[optind]);

          retval = (usr_opt.action == crypt_ios) ?
                    crypt_ios_fe(usr_opt.cryptopt.plain,
                                 usr_opt.cryptopt.salt) :
                    crypt_pix_fe(usr_opt.cryptopt.plain);
          break;
     case decrypt_bf:
     case decrypt_wl:
          if (argc != optind + 1)
               tty_error(ERR_USAGE, "no password to decrypt");
          usr_opt.decryptopt.cipher = (u_char *) str_alloc_copy(argv[optind]);
          /* no break here! */
     case resume:
          /* if `decrypt_bf', `decrypt_wl', `resume_bf', `resume_wl',
           * create the restore file in case of an abort event
           */
          save_session_if_signal_abort = true;

          if (usr_opt.action == resume) {
               if (argc != optind)
                    tty_error(ERR_USAGE,
                              "bad argument found `%s'", argv[optind]);

               session_load(usr_opt.decryptopt.restore_file);

               /* `usr_opt.decryptopt.regexpr' can be NULL,
                *  so we must check `usr_opt.decryptopt.wordlist' */
               usr_opt.action =
                    usr_opt.decryptopt.wordlist ? resume_wl: resume_bf;
          }

#if defined (HAVE_WORKING_FORK)
          if (usr_opt.daemonize) {
               cpid = fork();
               if (cpid == (pid_t) 0) {   /* child process */
                    /* checks the SCORE_FILE format */
                    fcheck(SCORE_FILE, HEAD_SCORE_TEXT);

                    /* add the line `HEAD_SCORE_TEXT"\n"' at the begin,
                     * if the file do not exists */
                    if (!(fscore = fopen(SCORE_FILE, "r"))) {
                         fscore = fopen(SCORE_FILE, "w");
                         fprintf(fscore, HEAD_SCORE_TEXT"\n");
                    }
                    fclose(fscore);
                    tty_message
                        ("%s -- running in daemon mode"
#if defined (HAVE_GETPID)
                         " [pid: %d]"
#endif
                         "...\n** WARNING: "
                         "sensible data could be written in the file `%s'!\n",
                         *argv,
#if defined (HAVE_GETPID)
                         (int) getpid(),
#endif
                         SCORE_FILE);
                    /* point stdin/stdout/stderr to /dev/null */
                    for (i = 0; i < 3; i++)
                         close(i);
                    i = open(NULL_DEV, O_RDWR);
                    if (i >= 0) {
                         dup2(i, 0);
                         dup2(i, 1);
                         dup2(i, 2);
                         if (i > 2)
                              close(i);
                    }
                    retval = cisco_decrypt();
                    return retval;
               } else if (cpid < (pid_t) 0)
                    tty_error(ERR_FORKING,
                              "cannot run in daemon mode : %s",
                              strerror(errno));
               else
                    return SUCCESS;     /* parent process */
          } else
#endif
               retval = cisco_decrypt();
          break;
     default:                  /* not enought paramethers entered */
          tty_error(ERR_USAGE, "nothing to do (?)");
     }

     mem_free_all();
     return retval;
}
Exemplo n.º 7
0
static void
opt_parse(int argc, char **argv, t_options *opt)
{
     int argval, n, opt_set[opt_last];

     /* initialize `opt_set' with the value 0 (option not used) */
     for (n = 0; n < opt_last; n++)
          opt_set[n] = opt_unset;

     /* process the options */
     opterr = 0;
     while (1) {
          argval = getopt_long(argc, argv, optstring, longopts, NULL);
          if (argval == -1)
               break;

          switch (argval) {
          case 0:
               break;
          case 'c':
               opt_set[opt_c]++;
               opt->action = crypt_ios;
               break;
          case 's':            /* set the salt string (4 character long) */
               opt_set[opt_s]++;
               opt->action = crypt_ios;
               if (strlen(optarg) != MD5_SALT_SIZE)
                    tty_error(ERR_USAGE,
                              "bad length (not %d bytes) for salt `%s'",
                              MD5_SALT_SIZE, optarg);
               opt->cryptopt.salt = (u_char *) str_alloc_copy(optarg);
               break;
#ifdef EGD_SUPPORT
          case 'e':
               opt_set[opt_e]++;
               opt->cryptopt.get_entropy = get_egd_entropy;
               if (optarg)
                    opt->cryptopt.egd_path = str_alloc_copy(optarg);
               break;
#endif
#ifdef DEV_RANDOM_SUPPORT
          case 'd':
               opt_set[opt_d]++;
               opt->cryptopt.get_entropy = get_dev_entropy;
               break;
#endif
#if defined (EGD_SUPPORT) || defined (DEV_RANDOM_SUPPORT)
          case 'y':
               opt_set[opt_y]++;
               opt->cryptopt.get_entropy = get_sys_entropy;
               break;
#endif
          case 'p':
               opt_set[opt_p]++;
               opt->action = crypt_pix;
               break;
          case 'l':
               opt_set[opt_l]++;
               n = sscanf(optarg, "%d:%d",
                          &opt->decryptopt.fromlen,
                          &opt->decryptopt.tolen);

               switch (n) {
               case 0:         /* option --length used with no values */
                    usage(ERR_USAGE);
                    break;
               case 1:         /* only 'fromlen' set */
                    opt->decryptopt.tolen = opt->decryptopt.fromlen;
               case 2:
                    if (opt->decryptopt.fromlen >
                        opt->decryptopt.tolen)
                         tty_error(ERR_USAGE,
                                   "bad order for `--length' limits");
                    if (opt->decryptopt.fromlen < 1)
                         tty_error(ERR_USAGE,
                                   "illegal downlimit for `--length'");
                    if (opt->decryptopt.tolen > MAX_PLAIN_SIZE)
                         tty_error(ERR_USAGE,
                                   "the `--length' upperlimit exceed `%d'",
                                   MAX_PLAIN_SIZE);
               }
               break;
          case 'b':            /* try the brute-force attack */
               opt_set[opt_b]++;
               opt->action = decrypt_bf;
               if (optarg)
                    opt->decryptopt.regexpr = str_alloc_copy(optarg);
               break;
          case 'w':            /* try the vocabulary attack */
               opt_set[opt_w]++;
               opt->action = decrypt_wl;
               opt->decryptopt.wordlist = str_alloc_copy(optarg);
               break;
#if defined (HAVE_WORKING_FORK)
          case 'D':
               opt_set[opt_D]++;
               opt->daemonize = 1;
               break;
#endif
          case 'r':
               opt_set[opt_r]++;
               opt->action = resume;
               /* default rescue file is `RESTORE_FILE' */
               opt->decryptopt.restore_file = optarg ?
                    str_alloc_copy(optarg) : str_alloc_copy(RESTORE_FILE);
               break;
          case 'q':            /* minimize the program output */
               opt_set[opt_q]++;
               opt->verbose = 0;
               break;
          case 'h':            /* help */
#if 0
               opt_set[opt_h]++;
#endif
               usage(SUCCESS);
               break;
          case 'v':            /* verbose mode */
               opt_set[opt_v]++;
               opt->verbose++;
               break;
          case 'L':
#if 0
               opt_set[opt_L]++;
#endif
               license();      /* GPL license message */
               exit(SUCCESS);
               break;
          case 'V':            /* program name, version, etc. */
#if 0
               opt_set[opt_V]++;
#endif
               version();
               exit(SUCCESS);
               break;
          case '?':
               tty_error(ERR_USAGE,
                         "ambiguous match or extraneous parameter `%s'",
                         argv[optind - 1]);
               break;
          default:   /* should catch nothing (?) */
               tty_error(ERR_USAGE, "illegal command line argument");
          }
     }

     /* check for option inconsistences */
     opt_check(opt_set);
}