Skip to content
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

[PM-14988] Use peercred / GetNamedPipeClientProcessId to gather info about process connecting to ssh agent #12065

Merged
merged 27 commits into from
Dec 11, 2024

Conversation

quexten
Copy link
Contributor

@quexten quexten commented Nov 20, 2024

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-14988

📔 Objective

We want to be able to make choices about what apps or processes to allow access to the ssh-agent to. Further, we want to show the user which app is requesting access to the ssh key.

On the unix socket, the connecting process is collected via peercred, on windows via GetNamedPipeClientProcessId. These are enriched with process data gathered via the sysinfo crate. Finally, the process name is handed out to the UI for showing what app is requesting access.

At the moment this is just the process, but this can be later enhanced, to map this to a desktop UI application, with a proper application name and icon.

Note

This points the russh-agent crate against an in-development PR branch. We should merge this PR only once the upstream is merged, and this PR references a pinned commit of the main branch.

📸 Screenshots

image

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@quexten quexten changed the title Km/test peercred Use peercred / GetNamedPipeClientProcessId to gather info about process connecting to ssh agent Nov 20, 2024
@quexten quexten changed the title Use peercred / GetNamedPipeClientProcessId to gather info about process connecting to ssh agent [PM-14988] Use peercred / GetNamedPipeClientProcessId to gather info about process connecting to ssh agent Nov 20, 2024
Copy link

codecov bot commented Nov 20, 2024

Codecov Report

Attention: Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.

Project coverage is 33.50%. Comparing base (ba4d7ea) to head (2e6197f).
Report is 26 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...desktop/src/platform/services/ssh-agent.service.ts 0.00% 3 Missing ⚠️
...esktop/src/platform/main/main-ssh-agent.service.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12065      +/-   ##
==========================================
- Coverage   33.50%   33.50%   -0.01%     
==========================================
  Files        2897     2897              
  Lines       90349    90352       +3     
  Branches    17165    17166       +1     
==========================================
  Hits        30268    30268              
- Misses      57690    57693       +3     
  Partials     2391     2391              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

github-actions bot commented Nov 20, 2024

Logo
Checkmarx One – Scan Summary & Detailsb49acbdd-712e-4fda-8569-77740310c1a6

New Issues

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 44 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 39 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 39 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 44 Attack Vector

Fixed Issues

Severity Issue Source File / Package
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html: 6

#[derive(Clone)]
pub struct BitwardenDesktopAgent {
keystore: ssh_agent::KeyStore,
cancellation_token: CancellationToken,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, String)>,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, (String, String))>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider creating a struct type for (String, String), as it is it would be quite easy to accidentally swap them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, had that on my list for later, but I'm adding it in this PR now. Nice!

#[derive(Clone)]
pub struct BitwardenDesktopAgent {
keystore: ssh_agent::KeyStore,
cancellation_token: CancellationToken,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, String)>,
show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, (String, String))>,
get_ui_response_rx: Arc<Mutex<tokio::sync::broadcast::Receiver<(u32, bool)>>>,
request_id: Arc<Mutex<u32>>,
is_running: Arc<tokio::sync::Mutex<bool>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't related to this PR, but I just noticed a small nit:
Instead of Arc<tokio::sync::Mutex<bool>>, it's usually best to just use AtomicBool. It's clearer in intent, and makes it impossible to accidentally hold the mutex open for too long

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the same go for u32? I.e should request_id use atomicu32?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd say it applies to request_id as well. I just noticed that BitwardenDesktopAgent implements clone as it's cloned for every connection, so we should still keep the Arc to make sure there's only one instance of the atomics:

    request_id: Arc<AtomicU32>,
    is_running: Arc<AtomicBool>,

We don't need to make the change in this PR if it's too cumbersome though.

pub fn get_peer_info(peer_pid: u32) -> Result<PeerInfo, String> {
let s = System::new_all();
if let Some(process) = s.process(Pid::from_u32(peer_pid)) {
let peer_process_name = match process.name().to_str() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs have some warnings about the use of name() on Linux: that it's limited to 15 characters and that it might not match the exe name. They recommend using exe() in most cases. Is this a concern for us?

https://docs.rs/sysinfo/latest/sysinfo/struct.Process.html#method.name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change it to exe since they recommend it.

However the plan on this long-term is not to use the exe/process if possible, but the app name if available. (I.e instead of "chrome.exe" it would be "Google Chrome", and so on + icon). For ssh running in iTerm2, it would show "iTerm2" since that's the "GUI app" the user uses.

(That's roughly what 1Password does [i think?])

Need to figure out how to get these across the platforms we support though, so that's long-term ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, that sounds good, once this is working, it would be nice to also bring it to the browser and DuckDuckGo integration.

One small question: Is this meant as a more informative dialog for the user rather than a secure attestation of what program is connecting to us? By that I mean, will we try to validate that the chrome.exe/Google Chrome binary is the real thing coming from Google as opposed to a random binary with that name? (Using code signatures maybe?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small question: Is this meant as a more informative dialog for the user rather than a secure attestation of what program is connecting to us? By that I mean, will we try to validate that the chrome.exe/Google Chrome binary is the real thing coming from Google as opposed to a random binary with that name? (Using code signatures maybe?)

For now just informational for the user.

However, I'd like for this to ultimately verify more. From what I gathered, 1P verifies signatures on mac/windows.

On linux, this verifies installation path I.e we could say "If something is installed in the system path, for .deb, flatpak, snap, etc", it is most likely legit, whereas something in ~/Downloads is not. Depending on the use-case, these would be blocked, or at least warned (require fingerprint validation).

And agree on the browser/ddg integration, would be really cool to be able to both give better guarantees, but also to show the connected browsers in the desktop UI.

Build a prototype for extended app info here, to prove it works, and to see constraints: #12166

@quexten quexten marked this pull request as draft November 27, 2024 14:17
@quexten quexten requested a review from dani-garcia December 4, 2024 16:41
@quexten quexten marked this pull request as ready for review December 4, 2024 16:41
dani-garcia
dani-garcia previously approved these changes Dec 5, 2024
Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I've commented on a couple of small changes, but none of them are blocking.

let message = (request_id, ("".to_string(), true));
let message = SshAgentUIRequest {
request_id,
cipher_id: "".to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it would be better represented by an Option<String>, if the value isn't always present

@quexten quexten requested a review from dani-garcia December 9, 2024 11:50
@quexten
Copy link
Contributor Author

quexten commented Dec 9, 2024

@dani-garcia running cargo fmt in desktop_native changed the formatting of a few files. Should I undo those changes or do we keep them (and possibly at some point look into adding that into the ci flow?).

Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, we can keep the extra formatting changes. I'll look into running fmt and clippy in CI.

@quexten quexten merged commit e8d8a81 into main Dec 11, 2024
37 of 38 checks passed
@quexten quexten deleted the km/test-peercred branch December 11, 2024 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants