Skip to content

Commit

Permalink
Prompt for private if SSH_KEY_PATH unset
Browse files Browse the repository at this point in the history
Allows the user to confirm they want to use the default private key.
During development it was noticed that the username was only being
filled in if prompting was allowed.
  • Loading branch information
omus committed Sep 22, 2017
1 parent 773d226 commit 23d2fd2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
12 changes: 6 additions & 6 deletions base/libgit2/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ function authenticate_ssh(libgit2credptr::Ptr{Ptr{Void}}, p::CredentialPayload,
end

if p.use_env && (!revised || !isfilled(cred))
if isempty(cred.user) && username_ptr != Cstring(C_NULL)
cred.user = unsafe_string(username_ptr)
end

cred.prvkey = Base.get(ENV, "SSH_KEY_PATH") do
default = joinpath(homedir(), ".ssh", "id_rsa")
if isempty(cred.prvkey) && isfile(default)
Expand All @@ -107,22 +111,18 @@ function authenticate_ssh(libgit2credptr::Ptr{Ptr{Void}}, p::CredentialPayload,
end

if p.remaining_prompts > 0 && (!revised || !isfilled(cred))
# if username is not provided or empty, then prompt for it
username = username_ptr != Cstring(C_NULL) ? unsafe_string(username_ptr) : ""
if isempty(username)
if isempty(cred.user) || username_ptr == Cstring(C_NULL)
url = git_url(scheme=p.scheme, host=p.host)
response = Base.prompt("Username for '$url'", default=cred.user)
isnull(response) && return user_abort()
cred.user = unsafe_get(response)
else
cred.user = username
end

url = git_url(scheme=p.scheme, host=p.host, username=cred.user)

# For SSH we need a private key location
last_private_key = cred.prvkey
if !isfile(cred.prvkey) || !revised
if !isfile(cred.prvkey) || !revised || !haskey(ENV, "SSH_KEY_PATH")
response = Base.prompt("Private key location for '$url'", default=cred.prvkey)
isnull(response) && return user_abort()
cred.prvkey = expanduser(unsafe_get(response))
Expand Down
49 changes: 38 additions & 11 deletions test/libgit2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2025,27 +2025,54 @@ mktempdir() do dir
url = "github.com:test/package.jl"

default_key = joinpath(home_dir, ".ssh", "id_rsa")
default_cred = LibGit2.SSHCredentials("git", "", default_key, default_key * ".pub")

# Copy the stored private/public
key = joinpath(KEY_DIR, "valid")
mkdir(dirname(default_key))
cp(key, default_key)
cp(key * ".pub", default_key * ".pub")

ssh_ex = quote
include($LIBGIT2_HELPER_PATH)
credential_loop($default_cred, $url, "git")
valid_key = joinpath(KEY_DIR, "valid")
valid_cred = LibGit2.SSHCredentials("git", "", valid_key, valid_key * ".pub")

valid_p_key = joinpath(KEY_DIR, "valid-passphrase")
passphrase = "secret"
valid_p_cred = LibGit2.SSHCredentials("git", passphrase, valid_p_key, valid_p_key * ".pub")

function gen_ex(cred)
quote
valid_cred = $cred

default_cred = deepcopy(valid_cred)
default_cred.prvkey = $default_key
default_cred.pubkey = $default_key * ".pub"

cp(valid_cred.prvkey, default_cred.prvkey)
cp(valid_cred.pubkey, default_cred.pubkey)

try
include($LIBGIT2_HELPER_PATH)
credential_loop(default_cred, $url, "git")
finally
rm(default_cred.prvkey)
rm(default_cred.pubkey)
end
end
end

withenv("SSH_KEY_PATH" => nothing,
"SSH_PUB_KEY_PATH" => nothing,
"SSH_KEY_PASS" => nothing,
HOME => home_dir) do

@test isfile(joinpath(homedir(), ".ssh", "id_rsa"))
# Automatically use the default key
ex = gen_ex(valid_cred)
err, auth_attempts = challenge_prompt(ex, [])
@test err == git_ok
@test auth_attempts == 1

err, auth_attempts = challenge_prompt(ssh_ex, [])
# Confirm the private key if any other prompting is required
ex = gen_ex(valid_p_cred)
challenges = [
"Private key location for '[email protected]' [$default_key]:" => "\n",
"Passphrase for $default_key:" => "$passphrase\n",
]
err, auth_attempts = challenge_prompt(ex, challenges)
@test err == git_ok
@test auth_attempts == 1
end
Expand Down

0 comments on commit 23d2fd2

Please sign in to comment.