New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

`cabal upload` reveals your password as you type it on MSYS2 #4128

Closed
RyanGlScott opened this Issue Nov 23, 2016 · 5 comments

Comments

Projects
None yet
4 participants
@RyanGlScott
Copy link
Member

RyanGlScott commented Nov 23, 2016

AFAICT, this is not only Windows-specific, but also MSYS2-specific, as I can't reproduce this on PowerShell. Steps to reproduce:

$ git clone https://github.com/RyanGlScott/code-page
$ cd code-page/
$ cabal configure --enable-tests
Resolving dependencies...
Configuring code-page-0.1.1...
$ cabal upload -d
No documentation tarball specified. Building documentation tarball...
Running Haddock for code-page-0.1.1...
Running hscolour for code-page-0.1.1...
Preprocessing library code-page-0.1.1...
Preprocessing test suite 'tests' for code-page-0.1.1...
Preprocessing library code-page-0.1.1...
Haddock coverage:
  42% (  8 / 19) in 'System.Win32.CodePage'
  Missing documentation for:
    CodePage
    getConsoleCP
    getConsoleOutputCP
    setConsoleCP
    setConsoleOutputCP
    getACP
    getOEMCP
    codePageEncoding
    mkCodePageEncoding
    isValidCodePage
    stringToUnicode
 100% ( 14 / 14) in 'System.IO.CodePage'
Documentation created: .\dist\doc\html\code-page-0.1.1-docs\.\index.html,
.\dist\doc\html\code-page-0.1.1-docs\.\code-page.txt
Preprocessing test suite 'tests' for code-page-0.1.1...
Documentation tarball created: dist\code-page-0.1.1-docs.tar.gz
Hackage username: me
Hackage password: hunter2

It shows my Hackage password (hunter2, in the fake example above) as I type it, which is a bit unsettling.

@RyanGlScott

This comment has been minimized.

Copy link
Member

RyanGlScott commented Nov 24, 2016

I did some digging, and it turns out that hGetEcho and hSetEcho don't work properly on MinTTY (which Cygwin/MSYS2 use). A workaround is to use the stty command. For example, here is a program which will hide your password as you type it on MinTTY:

module Main (main) where

import Control.Exception (bracket, throw)
import Control.Monad (void)
import System.Exit (ExitCode(..))
import System.IO (hGetContents, hFlush, stdin, stdout)
import System.Process (StdStream(..), createProcess, shell,
                       std_in, std_out, waitForProcess)

stty :: String -> IO String
stty arg = do
  let stty = (shell $ "stty " ++ arg) {
        std_in  = UseHandle stdin
      , std_out = CreatePipe
      }
  (_, mbStdout, _, rStty) <- createProcess stty
  exStty <- waitForProcess rStty
  case exStty of
    e@ExitFailure{} -> throw e
    ExitSuccess     -> maybe (return "") hGetContents mbStdout

getSTTYState :: IO String
getSTTYState = stty "-g"

setSTTYState :: String -> IO ()
setSTTYState = void . stty

promptPassword :: IO ()
promptPassword = do
  putStr "Password: "
  hFlush stdout
  passwd <- bracket getSTTYState setSTTYState $ \_ -> do
    void $ stty "-echo"
    getLine
  putStrLn $ "Your password is " ++ passwd

main :: IO ()
main = promptPassword

Of course, this isn't at all portable, since it won't even work on cmd.exe/PowerShell. Perhaps we could take a cue from terminal-size and default to the strategy above whenever we're not on a Windows console? It's easy enough to detect when you're not on a Windows console (just use System.IO.hIsTerminalDevice System.IO.stdin), but I don't know a reliable way to test if you're on MinTTY (other than check for the presence of the _ environmental variable, as GHC does, but this is obviously fallible). It might be safe to assume that if you're not on a Windows console, then stty is present.

@ezyang

This comment has been minimized.

Copy link
Contributor

ezyang commented Nov 25, 2016

I don't think it is unreasonable to use the same strategy as GHC (although I know sometimes GHCi gets it wrong), but IMO, any strategy which does the right thing when you run cabal from (1) mintty, (2) PowerShell, and (3) cmd.exe is good enough for me. Perhaps we can turn this into a little library that eventually other people can use.

In short, go for it! (You have commit bits right? :)

@RyanGlScott

This comment has been minimized.

Copy link
Member

RyanGlScott commented Dec 22, 2016

Very well, I've implemented these ideas in the echo library on Hackage. Now you can implement a MinTTY-compatible password prompt like this:

import System.IO.Echo

main :: IO ()
main = do
  foo <- withoutInputEcho getLine
  putStrLn $ "Your password is " ++ foo

So now the question becomes: should cabal-install add echo as a dependency, or should we inline the code from echo into cabal-install?

@ezyang

This comment has been minimized.

Copy link
Contributor

ezyang commented Dec 22, 2016

I think echo passes the "OK to depend on" test (whatever that is haha)!

RyanGlScott added a commit that referenced this issue Dec 22, 2016

23Skidoo added a commit that referenced this issue Dec 22, 2016

Merge pull request #4186 from haskell/echo
Depend on echo to fix #4128
@hvr

This comment has been minimized.

Copy link
Member

hvr commented Dec 22, 2016

@ezyang @RyanGlScott Fwiw, I consider an "OK to depend on" test whether the library follows the PVP, has a reasonably small dependency footprint (or at least not more than we already depend on), and has an API that's not going to change drastically in the foreseeable future (i.e. infrequent major version bumps), and looks written & documented reasonably well, as that gives us some confidence the library is stable and won't bitrot that easily...

PS: ...and there's also the Fairbairn threshold to consider...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment