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** randpass.c - Random password generation module of PWGEN program
32*/
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <time.h>
37
38#include "base/rand_util.h"
39#include "owntypes.h"
40#include "randpass.h"
41#include "smbl.h"
42
43/*
44** gen_rand_pass - generates random password of specified type
45** INPUT:
46**   char * - password string.
47**   int    - minimum password length.
48**   int    - maximum password length.
49**   unsigned int - password generation mode.
50** OUTPUT:
51**   int - password length or -1 on error.
52** NOTES:
53**   none.
54*/
55int
56gen_rand_pass (char *password_string, int minl, int maxl, unsigned int pass_mode)
57{
58  int i = 0;
59  int j = 0;
60  int length = 0;
61  char *str_pointer;
62  int random_weight[94];
63  int max_weight = 0;
64  int max_weight_element_number = 0;
65
66  if (minl > APG_MAX_PASSWORD_LENGTH || maxl > APG_MAX_PASSWORD_LENGTH ||
67      minl < 1 || maxl < 1 || minl > maxl)
68      return (-1);
69  for (i = 0; i <= 93; i++) random_weight[i] = 0;
70  length = base::RandInt(minl, maxl);
71  str_pointer = password_string;
72
73  for (i = 0; i < length; i++)
74    {
75/* Asign random weight in weight array if mode is present*/
76      for (j = 0; j <= 93 ; j++)
77         if ( ( (pass_mode & smbl[j].type) > 0) &&
78	     !( (S_RS & smbl[j].type) > 0))
79           random_weight[j] = base::RandInt(1, 20000);
80      j = 0;
81/* Find an element with maximum weight */
82      for (j = 0; j <= 93; j++)
83	if (random_weight[j] > max_weight)
84	  {
85	    max_weight = random_weight[j];
86	    max_weight_element_number = j;
87	  }
88/* Get password symbol */
89      *str_pointer = smbl[max_weight_element_number].ch;
90      str_pointer++;
91      max_weight = 0;
92      max_weight_element_number = 0;
93      for (j = 0; j <= 93; j++) random_weight[j] = 0;
94    }
95  *str_pointer = 0;
96  return (length);
97}
98
99/*
100** gen_rand_symbol - generates random password of specified type
101** INPUT:
102**   char * - symbol.
103**   unsigned int - symbol type.
104** OUTPUT:
105**   int - password length or -1 on error.
106** NOTES:
107**   none.
108*/
109int
110gen_rand_symbol (char *symbol, unsigned int mode)
111{
112  int j = 0;
113  char *str_pointer;
114  int random_weight[94];
115  int max_weight = 0;
116  int max_weight_element_number = 0;
117
118  for (j = 0; j <= 93; j++) random_weight[j] = 0;
119  str_pointer = symbol;
120  j = 0;
121/* Asign random weight in weight array if mode is present*/
122  for (j = 0; j <= 93 ; j++)
123     if ( ( (mode & smbl[j].type) > 0) &&
124         !( (S_RS & smbl[j].type) > 0))
125          random_weight[j] = base::RandInt(1, 20000);
126  j = 0;
127/* Find an element with maximum weight */
128  for (j = 0; j <= 93; j++)
129     if (random_weight[j] > max_weight)
130       {
131        max_weight = random_weight[j];
132        max_weight_element_number = j;
133       }
134/* Get password symbol */
135  *str_pointer = smbl[max_weight_element_number].ch;
136  max_weight = 0;
137  max_weight_element_number = 0;
138  return (0);
139}
140
141/*
142** is_restricted_symbol - detcts if symbol is restricted rigt now
143** INPUT:
144**   char - symbol.
145** OUTPUT:
146**   int - 0 - not restricted
147**         1 - restricted
148** NOTES:
149**   none.
150*/
151int
152is_restricted_symbol (char symbol)
153{
154  int j = 0;
155  for (j = 0; j <= 93 ; j++)
156    if (symbol == smbl[j].ch)
157      if ((S_RS & smbl[j].type) > 0)
158        return(1);
159  return(0);
160}
161