LCOV - code coverage report
Current view: top level - ext - readpassphrase.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 85 0.0 %
Date: 2021-11-24 03:28:48 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /*      $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $     */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  *
      18             :  * Sponsored in part by the Defense Advanced Research Projects
      19             :  * Agency (DARPA) and Air Force Research Laboratory, Air Force
      20             :  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
      21             :  */
      22             : 
      23             : /* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */
      24             : 
      25             : #include "orconfig.h"
      26             : 
      27             : #ifndef HAVE_READPASSPHRASE
      28             : 
      29             : #include <termios.h>
      30             : #include <signal.h>
      31             : #include <ctype.h>
      32             : #include <fcntl.h>
      33             : #include "ext/tor_readpassphrase.h"
      34             : #include <errno.h>
      35             : #include <string.h>
      36             : #include <unistd.h>
      37             : 
      38             : #ifndef _PATH_TTY
      39             : # define _PATH_TTY "/dev/tty"
      40             : #endif
      41             : 
      42             : #ifdef TCSASOFT
      43             : # define _T_FLUSH       (TCSAFLUSH|TCSASOFT)
      44             : #else
      45             : # define _T_FLUSH       (TCSAFLUSH)
      46             : #endif
      47             : 
      48             : /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */
      49             : #if !defined(_POSIX_VDISABLE) && defined(VDISABLE)
      50             : #  define _POSIX_VDISABLE       VDISABLE
      51             : #endif
      52             : 
      53             : #ifndef _NSIG
      54             : # ifdef NSIG
      55             : #  define _NSIG NSIG
      56             : # else
      57             : #  define _NSIG 128
      58             : # endif
      59             : #endif
      60             : 
      61             : static volatile sig_atomic_t signo[_NSIG];
      62             : 
      63             : static void handler(int);
      64             : 
      65             : char *
      66           0 : readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
      67             : {
      68           0 :         ssize_t bytes_written = 0;
      69           0 :         ssize_t nr;
      70           0 :         int input, output, save_errno, i, need_restart;
      71           0 :         char ch, *p, *end;
      72           0 :         struct termios term, oterm;
      73           0 :         struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
      74           0 :         struct sigaction savetstp, savettin, savettou, savepipe;
      75             : 
      76             :         /* I suppose we could alloc on demand in this case (XXX). */
      77           0 :         if (bufsiz == 0) {
      78           0 :                 errno = EINVAL;
      79           0 :                 return(NULL);
      80             :         }
      81             : 
      82           0 : restart:
      83           0 :         for (i = 0; i < _NSIG; i++)
      84           0 :                 signo[i] = 0;
      85           0 :         nr = -1;
      86           0 :         save_errno = 0;
      87           0 :         need_restart = 0;
      88             :         /*
      89             :          * Read and write to /dev/tty if available.  If not, read from
      90             :          * stdin and write to stderr unless a tty is required.
      91             :          */
      92           0 :         if ((flags & RPP_STDIN) ||
      93           0 :             (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
      94           0 :                 if (flags & RPP_REQUIRE_TTY) {
      95           0 :                         errno = ENOTTY;
      96           0 :                         return(NULL);
      97             :                 }
      98             :                 input = STDIN_FILENO;
      99             :                 output = STDERR_FILENO;
     100             :         }
     101             : 
     102             :         /*
     103             :          * Catch signals that would otherwise cause the user to end
     104             :          * up with echo turned off in the shell.  Don't worry about
     105             :          * things like SIGXCPU and SIGVTALRM for now.
     106             :          */
     107           0 :         sigemptyset(&sa.sa_mask);
     108           0 :         sa.sa_flags = 0;                /* don't restart system calls */
     109           0 :         sa.sa_handler = handler;
     110           0 :         (void)sigaction(SIGALRM, &sa, &savealrm);
     111           0 :         (void)sigaction(SIGHUP, &sa, &savehup);
     112           0 :         (void)sigaction(SIGINT, &sa, &saveint);
     113           0 :         (void)sigaction(SIGPIPE, &sa, &savepipe);
     114           0 :         (void)sigaction(SIGQUIT, &sa, &savequit);
     115           0 :         (void)sigaction(SIGTERM, &sa, &saveterm);
     116           0 :         (void)sigaction(SIGTSTP, &sa, &savetstp);
     117           0 :         (void)sigaction(SIGTTIN, &sa, &savettin);
     118           0 :         (void)sigaction(SIGTTOU, &sa, &savettou);
     119             : 
     120             :         /* Turn off echo if possible. */
     121           0 :         if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
     122           0 :                 memcpy(&term, &oterm, sizeof(term));
     123           0 :                 if (!(flags & RPP_ECHO_ON))
     124           0 :                         term.c_lflag &= ~(ECHO | ECHONL);
     125             : #ifdef VSTATUS
     126             :                 if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
     127             :                         term.c_cc[VSTATUS] = _POSIX_VDISABLE;
     128             : #endif
     129           0 :                 (void)tcsetattr(input, _T_FLUSH, &term);
     130             :         } else {
     131           0 :                 memset(&term, 0, sizeof(term));
     132           0 :                 term.c_lflag |= ECHO;
     133           0 :                 memset(&oterm, 0, sizeof(oterm));
     134           0 :                 oterm.c_lflag |= ECHO;
     135             :         }
     136             : 
     137             :         /* No I/O if we are already backgrounded. */
     138           0 :         if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
     139           0 :                 if (!(flags & RPP_STDIN))
     140           0 :                         bytes_written = write(output, prompt, strlen(prompt));
     141           0 :                 end = buf + bufsiz - 1;
     142           0 :                 p = buf;
     143           0 :                 while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
     144           0 :                         if (p < end) {
     145             : #if 0
     146             :                                 if ((flags & RPP_SEVENBIT))
     147             :                                         ch &= 0x7f;
     148             :                                 if (isalpha(ch)) {
     149             :                                         if ((flags & RPP_FORCELOWER))
     150             :                                                 ch = (char)tolower(ch);
     151             :                                         if ((flags & RPP_FORCEUPPER))
     152             :                                                 ch = (char)toupper(ch);
     153             :                                 }
     154             : #endif
     155           0 :                                 *p++ = ch;
     156             :                         }
     157             :                 }
     158           0 :                 *p = '\0';
     159           0 :                 save_errno = errno;
     160           0 :                 if (!(term.c_lflag & ECHO))
     161           0 :                         bytes_written = write(output, "\n", 1);
     162             :         }
     163             : 
     164           0 :         (void) bytes_written;
     165             : 
     166             :         /* Restore old terminal settings and signals. */
     167           0 :         if (memcmp(&term, &oterm, sizeof(term)) != 0) {
     168           0 :                 while (tcsetattr(input, _T_FLUSH, &oterm) == -1 &&
     169           0 :                     errno == EINTR)
     170           0 :                         continue;
     171             :         }
     172           0 :         (void)sigaction(SIGALRM, &savealrm, NULL);
     173           0 :         (void)sigaction(SIGHUP, &savehup, NULL);
     174           0 :         (void)sigaction(SIGINT, &saveint, NULL);
     175           0 :         (void)sigaction(SIGQUIT, &savequit, NULL);
     176           0 :         (void)sigaction(SIGPIPE, &savepipe, NULL);
     177           0 :         (void)sigaction(SIGTERM, &saveterm, NULL);
     178           0 :         (void)sigaction(SIGTSTP, &savetstp, NULL);
     179           0 :         (void)sigaction(SIGTTIN, &savettin, NULL);
     180           0 :         (void)sigaction(SIGTTOU, &savettou, NULL);
     181           0 :         if (input != STDIN_FILENO)
     182           0 :                 (void)close(input);
     183             : 
     184             :         /*
     185             :          * If we were interrupted by a signal, resend it to ourselves
     186             :          * now that we have restored the signal handlers.
     187             :          */
     188           0 :         for (i = 0; i < _NSIG; i++) {
     189           0 :                 if (signo[i]) {
     190           0 :                         kill(getpid(), i);
     191           0 :                         switch (i) {
     192           0 :                         case SIGTSTP:
     193             :                         case SIGTTIN:
     194             :                         case SIGTTOU:
     195           0 :                                 need_restart = 1;
     196             :                         }
     197             :                 }
     198             :         }
     199           0 :         if (need_restart)
     200           0 :                 goto restart;
     201             : 
     202           0 :         if (save_errno)
     203           0 :                 errno = save_errno;
     204           0 :         return(nr == -1 ? NULL : buf);
     205             : }
     206             : 
     207             : #if 0
     208             : char *
     209             : getpass(const char *prompt)
     210             : {
     211             :         static char buf[_PASSWORD_LEN + 1];
     212             : 
     213             :         return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF));
     214             : }
     215             : #endif
     216             : 
     217           0 : static void handler(int s)
     218             : {
     219             : 
     220           0 :         signo[s] = 1;
     221           0 : }
     222             : #endif /* HAVE_READPASSPHRASE */

Generated by: LCOV version 1.14