[GRASS-dev] db.login: interactive PW implemented

Hi,

when using db.login, I disliked to enter the password
in cleartext on command line. I have implemented an interactive
password query. The behaviour is now like this:

Example 1: Username and password specified:
  db.login user=bacava pass=secret

Example 2: Username and empty password specified:
  db.login user=bacava pass=""

Example 3: Username specified, password will be queried interactively:
  db.login user=bacava

The only thing which I don't know how to fix is that
G_gets() echoes the password. I wonder if we could have
a G_gets_silent() or something (lib/gis/gets.c).

Markus

(attachments)

db_login.diff (775 Bytes)

Markus Neteler wrote:

when using db.login, I disliked to enter the password
in cleartext on command line. I have implemented an interactive
password query. The behaviour is now like this:

Example 1: Username and password specified:
  db.login user=bacava pass=secret

Example 2: Username and empty password specified:
  db.login user=bacava pass=""

Example 3: Username specified, password will be queried interactively:
  db.login user=bacava

The only thing which I don't know how to fix is that
G_gets() echoes the password. I wonder if we could have
a G_gets_silent() or something (lib/gis/gets.c).

struct termios tios, tios2;

tcgetattr(STDIN_FILENO, &tios);
tios2 = tios;
tios2.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);

read password

tcsetattr(STDIN_FILENO, TCSANOW, &tios);

Markus
? OBJ.x86_64-unknown-linux-gnu
Index: main.c

RCS file: /grassrepository/grass6/db/db.login/main.c,v
retrieving revision 1.5
diff -u -r1.5 main.c
--- main.c 15 Nov 2006 13:36:28 -0000 1.5
+++ main.c 15 Nov 2006 13:56:06 -0000
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/dbmi.h>
@@ -53,6 +54,8 @@
   exit(EXIT_FAILURE);

     /* set connection */
+ if (!password->answer && isatty(fileno(stdin)) )
+ G_message("Enter your password:");
     if ( db_set_login ( driver->answer, database->answer, user->answer, password->answer ) == DB_FAILED ) {
   G_fatal_error ( _("Cannot set user/password") );
     }
_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

[I hit "send" too soon on the previous attempt.]

Markus Neteler wrote:

when using db.login, I disliked to enter the password
in cleartext on command line. I have implemented an interactive
password query. The behaviour is now like this:

Example 1: Username and password specified:
  db.login user=bacava pass=secret

Example 2: Username and empty password specified:
  db.login user=bacava pass=""

Example 3: Username specified, password will be queried interactively:
  db.login user=bacava

The only thing which I don't know how to fix is that
G_gets() echoes the password. I wonder if we could have
a G_gets_silent() or something (lib/gis/gets.c).

Roughly:

  #include <termios.h>
  #include <unistd.h>

  struct termios tios, tios2;
  
  tcgetattr(STDIN_FILENO, &tios);
  tios2 = tios;
  tios2.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);
  
  /* read password */
  
  tcsetattr(STDIN_FILENO, TCSANOW, &tios);

However, BSD historically used gtty/stty instead of tc{get,set}attr,
and some older systems used ioctl(TCGETS)/ioctl(TCSETS) (IIRC, Linux'
tc{get,set}attr are implemented on top of the ioctl()s).

And Windows uses something completely different (conio.h, maybe?).

--
Glynn Clements <glynn@gclements.plus.com>

Thanks, Glynn!
Implemented and working on Linux. The interactive password query is
now no longer echoeing the PW.

Paul: could you please make a test on Windows?
Any BSD tester around?

Markus

On Thu, Nov 16, 2006 at 12:11:54AM +0000, Glynn Clements wrote:

[I hit "send" too soon on the previous attempt.]

Markus Neteler wrote:

> when using db.login, I disliked to enter the password
> in cleartext on command line. I have implemented an interactive
> password query. The behaviour is now like this:
>
> Example 1: Username and password specified:
> db.login user=bacava pass=secret
>
> Example 2: Username and empty password specified:
> db.login user=bacava pass=""
>
> Example 3: Username specified, password will be queried interactively:
> db.login user=bacava
>
> The only thing which I don't know how to fix is that
> G_gets() echoes the password. I wonder if we could have
> a G_gets_silent() or something (lib/gis/gets.c).

Roughly:

  #include <termios.h>
  #include <unistd.h>

  struct termios tios, tios2;
  
  tcgetattr(STDIN_FILENO, &tios);
  tios2 = tios;
  tios2.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);
  
  /* read password */
  
  tcsetattr(STDIN_FILENO, TCSANOW, &tios);

However, BSD historically used gtty/stty instead of tc{get,set}attr,
and some older systems used ioctl(TCGETS)/ioctl(TCSETS) (IIRC, Linux'
tc{get,set}attr are implemented on top of the ioctl()s).

And Windows uses something completely different (conio.h, maybe?).

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements wrote:

> when using db.login, I disliked to enter the password
> in cleartext on command line. I have implemented an interactive
> password query. The behaviour is now like this:
>
> Example 1: Username and password specified:
> db.login user=bacava pass=secret
>
> Example 2: Username and empty password specified:
> db.login user=bacava pass=""
>
> Example 3: Username specified, password will be queried interactively:
> db.login user=bacava
>
> The only thing which I don't know how to fix is that
> G_gets() echoes the password. I wonder if we could have
> a G_gets_silent() or something (lib/gis/gets.c).

Roughly:

  #include <termios.h>
  #include <unistd.h>

  struct termios tios, tios2;
  
  tcgetattr(STDIN_FILENO, &tios);
  tios2 = tios;
  tios2.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);
  
  /* read password */
  
  tcsetattr(STDIN_FILENO, TCSANOW, &tios);

However, BSD historically used gtty/stty instead of tc{get,set}attr,
and some older systems used ioctl(TCGETS)/ioctl(TCSETS) (IIRC, Linux'
tc{get,set}attr are implemented on top of the ioctl()s).

BTW, there is some code in 5.3 to do this (when I wrote my previous
message, I could have sworn that something in GRASS did this, but I
couldn't find it at that time), in:

  src/libes/unused/unsupported/dig_to_dlg/tty.c
  src/libes/unused/unsupported/dlglabel/tty.c
  src/paint/Interface/driverlib/io.c
  src/paint/drivers.junk/anadex/open.c
  src/paint/drivers.junk/epson.24.180/open.c
  src/paint/drivers.junk/epson.24.90/open.c
  src/paint/drivers.junk/epson.8.90/open.c
  src.contrib/SCS/paint/Drivers/driverlib/io.c
  src.contrib/SCS/paint/Interface/driverlib/io.c

[Note that most of the above are essentially clones of each other.]

Of the above, src/paint/Interface/driverlib/io.c includes code for all
three interfaces, decided by header checks.

tcsetattr() uses "struct termios" from <termios.h>, ioctl(TCSETA) uses
"struct termio" from <termio.h>, while stty() uses "struct sgttyb"
from <sgtty.h>.

Also, note that using stty() requires $(COMPATLIB) to be added to the
link flags.

And Windows uses something completely different (conio.h, maybe?).

Windows has separate getch() and getche() functions; the latter echoes
characters as they are typed, the former doesn't. You can't disable
echoing for stdio.

BTW, some Unices (including Linux) have a getpass() function (not
defined by any standard, AFAICT). This specifically opens /dev/tty
rather than using stdin, so it works even if stdin is redirected.

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements wrote on 11/16/2006 03:03 PM:

Glynn Clements wrote:

when using db.login, I disliked to enter the password
in cleartext on command line. I have implemented an interactive
password query. The behaviour is now like this:

Example 1: Username and password specified:
  db.login user=bacava pass=secret

Example 2: Username and empty password specified:
  db.login user=bacava pass=""

Example 3: Username specified, password will be queried interactively:
  db.login user=bacava

The only thing which I don't know how to fix is that
G_gets() echoes the password. I wonder if we could have
a G_gets_silent() or something (lib/gis/gets.c).
      

Roughly:

  #include <termios.h>
  #include <unistd.h>

  struct termios tios, tios2;
  
  tcgetattr(STDIN_FILENO, &tios);
  tios2 = tios;
  tios2.c_lflag &= ~ECHO;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &tios2);
  
  /* read password */
  
  tcsetattr(STDIN_FILENO, TCSANOW, &tios);

However, BSD historically used gtty/stty instead of tc{get,set}attr,
and some older systems used ioctl(TCGETS)/ioctl(TCSETS) (IIRC, Linux'
tc{get,set}attr are implemented on top of the ioctl()s).
    
BTW, there is some code in 5.3 to do this (when I wrote my previous
message, I could have sworn that something in GRASS did this, but I
couldn't find it at that time), in:

  src/libes/unused/unsupported/dig_to_dlg/tty.c
  src/libes/unused/unsupported/dlglabel/tty.c
  src/paint/Interface/driverlib/io.c
  src/paint/drivers.junk/anadex/open.c
  src/paint/drivers.junk/epson.24.180/open.c
  src/paint/drivers.junk/epson.24.90/open.c
  src/paint/drivers.junk/epson.8.90/open.c
  src.contrib/SCS/paint/Drivers/driverlib/io.c
  src.contrib/SCS/paint/Interface/driverlib/io.c

[Note that most of the above are essentially clones of each other.]

Of the above, src/paint/Interface/driverlib/io.c includes code for all
three interfaces, decided by header checks.

tcsetattr() uses "struct termios" from <termios.h>, ioctl(TCSETA) uses
"struct termio" from <termio.h>, while stty() uses "struct sgttyb"
from <sgtty.h>.

Also, note that using stty() requires $(COMPATLIB) to be added to the
link flags.

And Windows uses something completely different (conio.h, maybe?).
    
Windows has separate getch() and getche() functions; the latter echoes
characters as they are typed, the former doesn't. You can't disable
echoing for stdio.

BTW, some Unices (including Linux) have a getpass() function (not
defined by any standard, AFAICT). This specifically opens /dev/tty
rather than using stdin, so it works even if stdin is redirected.

Thanks, but I am afraid that I am unable to decide/implement the further
suggestions - too
complicated for me.

Markus

Markus Neteler wrote:

Thanks, but I am afraid that I am unable to decide/implement the further
suggestions - too
complicated for me.

At a minimum, the new code should be conditional upon HAVE_TERMIOS_H,
otherwise db.login will simply fail to compile on platforms which
don't have it (e.g. Windows).

--
Glynn Clements <glynn@gclements.plus.com>

On Fri, Nov 17, 2006 at 07:46:33PM +0000, Glynn Clements wrote:

Markus Neteler wrote:

> Thanks, but I am afraid that I am unable to decide/implement the further
> suggestions - too
> complicated for me.

At a minimum, the new code should be conditional upon HAVE_TERMIOS_H,
otherwise db.login will simply fail to compile on platforms which
don't have it (e.g. Windows).

OK, I have conditionalized the hidden password upon HAVE_TERMIOS_H.

Markus