Implement SSH upload-pack fetches

This commit is contained in:
2026-08-25 20:31:10 +02:00
parent 5dbda4bbd2
commit 051e14235f
9 changed files with 1367 additions and 53 deletions

View File

@@ -12,12 +12,13 @@ use std::{
use ironstorage::{
command::{InsertInput, InsertRequest},
config::{Config, ConfigLoader, GitRemote},
config::{Config, ConfigLoader, GitRemote, SshFingerprint},
crypto::{DetachedSignatureBytes, KeyInfo, KeyStore, SecretProvider, SecretProviderError},
git::{
GitChangeKind, GitConflictChoice, GitConflictResolution, GitCredential,
GitCredentialProvider, GitError, GitFetchTransport, GitIdentity, GitOperationControl,
GitProgressPhase, GitRepository, GitSmartHttpTransport, PullOutcome,
GitProgressPhase, GitRemoteCredentialProvider, GitRepository, GitSmartHttpTransport,
PullOutcome, SshPassphraseProvider,
},
repository::{Repository, SecretBytes},
write::{InsertContent, OverwriteDecision, VaultWriter},
@@ -230,6 +231,24 @@ impl GitCredentialProvider for Credentials {
}
}
impl SshPassphraseProvider for Credentials {
fn ssh_key_passphrase(&self, fingerprint: &SshFingerprint) -> Result<SecretBytes, GitError> {
Err(GitError::SshKeyPassphraseUnavailable {
fingerprint: fingerprint.clone(),
})
}
}
fn http_credential(
configured: &GitRemote,
credentials: &dyn GitRemoteCredentialProvider,
) -> Result<GitCredential, GitError> {
let (server, application) = configured
.https_credentials()
.ok_or(GitError::CredentialsUnavailable)?;
credentials.credential(server, application)
}
struct SigningSecret(Vec<u8>);
impl SecretProvider for SigningSecret {
@@ -249,9 +268,10 @@ impl GitFetchTransport for CloningFetch {
fn fetch(
&self,
repository: &GitRepository,
_configured: &GitRemote,
credential: &GitCredential,
configured: &GitRemote,
credentials: &dyn GitRemoteCredentialProvider,
) -> Result<bool, GitError> {
let credential = http_credential(configured, credentials)?;
assert_eq!(credential.password(), b"token");
fs::write(repository.root().join(".gpg-id"), b"ALICE\n")
.map_err(|error| GitError::InvalidRepository(error.to_string()))?;
@@ -272,9 +292,9 @@ impl GitFetchTransport for OccupyingFetch {
&self,
repository: &GitRepository,
configured: &GitRemote,
credential: &GitCredential,
credentials: &dyn GitRemoteCredentialProvider,
) -> Result<bool, GitError> {
let fetched = CloningFetch.fetch(repository, configured, credential)?;
let fetched = CloningFetch.fetch(repository, configured, credentials)?;
fs::write(self.0.join("keep"), b"concurrent contents")
.map_err(|error| GitError::InvalidRepository(error.to_string()))?;
Ok(fetched)
@@ -287,9 +307,10 @@ impl GitFetchTransport for NoopFetch {
fn fetch(
&self,
_repository: &GitRepository,
_configured: &GitRemote,
credential: &GitCredential,
configured: &GitRemote,
credentials: &dyn GitRemoteCredentialProvider,
) -> Result<bool, GitError> {
let credential = http_credential(configured, credentials)?;
assert_eq!(credential.username(), "alice");
Ok(false)
}
@@ -302,7 +323,7 @@ impl GitFetchTransport for FailedFetch {
&self,
_repository: &GitRepository,
_configured: &GitRemote,
_credential: &GitCredential,
_credentials: &dyn GitRemoteCredentialProvider,
) -> Result<bool, GitError> {
Err(self.0.clone())
}