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