Lines 46-51
Link Here
|
46 |
#include "apr_general.h" |
46 |
#include "apr_general.h" |
47 |
#include "apr_signal.h" |
47 |
#include "apr_signal.h" |
48 |
|
48 |
|
|
|
49 |
#include <math.h> |
50 |
|
49 |
#if APR_HAVE_STDIO_H |
51 |
#if APR_HAVE_STDIO_H |
50 |
#include <stdio.h> |
52 |
#include <stdio.h> |
51 |
#endif |
53 |
#endif |
Lines 101-106
Link Here
|
101 |
|
103 |
|
102 |
apr_file_t *errfile; |
104 |
apr_file_t *errfile; |
103 |
apr_file_t *ftemp = NULL; |
105 |
apr_file_t *ftemp = NULL; |
|
|
106 |
FILE *FP = NULL; |
104 |
|
107 |
|
105 |
#define NL APR_EOL_STR |
108 |
#define NL APR_EOL_STR |
106 |
|
109 |
|
Lines 115-120
Link Here
|
115 |
} |
118 |
} |
116 |
} |
119 |
} |
117 |
|
120 |
|
|
|
121 |
static void seed_prng() |
122 |
{ |
123 |
int randBits = 0; |
124 |
int seedInt = 0; |
125 |
int toAdd = 0; |
126 |
int intSize = (8*(int)sizeof(int)); |
127 |
int charSize = (8*(int)sizeof(char)); |
128 |
if ( (!FP) && getenv("RANDOM_SEED") ) |
129 |
{ |
130 |
/* use the device specified by the user */ |
131 |
FP = fopen(getenv("RANDOM_SEED"), "r"); |
132 |
} else if (!FP) { |
133 |
/* use /dev/urandom for better (less predictable) seeding if available */ |
134 |
FP = fopen("/dev/urandom", "r"); |
135 |
} |
136 |
if (FP) |
137 |
{ |
138 |
while ( randBits < intSize ) { |
139 |
/* how many bits to read (maximum == bytes in a char) */ |
140 |
toAdd = (intSize - randBits) > charSize ? charSize : (intSize - randBits); |
141 |
/* we could watch the fgetc() call for EOF and warn the user, |
142 |
but the user should know better than to provide a small pool */ |
143 |
seedInt += ((int)fgetc(FP) % (int)pow(2,toAdd)) * (int)pow(2,randBits); |
144 |
randBits += toAdd; |
145 |
} |
146 |
(void) srand(seedInt); |
147 |
/* deliberately leave FP open in case seed_prng() is called again and |
148 |
FP behaves like a static file and always provides the same content; |
149 |
with devices like /dev/urandom and /dev/random, there would be bo reason |
150 |
not to fclose(FP) here */ |
151 |
} else { |
152 |
fprintf(stderr,"Warning: weak salt generation!\n"); |
153 |
fprintf(stderr,"For better security, install /dev/urandom or provide the name of a file or device\n"); |
154 |
fprintf(stderr,"that can provide enough random data in the environment variable RANDOM_SEED\n",(intSize/8)); |
155 |
(void) srand((int) time((time_t *) NULL)); |
156 |
} |
157 |
} |
158 |
|
159 |
static void generate_salt(char *s, size_t size) |
160 |
{ |
161 |
static unsigned char tbl[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
162 |
size_t i; |
163 |
int bitsUsed = 0; |
164 |
for (i = 0; i < size; ++i) { |
165 |
int idx = (int) (64.0 * rand() / (RAND_MAX + 1.0)); |
166 |
bitsUsed += 6; |
167 |
s[i] = tbl[idx]; |
168 |
/* re-seed the PRNG if already used an integer's worth of bytes, or if the next |
169 |
loop iteration would use more than an int, since the seed for rand() is an int. |
170 |
This will only need to happen on platforms with integers less than 48 bits. */ |
171 |
if ( (bitsUsed + 6) > (8*sizeof(int)) ) |
172 |
{ |
173 |
/* re-seed */ |
174 |
(void)seed_prng(); |
175 |
/* reset our counter */ |
176 |
bitsUsed = 0; |
177 |
} |
178 |
} |
179 |
} |
180 |
|
118 |
static void putline(apr_file_t *f, const char *l) |
181 |
static void putline(apr_file_t *f, const char *l) |
119 |
{ |
182 |
{ |
120 |
apr_file_puts(l, f); |
183 |
apr_file_puts(l, f); |
Lines 162-169
Link Here
|
162 |
break; |
225 |
break; |
163 |
|
226 |
|
164 |
case ALG_APMD5: |
227 |
case ALG_APMD5: |
165 |
(void) srand((int) time((time_t *) NULL)); |
228 |
(void)seed_prng(); |
166 |
to64(&salt[0], rand(), 8); |
229 |
generate_salt(&salt[0], 8); |
167 |
salt[8] = '\0'; |
230 |
salt[8] = '\0'; |
168 |
|
231 |
|
169 |
apr_md5_encode((const char *)pw, (const char *)salt, |
232 |
apr_md5_encode((const char *)pw, (const char *)salt, |
Lines 178-184
Link Here
|
178 |
#if !(defined(WIN32) || defined(NETWARE)) |
241 |
#if !(defined(WIN32) || defined(NETWARE)) |
179 |
case ALG_CRYPT: |
242 |
case ALG_CRYPT: |
180 |
default: |
243 |
default: |
181 |
(void) srand((int) time((time_t *) NULL)); |
244 |
(void)seed_prng(); |
182 |
to64(&salt[0], rand(), 8); |
245 |
to64(&salt[0], rand(), 8); |
183 |
salt[8] = '\0'; |
246 |
salt[8] = '\0'; |
184 |
|
247 |
|