mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 02:08:47 +00:00
tunnel: fix keyring panic on Linux (#185066)
tunnel: fix keyring panic on Linxu Fixes #184792 Reported on https://github.com/hwchen/keyring-rs/issues/132
This commit is contained in:
@@ -20,7 +20,7 @@ use async_trait::async_trait;
|
|||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, Utc};
|
||||||
use gethostname::gethostname;
|
use gethostname::gethostname;
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use std::{cell::Cell, fmt::Display, path::PathBuf, sync::Arc};
|
use std::{cell::Cell, fmt::Display, path::PathBuf, sync::Arc, thread};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use tunnels::{
|
use tunnels::{
|
||||||
contracts::PROD_FIRST_PARTY_APP_ID,
|
contracts::PROD_FIRST_PARTY_APP_ID,
|
||||||
@@ -210,6 +210,48 @@ const KEYCHAIN_ENTRY_LIMIT: usize = 128 * 1024;
|
|||||||
|
|
||||||
const CONTINUE_MARKER: &str = "<MORE>";
|
const CONTINUE_MARKER: &str = "<MORE>";
|
||||||
|
|
||||||
|
/// Implementation that wraps the KeyringStorage on Linux to avoid
|
||||||
|
/// https://github.com/hwchen/keyring-rs/issues/132
|
||||||
|
struct ThreadKeyringStorage {
|
||||||
|
s: Option<KeyringStorage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ThreadKeyringStorage {
|
||||||
|
fn thread_op<R, Fn>(&mut self, f: Fn) -> R
|
||||||
|
where
|
||||||
|
Fn: 'static + Send + FnOnce(&mut KeyringStorage) -> R,
|
||||||
|
R: 'static + Send,
|
||||||
|
{
|
||||||
|
let mut s = self.s.take().unwrap();
|
||||||
|
let handler = thread::spawn(move || (f(&mut s), s));
|
||||||
|
let (r, s) = handler.join().unwrap();
|
||||||
|
self.s = Some(s);
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ThreadKeyringStorage {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
s: Some(KeyringStorage::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StorageImplementation for ThreadKeyringStorage {
|
||||||
|
fn read(&mut self) -> Result<Option<StoredCredential>, WrappedError> {
|
||||||
|
self.thread_op(|s| s.read())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError> {
|
||||||
|
self.thread_op(move |s| s.store(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) -> Result<(), WrappedError> {
|
||||||
|
self.thread_op(|s| s.clear())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct KeyringStorage {
|
struct KeyringStorage {
|
||||||
// keywring storage can be split into multiple entries due to entry length limits
|
// keywring storage can be split into multiple entries due to entry length limits
|
||||||
@@ -325,7 +367,10 @@ impl Auth {
|
|||||||
return op(s);
|
return op(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
let mut keyring_storage = KeyringStorage::default();
|
let mut keyring_storage = KeyringStorage::default();
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let mut keyring_storage = ThreadKeyringStorage::default();
|
||||||
let mut file_storage = FileStorage(PersistedState::new(self.file_storage_path.clone()));
|
let mut file_storage = FileStorage(PersistedState::new(self.file_storage_path.clone()));
|
||||||
|
|
||||||
let keyring_storage_result = match std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN") {
|
let keyring_storage_result = match std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN") {
|
||||||
|
|||||||
Reference in New Issue
Block a user