Skip to content

Commit faae1c9

Browse files
committed
Revert "Replace PostmasterRandom() with a stronger way of generating randomness."
This reverts commit 9e083fd. That was a few bricks shy of a load: * Query cancel stopped working * Buildfarm member pademelon stopped working, because the box doesn't have /dev/urandom nor /dev/random. This clearly needs some more discussion, and a quite different patch, so revert for now.
1 parent 7d3235b commit faae1c9

File tree

9 files changed

+384
-244
lines changed

9 files changed

+384
-244
lines changed

contrib/pgcrypto/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pgcrypto/Makefile
22

33
INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \
4-
fortuna.c pgp-mpi-internal.c imath.c
4+
fortuna.c random.c pgp-mpi-internal.c imath.c
55
INT_TESTS = sha2
66

77
OSSL_SRCS = openssl.c pgp-mpi-openssl.c

contrib/pgcrypto/internal.c

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,8 @@ static time_t check_time = 0;
626626
static void
627627
system_reseed(void)
628628
{
629+
uint8 buf[1024];
630+
int n;
629631
time_t t;
630632
int skip = 1;
631633

@@ -640,34 +642,24 @@ system_reseed(void)
640642
else if (check_time == 0 ||
641643
(t - check_time) > SYSTEM_RESEED_CHECK_TIME)
642644
{
643-
uint8 buf;
644-
645645
check_time = t;
646646

647647
/* roll dice */
648-
px_get_random_bytes(&buf, 1);
649-
skip = (buf >= SYSTEM_RESEED_CHANCE);
650-
651-
/* clear 1 byte */
652-
px_memset(&buf, 0, sizeof(buf));
653-
}
654-
if (!skip)
655-
{
656-
/*
657-
* fortuna_add_entropy passes the input to SHA-256, so there's no
658-
* point in giving it more than 256 bits of input to begin with.
659-
*/
660-
uint8 buf[32];
661-
662-
if (!pg_strong_random(buf, sizeof(buf)))
663-
ereport(ERROR,
664-
(errcode(ERRCODE_INTERNAL_ERROR),
665-
errmsg("could not acquire random data")));
666-
fortuna_add_entropy(buf, sizeof(buf));
667-
668-
seed_time = t;
669-
px_memset(buf, 0, sizeof(buf));
648+
px_get_random_bytes(buf, 1);
649+
skip = buf[0] >= SYSTEM_RESEED_CHANCE;
670650
}
651+
/* clear 1 byte */
652+
px_memset(buf, 0, sizeof(buf));
653+
654+
if (skip)
655+
return;
656+
657+
n = px_acquire_system_randomness(buf);
658+
if (n > 0)
659+
fortuna_add_entropy(buf, n);
660+
661+
seed_time = t;
662+
px_memset(buf, 0, sizeof(buf));
671663
}
672664

673665
int

contrib/pgcrypto/random.c

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/*
2+
* random.c
3+
* Acquire randomness from system. For seeding RNG.
4+
*
5+
* Copyright (c) 2001 Marko Kreen
6+
* All rights reserved.
7+
*
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions
10+
* are met:
11+
* 1. Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27+
* SUCH DAMAGE.
28+
*
29+
* contrib/pgcrypto/random.c
30+
*/
31+
32+
#include "postgres.h"
33+
34+
#include "px.h"
35+
#include "utils/memdebug.h"
36+
37+
/* how many bytes to ask from system random provider */
38+
#define RND_BYTES 32
39+
40+
/*
41+
* Try to read from /dev/urandom or /dev/random on these OS'es.
42+
*
43+
* The list can be pretty liberal, as the device not existing
44+
* is expected event.
45+
*/
46+
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
47+
|| defined(__NetBSD__) || defined(__DragonFly__) \
48+
|| defined(__darwin__) || defined(__SOLARIS__) \
49+
|| defined(__hpux) || defined(__HPUX__) \
50+
|| defined(__CYGWIN__) || defined(_AIX)
51+
52+
#define TRY_DEV_RANDOM
53+
54+
#include <fcntl.h>
55+
#include <unistd.h>
56+
57+
static int
58+
safe_read(int fd, void *buf, size_t count)
59+
{
60+
int done = 0;
61+
char *p = buf;
62+
int res;
63+
64+
while (count)
65+
{
66+
res = read(fd, p, count);
67+
if (res <= 0)
68+
{
69+
if (errno == EINTR)
70+
continue;
71+
return PXE_DEV_READ_ERROR;
72+
}
73+
p += res;
74+
done += res;
75+
count -= res;
76+
}
77+
return done;
78+
}
79+
80+
static uint8 *
81+
try_dev_random(uint8 *dst)
82+
{
83+
int fd;
84+
int res;
85+
86+
fd = open("/dev/urandom", O_RDONLY, 0);
87+
if (fd == -1)
88+
{
89+
fd = open("/dev/random", O_RDONLY, 0);
90+
if (fd == -1)
91+
return dst;
92+
}
93+
res = safe_read(fd, dst, RND_BYTES);
94+
close(fd);
95+
if (res > 0)
96+
dst += res;
97+
return dst;
98+
}
99+
#endif
100+
101+
/*
102+
* Try to find randomness on Windows
103+
*/
104+
#ifdef WIN32
105+
106+
#define TRY_WIN32_GENRAND
107+
#define TRY_WIN32_PERFC
108+
109+
#include <windows.h>
110+
#include <wincrypt.h>
111+
112+
/*
113+
* this function is from libtomcrypt
114+
*
115+
* try to use Microsoft crypto API
116+
*/
117+
static uint8 *
118+
try_win32_genrand(uint8 *dst)
119+
{
120+
int res;
121+
HCRYPTPROV h = 0;
122+
123+
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
124+
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
125+
if (!res)
126+
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
127+
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET);
128+
if (!res)
129+
return dst;
130+
131+
res = CryptGenRandom(h, RND_BYTES, dst);
132+
if (res == TRUE)
133+
dst += RND_BYTES;
134+
135+
CryptReleaseContext(h, 0);
136+
return dst;
137+
}
138+
139+
static uint8 *
140+
try_win32_perfc(uint8 *dst)
141+
{
142+
int res;
143+
LARGE_INTEGER time;
144+
145+
res = QueryPerformanceCounter(&time);
146+
if (!res)
147+
return dst;
148+
149+
memcpy(dst, &time, sizeof(time));
150+
return dst + sizeof(time);
151+
}
152+
#endif /* WIN32 */
153+
154+
155+
/*
156+
* If we are not on Windows, then hopefully we are
157+
* on a unix-like system. Use the usual suspects
158+
* for randomness.
159+
*/
160+
#ifndef WIN32
161+
162+
#define TRY_UNIXSTD
163+
164+
#include <sys/types.h>
165+
#include <sys/time.h>
166+
#include <time.h>
167+
#include <unistd.h>
168+
169+
/*
170+
* Everything here is predictible, only needs some patience.
171+
*
172+
* But there is a chance that the system-specific functions
173+
* did not work. So keep faith and try to slow the attacker down.
174+
*/
175+
static uint8 *
176+
try_unix_std(uint8 *dst)
177+
{
178+
pid_t pid;
179+
int x;
180+
PX_MD *md;
181+
struct timeval tv;
182+
int res;
183+
184+
/* process id */
185+
pid = getpid();
186+
memcpy(dst, (uint8 *) &pid, sizeof(pid));
187+
dst += sizeof(pid);
188+
189+
/* time */
190+
gettimeofday(&tv, NULL);
191+
memcpy(dst, (uint8 *) &tv, sizeof(tv));
192+
dst += sizeof(tv);
193+
194+
/* pointless, but should not hurt */
195+
x = random();
196+
memcpy(dst, (uint8 *) &x, sizeof(x));
197+
dst += sizeof(x);
198+
199+
/* hash of uninitialized stack and heap allocations */
200+
res = px_find_digest("sha1", &md);
201+
if (res >= 0)
202+
{
203+
uint8 *ptr;
204+
uint8 stack[8192];
205+
int alloc = 32 * 1024;
206+
207+
VALGRIND_MAKE_MEM_DEFINED(stack, sizeof(stack));
208+
px_md_update(md, stack, sizeof(stack));
209+
ptr = px_alloc(alloc);
210+
VALGRIND_MAKE_MEM_DEFINED(ptr, alloc);
211+
px_md_update(md, ptr, alloc);
212+
px_free(ptr);
213+
214+
px_md_finish(md, dst);
215+
px_md_free(md);
216+
217+
dst += 20;
218+
}
219+
220+
return dst;
221+
}
222+
#endif
223+
224+
/*
225+
* try to extract some randomness for initial seeding
226+
*
227+
* dst should have room for 1024 bytes.
228+
*/
229+
unsigned
230+
px_acquire_system_randomness(uint8 *dst)
231+
{
232+
uint8 *p = dst;
233+
234+
#ifdef TRY_DEV_RANDOM
235+
p = try_dev_random(p);
236+
#endif
237+
#ifdef TRY_WIN32_GENRAND
238+
p = try_win32_genrand(p);
239+
#endif
240+
#ifdef TRY_WIN32_PERFC
241+
p = try_win32_perfc(p);
242+
#endif
243+
#ifdef TRY_UNIXSTD
244+
p = try_unix_std(p);
245+
#endif
246+
return p - dst;
247+
}

src/backend/libpq/auth.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ static void auth_failed(Port *port, int status, char *logdetail);
4545
static char *recv_password_packet(Port *port);
4646
static int recv_and_check_password_packet(Port *port, char **logdetail);
4747

48-
/*----------------------------------------------------------------
49-
* MD5 authentication
50-
*----------------------------------------------------------------
51-
*/
52-
static int CheckMD5Auth(Port *port, char **logdetail);
53-
5448

5549
/*----------------------------------------------------------------
5650
* Ident authentication
@@ -541,7 +535,9 @@ ClientAuthentication(Port *port)
541535
ereport(FATAL,
542536
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
543537
errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
544-
status = CheckMD5Auth(port, &logdetail);
538+
/* include the salt to use for computing the response */
539+
sendAuthRequest(port, AUTH_REQ_MD5, port->md5Salt, 4);
540+
status = recv_and_check_password_packet(port, &logdetail);
545541
break;
546542

547543
case uaPassword:
@@ -696,25 +692,10 @@ recv_password_packet(Port *port)
696692

697693

698694
/*----------------------------------------------------------------
699-
* MD5 and password authentication
695+
* MD5 authentication
700696
*----------------------------------------------------------------
701697
*/
702698

703-
static int
704-
CheckMD5Auth(Port *port, char **logdetail)
705-
{
706-
/* include the salt to use for computing the response */
707-
if (!pg_strong_random(port->md5Salt, sizeof(port->md5Salt)))
708-
{
709-
*logdetail = psprintf(_("Could not generate random salt"));
710-
return STATUS_ERROR;
711-
}
712-
713-
sendAuthRequest(port, AUTH_REQ_MD5, port->md5Salt, 4);
714-
return recv_and_check_password_packet(port, logdetail);
715-
}
716-
717-
718699
/*
719700
* Called when we have sent an authorization request for a password.
720701
* Get the response and check it.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy