On Sat, Jul 19, 2014 at 3:14 AM, Support via RT <[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
> openssl s_client -connect 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
> openssl s_client -connect 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