forked from mirrors/jj
Fix Git/SSH on Windows
There were two issues on my end: 1. `known_hosts` doesn't seem to be recognized 2. SSH Agent is ignored despite running A workaround for 1. is to set the HOME environment variable on Windows, so I added a hint to suggest this. Ideally we would add a `certificate_check` callback to the remote callbacks, but the git2 crate doesn't expose whether the certificate check already succeeded, which makes it useless for this purpose (as we'd be prompting users to accept a certificate even though that certificate is already known to be valid). As for 2., I changed the behavior from "check SSH Agent if some env variables exist" to "check SSH Agent and only fail if some env variables exist". On Windows SSH Agent doesn't use these env variables (but trying to communicate with it will still work), so now Windows properly works with SSH Agent.
This commit is contained in:
parent
cd0023e796
commit
104f8e154c
2 changed files with 34 additions and 13 deletions
|
@ -637,15 +637,30 @@ impl<'a> RemoteCallbacks<'a> {
|
|||
return Ok(creds);
|
||||
} else if let Some(username) = username_from_url {
|
||||
if allowed_types.contains(git2::CredentialType::SSH_KEY) {
|
||||
if std::env::var("SSH_AUTH_SOCK").is_ok()
|
||||
|| std::env::var("SSH_AGENT_PID").is_ok()
|
||||
{
|
||||
tracing::info!(username, "using ssh_key_from_agent");
|
||||
return git2::Cred::ssh_key_from_agent(username).map_err(|err| {
|
||||
tracing::error!(err = %err);
|
||||
err
|
||||
});
|
||||
// Try to get the SSH key from the agent by default, and report an error
|
||||
// only if it _seems_ like that's what the user wanted.
|
||||
//
|
||||
// Note that the env variables read below are **not** the only way to
|
||||
// communicate with the agent, which is why we request a key from it no
|
||||
// matter what.
|
||||
match git2::Cred::ssh_key_from_agent(username) {
|
||||
Ok(key) => {
|
||||
tracing::info!(username, "using ssh_key_from_agent");
|
||||
return Ok(key);
|
||||
}
|
||||
Err(err) => {
|
||||
if std::env::var("SSH_AUTH_SOCK").is_ok()
|
||||
|| std::env::var("SSH_AGENT_PID").is_ok()
|
||||
{
|
||||
tracing::error!(err = %err);
|
||||
return Err(err);
|
||||
}
|
||||
// There is no agent-related env variable so we
|
||||
// consider that the user doesn't care about using
|
||||
// the agent and proceed.
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref mut cb) = self.get_ssh_key {
|
||||
if let Some(path) = cb(username) {
|
||||
tracing::info!(username, path = ?path, "using ssh_key");
|
||||
|
|
|
@ -157,11 +157,17 @@ fn get_git_repo(store: &Store) -> Result<git2::Repository, CommandError> {
|
|||
|
||||
fn map_git_error(err: git2::Error) -> CommandError {
|
||||
if err.class() == git2::ErrorClass::Ssh {
|
||||
user_error_with_hint(
|
||||
err.to_string(),
|
||||
"Jujutsu uses libssh2, which doesn't respect ~/.ssh/config. Does `ssh -F /dev/null` \
|
||||
to the host work?",
|
||||
)
|
||||
let hint =
|
||||
if err.code() == git2::ErrorCode::Certificate && std::env::var_os("HOME").is_none() {
|
||||
"The HOME environment variable is not set, and might be required for Git to \
|
||||
successfully load certificates. Try setting it to the path of a directory that \
|
||||
contains a `.ssh` directory."
|
||||
} else {
|
||||
"Jujutsu uses libssh2, which doesn't respect ~/.ssh/config. Does `ssh -F \
|
||||
/dev/null` to the host work?"
|
||||
};
|
||||
|
||||
user_error_with_hint(err.to_string(), hint)
|
||||
} else {
|
||||
user_error(err.to_string())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue