You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by "Victor J. Orlikowski" <vj...@dulug.duke.edu> on 2002/07/09 11:34:29 UTC
[PATCH] Modifications to egd/prngd support
The following patch, for which I have to give much credit for the
inspiration to the OpenSSL guys, allows one to simply do a --with-egd
when doing a configure, which will cause the probe of a set of
pre-determined sockets for egd. One can still do a --with-egd=blah
with this patch.
Looking for comments/complaints, prior to a commit.
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.460
diff -u -d -r1.460 configure.in
--- configure.in 2 Jul 2002 21:33:43 -0000 1.460
+++ configure.in 9 Jul 2002 09:28:59 -0000
@@ -1544,11 +1544,12 @@
AC_ARG_WITH(egd,
[ --with-egd=<path> use egd-compatible socket],
- [ if test "$withval" = "yes"; then
- AC_ERROR([You must specify a default EGD socket path.])
+ [ AC_DEFINE(HAVE_EGD)
+ if test "$withval" = "yes"; then
+ AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, ["/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"])
+ else
+ AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, ["$withval"])
fi
- AC_DEFINE(HAVE_EGD)
- AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, [$withval])
AC_MSG_RESULT(EGD-compatible daemon)
rand="1"
])
Index: misc/unix/rand.c
===================================================================
RCS file: /home/cvs/apr/misc/unix/rand.c,v
retrieving revision 1.13
diff -u -d -r1.13 rand.c
--- misc/unix/rand.c 25 Jun 2002 21:24:07 -0000 1.13
+++ misc/unix/rand.c 9 Jul 2002 09:28:59 -0000
@@ -86,7 +86,7 @@
#ifdef DEV_RANDOM
int rnd;
- size_t got, tot;
+ apr_size_t got, tot;
if ((rnd = open(STR(DEV_RANDOM), O_RDONLY)) == -1)
return errno;
@@ -119,76 +119,87 @@
* 0x04 (report PID)
* 0xMM (length of PID string, not null-terminated) MM chars
*/
- int egd_socket, egd_path_len, rv;
+ static const char *egd_sockets[] = { EGD_DEFAULT_SOCKET, NULL };
+ const char **egdsockname = NULL;
+
+ int egd_socket, egd_path_len, rv, bad_errno;
struct sockaddr_un addr;
apr_socklen_t egd_addr_len;
- size_t resp_expected;
+ apr_size_t resp_expected;
unsigned char req[2], resp[255];
unsigned char *curbuf = buf;
- egd_path_len = strlen(STR(EGD_DEFAULT_SOCKET));
-
- if (egd_path_len > sizeof(addr.sun_path)) {
- return APR_EINVAL;
- }
-
- memset(&addr, 0, sizeof(struct sockaddr_un));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, STR(EGD_DEFAULT_SOCKET), egd_path_len);
- egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
- egd_path_len;
-
- egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
-
- if (egd_socket == -1) {
- return errno;
- }
+ for (egdsockname = egd_sockets; *egdsockname && length > 0; egdsockname++) {
+ egd_path_len = strlen(*egdsockname);
+
+ if (egd_path_len > sizeof(addr.sun_path)) {
+ return APR_EINVAL;
+ }
- rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, *egdsockname, egd_path_len);
+ egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
+ egd_path_len;
- if (rv == -1) {
- return errno;
- }
+ egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- /* EGD can only return 255 bytes of data at a time. Silly. */
- while (length > 0) {
- ssize_t srv;
- req[0] = 2; /* We'll block for now. */
- req[1] = length > 255 ? 255: length;
+ if (egd_socket == -1) {
+ return errno;
+ }
- srv = write(egd_socket, req, 2);
- if (srv == -1) {
- int bad_errno = errno;
+ rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return bad_errno;
+ if (rv == -1) {
+ bad_errno = errno;
+ continue;
}
- if (srv != 2) {
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return APR_EGENERAL; /* Try again. */
- }
+ /* EGD can only return 255 bytes of data at a time. Silly. */
+ while (length > 0) {
+ apr_ssize_t srv;
+ req[0] = 2; /* We'll block for now. */
+ req[1] = length > 255 ? 255: length;
- resp_expected = req[1];
- srv = read(egd_socket, resp, resp_expected);
- if (srv == -1) {
- int bad_errno = errno;
+ srv = write(egd_socket, req, 2);
+ if (srv == -1) {
+ bad_errno = errno;
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ break;
+ }
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return bad_errno;
+ if (srv != 2) {
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ return APR_EGENERAL;
+ }
+
+ resp_expected = req[1];
+ srv = read(egd_socket, resp, resp_expected);
+ if (srv == -1) {
+ bad_errno = errno;
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ return bad_errno;
+ }
+
+ memcpy(curbuf, resp, srv);
+ curbuf += srv;
+ length -= srv;
}
+
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ }
- memcpy(curbuf, resp, srv);
- curbuf += srv;
- length -= srv;
+ if (length > 0) {
+ /* We must have iterated through the list of sockets,
+ * and no go. Return the errno.
+ */
+ return bad_errno;
}
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
-
#elif defined(HAVE_TRUERAND) /* use truerand */
extern int randbyte(void); /* from the truerand library */
Thanks,
Victor
--
Victor J. Orlikowski | The Wall is Down, But the Threat Remains!
==================================================================
orlikowski@apache.org | vjo@dulug.duke.edu | vjo@us.ibm.com
Re: [PATCH] Modifications to egd/prngd support
Posted by Jeff Trawick <tr...@attglobal.net>.
"Victor J. Orlikowski" <vj...@dulug.duke.edu> writes:
> The following patch, for which I have to give much credit for the
> inspiration to the OpenSSL guys, allows one to simply do a --with-egd
> when doing a configure, which will cause the probe of a set of
> pre-determined sockets for egd. One can still do a --with-egd=blah
> with this patch.
>
> Looking for comments/complaints, prior to a commit.
+1 (concept)
As a follow-on I'd love to see an APR configure option which is
equivalent to:
if this system has something like /dev/random then
use /dev/random (or whatever)
else
pretend the user specified --with-egd
Then the user of a binary build would have the opportunity to add
random support without rebuilding APR... for something like an Apache
binary build, further function (e.g., mod_auth_digest) could be made
to work by the user without rebuilding Apache...
> Index: configure.in
> ===================================================================
> RCS file: /home/cvs/apr/configure.in,v
> retrieving revision 1.460
> diff -u -d -r1.460 configure.in
> --- configure.in 2 Jul 2002 21:33:43 -0000 1.460
> +++ configure.in 9 Jul 2002 09:28:59 -0000
> @@ -1544,11 +1544,12 @@
>
> AC_ARG_WITH(egd,
> [ --with-egd=<path> use egd-compatible socket],
probably "=<path>" should be surrounded with [[]], or whatever it
takes to display
--with-egd[=<path>] use egd-compatible socket
when they do ./configure --help
> - [ if test "$withval" = "yes"; then
> - AC_ERROR([You must specify a default EGD socket path.])
> + [ AC_DEFINE(HAVE_EGD)
> + if test "$withval" = "yes"; then
> + AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, ["/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"])
> + else
> + AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, ["$withval"])
> fi
> - AC_DEFINE(HAVE_EGD)
> - AC_DEFINE_UNQUOTED(EGD_DEFAULT_SOCKET, [$withval])
> AC_MSG_RESULT(EGD-compatible daemon)
> rand="1"
> ])
> Index: misc/unix/rand.c
> ===================================================================
> RCS file: /home/cvs/apr/misc/unix/rand.c,v
> retrieving revision 1.13
> diff -u -d -r1.13 rand.c
> --- misc/unix/rand.c 25 Jun 2002 21:24:07 -0000 1.13
> +++ misc/unix/rand.c 9 Jul 2002 09:28:59 -0000
> @@ -86,7 +86,7 @@
> #ifdef DEV_RANDOM
>
> int rnd;
> - size_t got, tot;
> + apr_size_t got, tot;
>
> if ((rnd = open(STR(DEV_RANDOM), O_RDONLY)) == -1)
> return errno;
> @@ -119,76 +119,87 @@
> * 0x04 (report PID)
> * 0xMM (length of PID string, not null-terminated) MM chars
> */
> - int egd_socket, egd_path_len, rv;
> + static const char *egd_sockets[] = { EGD_DEFAULT_SOCKET, NULL };
> + const char **egdsockname = NULL;
> +
> + int egd_socket, egd_path_len, rv, bad_errno;
> struct sockaddr_un addr;
> apr_socklen_t egd_addr_len;
> - size_t resp_expected;
> + apr_size_t resp_expected;
> unsigned char req[2], resp[255];
> unsigned char *curbuf = buf;
>
> - egd_path_len = strlen(STR(EGD_DEFAULT_SOCKET));
> -
> - if (egd_path_len > sizeof(addr.sun_path)) {
> - return APR_EINVAL;
> - }
> -
> - memset(&addr, 0, sizeof(struct sockaddr_un));
> - addr.sun_family = AF_UNIX;
> - memcpy(addr.sun_path, STR(EGD_DEFAULT_SOCKET), egd_path_len);
> - egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
> - egd_path_len;
> -
> - egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
> -
> - if (egd_socket == -1) {
> - return errno;
> - }
> + for (egdsockname = egd_sockets; *egdsockname && length > 0; egdsockname++) {
> + egd_path_len = strlen(*egdsockname);
> +
> + if (egd_path_len > sizeof(addr.sun_path)) {
> + return APR_EINVAL;
> + }
>
> - rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
> + memset(&addr, 0, sizeof(struct sockaddr_un));
> + addr.sun_family = AF_UNIX;
> + memcpy(addr.sun_path, *egdsockname, egd_path_len);
> + egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
> + egd_path_len;
>
> - if (rv == -1) {
> - return errno;
> - }
> + egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
>
> - /* EGD can only return 255 bytes of data at a time. Silly. */
> - while (length > 0) {
> - ssize_t srv;
> - req[0] = 2; /* We'll block for now. */
> - req[1] = length > 255 ? 255: length;
> + if (egd_socket == -1) {
> + return errno;
> + }
>
> - srv = write(egd_socket, req, 2);
> - if (srv == -1) {
> - int bad_errno = errno;
> + rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
>
> - shutdown(egd_socket, SHUT_RDWR);
> - close(egd_socket);
> - return bad_errno;
> + if (rv == -1) {
> + bad_errno = errno;
> + continue;
> }
>
> - if (srv != 2) {
> - shutdown(egd_socket, SHUT_RDWR);
> - close(egd_socket);
> - return APR_EGENERAL; /* Try again. */
> - }
> + /* EGD can only return 255 bytes of data at a time. Silly. */
> + while (length > 0) {
> + apr_ssize_t srv;
> + req[0] = 2; /* We'll block for now. */
> + req[1] = length > 255 ? 255: length;
>
> - resp_expected = req[1];
> - srv = read(egd_socket, resp, resp_expected);
> - if (srv == -1) {
> - int bad_errno = errno;
> + srv = write(egd_socket, req, 2);
> + if (srv == -1) {
> + bad_errno = errno;
> + shutdown(egd_socket, SHUT_RDWR);
> + close(egd_socket);
> + break;
> + }
>
> - shutdown(egd_socket, SHUT_RDWR);
> - close(egd_socket);
> - return bad_errno;
> + if (srv != 2) {
> + shutdown(egd_socket, SHUT_RDWR);
> + close(egd_socket);
> + return APR_EGENERAL;
> + }
> +
> + resp_expected = req[1];
> + srv = read(egd_socket, resp, resp_expected);
> + if (srv == -1) {
> + bad_errno = errno;
> + shutdown(egd_socket, SHUT_RDWR);
> + close(egd_socket);
> + return bad_errno;
> + }
> +
> + memcpy(curbuf, resp, srv);
> + curbuf += srv;
> + length -= srv;
> }
> +
> + shutdown(egd_socket, SHUT_RDWR);
> + close(egd_socket);
> + }
>
> - memcpy(curbuf, resp, srv);
> - curbuf += srv;
> - length -= srv;
> + if (length > 0) {
> + /* We must have iterated through the list of sockets,
> + * and no go. Return the errno.
> + */
> + return bad_errno;
> }
>
> - shutdown(egd_socket, SHUT_RDWR);
> - close(egd_socket);
> -
> #elif defined(HAVE_TRUERAND) /* use truerand */
>
> extern int randbyte(void); /* from the truerand library */
>
> Thanks,
> Victor
> --
> Victor J. Orlikowski | The Wall is Down, But the Threat Remains!
> ==================================================================
> orlikowski@apache.org | vjo@dulug.duke.edu | vjo@us.ibm.com
>
--
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...