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...