Lines 46-51
Link Here
|
46 |
#include "ap.h" |
46 |
#include "ap.h" |
47 |
#include "ap_md5.h" |
47 |
#include "ap_md5.h" |
48 |
#include "ap_sha1.h" |
48 |
#include "ap_sha1.h" |
|
|
49 |
#include <math.h> |
49 |
|
50 |
|
50 |
#ifdef HAVE_CRYPT_H |
51 |
#ifdef HAVE_CRYPT_H |
51 |
#include <crypt.h> |
52 |
#include <crypt.h> |
Lines 94-99
Link Here
|
94 |
static char *tname_buf = NULL; |
95 |
static char *tname_buf = NULL; |
95 |
#endif |
96 |
#endif |
96 |
|
97 |
|
|
|
98 |
FILE *FP = NULL; |
99 |
|
97 |
/* |
100 |
/* |
98 |
* Get a line of input from the user, not including any terminating |
101 |
* Get a line of input from the user, not including any terminating |
99 |
* newline. |
102 |
* newline. |
Lines 127-132
Link Here
|
127 |
fputc('\n', f); |
130 |
fputc('\n', f); |
128 |
} |
131 |
} |
129 |
|
132 |
|
|
|
133 |
|
134 |
static void seed_prng() |
135 |
{ |
136 |
int randBits = 0; |
137 |
int seedInt = 0; |
138 |
int toAdd = 0; |
139 |
int intSize = (8*(int)sizeof(int)); |
140 |
int charSize = (8*(int)sizeof(char)); |
141 |
if ( (!FP) && getenv("RANDOM_SEED") ) |
142 |
{ |
143 |
/* use the device specified by the user */ |
144 |
FP = fopen(getenv("RANDOM_SEED"), "r"); |
145 |
} else if (!FP) { |
146 |
/* use /dev/urandom for better (less predictable) seeding if available */ |
147 |
FP = fopen("/dev/urandom", "r"); |
148 |
} |
149 |
if (FP) |
150 |
{ |
151 |
while ( randBits < intSize ) { |
152 |
/* how many bits to read (maximum == bytes in a char) */ |
153 |
toAdd = (intSize - randBits) > charSize ? charSize : (intSize - randBits); |
154 |
/* we could watch the fgetc() call for EOF and warn the user, |
155 |
but the user should know better than to provide a small pool */ |
156 |
seedInt += ((int)fgetc(FP) % (int)pow(2,toAdd)) * (int)pow(2,randBits); |
157 |
randBits += toAdd; |
158 |
} |
159 |
(void) srand(seedInt); |
160 |
/* deliberately leave FP open in case seed_prng() is called again and |
161 |
FP behaves like a static file and always provides the same content; |
162 |
with devices like /dev/urandom and /dev/random, there would be bo reason |
163 |
not to fclose(FP) here */ |
164 |
} else { |
165 |
fprintf(stderr,"Warning: weak salt generation!\n"); |
166 |
fprintf(stderr,"For better security, install /dev/urandom or provide the name of a file or device\n"); |
167 |
fprintf(stderr,"that can provide enough random data in the environment variable RANDOM_SEED\n",(intSize/8)); |
168 |
(void) srand((int) time((time_t *) NULL)); |
169 |
} |
170 |
} |
171 |
|
172 |
static void generate_salt(char *s, size_t size) |
173 |
{ |
174 |
static unsigned char tbl[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
175 |
size_t i; |
176 |
int bitsUsed = 0; |
177 |
for (i = 0; i < size; ++i) { |
178 |
int idx = (int) (64.0 * rand() / (RAND_MAX + 1.0)); |
179 |
bitsUsed += 6; |
180 |
s[i] = tbl[idx]; |
181 |
/* re-seed the PRNG if already used an integer's worth of bytes, or if the next |
182 |
loop iteration would use more than an int, since the seed for rand() is an int. |
183 |
This will only need to happen on platforms with integers less than 48 bits. */ |
184 |
if ( (bitsUsed + 6) > (8*sizeof(int)) ) |
185 |
{ |
186 |
/* re-seed */ |
187 |
(void)seed_prng(); |
188 |
/* reset our counter */ |
189 |
bitsUsed = 0; |
190 |
} |
191 |
} |
192 |
} |
193 |
|
130 |
/* |
194 |
/* |
131 |
* Make a password record from the given information. A zero return |
195 |
* Make a password record from the given information. A zero return |
132 |
* indicates success; failure means that the output buffer contains an |
196 |
* indicates success; failure means that the output buffer contains an |
Lines 171-178
Link Here
|
171 |
break; |
235 |
break; |
172 |
|
236 |
|
173 |
case ALG_APMD5: |
237 |
case ALG_APMD5: |
174 |
(void) srand((int) time((time_t *) NULL)); |
238 |
(void)seed_prng(); |
175 |
ap_to64(&salt[0], rand(), 8); |
239 |
generate_salt(&salt[0], 8); |
176 |
salt[8] = '\0'; |
240 |
salt[8] = '\0'; |
177 |
|
241 |
|
178 |
ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, |
242 |
ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, |
Lines 186-192
Link Here
|
186 |
|
250 |
|
187 |
case ALG_CRYPT: |
251 |
case ALG_CRYPT: |
188 |
default: |
252 |
default: |
189 |
(void) srand((int) time((time_t *) NULL)); |
253 |
(void)seed_prng(); |
190 |
ap_to64(&salt[0], rand(), 8); |
254 |
ap_to64(&salt[0], rand(), 8); |
191 |
salt[8] = '\0'; |
255 |
salt[8] = '\0'; |
192 |
|
256 |
|