-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Implement getpasswd
, fix up github two-factor authentication
#8228
Comments
getpasswd
, fix up two-factor authenticationgetpasswd
, fix up github two-factor authentication
The Python getpass function may be helpful. There is also getpass.c from glibc, and a thread on stackoverflow. (We should certainly be able to put together a pure-Julia implementation, but it would be good to take a quick look at other implementations in case there are subtleties.) |
Note that we shouldn't keep the password in memory longer than necessary; probably better to be paranoid and to overwrite the string buffer with zeros when we are done; one also needs to be a bit careful in the |
@Keno, what's the best way to do prompting with the REPL? I'm assuming we don't want a new REPL mode for this. |
Well, we should implement a simple "prompt" function, but basically what you do is construct a |
Hmm. I'm messing with this and my need to refactor is getting strong... |
How does this differ from |
It's quite possible that STDIN is coming from something other than the terminal. Ideally, this should be nicely integrated with our line editing and allow backspace to work, etc. |
However, password input requires a bit different interface, because you don't want the password to appear as it is typed. And sending passwords via IJulia requires even more thought about security; I wouldn't recommend it for now. |
I think this should be reopened at PkgDev.jl. @wildart @jakebolewski how much of this is already functioning? |
A |
I use libc |
The man page for |
Does newer libuv maybe have something for this? |
I think it is easier to write pure julia implementation. |
It does not. @wildart please be more careful to not assume that a posix libc is present. Especially in interactive code that does not get tested on CI. |
Can this please get a 0.5 label? Until this is fixed, there is a major regression for windows users, i.e. that they can't work with private package repos at all. |
Somebody with access to a windows machine please test the following:
Tests for this are nontrivial, since it depends on the exact state of the tty which we can't really emulate. |
Don't we want this not to echo what gets typed? |
Yes, that's what happens in raw mode. |
At least on unix. |
Raw mode isn't really working on Windows then. And one or both of the |
Can we just use _getch on Windows? The more I look into this, the more I think we should just use |
The following works for me on Mac, GNU/Linux, and Windows, though it would probably be good to handle the backspace key and other niceties on Windows: @windows_only function getpass(prompt::AbstractString)
print(prompt)
p = UInt8[]
sizehint!(p, 128)
while true
c = ccall(:_getch, Cint, ())
c < 16 && break
push!(p, c)
end
s = bytestring(p)
fill!(p, 0)
return s
end
@unix_only getpass(prompt::AbstractString) = pointer_to_string(ccall(:getpass, Cstring, (Cstring,), prompt), true) |
That sounds like it'll be good enough for now. Certainly better than trying to ccall something that doesn't exist. |
Here's a somewhat improved version, that handles backspace but ignores other control characters as well as arrow and function keys: @windows_only function getpass(prompt::AbstractString)
print(prompt)
flush(STDOUT)
p = Array(UInt8, 128) # mimic Unix getpass in ignoring more than 128-char passwords
# (also avoids any potential memory copies arising from push!)
plen = 0
while true
c = ccall(:_getch, UInt8, ())
if c == 0xff || c == UInt8('\n') || c == UInt8('\r')
break # EOF or return
elseif c == 0x00 || c == 0xe0
ccall(:_getch, UInt8, ()) # ignore function/arrow keys
elseif c == UInt8('\b') && plen > 0
plen -= 1 # delete last character on backspace
elseif !iscntrl(Char(c)) && plen < 128
p[plen += 1] = c
end
end
s = bytestring(pointer(p), plen)
fill!(p, 0) # don't leave password in memory
return s
end
@unix_only getpass(prompt::AbstractString) = pointer_to_string(ccall(:getpass, Cstring, (Cstring,), prompt), true) There is also a |
i find that hard to believe since we depend on it for the REPL to print correctly |
Ah, apologies, it looks like Keno's code does work when built into the sysimg but not when called from the repl. My bad. |
I wonder if |
Just tried it, it's not even installed on my Fedora 23 box (on which I installed all kinds of packages over the years). So no. |
Note that one of the things that we have to be very careful of is accidentally leaving extra copies of the password in memory. e.g. @Keno's version calls
Also, |
- handle https & ssh connections - new credential types added caching of credentials in `update` added cross-platform `getpass` implementation [JuliaLang#8228] added comments and documentation show last saved value for pub/priv key path instead of default key path move `getpass` to `Base` introduced SSH credential type for cached credentials changed PK variable to `SSH_KEY_PATH`, added PbK guessing from PK
- handle https & ssh connections - new credential types added caching of credentials in `update` added cross-platform `getpass` implementation [JuliaLang#8228] added comments and documentation show last saved value for pub/priv key path instead of default key path move `getpass` to `Base` introduced SSH credential type for cached credentials changed PK variable to `SSH_KEY_PATH`, added PbK guessing from PK
#5252#6668 added support for github two-factor authentication. However, the implementation is a bit ugly: in the worst case, the user has to enter her password 4 times(!).The nicest way to handle this would probably be to implement a
getpasswd
(orgetpass
) function, which reads in a password without echoing, and then passes that onto curl viacurl -K -
(which reads a config file from stdin).The text was updated successfully, but these errors were encountered: