"Fossies" - the Fresh Open Source Software Archive

Member "apg-2.2.3/apg.c" (12 Sep 2003, 23581 Bytes) of package /linux/privat/old/apg-2.2.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2 ** Copyright (c) 1999, 2000, 2001, 2002, 2003
    3 ** Adel I. Mirzazhanov. All rights reserved
    4 **
    5 ** Redistribution and use in source and binary forms, with or without
    6 ** modification, are permitted provided that the following conditions
    7 ** are met:
    8 ** 
    9 **     1.Redistributions of source code must retain the above copyright notice,
   10 **       this list of conditions and the following disclaimer. 
   11 **     2.Redistributions in binary form must reproduce the above copyright
   12 **       notice, this list of conditions and the following disclaimer in the
   13 **       documentation and/or other materials provided with the distribution. 
   14 **     3.The name of the author may not be used to endorse or promote products
   15 **       derived from this software without specific prior written permission. 
   16 **        
   17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
   18 ** OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
   19 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20 ** ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
   21 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
   23 ** GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
   24 ** INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
   25 ** WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
   26 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   27 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28 */
   29 
   30 /*
   31 ** Main Module of apg programm
   32 */
   33 #include <stdio.h>
   34 #include <stdlib.h>
   35 #if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
   36 #include <strings.h>
   37 #endif
   38 #include <string.h>
   39 #include <time.h>
   40 
   41 #ifndef APG_USE_SHA
   42 #define APG_VERSION "2.2.3 (PRNG: X9.17/CAST)"
   43 #else /* APG_USE_SHA */
   44 #define APG_VERSION "2.2.3 (PRNG: X9.17/SHA-1)"
   45 #endif /* APG_USE_SHA */
   46 
   47 #ifdef __NetBSD__
   48 #include <unistd.h>
   49 #endif
   50 
   51 #if defined(__sun) || defined(sun) || defined(linux) || defined(__linux) || defined(__linux__)
   52 #include <crypt.h>
   53 #endif
   54 
   55 #define MAX_MODE_LENGTH   4
   56 #define DEFAULT_MIN_PASS_LEN 8
   57 #define DEFAULT_MAX_PASS_LEN 10
   58 #define DEFAULT_NUM_OF_PASS 6
   59 
   60 #ifndef _XOPEN_SOURCE
   61 #define _XOPEN_SOURCE
   62 #endif
   63 
   64 #ifndef __NetBSD__
   65 #include <unistd.h>
   66 #endif
   67 
   68 #ifdef __CYGWIN__
   69 #undef APG_USE_CRYPT
   70 #endif /* __CYGWIN__ */
   71 
   72 #ifdef CLISERV
   73 #include <sys/socket.h>
   74 #include <netinet/in.h>
   75 #include <arpa/inet.h>
   76 #include <syslog.h>
   77 #define MAXSOCKADDDR 128
   78 #endif /* CLISERV */
   79 
   80 #include "owntypes.h"
   81 #include "pronpass.h"
   82 #include "randpass.h"
   83 #include "restrict.h"
   84 #include "bloom.h"
   85 #include "rnd.h"
   86 #include "errs.h"
   87 #include "getopt.h"
   88 #include "convert.h"
   89 
   90  struct pass_m {
   91         unsigned int pass;           /* password generation mode        */
   92         unsigned int filter;             /* password generation mode        */
   93     };
   94 #ifndef CLISERV
   95 UINT32 get_user_seq (void);
   96 UINT32 com_line_user_seq (char * seq);
   97 char *crypt_passstring (const char *p);
   98 void print_help (void);
   99 #endif /* CLISERV */
  100 
  101 int main (int argc, char *argv[]);
  102 void checkopt(char *opt);
  103 int construct_mode(char *str_mode, struct pass_m * mde);
  104 
  105 /*
  106 ** main()
  107 */
  108 int
  109 main (int argc, char *argv[])
  110 {
  111  int i = 0;
  112  int restrict_res = 0;
  113  
  114  char *pass_string;
  115  char *hyph_pass_string;
  116  time_t tme;
  117  
  118  
  119  int option = 0;                         /* programm option                 */
  120 
  121  int algorithm = 0;                      /* algorithm for generation        */
  122  int restrictions_present = FALSE;       /* restrictions flag               */
  123  int plain_restrictions_present = FALSE; /* dictionary restrictions_flag    */
  124  int bloom_restrict_present = FALSE;     /* bloom filter restrictions flag  */
  125  int paranoid_bloom_restrict_present = FALSE;     /* paranoid bloom filter restrictions flag  */
  126  int filter_restrict_present = FALSE;    /* filter restrictions flag        */
  127  int exclude_list_present = FALSE;       /* exclude list present            */
  128  int quiet_present = FALSE;              /* quiet mode flag                 */
  129  int hyph_req_present = FALSE;           /* Request to print hyphenated password              */
  130  char *restrictions_file;                /* dictionary file name            */
  131  char *plain_restrictions_file;          /* dictionary file name            */
  132  struct pass_m mode;
  133  unsigned int pass_mode_present = FALSE; /* password generation mode flag   */
  134  USHORT min_pass_length = DEFAULT_MIN_PASS_LEN;             /* min password length             */
  135  USHORT max_pass_length = DEFAULT_MAX_PASS_LEN;             /* max password length             */
  136  USHORT min_substr_len = 0;              /* min substring length to check if
  137                                          ** paranoid check is used          */
  138  int number_of_pass = DEFAULT_NUM_OF_PASS;                 /* number of passwords to generate */
  139  UINT32 user_defined_seed = 0L;          /* user defined random seed        */
  140  int user_defined_seed_present = FALSE;  /* user defined random seed flag   */
  141  char *str_mode;                         /* string mode pointer             */
  142 #ifndef CLISERV
  143  char *com_line_seq;
  144  char *spell_pass_string;
  145  int spell_present = FALSE;              /* spell password mode flag        */
  146  unsigned int delimiter_flag_present = FALSE;
  147 #ifdef APG_USE_CRYPT
  148  char *crypt_string;
  149  unsigned int show_crypt_text = FALSE;   /* display crypt(3)'d text flag    */
  150 #endif /* APG_USE_CRYPT */
  151 #endif /* CLISERV */
  152 #ifdef CLISERV
  153 #if defined(sgi) || defined(__APPLE__) || defined(__QNX__) /* Thanks to Andrew J. Caird */
  154  typedef unsigned int socklen_t;
  155 #endif
  156  socklen_t len;
  157  struct sockaddr_in *cliaddr;
  158  char delim[2]={0x0d,0x0a};
  159  char *out_pass;
  160  char *peer_ip_unknown = "UNKNOWN";
  161  char *peer_ip;
  162 
  163  openlog(argv[0], LOG_PID, LOG_DAEMON);
  164  cliaddr = (struct sockaddr_in *)calloc(1,MAXSOCKADDDR);
  165  len = MAXSOCKADDDR;
  166  if( getpeername(0, (struct sockaddr *)cliaddr, &len) != 0)
  167   {
  168    err_sys("getpeername");
  169    peer_ip = peer_ip_unknown;
  170   }
  171  else
  172   {
  173    peer_ip = inet_ntoa(cliaddr->sin_addr);
  174   }
  175  syslog (LOG_INFO, "password generation request from %s.%d\n", peer_ip, htons(cliaddr->sin_port));
  176 #endif /* CLISERV */
  177 
  178  /*
  179  ** Analize options
  180  */
  181 #ifndef CLISERV
  182 #ifdef APG_USE_CRYPT
  183  while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:sdc:n:m:x:htvylq")) != -1)
  184 #else /* APG_USE_CRYPT */
  185  while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:sdc:n:m:x:htvlq")) != -1)
  186 #endif /* APG_USE_CRYPT */
  187 #else /* CLISERV */
  188  while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:n:m:x:vt")) != -1)
  189 #endif /* CLISERV */
  190   {
  191    switch (option)
  192     {
  193      case 'M': /* mode parameter */
  194       str_mode = apg_optarg;
  195       if( (construct_mode(str_mode,&mode)) == -1)
  196          err_app_fatal("construct_mode","wrong parameter");
  197       pass_mode_present = TRUE;
  198       if(mode.filter != 0)
  199         {
  200          filter_restrict_present = TRUE;
  201      restrictions_present = TRUE;
  202     }
  203       break;
  204      case 'E': /* exclude char */
  205       if(set_exclude_list(apg_optarg)==-1)
  206          err_app_fatal("set_exclude_list","string is too long (max. 93 characters)");
  207       exclude_list_present = TRUE;
  208       break;
  209      case 'a': /* algorithm specification */
  210       checkopt(apg_optarg);
  211       algorithm = atoi (apg_optarg);
  212       break;
  213      case 'r': /* restrictions */
  214       restrictions_present = TRUE;
  215       plain_restrictions_present = TRUE;
  216       plain_restrictions_file = apg_optarg;
  217       break;
  218      case 'b': /* bloom restrictions */
  219       restrictions_present = TRUE;
  220       bloom_restrict_present = TRUE;
  221       restrictions_file = apg_optarg;
  222       break;
  223      case 'p': /* paranoid bloom restrictions */
  224       checkopt(apg_optarg);
  225       min_substr_len = atoi (apg_optarg);
  226       paranoid_bloom_restrict_present = TRUE;
  227       break;
  228 #ifndef CLISERV
  229      case 'l':
  230       spell_present = TRUE;
  231       break;
  232 #if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
  233      case 's': /* user random seed required */
  234       user_defined_seed = get_user_seq ();
  235       user_defined_seed_present = TRUE;
  236       break;
  237 #endif /* WIN32 */
  238      case 'c': /* user random seed given in command line */
  239       com_line_seq = apg_optarg;
  240       user_defined_seed = com_line_user_seq (com_line_seq);
  241       user_defined_seed_present = TRUE;
  242       break;
  243      case 'd': /* no delimiters option */
  244       delimiter_flag_present = TRUE;
  245       break;
  246      case 'q': /* quiet mode */
  247       quiet_present = TRUE;
  248       break;
  249 #ifdef APG_USE_CRYPT
  250      case 'y': /* display crypt(3)'d text next to passwords */
  251       show_crypt_text = TRUE;
  252       break;                                                                  
  253 #endif /* APG_USE_CRYPT */
  254 #endif /* CLISERV */
  255      case 'n': /* number of password specification */
  256       checkopt(apg_optarg);
  257       number_of_pass = atoi (apg_optarg);
  258       break;
  259      case 'm': /* min password length */
  260       checkopt(apg_optarg);
  261       min_pass_length = (USHORT) atoi (apg_optarg);
  262       break;
  263      case 'x': /* max password length */
  264       checkopt(apg_optarg);
  265       max_pass_length = (USHORT) atoi (apg_optarg);
  266       break;
  267      case 't': /* request to print hyphenated password */
  268       hyph_req_present = TRUE;
  269       break;
  270 #ifndef CLISERV
  271      case 'h': /* print help */
  272       print_help ();
  273       return (0);
  274 #endif /* CLISERV */
  275      case 'v': /* print version */
  276       printf ("APG (Automated Password Generator)");
  277       printf ("\nversion %s", APG_VERSION);
  278       printf ("\nCopyright (c) 1999, 2000, 2001, 2002, 2003 Adel I. Mirzazhanov\n");
  279       return (0);
  280      default: /* print help end exit */
  281 #ifndef CLISERV
  282       print_help ();
  283 #endif /* CLISERV */
  284       exit (-1);
  285     }
  286   }
  287  if (pass_mode_present != TRUE)
  288     mode.pass = S_SS | S_NB | S_CL | S_SL;
  289  if (exclude_list_present == TRUE)
  290     mode.pass = mode.pass | S_RS;
  291  if( (tme = time(NULL)) == ( (time_t)-1))
  292     err_sys("time");
  293  if (user_defined_seed_present != TRUE)
  294     x917_setseed ( (UINT32)tme, quiet_present);
  295  else
  296     x917_setseed (user_defined_seed ^ (UINT32)tme, quiet_present);
  297  if (min_pass_length > max_pass_length)
  298     max_pass_length = min_pass_length;
  299  /* main code section */
  300  
  301  /*
  302  ** reserv space for password and hyphenated password and report of errors
  303  ** 18 because the maximum length of element for hyphenated password is 17
  304  */
  305  if ( (pass_string = (char *)calloc (1, (size_t)(max_pass_length + 1)))==NULL ||
  306       (hyph_pass_string = (char *)calloc (1, (size_t)(max_pass_length*18)))==NULL)
  307       err_sys_fatal("calloc");
  308 #ifndef CLISERV
  309 #ifdef APG_USE_CRYPT
  310  if (show_crypt_text == TRUE)
  311    if ((crypt_string = (char *)calloc (1, 255))==NULL)      
  312       err_sys_fatal("calloc");
  313 #endif /* APG_USE_CRYPT */
  314 #endif /* CLISERV */
  315 #ifdef CLISERV
  316  if ( (out_pass = (char *)calloc(1, (size_t)(max_pass_length*19 + 4))) == NULL)
  317       err_sys_fatal("calloc");
  318 #endif /* CLISERV */
  319  /*
  320  ** generate required amount of passwords using specified algorithm
  321  ** and check for restrictions if specified with command line parameters
  322  */
  323  while (i < number_of_pass)
  324   {
  325    if (algorithm == 0)
  326     {
  327      if (gen_pron_pass(pass_string, hyph_pass_string,
  328                        min_pass_length, max_pass_length, mode.pass) == -1)
  329         err_app_fatal("apg","wrong password length parameter");
  330 #ifndef CLISERV
  331 #ifdef APG_USE_CRYPT
  332      if (show_crypt_text == TRUE)
  333          (void) memcpy ((void *)crypt_string,
  334                     (void *)crypt_passstring (pass_string), 255);
  335 #endif /* APG_USE_CRYPT */
  336 #endif /* CLISERV */
  337      /***************************************
  338      ** ALGORITHM = 0 RESTRICTIONS = PRESENT
  339      ****************************************/
  340      if (restrictions_present == TRUE)
  341        {
  342         /* Filter check */
  343         if (filter_restrict_present == TRUE)
  344       restrict_res = filter_check_pass(pass_string, mode.filter);
  345     /* Bloom-filter check */
  346     if (restrict_res == 0)
  347      {
  348       if (bloom_restrict_present == TRUE)
  349        {
  350         if(paranoid_bloom_restrict_present != TRUE)
  351               restrict_res = bloom_check_pass(pass_string, restrictions_file);
  352         else
  353           restrict_res = paranoid_bloom_check_pass(pass_string, restrictions_file, min_substr_len);
  354        }
  355      }
  356      /* Dictionary check */
  357      if (restrict_res == 0)
  358       if (plain_restrictions_present == TRUE)
  359             restrict_res = check_pass(pass_string, plain_restrictions_file);
  360 
  361 
  362         switch (restrict_res)
  363       {
  364       case 0:
  365 #ifndef CLISERV
  366             fprintf (stdout, "%s", pass_string);
  367             if (hyph_req_present == TRUE)
  368           fprintf (stdout, " (%s)", hyph_pass_string);
  369 #ifdef APG_USE_CRYPT
  370             if (show_crypt_text == TRUE)
  371           fprintf (stdout, " %s", crypt_string);
  372 #endif /* APG_USE_CRYPT */
  373         if (spell_present == TRUE)
  374          {
  375           spell_pass_string = spell_word(pass_string, spell_pass_string);
  376           fprintf (stdout, (" %s"), spell_pass_string);
  377           free((void*)spell_pass_string);
  378          }
  379         if ( delimiter_flag_present == FALSE )
  380            fprintf (stdout, "\n");
  381         fflush (stdout);
  382 #else /* CLISERV */
  383             if (hyph_req_present == TRUE)
  384              snprintf(out_pass, max_pass_length*19 + 4, "%s (%s)", pass_string, hyph_pass_string);
  385         else
  386              snprintf(out_pass, max_pass_length*19 + 4, "%s", pass_string);     
  387         write (0, (void*) out_pass, strlen(out_pass));
  388         write (0, (void*)&delim[0],2);
  389 #endif /* CLISERV */
  390         i++;
  391         break;
  392       case 1:
  393         break;
  394       case -1:
  395         err_sys_fatal ("check_pass");
  396       default:
  397         break;
  398       } /* switch */
  399        }
  400      /******************************************
  401      ** ALGORITHM = 0 RESTRICTIONS = NOT_PRESENT
  402      *******************************************/
  403      else
  404        {
  405 #ifndef CLISERV
  406         fprintf (stdout, "%s", pass_string);
  407         if (hyph_req_present == TRUE)
  408       fprintf (stdout, " (%s)", hyph_pass_string);
  409 #ifdef APG_USE_CRYPT
  410         if (show_crypt_text == TRUE)
  411       fprintf (stdout, " %s", crypt_string);
  412 #endif /* APG_USE_CRYPT */
  413     if (spell_present == TRUE)
  414      {
  415       spell_pass_string = spell_word(pass_string, spell_pass_string);
  416       fprintf (stdout, (" %s"), spell_pass_string);
  417       free((void*)spell_pass_string);
  418      }
  419         if ( delimiter_flag_present == FALSE )
  420        fprintf (stdout, "\n");
  421     fflush (stdout);
  422 #else /* CLISERV */
  423         if (hyph_req_present == TRUE)
  424          snprintf(out_pass, max_pass_length*19 + 4, "%s (%s)", pass_string, hyph_pass_string);
  425     else
  426          snprintf(out_pass, max_pass_length*19 + 4, "%s", pass_string);     
  427     write (0, (void*) out_pass, strlen(out_pass));
  428     write (0, (void*)&delim[0],2);
  429 #endif /* CLISERV */
  430     i++;
  431        }
  432     }
  433    /***************************************
  434    ** ALGORITHM = 1
  435    ****************************************/
  436    else if (algorithm == 1)
  437     {
  438      if (gen_rand_pass(pass_string, min_pass_length,
  439                        max_pass_length, mode.pass) == -1)
  440         err_app_fatal("apg","wrong password length parameter");
  441 #ifndef CLISERV
  442 #ifdef APG_USE_CRYPT
  443      if (show_crypt_text == TRUE)
  444          (void)memcpy ((void *)crypt_string,
  445                    (void *)crypt_passstring(pass_string), 255);
  446 #endif /* APG_USE_CRYPT */
  447 #endif /* CLISERV */
  448      /***************************************
  449      ** ALGORITHM = 1 RESTRICTIONS = PRESENT
  450      ****************************************/
  451      if ( (restrictions_present == TRUE))
  452        {
  453         /* Filter check */
  454         if (filter_restrict_present == TRUE)
  455       restrict_res = filter_check_pass(pass_string, mode.filter);
  456     /* Bloom-filter check */
  457     if (restrict_res == 0)
  458      {
  459       if (bloom_restrict_present == TRUE)
  460        {
  461         if(paranoid_bloom_restrict_present != TRUE)
  462               restrict_res = bloom_check_pass(pass_string, restrictions_file);
  463         else
  464           restrict_res = paranoid_bloom_check_pass(pass_string, restrictions_file, min_substr_len);
  465        }
  466      }
  467      /* Dictionary check */
  468      if (restrict_res == 0)
  469       if (plain_restrictions_present == TRUE)
  470             restrict_res = check_pass(pass_string, plain_restrictions_file);
  471 
  472 
  473         switch (restrict_res)
  474       {
  475       case 0:
  476 #ifndef CLISERV
  477 #ifdef APG_USE_CRYPT
  478             if (show_crypt_text==TRUE)
  479           fprintf (stdout, "%s %s", pass_string, crypt_string);
  480         else
  481 #endif /* APG_USE_CRYPT */
  482           fprintf (stdout, "%s", pass_string);
  483         if (spell_present == TRUE)
  484          {
  485           spell_pass_string = spell_word(pass_string, spell_pass_string);
  486           fprintf (stdout, (" %s"), spell_pass_string);
  487           free((void*)spell_pass_string);
  488          }
  489         if ( delimiter_flag_present == FALSE )
  490            fprintf (stdout, "\n");
  491         fflush (stdout);
  492 #else /* CLISERV */
  493         write (0, (void*)pass_string, strlen(pass_string));
  494         write (0, (void*)&delim[0],2);
  495 #endif /* CLISERV */
  496         i++;
  497         break;
  498       case 1:
  499         break;
  500       case -1:
  501         err_sys_fatal ("check_pass");
  502       default:
  503         break;
  504       } /* switch */
  505        }
  506      /***************************************
  507      ** ALGORITHM = 1 RESTRICTIONS = PRESENT
  508      ****************************************/
  509      else
  510        {
  511 #ifndef CLISERV
  512 #ifdef APG_USE_CRYPT
  513         if (show_crypt_text==TRUE)
  514           fprintf (stdout, "%s %s", pass_string, crypt_string);
  515     else
  516 #endif /* APG_USE_CRYPT */
  517           fprintf (stdout, "%s", pass_string);
  518     if (spell_present == TRUE)
  519      {
  520       spell_pass_string = spell_word(pass_string, spell_pass_string);
  521       fprintf (stdout, (" %s"), spell_pass_string);
  522       free((void*)spell_pass_string);
  523      }
  524     if ( delimiter_flag_present == FALSE )
  525        fprintf (stdout, "\n");
  526     fflush (stdout);
  527 #else /* CLISERV */
  528     write (0, (void*)pass_string, strlen(pass_string));
  529     write (0, (void*)&delim[0],2);
  530 #endif /* CLISERV */
  531     i++;
  532        }
  533     } /* end of if (algorithm == 1) */
  534    else
  535      err_app_fatal ("apg","wrong algorithm type");
  536 
  537    restrict_res = 0;
  538   } /* end of while (i <= number_of_pass) */
  539  free((void*)pass_string);
  540  free((void*)hyph_pass_string);
  541 #ifndef CLISERV
  542 #ifdef APG_USE_CRYPT
  543  if (show_crypt_text==TRUE)
  544     free((void*)crypt_string);
  545 #endif /* APG_USE_CRYPT */
  546 #endif /* CLISERV */
  547 #ifdef CLISERV
  548  free ((void *)out_pass);
  549  free ((void *)cliaddr);
  550  close (0);
  551  closelog();
  552 #endif /* CLISERV */
  553  return(0);
  554 } /* end of main */
  555 
  556 #ifndef CLISERV
  557 #if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
  558 /*
  559 ** get_user_seq() - Routine that gets user random sequense
  560 ** and generates sutable random seed according to it.
  561 ** INPUT:
  562 **   void
  563 ** OUTPUT:
  564 **   UINT32 - random seed
  565 ** NOTES:
  566 **   none
  567 */
  568 UINT32
  569 get_user_seq (void)
  570 {
  571  char * seq;
  572  UINT32 prom[2] = { 0L, 0L };
  573  UINT32 sdres = 0L;
  574  printf ("\nPlease enter some random data (only first %d are significant)\n", sizeof(prom));
  575  seq = (char *)getpass("(eg. your old password):>");
  576  if (strlen(seq) < sizeof(prom))
  577   (void)memcpy((void *)&prom[0], (void *)seq, (int)strlen(seq));
  578  else
  579   (void)memcpy((void *)&prom[0], (void *)seq, sizeof(prom));
  580  sdres = prom[0]^prom[1];
  581  return (sdres);
  582 }
  583 #endif /* WIN32 */
  584 /*
  585 ** com_line_user_seq() - Routine that gets user random sequense
  586 ** from command line and generates sutable random seed according to it
  587 ** INPUT:
  588 **   char * - command line seed
  589 ** OUTPUT:
  590 **   UINT32 - random seed
  591 ** NOTES:
  592 **   none
  593 */
  594 UINT32
  595 com_line_user_seq (char * seq)
  596 {
  597  UINT32 prom[2] = { 0L, 0L };
  598  UINT32 sdres = 0L;
  599  if (strlen(seq) < sizeof (prom))
  600   (void)memcpy((void *)&prom[0], (void *)seq, (int)strlen(seq));
  601  else
  602   (void)memcpy((void *)&prom[0], (void *)seq, sizeof(prom));
  603  sdres = prom[0]^prom[1];
  604  return (sdres);
  605 }
  606 
  607 /*
  608 ** print_help() - print help :)))
  609 ** INPUT:
  610 **   none.
  611 ** OUTPUT:
  612 **   help info to the stdout.
  613 ** NOTES:
  614 **   none.
  615 */
  616 void
  617 print_help (void)
  618 {
  619  printf ("\napg   Automated Password Generator\n");
  620  printf ("        Copyright (c) Adel I. Mirzazhanov\n");
  621  printf ("\napg   [-a algorithm] [-r file] \n");
  622  printf ("      [-M mode] [-E char_string] [-n num_of_pass] [-m min_pass_len]\n");
  623  printf ("      [-x max_pass_len] [-c cl_seed] [-d] [-s] [-h] [-y] [-q]\n");
  624  printf ("\n-M mode         new style password modes\n");
  625  printf ("-E char_string  exclude characters from password generation process\n");
  626  printf ("-r file         apply dictionary check against file\n");
  627  printf ("-b filter_file  apply bloom filter check against filter_file\n");
  628  printf ("                (filter_file should be created with apgbfm(1) utility)\n");
  629  printf ("-p substr_len   paranoid modifier for bloom filter check\n");
  630  printf ("-a algorithm    choose algorithm\n");
  631  printf ("                 1 - random password generation according to\n");
  632  printf ("                     password modes\n");
  633  printf ("                 0 - pronounceable password generation\n");
  634  printf ("-n num_of_pass  generate num_of_pass passwords\n");
  635  printf ("-m min_pass_len minimum password length\n");
  636  printf ("-x max_pass_len maximum password length\n");
  637 #if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
  638  printf ("-s              ask user for a random seed for password\n");
  639  printf ("                generation\n");
  640 #endif /* WIN32 */
  641  printf ("-c cl_seed      use cl_seed as a random seed for password\n");
  642  printf ("-d              do NOT use any delimiters between generated passwords\n");
  643  printf ("-l              spell generated password\n");
  644  printf ("-t              print pronunciation for generated pronounceable password\n");
  645 #ifdef APG_USE_CRYPT
  646  printf ("-y              print crypted passwords\n");
  647 #endif /* APG_USE_CRYPT */
  648  printf ("-q              quiet mode (do not print warnings)\n");
  649  printf ("-h              print this help screen\n");
  650  printf ("-v              print version information\n");
  651 }
  652 
  653 #ifdef APG_USE_CRYPT
  654 /*
  655 ** crypt_passstring() - produce crypted password.
  656 ** INPUT:
  657 **   const char * - password string
  658 ** OUTPUT:
  659 **   char * - crypted password 
  660 ** NOTES:
  661 **   none.
  662 */
  663 char * crypt_passstring (const char *p)
  664 {
  665  char salt[10];
  666  gen_rand_pass (salt, 10, 10, S_SL|S_CL|S_NB);
  667  return (crypt(p, salt));
  668 }
  669 #endif /* APG_USE_CRYPT */
  670 #endif /* CLISERV */
  671 
  672 /*
  673 ** checkopt() - check options.
  674 ** INPUT:
  675 **   char * - options string.
  676 ** OUTPUT:
  677 **   none.
  678 ** NOTES:
  679 **   option should contain only numeral symbols.
  680 */
  681 void
  682 checkopt(char *opt)
  683 {
  684  int i;
  685 
  686  for(i=0; i < strlen(opt);i++)
  687   if(opt[i] != '0' && opt[i] != '1' && opt[i] != '2' && opt[i] != '3' &&
  688      opt[i] != '4' && opt[i] != '5' && opt[i] != '6' && opt[i] != '7' &&
  689      opt[i] != '8' && opt[i] != '9')
  690       err_app_fatal ("checkopt", "wrong option format");
  691 }
  692 
  693 /*
  694 ** construct_mode() - construct mode for password
  695 ** generation from string.
  696 ** INPUT:
  697 **   char * - string mode.
  698 ** OUTPUT:
  699 **   int - return code.
  700 **     0 - OK
  701 **    -1 - ERROR
  702 ** NOTES:
  703 **   none.
  704 */
  705 int construct_mode(char *s_mode, struct  pass_m * mde)
  706 {
  707  unsigned int mode = 0;
  708  unsigned int filter = 0;
  709  int ch = 0;
  710  int i = 0;
  711  int str_length = 0;
  712  
  713  str_length = strlen(s_mode);
  714  
  715  if (str_length > MAX_MODE_LENGTH)
  716      return(-1);
  717  for (i=0; i < str_length; i++)
  718   {
  719    ch = (int)*s_mode;
  720    switch(ch)
  721     {
  722      case 'S':
  723       mode = mode | S_SS;
  724       filter = filter | S_SS;
  725       break;
  726      case 'N':
  727       mode = mode | S_NB;
  728       filter = filter | S_NB;
  729       break;
  730      case 'C':
  731       mode = mode | S_CL;
  732       filter = filter | S_CL;
  733       break;
  734      case 'L':
  735       mode = mode | S_SL;
  736       filter = filter | S_SL;
  737       break;
  738      case 's':
  739       mode = mode | S_SS;
  740       break;
  741      case 'n':
  742       mode = mode | S_NB;
  743       break;
  744      case 'c':
  745       mode = mode | S_CL;
  746       break;
  747      case 'l':
  748       mode = mode | S_SL;
  749       break;
  750      default:
  751       return(-1);
  752       break;
  753     }
  754    s_mode++;
  755   }
  756  mde->pass = mode;
  757  mde->filter = filter;
  758  return (0);
  759 }
  760