"Victor J. Orlikowski" <[EMAIL PROTECTED]> 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!
> ==================================================================
> [EMAIL PROTECTED]  | [EMAIL PROTECTED] | [EMAIL PROTECTED]
> 

-- 
Jeff Trawick | [EMAIL PROTECTED]
Born in Roswell... married an alien...

Reply via email to