diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gnulib.modules | 1 | ||||
-rw-r--r-- | include/mailutils/mutil.h | 2 | ||||
-rw-r--r-- | include/mailutils/stream.h | 3 | ||||
-rw-r--r-- | include/mailutils/sys/file_stream.h | 4 | ||||
-rw-r--r-- | libmailutils/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/file_stream.c | 94 | ||||
-rw-r--r-- | libmailutils/getpass.c | 59 | ||||
-rw-r--r-- | mu/mu.h | 2 | ||||
-rw-r--r-- | mu/pop.c | 35 | ||||
-rw-r--r-- | mu/shell.c | 28 | ||||
-rw-r--r-- | pop3d/popauth.c | 68 |
12 files changed, 236 insertions, 63 deletions
diff --git a/configure.ac b/configure.ac index 509a56991..796c4687a 100644 --- a/configure.ac +++ b/configure.ac @@ -517,3 +517,3 @@ extern char *strsignal (int); AC_CHECK_FUNCS(mkstemp sigaction sysconf getdelim setreuid \ - setresuid seteuid setlocale vfork _exit) + setresuid seteuid setlocale vfork _exit tcgetattr tcsetattr) diff --git a/gnulib.modules b/gnulib.modules index 4368cf7c2..66399597e 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -10,3 +10,2 @@ crypto/des getline -getpass-gnu gettext diff --git a/include/mailutils/mutil.h b/include/mailutils/mutil.h index 7acc021cf..86d2243e7 100644 --- a/include/mailutils/mutil.h +++ b/include/mailutils/mutil.h @@ -159,2 +159,4 @@ extern int mu_parse_stream_perm_string (int *pmode, const char *str, +extern int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt, + char **passptr); diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h index c076ade11..d951f3425 100644 --- a/include/mailutils/stream.h +++ b/include/mailutils/stream.h @@ -76,2 +76,5 @@ enum mu_buffer_type +#define MU_IOCTL_GET_ECHO 12 +#define MU_IOCTL_SET_ECHO 13 + #define MU_TRANSPORT_INPUT 0 diff --git a/include/mailutils/sys/file_stream.h b/include/mailutils/sys/file_stream.h index 70c576ab7..581d28941 100644 --- a/include/mailutils/sys/file_stream.h +++ b/include/mailutils/sys/file_stream.h @@ -23,3 +23,4 @@ -#define _MU_FILE_STREAM_TEMP 0x01 +#define _MU_FILE_STREAM_TEMP 0x01 +#define _MU_FILE_STREAM_ECHO_OFF 0x02 @@ -31,2 +32,3 @@ struct _mu_file_stream char *filename; + void *echo_state; }; diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index e05edd883..3f083e01d 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am @@ -86,2 +86,3 @@ libmailutils_la_SOURCES = \ gdebug.c\ + getpass.c\ gocs.c\ diff --git a/libmailutils/file_stream.c b/libmailutils/file_stream.c index 247768c25..578f4829e 100644 --- a/libmailutils/file_stream.c +++ b/libmailutils/file_stream.c @@ -25,2 +25,5 @@ #include <sys/stat.h> +#if HAVE_TERMIOS_H +# include <termios.h> +#endif @@ -185,2 +188,4 @@ fd_done (struct _mu_stream *str) free (fstr->filename); + if (fstr->echo_state) + free (fstr->echo_state); } @@ -196,2 +201,6 @@ fd_error_string (struct _mu_stream *str, int rc) +#ifndef TCSASOFT +# define TCSASOFT 0 +#endif + static int @@ -220,13 +229,82 @@ fd_ioctl (struct _mu_stream *str, int code, void *ptr) case MU_IOCTL_GET_TRANSPORT_BUFFER: - { - struct mu_buffer_query *qp = ptr; - return mu_stream_get_buffer (str, qp); - } + if (!ptr) + return EINVAL; + else + { + struct mu_buffer_query *qp = ptr; + return mu_stream_get_buffer (str, qp); + } case MU_IOCTL_SET_TRANSPORT_BUFFER: - { - struct mu_buffer_query *qp = ptr; - return mu_stream_set_buffer (str, qp->buftype, qp->bufsize); - } + if (!ptr) + return EINVAL; + else + { + struct mu_buffer_query *qp = ptr; + return mu_stream_set_buffer (str, qp->buftype, qp->bufsize); + } + + case MU_IOCTL_SET_ECHO: + if (!ptr) + return EINVAL; + else + { + int status; + struct termios t; + int state = *(int*)ptr; +#if HAVE_TCGETATTR + if (state == 0) + { + if (fstr->flags & _MU_FILE_STREAM_ECHO_OFF) + return 0; + status = tcgetattr (fstr->fd, &t); + if (status == 0) + { + fstr->echo_state = malloc (sizeof (t)); + if (!fstr->echo_state) + return ENOMEM; + memcpy (fstr->echo_state, &t, sizeof (t)); + + t.c_lflag &= ~(ECHO | ISIG); + status = tcsetattr (fstr->fd, TCSAFLUSH | TCSASOFT, &t); + if (status == 0) + fstr->flags |= _MU_FILE_STREAM_ECHO_OFF; + } + if (status) + { + status = errno; + if (fstr->echo_state) + { + free (fstr->echo_state); + fstr->echo_state = NULL; + } + } + } + else + { + if (!(fstr->flags & _MU_FILE_STREAM_ECHO_OFF)) + return 0; + if (tcsetattr (fstr->fd, TCSAFLUSH | TCSASOFT, fstr->echo_state)) + status = errno; + else + { + status = 0; + free (fstr->echo_state); + fstr->echo_state = NULL; + fstr->flags &= ~_MU_FILE_STREAM_ECHO_OFF; + } + } + return status; +#else + return ENOSYS; +#endif + } + case MU_IOCTL_GET_ECHO: + if (!ptr) + return EINVAL; + else + *(int*)ptr = fstr->flags & _MU_FILE_STREAM_ECHO_OFF; + break; + default: diff --git a/libmailutils/getpass.c b/libmailutils/getpass.c new file mode 100644 index 000000000..8a37c52cc --- /dev/null +++ b/libmailutils/getpass.c @@ -0,0 +1,59 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002, 2004, + 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> + +#include <mailutils/types.h> +#include <mailutils/stream.h> +#include <mailutils/mutil.h> +#include <mailutils/cstr.h> + +int +mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt, + char **passptr) +{ + int status; + int echo_state = 0; + size_t size = 0; + char *buf = NULL; + + status = mu_stream_write (out, prompt, strlen (prompt), NULL); + if (status) + return status; + mu_stream_flush (out); + status = mu_stream_ioctl (in, MU_IOCTL_SET_ECHO, &echo_state); + if (status == 0) + echo_state = 1; + status = mu_stream_getline (in, &buf, &size, NULL); + if (echo_state) + { + mu_stream_ioctl (in, MU_IOCTL_SET_ECHO, &echo_state); + mu_stream_write (out, "\n", 1, NULL); + } + if (status == 0) + { + mu_rtrim_cset (buf, "\n"); + *passptr = buf; + } + return 0; +} + @@ -40,3 +40,3 @@ extern mu_vartab_t mutool_prompt_vartab; extern int mutool_shell_interactive; -extern mu_stream_t mustrout; +extern mu_stream_t mustrin, mustrout; int mutool_shell (const char *name, struct mutool_command *cmd); @@ -456,18 +456,2 @@ com_noop (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) -static void -echo_off (struct termios *stored_settings) -{ - struct termios new_settings; - tcgetattr (0, stored_settings); - new_settings = *stored_settings; - new_settings.c_lflag &= (~ECHO); - tcsetattr (0, TCSANOW, &new_settings); -} - -static void -echo_on (struct termios *stored_settings) -{ - tcsetattr (0, TCSANOW, stored_settings); -} - static int @@ -476,4 +460,3 @@ com_pass (int argc, char **argv) int status; - char pass[256]; - char *pwd; + char *pwd, *passbuf = NULL; @@ -481,13 +464,6 @@ com_pass (int argc, char **argv) { - struct termios stored_settings; - - printf ("passwd:"); - fflush (stdout); - echo_off (&stored_settings); - fgets (pass, sizeof pass, stdin); - echo_on (&stored_settings); - putchar ('\n'); - fflush (stdout); - pass[strlen (pass) - 1] = '\0'; /* nuke the trailing line. */ - pwd = pass; + status = mu_getpass (mustrin, mustrout, "Password:", &passbuf); + if (status) + return status; + pwd = passbuf; } @@ -501,2 +477,3 @@ com_pass (int argc, char **argv) } + free (passbuf); return status; diff --git a/mu/shell.c b/mu/shell.c index 4abaef4dc..1ca73e79a 100644 --- a/mu/shell.c +++ b/mu/shell.c @@ -35,3 +35,3 @@ mu_vartab_t mutool_prompt_vartab; int mutool_shell_interactive; -mu_stream_t mustrout; +mu_stream_t mustrin, mustrout; @@ -372,4 +372,9 @@ readline (char *prompt) } - if (getline (&buf, &size, stdin) <= 0) - return NULL; + if (mu_stream_getline (mustrin, &buf, &size, &n) || n == 0) + { + free (buf); + buf = NULL; + size = 0; + return NULL; + } return buf; @@ -468,2 +473,11 @@ mutool_shell (const char *name, struct mutool_command *cmd) + rc = mu_stdio_stream_create (&mustrin, MU_STDIN_FD, + MU_STREAM_READ); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", + "MU_STDIN_FD", rc); + return 1; + } + rc = mu_stdio_stream_create (&mustrout, MU_STDOUT_FD, @@ -472,6 +486,7 @@ mutool_shell (const char *name, struct mutool_command *cmd) { - mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", "1", rc); + mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", + "MU_STDOUT_FD", rc); return 1; - } - + } + mutool_shell_interactive = isatty (0); @@ -523,2 +538,3 @@ mutool_shell (const char *name, struct mutool_command *cmd) finish_readline (); + mu_stream_destroy (&mustrin); mu_stream_destroy (&mustrout); diff --git a/pop3d/popauth.c b/pop3d/popauth.c index 9f73d60ed..f8505f949 100644 --- a/pop3d/popauth.c +++ b/pop3d/popauth.c @@ -76,3 +76,3 @@ static struct argp_option options[] = " For the file owner: --list\n" - " For a user: --modify --username <username>\n"), 2 }, + " For a user: --modify --user <username>\n"), 2 }, @@ -107,3 +107,3 @@ set_db_perms (struct argp_state *astate, char *opt, int *pperm) - if (mu_isdigit(opt[0])) + if (mu_isdigit (opt[0])) { @@ -448,17 +448,53 @@ fill_pass (struct action_data *ap) char *p; + mu_stream_t in, out; + int rc; + + rc = mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_READ); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", + "MU_STDIN_FD", rc); + return; + } + + rc = mu_stdio_stream_create (&out, MU_STDOUT_FD, MU_STREAM_WRITE); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", + "MU_STDOUT_FD", rc); + return; + } - while (1) { - if (ap->passwd) - free (ap->passwd); - p = getpass (_("Password:")); - if (!p) - exit (EX_DATAERR); - ap->passwd = strdup (p); - /* TRANSLATORS: Please try to format this string so that it has - the same length as the translation of 'Password:' above */ - p = getpass (_("Confirm :")); - if (strcmp (ap->passwd, p) == 0) - break; - mu_error (_("Passwords differ. Please retry.")); - } + while (1) + { + if (ap->passwd) + free (ap->passwd); + rc = mu_getpass (in, out, _("Password:"), &p); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_getpass", NULL, rc); + exit (EX_DATAERR); + } + + if (!p) + exit (EX_DATAERR); + + ap->passwd = strdup (p); + /* TRANSLATORS: Please try to format this string so that it has + the same length as the translation of 'Password:' above */ + rc = mu_getpass (in, out, _("Confirm :"), &p); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_getpass", NULL, rc); + exit (EX_DATAERR); + } + + if (!p) + exit (EX_DATAERR); + if (strcmp (ap->passwd, p) == 0) + break; + mu_error (_("Passwords differ. Please retry.")); + } + mu_stream_destroy (&in); + mu_stream_destroy (&out); } |