bug using gpg in win98/me

5468696A6D656E thijmen at xs4all.nl
Mon Feb 2 16:29:10 CET 2004


As i posted on the users mailinglist, i found a bug in
util/ttyio.c where on WIN32 platforms CreateFile is used to open
a console. An excerpt from:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/createfile.asp

Windows Me/98/95:   The file system restricts CreateFile to creating or opening files; you cannot create or open the other 
objects mentioned above. See the topics referenced in See Also at the end of this reference page for more information on 
which of these facilities are available on these systems, and how to access them.

This includes the use of CONOUT$ and CONIN$ for opening a console.

Since most compilers on win32 prefectly understand the code used for unix/linux
to do the same, here is a patch. This should be tested against the prefered compiler
for gpg on win32. It works fine under Visual C 6.0 and 7.0.

The bug occures when you try to use gpg with pipes and try one of the
commands which cannot be used with --batch (e.g. --signkey) on win95/98 and ME.

As you will see, the patch mostly deletes code and instead uses the code
which is used on unix/linux. (killing a few #ifdef's is always nice ;)

I was not to sure whether to open stdout or stderr, but stderr was used
in batchmode for unix, so i used that.

Patch is created using diff -c ttyio-orig.c ttyio.c > ttyio_c.patch
If you want a different format, let me know

*** ttyio-orig.c	Wed Jul 30 18:19:36 2003
--- ttyio.c	Mon Feb  2 15:56:59 2004
***************
*** 51,69 ****
  
  #define CONTROL_D ('D' - 'A' + 1)
  
- #ifdef _WIN32 /* use the odd Win32 functions */
- static struct {
-     HANDLE in, out;
- } con;
- #define DEF_INPMODE  (ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT    \
- 					|ENABLE_PROCESSED_INPUT )
- #define HID_INPMODE  (ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT )
- #define DEF_OUTMODE  (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT)
- 
- #else /* yeah, we have a real OS */
  static FILE *ttyfp = NULL;
- #endif
- 
  static int initialized;
  static int last_prompt_len;
  static int batchmode;
--- 51,57 ----
***************
*** 124,160 ****
      if( initialized )
  	return;
  
! #if defined(_WIN32)
!     {
! 	SECURITY_ATTRIBUTES sa;
! 
! 	memset(&sa, 0, sizeof(sa));
! 	sa.nLength = sizeof(sa);
! 	sa.bInheritHandle = TRUE;
! 	con.out = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE,
! 			       FILE_SHARE_READ|FILE_SHARE_WRITE,
! 			       &sa, OPEN_EXISTING, 0, 0 );
! 	if( con.out == INVALID_HANDLE_VALUE )
! 	    log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() );
! 	memset(&sa, 0, sizeof(sa));
! 	sa.nLength = sizeof(sa);
! 	sa.bInheritHandle = TRUE;
! 	con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE,
! 			       FILE_SHARE_READ|FILE_SHARE_WRITE,
! 			       &sa, OPEN_EXISTING, 0, 0 );
! 	if( con.in == INVALID_HANDLE_VALUE )
! 	    log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() );
!     }
!     SetConsoleMode(con.in, DEF_INPMODE );
!     SetConsoleMode(con.out, DEF_OUTMODE );
! 
! #elif defined(__EMX__)
      ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
  #else
      ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
      if( !ttyfp ) {
  	log_error("cannot open `%s': %s\n", tty_get_ttyname (),
                    strerror(errno) );
  	exit(2);
      }
  #endif
--- 112,130 ----
      if( initialized )
  	return;
  
! #if defined(__EMX__)
      ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
  #else
+ # if defined(_WIN32)
+     ttyfp = stderr;
+     if( !ttyfp ) {
+         log_error("empty stderr: %s\n", strerror(errno) );
+ # else
      ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
      if( !ttyfp ) {
  	log_error("cannot open `%s': %s\n", tty_get_ttyname (),
                    strerror(errno) );
+ # endif
  	exit(2);
      }
  #endif
***************
*** 194,220 ****
  	init_ttyfp();
  
      va_start( arg_ptr, fmt ) ;
- #ifdef _WIN32
-     {   
-         char *buf = NULL;
-         int n;
- 	DWORD nwritten;
- 
- 	n = vasprintf(&buf, fmt, arg_ptr);
- 	if( !buf )
- 	    log_bug("vasprintf() failed\n");
-         
- 	if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) )
- 	    log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
- 	if( n != nwritten )
- 	    log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
- 	last_prompt_len += n;
-         m_free (buf);
-     }
- #else
      last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
      fflush(ttyfp);
- #endif
      va_end(arg_ptr);
  }
  
--- 164,171 ----
***************
*** 325,365 ****
      buf = m_alloc(n=50);
      i = 0;
  
! #ifdef _WIN32 /* windoze version */
!     if( hidden )
! 	SetConsoleMode(con.in, HID_INPMODE );
! 
!     for(;;) {
! 	DWORD nread;
! 
! 	if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) )
! 	    log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() );
! 	if( !nread )
! 	    continue;
! 	if( *cbuf == '\n' )
! 	    break;
! 
! 	if( !hidden )
! 	    last_prompt_len++;
! 	c = *cbuf;
! 	if( c == '\t' )
! 	    c = ' ';
! 	else if( c > 0xa0 )
! 	    ; /* we don't allow 0xa0, as this is a protected blank which may
! 	       * confuse the user */
! 	else if( iscntrl(c) )
! 	    continue;
! 	if( !(i < n-1) ) {
! 	    n += 50;
! 	    buf = m_realloc( buf, n );
! 	}
! 	buf[i++] = c;
!     }
! 
!     if( hidden )
! 	SetConsoleMode(con.in, DEF_INPMODE );
! 
! #elif defined(__riscos__)
      do {
          c = riscos_getchar();
          if (c == 0xa || c == 0xd) { /* Return || Enter */
--- 276,282 ----
      buf = m_alloc(n=50);
      i = 0;
  
! #if defined(__riscos__)
      do {
          c = riscos_getchar();
          if (c == 0xa || c == 0xd) { /* Return || Enter */
***************
*** 399,405 ****
          }
      } while (c != '\n');
      i = (i>0) ? i-1 : 0;
! #else /* unix version */
      if( hidden ) {
  #ifdef HAVE_TCGETATTR
  	struct termios term;
--- 316,322 ----
          }
      } while (c != '\n');
      i = (i>0) ? i-1 : 0;
! #else /* unix/win32 version */
      if( hidden ) {
  #ifdef HAVE_TCGETATTR
  	struct termios term;




More information about the Gnupg-devel mailing list