/* uulogin.c --- query the password of an anonymous UUCP user. Copyright (C) 1996, 1999 Ralph Schleicher */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #ifndef _PATH_UUCICO #define _PATH_UUCICO "/usr/libexec/uucp/uucico" #endif /* Program name. */ #define PROGRAM "uulogin" /* Default user name. */ #define USER "anonymous UUCP" /* Password timeout in seconds. */ #define TIMEOUT 60 /* Short program invocation name. */ static char *program_name; /* Argument vector for calling uucico(8). Special argument "%u" is replaced by the user name. */ static char *exec_arg[] = { _PATH_UUCICO, "-u", "%u", NULL, }; /* Terminal file descriptor. */ static int term_desc = -1; /* Original terminal mode. */ static struct termios term_mode; /* Forward declarations. */ static void set_echo (int flag); static void cleanup (int sig); /* Program entry point. */ int main (int arg_count, char *arg_vec[]) { char *user, *pass, *end; int size, length; int result, i; if (arg_vec[0] == NULL) abort (); program_name = strrchr (arg_vec[0], '/'); if (program_name == NULL) program_name = arg_vec[0]; else ++program_name; if (*program_name == 0) program_name = PROGRAM; if (arg_count > 2) { fprintf (stderr, "Usage: %s [user]\n", program_name); exit (EXIT_FAILURE); } if (arg_count > 1) user = arg_vec[1]; else user = USER; openlog (program_name, LOG_PID, LOG_AUTH); signal (SIGHUP, &cleanup); signal (SIGINT, &cleanup); signal (SIGQUIT, &cleanup); signal (SIGTERM, &cleanup); signal (SIGALRM, &cleanup); fprintf (stdout, "Please enter your email address as password.\n"); fprintf (stdout, "Password: "); fflush (stdout); set_echo (0); alarm (TIMEOUT); pass = NULL; size = 0; result = getdelim (&pass, &size, '\n', stdin); set_echo (1); if (result < 1) exit (EXIT_FAILURE); length = strlen (pass); if (length < result) exit (EXIT_FAILURE); end = strchr (pass, '\n'); if (end != NULL) *end = 0; else exit (EXIT_FAILURE); syslog (LOG_NOTICE, "User `%s' sent `%s' as password\n", user, pass); for (i = 1; exec_arg[i]; ++i) { if (strcmp (exec_arg[i], "%u") == 0) exec_arg[i] = user; } execv (exec_arg[0], exec_arg); syslog (LOG_ERR, "%s: %s\n", exec_arg[0], strerror (errno)); exit (EXIT_FAILURE); } /* Turn character echoing on or off. */ static void set_echo (int flag) { struct termios mode; int result; if (term_desc < 0) { term_desc = open ("/dev/tty", O_RDWR); if (term_desc < 0) { fprintf (stderr, "%s:/dev/tty: %s\n", program_name, strerror (errno)); exit (EXIT_FAILURE); } result = tcgetattr (term_desc, &term_mode); if (result < 0) { fprintf (stderr, "%s:/dev/tty: %s\n", program_name, strerror (errno)); exit (EXIT_FAILURE); } } memcpy (&mode, &term_mode, sizeof (struct termios)); if (flag != 0) mode.c_lflag |= ECHO; else mode.c_lflag &= ~ ECHO; result = tcsetattr (term_desc, TCSAFLUSH, &mode); if (result < 0) { fprintf (stderr, "%s:/dev/tty: %s\n", program_name, strerror (errno)); exit (EXIT_FAILURE); } } /* Signal handler. */ static void cleanup (int sig) { if (term_desc >= 0) tcsetattr (term_desc, TCSAFLUSH, &term_mode); syslog (LOG_NOTICE, ": Caught signal %d\n", sig); if (sig == SIGALRM) fprintf (stderr, "\nNow is the time for a timeout.\n"); exit (EXIT_FAILURE); } /* * local variables: * compile-command: "gcc -g -Wall -W -o uulogin uulogin.c " * end: */