| 
					
				 | 
			
			
				@@ -71,6 +71,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <readpassphrase.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #elif !defined(_WIN32) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "readpassphrase.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <conio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifndef HAVE_GETTIMEOFDAY 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -3248,16 +3250,77 @@ tor_sleep_msec(int msec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** Emit the password prompt <b>prompt</b>, then read up to <b>buflen</b> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * characters of passphrase into <b>output</b>. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * bytes of passphrase into <b>output</b>. Return the number of bytes in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the passphrase, excluding terminating NUL. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ssize_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 tor_getpass(const char *prompt, char *output, size_t buflen) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   tor_assert(buflen <= SSIZE_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(buflen >= 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #if defined(HAVE_READPASSPHRASE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   char *pwd = readpassphrase(prompt, output, buflen, RPP_ECHO_OFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (pwd == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return strlen(pwd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(_WIN32) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int r = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (*prompt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _putch(*prompt++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(buflen <= INT_MAX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  wchar_t *buf = tor_calloc(buflen, sizeof(wchar_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  wchar_t *ptr = buf, *lastch = buf + buflen - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (ptr < lastch) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    wint_t ch = _getwch(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch (ch) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case '\r': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case '\n': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case WEOF: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto done_reading; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto done; /* Can't actually read ctrl-c this way. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case '\b': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ptr > buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          --ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 0xe0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ch = _getwch(); /* Ignore; this is a function or arrow key */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        *ptr++ = ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done_reading: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifndef WC_ERR_INVALID_CHARS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define WC_ERR_INVALID_CHARS 0x80 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Now convert it to UTF-8 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  r = WideCharToMultiByte(CP_UTF8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          WC_NO_BEST_FIT_CHARS|WC_ERR_INVALID_CHARS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          buf, (int)(ptr-buf), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          output, (int)(buflen-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          NULL, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (r <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    r = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    goto done; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(r < (int)buflen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  output[r] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SecureZeroMemory(buf, sizeof(wchar_t)*buflen); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #elif defined(HAVE_GETPASS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* XXX We shouldn't actually use this; it's deprecated to hell and back */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   memset(output, 0, buflen); 
			 |