-
-
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
Support using EOF char (^D) to abort credential prompt #23092
Conversation
Note the additional tests produce more of the warnings:
The warnings will go away once #20621 is merged. |
base/libgit2/utils.jl
Outdated
isempty(uinput) && return Nullable{String}() # Encountered EOF | ||
uinput = chomp(uinput) | ||
end | ||
Nullable{String}(isempty(uinput) ? default : uinput) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is anything externally (PkgDev maybe) using this function that will notice the API change to returning a Nullable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. This is used by PkgDev.
What's the recommended procedure for deprecating a function's return type? Should I deprecate prompt(::AbstractString)
and introduce the following:
prompt(::Type{Nullable{String}}, msg::AbstractString; default::AbstractString="", password::Bool=false)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that'll work, it's not the prettiest or most concise but it would do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we would deprecate prompt(::AbstractString)::AbstractString
for Julia 0.7 and introduce prompt(::Type{Nullable{String}}, ::AbstractString)
.
For Julia 1.0 we would deprecate prompt(::Type{Nullable{String}}, ::AbstractString)
in favor of prompt(::AbstractString)::Nullable{String}
? I guess we could do this after 1.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I came up with a better plan. Since this function isn't LibGit2 specific I'll moved this function into Base
. That way we can have Base.prompt
and the deprecated LibGit2.prompt
without having to change the method parameters.
base/libgit2/callbacks.jl
Outdated
response = prompt("Passphrase for $privatekey", password=true) | ||
isnull(response) && return user_abort() | ||
passdef = unsafe_get(response) | ||
isempty(passdef) && return user_abort() # Ambiguous if EOF or newline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there still a way to specify / use passwordless keys? (likewise for the other "Ambiguous" comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using ssh-keygen
a passwordless key wouldn't pass the passphrase_required
check.
For username/password I don't think LibGit2 will hit this callback unless it requires a password. I'll try to come up with an example for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some digging into this.
For SSH having a empty passphrase is considered as not having any passphrase at all. Since we can tell the difference between SSH keys that do and do not require passphrases (encrypted private keys have second line as "Proc-Type: 4,ENCRYPTED") and only prompt when a private key is encrypted it should be safe to abort if a empty passphrase is entered at the prompt.
For HTTP I ended up doing some experimentation with httpbin and using empty passwords for both HTTP Basic and Digest authentication. Both seem to consider an empty password invalid and will re-prompt for credentials.
test/libgit2.jl
Outdated
@test err == 0 | ||
@test auth_attempts == 1 | ||
end | ||
|
||
# TODO: Tests are currently broken. Credential callback prompts for: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you fixing this entire TODO or only part of it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TODO is done and should be removed.
withenv("SSH_KEY_PATH" => nothing, | ||
"SSH_PUB_KEY_PATH" => nothing, | ||
"SSH_KEY_PASS" => nothing, | ||
(Sys.iswindows() ? "USERPROFILE" : "HOME") => tempdir()) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this relying on tempdir happening to not have any key files in it? probably unlikely, but never know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I specifically need to set the HOME to be a directory that doesn't contain the file ".ssh/id_rsa". I'll add a comment and a test ensuring that this is the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this check and the comment.
As part of the supporting EOF update (#23092) we needed to deprecate the original `LibGit2.prompt` since the return type changed. Since packages like PkgDev make use of the `prompt` function and the function itself isn't LibGit2 specific it seemed best to move it into Base. This allows us to deprecate the original `prompt` without having to change the function name or modify the parameters.
As part of the supporting EOF update (#23092) we needed to deprecate the original `LibGit2.prompt` since the return type changed. Since packages like PkgDev make use of the `prompt` function and the function itself isn't LibGit2 specific it seemed best to move it into Base. This allows us to deprecate the original `prompt` without having to change the function name or modify the parameters.
CI failure looks unrelated. I updated the PR description to mention all changes. |
As part of the supporting EOF update (#23092) we needed to deprecate the original `LibGit2.prompt` since the return type changed. Since packages like PkgDev make use of the `prompt` function and the function itself isn't LibGit2 specific it seemed best to move it into Base. This allows us to deprecate the original `prompt` without having to change the function name or modify the parameters.
Rebased changes to fix conflicts. Needed to update the LibGit2 test where the user provides an empty private key filename at the prompt (#23108). diff --git a/test/libgit2.jl b/test/libgit2.jl
--- a/test/libgit2.jl
+++ b/test/libgit2.jl
@@ -1676,16 +1676,15 @@ mktempdir() do dir
@test err == abort_prompt
@test auth_attempts == 1
- # User provides an empty private key
- # TODO: Should trigger a re-prompt.
+ # User provides an empty private key which triggers a re-prompt
challenges = [
"Private key location for '[email protected]':" => "\n",
"Public key location for '[email protected]' [.pub]:" => "\n",
- "Passphrase for :" => "\n",
+ "Private key location for '[email protected]':" => "\x04",
]
err, auth_attempts = challenge_prompt(ssh_cmd, challenges)
@test err == abort_prompt
- @test auth_attempts == 1
+ @test auth_attempts == 2
end |
Without this an empty string in the `username_ptr` will never prompt the user for a new username. Has not been seen in the wild.
As part of the supporting EOF update (#23092) we needed to deprecate the original `LibGit2.prompt` since the return type changed. Since packages like PkgDev make use of the `prompt` function and the function itself isn't LibGit2 specific it seemed best to move it into Base. This allows us to deprecate the original `prompt` without having to change the function name or modify the parameters.
Rebased again to deal with conflicts from #23040. Planning to merge this tomorrow. |
Part of #20725.
Supports using EOF to abort the credential prompt. This is important as newlines can be used to select the default value.
Note that for password prompts it is currently not possible to tell the difference between an EOF and a newline. The PR behaviour is to assume an EOF was given.
Additional changes include:
LibGit2.prompt(::AbstractString) -> String
withBase.prompt(::AbstractString) -> Nullable{String}
LibGit2.user_abort
function which is only meant for internal use.credential_loop
can now distinguish between "" and C_NULL.