Hi Jeff,

Thanks for forwarding your patch from October 2013, looks like I missed
that one when searching for an earlier solution.
Do you know why your patch didn't make it into the OpenSSL
(master/current) branch(es) ?

Sidenote - I found yet another, third, very similar approach in
apps/apps.c on line 3370 from master:

#if defined(_WIN32) && defined(STD_INPUT_HANDLE)


The master branch compiles succesfully on Windows using msys/mingw(64),
including proper assembly code.


Peter Mosmans


On 19-7-2014 22:48, Jeff Trawick wrote:
> On Sat, Jul 19, 2014 at 3:14 AM, Support via RT <[email protected]
> <mailto:[email protected]>> wrote:
>
>
>     Hi,
>
>     When using OpenSSL on Windows I noticed that it's impossible to
>     redirect
>     / pipe commands directly to openssl s_client. The client apparently
>     keeps waiting for user input. For example, the following commands
>     don' t
>     work (the connection times out or waits for user input).
>     echo Q | openssl s_client -connect www.google.com:443
>     <http://www.google.com:443>
>     openssl s_client -connect www.google.com:443
>     <http://www.google.com:443> < file_containing_QUIT_and_EOL
>
>     In 2013 there was a discussion about this on the OpenSSL users
>     mailinglist (see
>     
> http://openssl.6102.n7.nabble.com/openssl-s-client-takes-over-30-seconds-to-complete-on-Windows-td45781.html
>     Other discussions can be found on StackOverflow, for example
>     
> http://stackoverflow.com/questions/16823068/gnuwin32-openssl-s-client-conn-to-websphere-mq-server-not-closing-at-eof-hangs
>     or
>     http://stackoverflow.com/questions/9450120/openssl-hangs-and-does-not-exit
>
>     Apparently the solution is already implemented in apps/s_client.c
>     (line
>     1836-1840) with the WaitForSingleObject call.
>
>     #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
>                             /* Under Windows/DOS we make the
>     assumption that
>     we can
>                  * always write to the tty: therefore if we need to
>                  * write to the tty we just fall through. Otherwise
>                  * we timeout the select every second and see if there
>                  * are any keypresses. Note: this is a hack, in a proper
>                  * Windows application we wouldn't do this.
>                  */
>                 i=0;
>                 if(!write_tty) {
>                     if(read_tty) {
>                         tv.tv_sec = 1;
>                         tv.tv_usec = 0;
>                         i=select(width,(void *)&readfds,(void *)&writefds,
>                              NULL,&tv);
>     #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
>                         if(!i && (!_kbhit() || !read_tty) ) continue;
>     #else
>                         if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 ==
>     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) ||
>     !read_tty) )
>     continue;
>     #endif
>
>     However the statement that fixes this (the WaitForSingleObject call )
>     (almost) never gets compiled on Windows, at least not when
>     OPENSSL_SYS_WINCE or OPENSSL_SYS_MSDOS are defined. The latter is
>     (among
>     other places) defined in e_os2.h (line 119-126)
>
>     /* Anything that tries to look like Microsoft is "Windows" */
>     #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) ||
>     defined(OPENSSL_SYS_WINCE)
>     # undef OPENSSL_SYS_UNIX
>     # define OPENSSL_SYS_WINDOWS
>     # ifndef OPENSSL_SYS_MSDOS
>     #  define OPENSSL_SYS_MSDOS
>     # endif
>     #endif
>
>     This effectively means that OPENSSL_SYS_MSDOS is (almost) always
>     defined
>     when compiling for Windows, rendering the solution useless.
>
>     Please find attached a patch for the OpenSSL master branch, where
>     apps/s_client.c is modified. It removes the OPENSSL_SYS_MSDOS
>     requirement.
>     After patching, input/output isn't blocked anymore and the following
>     commands work:
>     echo Q | openssl s_client -connect www.google.com:443
>     <http://www.google.com:443>
>     openssl s_client -connect www.google.com:443
>     <http://www.google.com:443> < file_containing_QUIT_and_EOL
>
>     Tested under Windows when compiling on msys with mingw / mingw64.
>     Please
>     note that I haven't tested compiling on Cygwin.
>     The WaitForSingleObject function is supported by Windows CE 5.0
>     and higher.
>
>
>     Hope this helps someone,
>     thanks for your consideration,
>
>     Peter Mosmans
>
>
> Hopefully somebody will have a look at this.
>
> The patch I posted last year seems a bit more correct platform-wise
> IMHO, but the real problem is shoving in all this platform "support"
> over time without introducing appropriate abstractions.
>
> http://openssl.6102.n7.nabble.com/PATCH-s-client-Fix-keypress-requirement-with-redirected-input-on-Windows-tt46787.html#none
> http://openssl.6102.n7.nabble.com/attachment/46787/0/s_client_USE_STD_INPUT_HANDLE.txt
>
>
>
>
>     diff --git a/apps/s_client.c b/apps/s_client.c
>     index e1be6a9..f2bc1fd 100644
>     --- a/apps/s_client.c
>     +++ b/apps/s_client.c
>     @@ -1833,7 +1833,7 @@ SSL_set_tlsext_status_ids(con, ids);
>                                             tv.tv_usec = 0;
>                                             i=select(width,(void
>     *)&readfds,(void *)&writefds,
>                                                      NULL,&tv);
>     -#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
>     +#if defined(OPENSSL_SYS_WINCE)
>                                             if(!i && (!_kbhit() ||
>     !read_tty) ) continue;
>      #else
>                                             if(!i && (!((_kbhit()) ||
>     (WAIT_OBJECT_0 ==
>     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) ||
>     !read_tty) ) continue;
>     @@ -2044,7 +2044,7 @@ printf("read=%d pending=%d
>     peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240
>                             }
>
>      #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
>     -#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
>     +#if defined(OPENSSL_SYS_WINCE)
>                     else if (_kbhit())
>      #else
>                     else if ((_kbhit()) || (WAIT_OBJECT_0 ==
>     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
>
>
>
>
> -- 
> Born in Roswell... married an alien...
> http://emptyhammock.com/
> http://edjective.org/
>

Reply via email to