View | Details | Raw Unified | Return to bug 31440
Collapse All | Expand All

(-)./support/htpasswd.c (-3 / +66 lines)
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

Return to bug 31440