~ubuntu-branches/ubuntu/maverick/kdebase-workspace/maverick-proposed

« back to all changes in this revision

Viewing changes to kdm/backend/genauth.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-07-08 01:11:52 UTC
  • mfrom: (1.1.43 upstream)
  • Revision ID: james.westby@ubuntu.com-20100708011152-z0h26httnjr91mmy
Tags: 4:4.4.92-0ubuntu1
* New upstream rc release:
  - Bump kde-sc-dev-latest to 4.4.92
  - Refresh patches
  - Update symbols
  - plasma-widgets-workspace replaces/conflicts plasma-widget-logout

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
#endif
77
77
 
78
78
static int
79
 
getPrngdBytes( char *buf, int len,
80
 
               unsigned short tcp_port, const char *socket_path )
 
79
getPrngdBytes(char *buf, int len,
 
80
              unsigned short tcp_port, const char *socket_path)
81
81
{
82
 
        int fd, addr_len, rval, errors;
83
 
        char msg[2];
84
 
        struct sockaddr *addr;
85
 
        struct sockaddr_in addr_in;
86
 
        struct sockaddr_un addr_un;
87
 
        int af;
88
 
        SIGFUNC old_sigpipe;
89
 
 
90
 
        if (tcp_port) {
91
 
                memset( &addr_in, 0, sizeof(addr_in) );
92
 
                af = addr_in.sin_family = AF_INET;
93
 
                addr_in.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
94
 
                addr_in.sin_port = htons( tcp_port );
95
 
                addr_len = sizeof(addr_in);
96
 
                addr = (struct sockaddr *)&addr_in;
97
 
        } else if (*socket_path) {
98
 
                unsigned spl = strlen( socket_path );
99
 
                if (spl >= sizeof(addr_un.sun_path)) {
100
 
                        logError( "get_random_prngd: "
101
 
                                  "Random pool path is too long\n" );
102
 
                        return -1;
103
 
                }
104
 
                af = addr_un.sun_family = AF_UNIX;
105
 
                strncpy( addr_un.sun_path, socket_path,
106
 
                         sizeof(addr_un.sun_path) );
107
 
                addr_len = offsetof(struct sockaddr_un, sun_path) + spl + 1;
108
 
                addr = (struct sockaddr *)&addr_un;
109
 
        } else
110
 
                return -1;
111
 
 
112
 
        old_sigpipe = Signal( SIGPIPE, SIG_IGN );
113
 
 
114
 
        errors = 0;
115
 
        rval = -1;
 
82
    int fd, addr_len, rval, errors;
 
83
    char msg[2];
 
84
    struct sockaddr *addr;
 
85
    struct sockaddr_in addr_in;
 
86
    struct sockaddr_un addr_un;
 
87
    int af;
 
88
    SIGFUNC old_sigpipe;
 
89
 
 
90
    if (tcp_port) {
 
91
        memset(&addr_in, 0, sizeof(addr_in));
 
92
        af = addr_in.sin_family = AF_INET;
 
93
        addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 
94
        addr_in.sin_port = htons(tcp_port);
 
95
        addr_len = sizeof(addr_in);
 
96
        addr = (struct sockaddr *)&addr_in;
 
97
    } else if (*socket_path) {
 
98
        unsigned spl = strlen(socket_path);
 
99
        if (spl >= sizeof(addr_un.sun_path)) {
 
100
            logError("get_random_prngd: "
 
101
                     "Random pool path is too long\n");
 
102
            return -1;
 
103
        }
 
104
        af = addr_un.sun_family = AF_UNIX;
 
105
        strncpy(addr_un.sun_path, socket_path,
 
106
                sizeof(addr_un.sun_path));
 
107
        addr_len = offsetof(struct sockaddr_un, sun_path) + spl + 1;
 
108
        addr = (struct sockaddr *)&addr_un;
 
109
    } else {
 
110
        return -1;
 
111
    }
 
112
 
 
113
    old_sigpipe = Signal(SIGPIPE, SIG_IGN);
 
114
 
 
115
    errors = 0;
 
116
    rval = -1;
116
117
  reopen:
117
 
        if ((fd = socket( af, SOCK_STREAM, 0 )) < 0) {
118
 
                logError( "Could not create socket: %m\n" );
119
 
                goto done;
120
 
        }
121
 
 
122
 
        if (connect( fd, (struct sockaddr *)addr, addr_len )) {
123
 
                if (af == AF_INET)
124
 
                        logError( "Could not connect to PRNGD port %d: %m\n",
125
 
                                  tcp_port );
126
 
                else
127
 
                        logError( "Could not connect to PRNGD socket %\"s: %m\n",
128
 
                                  socket_path );
129
 
                goto done;
130
 
        }
131
 
 
132
 
        /* Send blocking read request to PRNGD */
133
 
        msg[0] = 0x02;
134
 
        msg[1] = len;
135
 
 
136
 
        if (writer( fd, msg, sizeof(msg) ) != sizeof(msg)) {
137
 
                if (errno == EPIPE && errors < 10) {
138
 
                        close( fd );
139
 
                        errors++;
140
 
                        goto reopen;
141
 
                }
142
 
                logError( "Could not write to PRNGD socket: %m\n" );
143
 
                goto done;
144
 
        }
145
 
 
146
 
        if (reader( fd, buf, len ) != len) {
147
 
                if (errno == EPIPE && errors < 10) {
148
 
                        close( fd );
149
 
                        errors++;
150
 
                        goto reopen;
151
 
                }
152
 
                logError( "Could not read from PRNGD socket: %m\n" );
153
 
                goto done;
154
 
        }
155
 
 
156
 
        rval = 0;
 
118
    if ((fd = socket(af, SOCK_STREAM, 0)) < 0) {
 
119
        logError("Could not create socket: %m\n");
 
120
        goto done;
 
121
    }
 
122
 
 
123
    if (connect(fd, (struct sockaddr *)addr, addr_len)) {
 
124
        if (af == AF_INET)
 
125
            logError("Could not connect to PRNGD port %d: %m\n",
 
126
                     tcp_port);
 
127
        else
 
128
            logError("Could not connect to PRNGD socket %\"s: %m\n",
 
129
                     socket_path);
 
130
        goto done;
 
131
    }
 
132
 
 
133
    /* Send blocking read request to PRNGD */
 
134
    msg[0] = 0x02;
 
135
    msg[1] = len;
 
136
 
 
137
    if (writer(fd, msg, sizeof(msg)) != sizeof(msg)) {
 
138
        if (errno == EPIPE && errors < 10) {
 
139
            close(fd);
 
140
            errors++;
 
141
            goto reopen;
 
142
        }
 
143
        logError("Could not write to PRNGD socket: %m\n");
 
144
        goto done;
 
145
    }
 
146
 
 
147
    if (reader(fd, buf, len) != len) {
 
148
        if (errno == EPIPE && errors < 10) {
 
149
            close(fd);
 
150
            errors++;
 
151
            goto reopen;
 
152
        }
 
153
        logError("Could not read from PRNGD socket: %m\n");
 
154
        goto done;
 
155
    }
 
156
 
 
157
    rval = 0;
157
158
  done:
158
 
        Signal( SIGPIPE, old_sigpipe );
159
 
        if (fd != -1)
160
 
                        close( fd );
161
 
        return rval;
 
159
    Signal(SIGPIPE, old_sigpipe);
 
160
    if (fd != -1)
 
161
        close(fd);
 
162
    return rval;
162
163
}
163
164
 
164
165
/* ####################################################################### */
166
167
/*
167
168
 * Stolen from the Linux kernel.
168
169
 *
169
 
 * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
 
170
 * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
170
171
 * rights reserved.
171
172
 *
172
173
 * Redistribution and use in source and binary forms, with or without
199
200
static unsigned epool[32], erotate, eadd_ptr;
200
201
 
201
202
static void
202
 
addEntropy( unsigned const *in, int nwords )
 
203
addEntropy(unsigned const *in, int nwords)
203
204
{
204
 
        static unsigned const twist_table[8] = {
205
 
                         0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
206
 
                0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
207
 
        unsigned i, w;
208
 
        int new_rotate;
 
205
    static unsigned const twist_table[8] = {
 
206
                 0, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
 
207
        0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
 
208
    unsigned i, w;
 
209
    int new_rotate;
209
210
 
210
 
        while (nwords--) {
211
 
                w = *in++;
212
 
                w = (w<<erotate | w>>(32-erotate)) & 0xffffffff;
213
 
                i = eadd_ptr = (eadd_ptr - 1) & 31;
214
 
                new_rotate = erotate + 14;
215
 
                if (i)
216
 
                        new_rotate = erotate + 7;
217
 
                erotate = new_rotate & 31;
218
 
                w ^= epool[(i + 26) & 31];
219
 
                w ^= epool[(i + 20) & 31];
220
 
                w ^= epool[(i + 14) & 31];
221
 
                w ^= epool[(i + 7) & 31];
222
 
                w ^= epool[(i + 1) & 31];
223
 
                w ^= epool[i];
224
 
                epool[i] = (w >> 3) ^ twist_table[w & 7];
225
 
        }
 
211
    while (nwords--) {
 
212
        w = *in++;
 
213
        w = (w << erotate | w >> (32 - erotate)) & 0xffffffff;
 
214
        i = eadd_ptr = (eadd_ptr - 1) & 31;
 
215
        new_rotate = erotate + 14;
 
216
        if (i)
 
217
            new_rotate = erotate + 7;
 
218
        erotate = new_rotate & 31;
 
219
        w ^= epool[(i + 26) & 31];
 
220
        w ^= epool[(i + 20) & 31];
 
221
        w ^= epool[(i + 14) & 31];
 
222
        w ^= epool[(i + 7) & 31];
 
223
        w ^= epool[(i + 1) & 31];
 
224
        w ^= epool[i];
 
225
        epool[i] = (w >> 3) ^ twist_table[w & 7];
 
226
    }
226
227
}
227
228
 
228
229
/* ####################################################################### */
242
243
 
243
244
/* This is the central step in the MD5 algorithm. */
244
245
#define pmd5_step(f, w, x, y, z, data, s) \
245
 
                (w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x)
 
246
        (w += (f(x, y, z) + data) & 0xffffffff, w = w<<s | w>>(32-s), w += x)
246
247
 
247
248
/*
248
249
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
249
250
 * reflect the addition of 16 longwords of new data.
250
251
 */
251
252
static void
252
 
pMD5Hash( unsigned *out, unsigned const in[16] )
 
253
pMD5Hash(unsigned *out, unsigned const in[16])
253
254
{
254
 
        unsigned a, b, c, d;
255
 
 
256
 
        a = out[0];
257
 
        b = out[1];
258
 
        c = out[2];
259
 
        d = out[3];
260
 
 
261
 
        pmd5_step( F1, a, b, c, d, in[0] + 0xd76aa478, 7 );
262
 
        pmd5_step( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 );
263
 
        pmd5_step( F1, c, d, a, b, in[2] + 0x242070db, 17 );
264
 
        pmd5_step( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 );
265
 
        pmd5_step( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 );
266
 
        pmd5_step( F1, d, a, b, c, in[5] + 0x4787c62a, 12 );
267
 
        pmd5_step( F1, c, d, a, b, in[6] + 0xa8304613, 17 );
268
 
        pmd5_step( F1, b, c, d, a, in[7] + 0xfd469501, 22 );
269
 
        pmd5_step( F1, a, b, c, d, in[8] + 0x698098d8, 7 );
270
 
        pmd5_step( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 );
271
 
        pmd5_step( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 );
272
 
        pmd5_step( F1, b, c, d, a, in[11] + 0x895cd7be, 22 );
273
 
        pmd5_step( F1, a, b, c, d, in[12] + 0x6b901122, 7 );
274
 
        pmd5_step( F1, d, a, b, c, in[13] + 0xfd987193, 12 );
275
 
        pmd5_step( F1, c, d, a, b, in[14] + 0xa679438e, 17 );
276
 
        pmd5_step( F1, b, c, d, a, in[15] + 0x49b40821, 22 );
277
 
 
278
 
        pmd5_step( F2, a, b, c, d, in[1] + 0xf61e2562, 5 );
279
 
        pmd5_step( F2, d, a, b, c, in[6] + 0xc040b340, 9 );
280
 
        pmd5_step( F2, c, d, a, b, in[11] + 0x265e5a51, 14 );
281
 
        pmd5_step( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 );
282
 
        pmd5_step( F2, a, b, c, d, in[5] + 0xd62f105d, 5 );
283
 
        pmd5_step( F2, d, a, b, c, in[10] + 0x02441453, 9 );
284
 
        pmd5_step( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 );
285
 
        pmd5_step( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 );
286
 
        pmd5_step( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 );
287
 
        pmd5_step( F2, d, a, b, c, in[14] + 0xc33707d6, 9 );
288
 
        pmd5_step( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 );
289
 
        pmd5_step( F2, b, c, d, a, in[8] + 0x455a14ed, 20 );
290
 
        pmd5_step( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 );
291
 
        pmd5_step( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 );
292
 
        pmd5_step( F2, c, d, a, b, in[7] + 0x676f02d9, 14 );
293
 
        pmd5_step( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 );
294
 
 
295
 
        pmd5_step( F3, a, b, c, d, in[5] + 0xfffa3942, 4 );
296
 
        pmd5_step( F3, d, a, b, c, in[8] + 0x8771f681, 11 );
297
 
        pmd5_step( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 );
298
 
        pmd5_step( F3, b, c, d, a, in[14] + 0xfde5380c, 23 );
299
 
        pmd5_step( F3, a, b, c, d, in[1] + 0xa4beea44, 4 );
300
 
        pmd5_step( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 );
301
 
        pmd5_step( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 );
302
 
        pmd5_step( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 );
303
 
        pmd5_step( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 );
304
 
        pmd5_step( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 );
305
 
        pmd5_step( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 );
306
 
        pmd5_step( F3, b, c, d, a, in[6] + 0x04881d05, 23 );
307
 
        pmd5_step( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 );
308
 
        pmd5_step( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 );
309
 
        pmd5_step( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 );
310
 
        pmd5_step( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 );
311
 
 
312
 
        pmd5_step( F4, a, b, c, d, in[0] + 0xf4292244, 6 );
313
 
        pmd5_step( F4, d, a, b, c, in[7] + 0x432aff97, 10 );
314
 
        pmd5_step( F4, c, d, a, b, in[14] + 0xab9423a7, 15 );
315
 
        pmd5_step( F4, b, c, d, a, in[5] + 0xfc93a039, 21 );
316
 
        pmd5_step( F4, a, b, c, d, in[12] + 0x655b59c3, 6 );
317
 
        pmd5_step( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 );
318
 
        pmd5_step( F4, c, d, a, b, in[10] + 0xffeff47d, 15 );
319
 
        pmd5_step( F4, b, c, d, a, in[1] + 0x85845dd1, 21 );
320
 
        pmd5_step( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 );
321
 
        pmd5_step( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 );
322
 
        pmd5_step( F4, c, d, a, b, in[6] + 0xa3014314, 15 );
323
 
        pmd5_step( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 );
324
 
        pmd5_step( F4, a, b, c, d, in[4] + 0xf7537e82, 6 );
325
 
        pmd5_step( F4, d, a, b, c, in[11] + 0xbd3af235, 10 );
326
 
        pmd5_step( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 );
327
 
        pmd5_step( F4, b, c, d, a, in[9] + 0xeb86d391, 21 );
328
 
 
329
 
        out[0] += a;
330
 
        out[1] += b;
331
 
        out[2] += c;
332
 
        out[3] += d;
 
255
    unsigned a, b, c, d;
 
256
 
 
257
    a = out[0];
 
258
    b = out[1];
 
259
    c = out[2];
 
260
    d = out[3];
 
261
 
 
262
    pmd5_step(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
 
263
    pmd5_step(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
 
264
    pmd5_step(F1, c, d, a, b, in[2] + 0x242070db, 17);
 
265
    pmd5_step(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
 
266
    pmd5_step(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
 
267
    pmd5_step(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
 
268
    pmd5_step(F1, c, d, a, b, in[6] + 0xa8304613, 17);
 
269
    pmd5_step(F1, b, c, d, a, in[7] + 0xfd469501, 22);
 
270
    pmd5_step(F1, a, b, c, d, in[8] + 0x698098d8, 7);
 
271
    pmd5_step(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
 
272
    pmd5_step(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
 
273
    pmd5_step(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
 
274
    pmd5_step(F1, a, b, c, d, in[12] + 0x6b901122, 7);
 
275
    pmd5_step(F1, d, a, b, c, in[13] + 0xfd987193, 12);
 
276
    pmd5_step(F1, c, d, a, b, in[14] + 0xa679438e, 17);
 
277
    pmd5_step(F1, b, c, d, a, in[15] + 0x49b40821, 22);
 
278
 
 
279
    pmd5_step(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
 
280
    pmd5_step(F2, d, a, b, c, in[6] + 0xc040b340, 9);
 
281
    pmd5_step(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
 
282
    pmd5_step(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
 
283
    pmd5_step(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
 
284
    pmd5_step(F2, d, a, b, c, in[10] + 0x02441453, 9);
 
285
    pmd5_step(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
 
286
    pmd5_step(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
 
287
    pmd5_step(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
 
288
    pmd5_step(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
 
289
    pmd5_step(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
 
290
    pmd5_step(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
 
291
    pmd5_step(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
 
292
    pmd5_step(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
 
293
    pmd5_step(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
 
294
    pmd5_step(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
 
295
 
 
296
    pmd5_step(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
 
297
    pmd5_step(F3, d, a, b, c, in[8] + 0x8771f681, 11);
 
298
    pmd5_step(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
 
299
    pmd5_step(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
 
300
    pmd5_step(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
 
301
    pmd5_step(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
 
302
    pmd5_step(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
 
303
    pmd5_step(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
 
304
    pmd5_step(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
 
305
    pmd5_step(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
 
306
    pmd5_step(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
 
307
    pmd5_step(F3, b, c, d, a, in[6] + 0x04881d05, 23);
 
308
    pmd5_step(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
 
309
    pmd5_step(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
 
310
    pmd5_step(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
 
311
    pmd5_step(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
 
312
 
 
313
    pmd5_step(F4, a, b, c, d, in[0] + 0xf4292244, 6);
 
314
    pmd5_step(F4, d, a, b, c, in[7] + 0x432aff97, 10);
 
315
    pmd5_step(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
 
316
    pmd5_step(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
 
317
    pmd5_step(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
 
318
    pmd5_step(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
 
319
    pmd5_step(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
 
320
    pmd5_step(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
 
321
    pmd5_step(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
 
322
    pmd5_step(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
 
323
    pmd5_step(F4, c, d, a, b, in[6] + 0xa3014314, 15);
 
324
    pmd5_step(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
 
325
    pmd5_step(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
 
326
    pmd5_step(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
 
327
    pmd5_step(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
 
328
    pmd5_step(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
 
329
 
 
330
    out[0] += a;
 
331
    out[1] += b;
 
332
    out[2] += c;
 
333
    out[3] += d;
333
334
}
334
335
 
335
336
/* ####################################################################### */
336
337
 
337
338
 
338
339
static int
339
 
sumFile( const char *name, int len, int whence, long offset )
 
340
sumFile(const char *name, int len, int whence, long offset)
340
341
{
341
 
        int fd, i, cnt, readlen = 0;
342
 
        unsigned char buf[0x1000];
 
342
    int fd, i, cnt, readlen = 0;
 
343
    unsigned char buf[0x1000];
343
344
 
344
 
        if ((fd = open( name, O_RDONLY )) < 0) {
345
 
                debug( "cannot open entropy source %\"s: %m\n", name );
346
 
                return -1;
347
 
        }
348
 
        lseek( fd, offset, whence );
349
 
        while (readlen < len) {
350
 
                if (!(cnt = read( fd, buf, sizeof(buf) )))
351
 
                        break;
352
 
                if (cnt < 0) {
353
 
                        close( fd );
354
 
                        debug( "cannot read entropy source %\"s: %m\n", name );
355
 
                        return -1;
356
 
                }
357
 
                readlen += cnt;
358
 
                if (sizeof(unsigned) == 4)
359
 
                        addEntropy( (unsigned *)buf, (cnt + 3) / 4 );
360
 
                else {
361
 
                        unsigned buf2[sizeof(buf) / 4];
362
 
                        for (i = 0; i < cnt; i += 8) {
363
 
                                buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff;
364
 
                                buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32;
365
 
                        }
366
 
                        addEntropy( buf2, (cnt + 3) / 4 );
367
 
                }
368
 
        }
369
 
        close( fd );
370
 
        debug( "read %d bytes from entropy source %\"s\n", readlen, name );
371
 
        return readlen;
 
345
    if ((fd = open(name, O_RDONLY)) < 0) {
 
346
        debug("cannot open entropy source %\"s: %m\n", name);
 
347
        return -1;
 
348
    }
 
349
    lseek(fd, offset, whence);
 
350
    while (readlen < len) {
 
351
        if (!(cnt = read(fd, buf, sizeof(buf))))
 
352
            break;
 
353
        if (cnt < 0) {
 
354
            close(fd);
 
355
            debug("cannot read entropy source %\"s: %m\n", name);
 
356
            return -1;
 
357
        }
 
358
        readlen += cnt;
 
359
        if (sizeof(unsigned) == 4) {
 
360
            addEntropy((unsigned *)buf, (cnt + 3) / 4);
 
361
        } else {
 
362
            unsigned buf2[sizeof(buf) / 4];
 
363
            for (i = 0; i < cnt; i += 8) {
 
364
                buf2[i / 4] = *(unsigned *)(buf + i) & 0xffffffff;
 
365
                buf2[i / 4 + 1] = *(unsigned *)(buf + i) >> 32;
 
366
            }
 
367
            addEntropy(buf2, (cnt + 3) / 4);
 
368
        }
 
369
    }
 
370
    close(fd);
 
371
    debug("read %d bytes from entropy source %\"s\n", readlen, name);
 
372
    return readlen;
372
373
}
373
374
 
374
375
void
375
 
addTimerEntropy( void )
 
376
addTimerEntropy(void)
376
377
{
377
 
        struct timeval now;
378
 
        gettimeofday( &now, 0 );
379
 
        addEntropy( (unsigned *)&now, sizeof(now)/sizeof(unsigned) );
 
378
    struct timeval now;
 
379
    gettimeofday(&now, 0);
 
380
    addEntropy((unsigned *)&now, sizeof(now) / sizeof(unsigned));
380
381
}
381
382
 
382
383
#define BSIZ 0x10000
383
384
 
384
385
void
385
 
addOtherEntropy( void )
 
386
addOtherEntropy(void)
386
387
{
387
 
        addTimerEntropy();
388
 
        /* XXX -- setup-specific ... use some common ones */
389
 
        sumFile( "/var/log/messages", 0x1000, SEEK_END, -0x1000 );
390
 
        sumFile( "/var/log/syslog", 0x1000, SEEK_END, -0x1000 );
391
 
        sumFile( "/var/log/debug", 0x1000, SEEK_END, -0x1000 );
392
 
        sumFile( "/var/log/kern.log", 0x1000, SEEK_END, -0x1000 );
393
 
        sumFile( "/var/log/daemon.log", 0x1000, SEEK_END, -0x1000 );
 
388
    addTimerEntropy();
 
389
    /* XXX -- setup-specific ... use some common ones */
 
390
    sumFile("/var/log/messages", 0x1000, SEEK_END, -0x1000);
 
391
    sumFile("/var/log/syslog", 0x1000, SEEK_END, -0x1000);
 
392
    sumFile("/var/log/debug", 0x1000, SEEK_END, -0x1000);
 
393
    sumFile("/var/log/kern.log", 0x1000, SEEK_END, -0x1000);
 
394
    sumFile("/var/log/daemon.log", 0x1000, SEEK_END, -0x1000);
394
395
/* root hardly ever has an own box ... maybe pick a random mailbox instead? eek ...
395
 
        sumFile( "/var/spool/mail/root", 0x1000, SEEK_END, -0x1000 );
 
396
    sumFile("/var/spool/mail/root", 0x1000, SEEK_END, -0x1000);
396
397
*/
397
398
}
398
399
 
399
400
void
400
 
addPreGetEntropy( void )
 
401
addPreGetEntropy(void)
401
402
{
402
 
        static long offset;
403
 
        int readlen;
 
403
    static long offset;
 
404
    int readlen;
404
405
 
405
 
        addTimerEntropy();
406
 
        if ((readlen = sumFile( randomFile, BSIZ, SEEK_SET, offset )) == BSIZ) {
407
 
                offset += readlen;
 
406
    addTimerEntropy();
 
407
    if ((readlen = sumFile(randomFile, BSIZ, SEEK_SET, offset)) == BSIZ) {
 
408
        offset += readlen;
408
409
#if defined(__i386__) || defined(amiga)
409
 
                if (!strcmp( randomFile, "/dev/mem" )) {
410
 
                        if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
411
 
                                offset = 0x100000;
412
 
                        else if (offset == 0xf00000) /* skip 15-16MB memory hole */
413
 
                                offset = 0x1000000;
414
 
                }
 
410
        if (!strcmp(randomFile, "/dev/mem")) {
 
411
            if (offset == 0xa0000) /* skip 640kB-1MB ROM mappings */
 
412
                offset = 0x100000;
 
413
            else if (offset == 0xf00000) /* skip 15-16MB memory hole */
 
414
                offset = 0x1000000;
 
415
        }
415
416
#endif
416
 
                return;
417
 
        } else if (readlen >= 0 && offset) {
418
 
                if ((offset = sumFile( randomFile, BSIZ, SEEK_SET, 0 )) == BSIZ)
419
 
                        return;
420
 
        }
421
 
        logError( "Cannot read randomFile %\"s; "
422
 
                  "X cookies may be easily guessable\n", randomFile );
 
417
        return;
 
418
    } else if (readlen >= 0 && offset) {
 
419
        if ((offset = sumFile(randomFile, BSIZ, SEEK_SET, 0)) == BSIZ)
 
420
            return;
 
421
    }
 
422
    logError("Cannot read randomFile %\"s; "
 
423
             "X cookies may be easily guessable\n", randomFile);
423
424
}
424
425
#endif
425
426
 
426
427
/* len MUST be multiple of sizeof(unsigned) and not more than 16! */
427
428
/* auth MUST be sizeof(unsigned)-aligned! */
428
429
int
429
 
generateAuthData( char *auth, int len )
 
430
generateAuthData(char *auth, int len)
430
431
{
431
432
#ifdef HAVE_ARC4RANDOM
432
 
        int i;
433
 
        unsigned *rnd = (unsigned *)auth;
434
 
        if (sizeof(unsigned) == 4)
435
 
                for (i = 0; i < len; i += 4)
436
 
                        rnd[i / 4] = arc4random();
437
 
        else
438
 
                for (i = 0; i < len; i += 8)
439
 
                        rnd[i / 8] = arc4random() | (arc4random() << 32);
440
 
        return True;
 
433
    int i;
 
434
    unsigned *rnd = (unsigned *)auth;
 
435
    if (sizeof(unsigned) == 4)
 
436
        for (i = 0; i < len; i += 4)
 
437
            rnd[i / 4] = arc4random();
 
438
    else
 
439
        for (i = 0; i < len; i += 8)
 
440
            rnd[i / 8] = arc4random() | (arc4random() << 32);
 
441
    return True;
441
442
#else
442
 
        int fd;
443
 
        const char *rd = randomDevice;
 
443
    int fd;
 
444
    const char *rd = randomDevice;
444
445
# ifdef DEV_RANDOM
445
 
        if (!*rd)
446
 
                rd = DEV_RANDOM;
 
446
    if (!*rd)
 
447
        rd = DEV_RANDOM;
447
448
# else
448
 
        if (*rd) {
 
449
    if (*rd) {
449
450
# endif
450
 
                if ((fd = open( rd, O_RDONLY )) >= 0) {
451
 
                        if (read( fd, auth, len ) == len) {
452
 
                                close( fd );
453
 
                                return True;
454
 
                        }
455
 
                        close( fd );
456
 
                        logError( "Cannot read randomDevice %\"s: %m\n", rd );
457
 
                } else
458
 
                        logError( "Cannot open randomDevice %\"s: %m\n", rd );
 
451
        if ((fd = open(rd, O_RDONLY)) >= 0) {
 
452
            if (read(fd, auth, len) == len) {
 
453
                close(fd);
 
454
                return True;
 
455
            }
 
456
            close(fd);
 
457
            logError("Cannot read randomDevice %\"s: %m\n", rd);
 
458
        } else
 
459
            logError("Cannot open randomDevice %\"s: %m\n", rd);
459
460
# ifdef DEV_RANDOM
460
 
                return False;
 
461
        return False;
461
462
# else
462
 
        }
463
 
 
464
 
        if (!getPrngdBytes( auth, len, prngdPort, prngdSocket ))
465
 
                return True;
466
 
 
467
 
        {
468
 
                unsigned *rnd = (unsigned *)auth;
469
 
                unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
470
 
                addPreGetEntropy();
471
 
                pMD5Hash( tmp, epool );
472
 
                addEntropy( tmp, 1 );
473
 
                pMD5Hash( tmp, epool + 16 );
474
 
                addEntropy( tmp + 2, 1 );
475
 
                if (sizeof(unsigned) == 4)
476
 
                        memcpy( auth, tmp, len );
477
 
                else {
478
 
                        int i;
479
 
                        for (i = 0; i < len; i += 8)
480
 
                                rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32);
481
 
                }
482
 
        }
483
 
        return True;
 
463
    }
 
464
 
 
465
    if (!getPrngdBytes(auth, len, prngdPort, prngdSocket))
 
466
        return True;
 
467
 
 
468
    {
 
469
        unsigned *rnd = (unsigned *)auth;
 
470
        unsigned tmp[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
 
471
        addPreGetEntropy();
 
472
        pMD5Hash(tmp, epool);
 
473
        addEntropy(tmp, 1);
 
474
        pMD5Hash(tmp, epool + 16);
 
475
        addEntropy(tmp + 2, 1);
 
476
        if (sizeof(unsigned) == 4) {
 
477
            memcpy(auth, tmp, len);
 
478
        } else {
 
479
            int i;
 
480
            for (i = 0; i < len; i += 8)
 
481
                rnd[i / 8] = tmp[i / 4] | (tmp[i / 4 + 1] << 32);
 
482
        }
 
483
    }
 
484
    return True;
484
485
# endif
485
486
#endif
486
487
}
487
488
 
488
489
#ifndef HAVE_ARC4RANDOM
489
490
int
490
 
secureRandom( void )
 
491
secureRandom(void)
491
492
{
492
 
        int rslt;
493
 
        generateAuthData( (char *)&rslt, sizeof(int) );
494
 
        return rslt & 0x7fffffff;
 
493
    int rslt;
 
494
    generateAuthData((char *)&rslt, sizeof(int));
 
495
    return rslt & 0x7fffffff;
495
496
}
496
497
#endif