LCOV - code coverage report
Current view: top level - lib/term - getpass.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 6 0.0 %
Date: 2021-11-24 03:28:48 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003-2004, Roger Dingledine
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file getpass.c
       8             :  * \brief Cross-platform wrapper to read passphrases from the terminal.
       9             :  **/
      10             : 
      11             : #include "lib/term/getpass.h"
      12             : 
      13             : #include "lib/log/util_bug.h"
      14             : #include "lib/malloc/malloc.h"
      15             : 
      16             : #ifdef _WIN32
      17             : #include <windows.h>
      18             : #include <conio.h>
      19             : #include <wchar.h>
      20             : /* Some mingw headers lack these. :p */
      21             : #if defined(HAVE_DECL__GETWCH) && !HAVE_DECL__GETWCH
      22             : wint_t _getwch(void);
      23             : #endif
      24             : #ifndef WEOF
      25             : #define WEOF (wchar_t)(0xFFFF)
      26             : #endif
      27             : #if defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY
      28             : static inline void
      29             : SecureZeroMemory(PVOID ptr, SIZE_T cnt)
      30             : {
      31             :   volatile char *vcptr = (volatile char*)ptr;
      32             :   while (cnt--)
      33             :     *vcptr++ = 0;
      34             : }
      35             : #endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */
      36             : #elif defined(HAVE_READPASSPHRASE_H)
      37             : #include <readpassphrase.h>
      38             : #else
      39             : #include "ext/tor_readpassphrase.h"
      40             : #endif /* defined(_WIN32) || ... */
      41             : 
      42             : #include <stdlib.h>
      43             : #include <string.h>
      44             : 
      45             : /** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b>
      46             :  * bytes of passphrase into <b>output</b>. Return the number of bytes in
      47             :  * the passphrase, excluding terminating NUL.
      48             :  */
      49             : ssize_t
      50           0 : tor_getpass(const char *prompt, char *output, size_t buflen)
      51             : {
      52           0 :   tor_assert(buflen <= SSIZE_MAX);
      53           0 :   tor_assert(buflen >= 1);
      54             : #if defined(HAVE_READPASSPHRASE)
      55           0 :   char *pwd = readpassphrase(prompt, output, buflen, RPP_ECHO_OFF);
      56           0 :   if (pwd == NULL)
      57             :     return -1;
      58           0 :   return strlen(pwd);
      59             : #elif defined(_WIN32)
      60             :   int r = -1;
      61             :   while (*prompt) {
      62             :     _putch(*prompt++);
      63             :   }
      64             : 
      65             :   tor_assert(buflen <= INT_MAX);
      66             :   wchar_t *buf = tor_calloc(buflen, sizeof(wchar_t));
      67             : 
      68             :   wchar_t *ptr = buf, *lastch = buf + buflen - 1;
      69             :   while (ptr < lastch) {
      70             :     wint_t ch = _getwch();
      71             :     switch (ch) {
      72             :       case '\r':
      73             :       case '\n':
      74             :       case WEOF:
      75             :         goto done_reading;
      76             :       case 3:
      77             :         goto done; /* Can't actually read ctrl-c this way. */
      78             :       case '\b':
      79             :         if (ptr > buf)
      80             :           --ptr;
      81             :         continue;
      82             :       case 0:
      83             :       case 0xe0:
      84             :         ch = _getwch(); /* Ignore; this is a function or arrow key */
      85             :         break;
      86             :       default:
      87             :         *ptr++ = ch;
      88             :         break;
      89             :     }
      90             :   }
      91             :  done_reading:
      92             :   ;
      93             : 
      94             : #ifndef WC_ERR_INVALID_CHARS
      95             : #define WC_ERR_INVALID_CHARS 0x80
      96             : #endif
      97             : 
      98             :   /* Now convert it to UTF-8 */
      99             :   r = WideCharToMultiByte(CP_UTF8,
     100             :                           WC_NO_BEST_FIT_CHARS|WC_ERR_INVALID_CHARS,
     101             :                           buf, (int)(ptr-buf),
     102             :                           output, (int)(buflen-1),
     103             :                           NULL, NULL);
     104             :   if (r <= 0) {
     105             :     r = -1;
     106             :     goto done;
     107             :   }
     108             : 
     109             :   tor_assert(r < (int)buflen);
     110             : 
     111             :   output[r] = 0;
     112             : 
     113             :  done:
     114             :   SecureZeroMemory(buf, sizeof(wchar_t)*buflen);
     115             :   tor_free(buf);
     116             :   return r;
     117             : #else
     118             : #error "No implementation for tor_getpass found!"
     119             : #endif /* defined(HAVE_READPASSPHRASE) || ... */
     120             : }

Generated by: LCOV version 1.14