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