-
-
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
Test LibGit2 SSH authentication #17651
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,9 @@ | |
|
||
#@testset "libgit2" begin | ||
|
||
isdefined(:TestHelpers) || include(joinpath(dirname(@__FILE__), "TestHelpers.jl")) | ||
using TestHelpers | ||
|
||
const LIBGIT2_MIN_VER = v"0.23.0" | ||
|
||
######### | ||
|
@@ -567,6 +570,180 @@ mktempdir() do dir | |
@test creds.user == creds_user | ||
@test creds.pass == creds_pass | ||
#end | ||
|
||
#@testset "SSH" begin | ||
sshd_command = "" | ||
ssh_repo = joinpath(dir, "Example.SSH") | ||
if !is_windows() | ||
try | ||
# SSHD needs to be executed by its full absolute path | ||
sshd_command = strip(readstring(`which sshd`)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's not the purpose of this command. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh. add a comment that says that. |
||
catch | ||
warn("Skipping SSH tests (Are `which` and `sshd` installed?)") | ||
end | ||
end | ||
if !isempty(sshd_command) | ||
mktempdir() do fakehomedir | ||
mkdir(joinpath(fakehomedir,".ssh")) | ||
# Unsetting the SSH agent serves two purposes. First, we make | ||
# sure that we don't accidentally pick up an existing agent, | ||
# and second we test that we fall back to using a key file | ||
# if the agent isn't present. | ||
withenv("HOME"=>fakehomedir,"SSH_AUTH_SOCK"=>nothing) do | ||
# Generate user file, first an unencrypted one | ||
wait(spawn(`ssh-keygen -N "" -C juliatest@localhost -f $fakehomedir/.ssh/id_rsa`)) | ||
|
||
# Generate host keys | ||
wait(spawn(`ssh-keygen -f $fakehomedir/ssh_host_rsa_key -N '' -t rsa`)) | ||
wait(spawn(`ssh-keygen -f $fakehomedir/ssh_host_dsa_key -N '' -t dsa`)) | ||
|
||
our_ssh_port = rand(13000:14000) # Chosen arbitrarily | ||
|
||
key_option = "AuthorizedKeysFile $fakehomedir/.ssh/id_rsa.pub" | ||
pidfile_option = "PidFile $fakehomedir/sshd.pid" | ||
sshp = agentp = nothing | ||
logfile = tempname() | ||
ssh_debug = false | ||
function spawn_sshd() | ||
debug_flags = ssh_debug ? `-d -d` : `` | ||
_p = open(logfile, "a") do logfilestream | ||
spawn(pipeline(pipeline(`$sshd_command | ||
-e -f /dev/null $debug_flags | ||
-h $fakehomedir/ssh_host_rsa_key | ||
-h $fakehomedir/ssh_host_dsa_key -p $our_ssh_port | ||
-o $pidfile_option | ||
-o 'Protocol 2' | ||
-o $key_option | ||
-o 'UsePrivilegeSeparation no' | ||
-o 'StrictModes no'`,STDOUT),stderr=logfilestream)) | ||
end | ||
# Give the SSH server 5 seconds to start up | ||
yield(); sleep(5) | ||
_p | ||
end | ||
sshp = spawn_sshd() | ||
|
||
TIOCSCTTY_str = "ccall(:ioctl, Void, (Cint, Cint, Int64), 0, | ||
(is_bsd() || is_apple()) ? 0x20007461 : is_linux() ? 0x540E : | ||
error(\"Fill in TIOCSCTTY for this OS here\"), 0)" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this test just going to fail completely on freebsd then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, unless you a) tell me the value of TIOCSCTTY on freebsd and other relevant platforms or b) prevent @vtjnash from merging the patch that makes this necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although given that most of Apple's userland is freebsd, I wouldn't be surprised if the value is the same. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mhm, looks like it's the same as on OS X |
||
|
||
# To fail rather than hang | ||
function killer_task(p, master) | ||
@async begin | ||
sleep(10) | ||
kill(p) | ||
if isopen(master) | ||
nb_available(master) > 0 && | ||
write(logfile, | ||
readavailable(master)) | ||
close(master) | ||
end | ||
end | ||
end | ||
|
||
try | ||
function try_clone(challenges = []) | ||
cmd = """ | ||
repo = nothing | ||
try | ||
$TIOCSCTTY_str | ||
reponame = "ssh://$(ENV["USER"])@localhost:$our_ssh_port$cache_repo" | ||
repo = LibGit2.clone(reponame, "$ssh_repo") | ||
catch err | ||
open("$logfile","a") do f | ||
println(f,"HOME: ",ENV["HOME"]) | ||
println(f, err) | ||
end | ||
finally | ||
finalize(repo) | ||
end | ||
""" | ||
# We try to be helpful by desparately looking for | ||
# a way to prompt the password interactively. Pretend | ||
# to be a TTY to suppress those shenanigans. Further, we | ||
# need to detach and change the controlling terminal with | ||
# TIOCSCTTY, since getpass opens the controlling terminal | ||
TestHelpers.with_fake_pty() do slave, master | ||
err = Base.Pipe() | ||
let p = spawn(detach( | ||
`$(Base.julia_cmd()) --startup-file=no -e $cmd`),slave,slave,STDERR) | ||
killer_task(p, master) | ||
for (challenge, response) in challenges | ||
readuntil(master, challenge) | ||
sleep(1) | ||
print(master, response) | ||
end | ||
sleep(2) | ||
wait(p) | ||
close(master) | ||
end | ||
end | ||
@test isfile(joinpath(ssh_repo,"testfile")) | ||
rm(ssh_repo, recursive = true) | ||
end | ||
|
||
# Should use the default files, no interaction required. | ||
try_clone() | ||
ssh_debug && (kill(sshp); sshp = spawn_sshd()) | ||
|
||
# Ok, now encrypt the file and test with that (this also | ||
# makes sure that we don't accidentally fall back to the | ||
# unencrypted version) | ||
wait(spawn(`ssh-keygen -p -N "xxxxx" -f $fakehomedir/.ssh/id_rsa`)) | ||
|
||
# Try with the encrypted file. Needs a password. | ||
try_clone(["Passphrase"=>"xxxxx\r\n"]) | ||
ssh_debug && (kill(sshp); sshp = spawn_sshd()) | ||
|
||
# Move the file. It should now ask for the location and | ||
# then the passphrase | ||
mv("$fakehomedir/.ssh/id_rsa","$fakehomedir/.ssh/id_rsa2") | ||
cp("$fakehomedir/.ssh/id_rsa.pub","$fakehomedir/.ssh/id_rsa2.pub") | ||
try_clone(["location"=>"$fakehomedir/.ssh/id_rsa2\n", | ||
"Passphrase"=>"xxxxx\n"]) | ||
mv("$fakehomedir/.ssh/id_rsa2","$fakehomedir/.ssh/id_rsa") | ||
rm("$fakehomedir/.ssh/id_rsa2.pub") | ||
|
||
# Ok, now start an agent | ||
agent_sock = tempname() | ||
agentp = spawn(`ssh-agent -a $agent_sock -d`) | ||
while stat(agent_sock).mode == 0 # Wait until the agent is started | ||
sleep(1) | ||
end | ||
|
||
# fake pty is required for the same reason as in try_clone | ||
# above | ||
withenv("SSH_AUTH_SOCK" => agent_sock) do | ||
TestHelpers.with_fake_pty() do slave, master | ||
cmd = """ | ||
$TIOCSCTTY_str | ||
run(pipeline(`ssh-add $fakehomedir/.ssh/id_rsa`, | ||
stderr = DevNull)) | ||
""" | ||
addp = spawn(detach(`$(Base.julia_cmd()) --startup-file=no -e $cmd`), | ||
slave, slave, STDERR) | ||
killer_task(addp, master) | ||
sleep(2) | ||
write(master, "xxxxx\n") | ||
wait(addp) | ||
end | ||
|
||
# Should now use the agent | ||
try_clone() | ||
end | ||
catch err | ||
println("SSHD logfile contents follows:") | ||
println(readstring(logfile)) | ||
rethrow(err) | ||
finally | ||
rm(logfile) | ||
sshp !== nothing && kill(sshp) | ||
agentp !== nothing && kill(agentp) | ||
end | ||
end | ||
end | ||
end | ||
#end | ||
end | ||
|
||
#end |
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.
not
libgit2
butlibgit2-online
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.
No, these tests are in libgit2, since they don't require a network connection but they do require
lo
. I suppose we could split them out yet again, but not sure it's worth it. @tkelman?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 seems fine, I rarely see net_on not true. WSL is one of the few places that's 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.
World Surf League?
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.
windows subsystem for linux - aka bash on ubuntu on windows