From a42bbd7ffd94b9f94e761ab5ae371fd8dee44198 Mon Sep 17 00:00:00 2001
From: Kiril Videlov
Date: Fri, 9 Feb 2024 17:31:16 +0100
Subject: [PATCH] feat: adds support for omitting host certificate checks when
authenticating with ssh
---
gitbutler-app/src/gb_repository/repository.rs | 6 +++++
.../src/project_repository/repository.rs | 23 +++++++++++++++----
gitbutler-app/src/projects/project.rs | 2 ++
gitbutler-app/src/projects/storage.rs | 5 ++++
gitbutler-ui/src/lib/backend/projects.ts | 2 ++
.../src/lib/components/PreferencesForm.svelte | 21 ++++++++++++++++-
.../routes/[projectId]/settings/+page.svelte | 5 ++--
7 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/gitbutler-app/src/gb_repository/repository.rs b/gitbutler-app/src/gb_repository/repository.rs
index 50dd4cd2f..a6eaec590 100644
--- a/gitbutler-app/src/gb_repository/repository.rs
+++ b/gitbutler-app/src/gb_repository/repository.rs
@@ -143,6 +143,9 @@ impl Repository {
};
let mut callbacks = git2::RemoteCallbacks::new();
+ if self.project.omit_certificate_check.unwrap_or(false) {
+ callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
+ }
callbacks.push_update_reference(move |refname, message| {
tracing::debug!(
project_id = %self.project.id,
@@ -194,6 +197,9 @@ impl Repository {
// Set the remote's callbacks
let mut callbacks = git2::RemoteCallbacks::new();
+ if self.project.omit_certificate_check.unwrap_or(false) {
+ callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
+ }
callbacks.push_update_reference(move |refname, message| {
tracing::debug!(
project_id = %self.project.id,
diff --git a/gitbutler-app/src/project_repository/repository.rs b/gitbutler-app/src/project_repository/repository.rs
index 86952394f..f0fa3f1ec 100644
--- a/gitbutler-app/src/project_repository/repository.rs
+++ b/gitbutler-app/src/project_repository/repository.rs
@@ -287,6 +287,9 @@ impl Repository {
.ok_or(RemoteError::Auth)?;
let mut callbacks = git2::RemoteCallbacks::new();
+ if self.project.omit_certificate_check.unwrap_or(false) {
+ callbacks.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
+ }
let bytes_pushed = Arc::new(AtomicUsize::new(0));
let total_objects = Arc::new(AtomicUsize::new(0));
{
@@ -353,12 +356,18 @@ impl Repository {
let auth_flows = credentials.help(self, branch.remote())?;
for (mut remote, callbacks) in auth_flows {
if let Some(url) = remote.url().context("failed to get remote url")? {
- ssh::check_known_host(&url).context("failed to check known host")?;
+ if !self.project.omit_certificate_check.unwrap_or(false) {
+ ssh::check_known_host(&url).context("failed to check known host")?;
+ }
}
for callback in callbacks {
+ let mut cbs: git2::RemoteCallbacks = callback.into();
+ if self.project.omit_certificate_check.unwrap_or(false) {
+ cbs.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
+ }
match remote.push(
&[refspec.as_str()],
- Some(&mut git2::PushOptions::new().remote_callbacks(callback.into())),
+ Some(&mut git2::PushOptions::new().remote_callbacks(cbs)),
) {
Ok(()) => {
tracing::info!(
@@ -395,11 +404,17 @@ impl Repository {
let auth_flows = credentials.help(self, remote_name)?;
for (mut remote, callbacks) in auth_flows {
if let Some(url) = remote.url().context("failed to get remote url")? {
- ssh::check_known_host(&url).context("failed to check known host")?;
+ if !self.project.omit_certificate_check.unwrap_or(false) {
+ ssh::check_known_host(&url).context("failed to check known host")?;
+ }
}
for callback in callbacks {
let mut fetch_opts = git2::FetchOptions::new();
- fetch_opts.remote_callbacks(callback.into());
+ let mut cbs: git2::RemoteCallbacks = callback.into();
+ if self.project.omit_certificate_check.unwrap_or(false) {
+ cbs.certificate_check(|_, _| Ok(git2::CertificateCheckStatus::CertificateOk));
+ }
+ fetch_opts.remote_callbacks(cbs);
fetch_opts.prune(git2::FetchPrune::On);
match remote.fetch(&[refspec], Some(&mut fetch_opts)) {
diff --git a/gitbutler-app/src/projects/project.rs b/gitbutler-app/src/projects/project.rs
index 31aacc5c6..e55c23c17 100644
--- a/gitbutler-app/src/projects/project.rs
+++ b/gitbutler-app/src/projects/project.rs
@@ -76,6 +76,8 @@ pub struct Project {
pub gitbutler_code_push_state: Option,
#[serde(default)]
pub project_data_last_fetch: Option,
+ #[serde(default)]
+ pub omit_certificate_check: Option,
}
impl AsRef for Project {
diff --git a/gitbutler-app/src/projects/storage.rs b/gitbutler-app/src/projects/storage.rs
index eaff7823e..53f6cc4cc 100644
--- a/gitbutler-app/src/projects/storage.rs
+++ b/gitbutler-app/src/projects/storage.rs
@@ -46,6 +46,7 @@ pub struct UpdateRequest {
pub ok_with_force_push: Option,
pub gitbutler_code_push_state: Option,
pub project_data_last_fetched: Option,
+ pub omit_certificate_check: Option,
}
#[derive(Debug, thiserror::Error)]
@@ -130,6 +131,10 @@ impl Storage {
*project.ok_with_force_push = ok_with_force_push;
}
+ if let Some(omit_certificate_check) = update_request.omit_certificate_check {
+ project.omit_certificate_check = Some(omit_certificate_check);
+ }
+
self.storage
.write(PROJECTS_FILE, &serde_json::to_string_pretty(&projects)?)?;
diff --git a/gitbutler-ui/src/lib/backend/projects.ts b/gitbutler-ui/src/lib/backend/projects.ts
index 8bac56598..07823827e 100644
--- a/gitbutler-ui/src/lib/backend/projects.ts
+++ b/gitbutler-ui/src/lib/backend/projects.ts
@@ -32,6 +32,7 @@ export type Project = {
api?: CloudProject & { sync: boolean };
preferred_key: Key;
ok_with_force_push: boolean;
+ omit_certificate_check: boolean | undefined;
};
export class ProjectService {
@@ -70,6 +71,7 @@ export class ProjectService {
api?: CloudProject & { sync: boolean };
preferred_key?: Key;
okWithForcePush?: boolean;
+ omitCertificateCheck?: boolean;
}) {
await invoke('update_project', { project: params });
this.reload();
diff --git a/gitbutler-ui/src/lib/components/PreferencesForm.svelte b/gitbutler-ui/src/lib/components/PreferencesForm.svelte
index 6896b3684..88207385e 100644
--- a/gitbutler-ui/src/lib/components/PreferencesForm.svelte
+++ b/gitbutler-ui/src/lib/components/PreferencesForm.svelte
@@ -7,11 +7,13 @@
export let project: Project;
let allowForcePushing = project?.ok_with_force_push;
+ let omitCertificateCheck = project?.omit_certificate_check;
const runCommitHooks = projectRunCommitHooks(project.id);
const dispatch = createEventDispatcher<{
updated: {
- ok_with_force_push: boolean;
+ ok_with_force_push?: boolean;
+ omit_certificate_check?: boolean;
};
}>();
@@ -35,6 +37,23 @@
never force push to the trunk.
+
+
+ Enabling this will ignore host certificate checks when authenticating with ssh.
+
+