Skip to content

Commit f9e921f

Browse files
authored
Merge pull request #116 from Firstp1ck/feat/passwordless-sudo
Feat/passwordless sudo
2 parents a4dd983 + e70fb86 commit f9e921f

32 files changed

Lines changed: 2265 additions & 366 deletions

config/settings.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ clipboard_suffix = Check PKGBUILD and source for suspicious and malicious activi
4040
# Recommended to keep this false for safety unless you understand the risks of executing package operations directly.
4141
skip_preflight = true
4242

43+
# Passwordless sudo
44+
# When true, Pacsea will use passwordless sudo for install operations if configured on the system.
45+
# When false (default), Pacsea will always show the password prompt even if passwordless sudo is available.
46+
# This acts as an additional safety barrier requiring explicit opt-in.
47+
# To use this feature, you must also have passwordless sudo configured in /etc/sudoers or /etc/sudoers.d/
48+
use_passwordless_sudo = false
49+
4350
# Mirrors
4451
# Select one or more countries (comma-separated). Example: "Switzerland, Germany, Austria"
4552
selected_countries = Worldwide

dev/PR/PR_feat-extended-news.md

Lines changed: 0 additions & 101 deletions
This file was deleted.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# PR Review: feat/passwordless-sudo (Passwordless Sudo)
2+
3+
**Branch:** `feat/passwordless-sudo`
4+
**PR file:** `PR_feat-passwordless-sudo.md`
5+
**Implementation plan:** `dev/IMPROVEMENTS/PASSWORDLESS_SUDO_IMPLEMENTATION_PLAN.md`
6+
7+
This document summarizes the review of the passwordless sudo pull request, including security considerations, alignment with project standards (CONTRIBUTING.md, AGENTS.md), and concrete suggestions for improvements. **No code changes were made; this is review-only.**
8+
9+
---
10+
11+
## 1. Summary of changes reviewed
12+
13+
- **`src/logic/password.rs`**`check_passwordless_sudo_available()`, `should_use_passwordless_sudo()`, password validation; test env var handling.
14+
- **`src/theme/types.rs`**`Settings.use_passwordless_sudo`, `Default`.
15+
- **`src/theme/settings/parse_settings.rs`** — Parsing of `use_passwordless_sudo` (and aliases).
16+
- **`config/settings.conf`** — New option and comments.
17+
- **`src/install/direct.rs`** — Install/remove flows; when to show `PasswordPrompt` vs proceed with `None` password.
18+
- **`src/args/update.rs`** — CLI update path and its password/passwordless handling.
19+
- **`tests/passwordless_sudo/`** — Helpers, integration tests (install, update, remove, downgrade, filesync).
20+
- **`dev/PR/PR_feat-passwordless-sudo.md`** — PR description and checklist.
21+
22+
---
23+
24+
## 2. Security review
25+
26+
### 2.1 Critical: Test env var honored in production
27+
28+
**Location:** `src/logic/password.rs``check_passwordless_sudo_available()` and `should_use_passwordless_sudo()`.
29+
30+
**Finding:**
31+
`PACSEA_TEST_SUDO_PASSWORDLESS` is read in **all builds** (including release). If an attacker or script runs the application with `PACSEA_TEST_SUDO_PASSWORDLESS=1`, the app will treat passwordless sudo as enabled even when `use_passwordless_sudo` is `false` in settings. That bypasses the intended opt-in and weakens the safety barrier.
32+
33+
**Suggestion:**
34+
- Honor `PACSEA_TEST_SUDO_PASSWORDLESS` only when the process is clearly in a test context, for example:
35+
- Only when another env var set exclusively by the test harness is present (e.g. `PACSEA_INTEGRATION_TEST=1`), or
36+
- When compiled with a test-only cfg (if you introduce a dedicated test binary or build profile that sets such a cfg).
37+
- In production code paths, ignore `PACSEA_TEST_SUDO_PASSWORDLESS` so that the only way to enable passwordless sudo is via `use_passwordless_sudo` in settings.
38+
39+
### 2.2 Password handling
40+
41+
**Location:** `src/logic/password.rs``validate_sudo_password()`.
42+
43+
**Finding:**
44+
- Password is escaped with `shell_single_quote()` before being passed to the shell command.
45+
- No password is written to logs (e.g. in `args/update.rs`, the log uses a shape that omits the password).
46+
47+
**Suggestion:**
48+
- Keep avoiding any logging or tracing of password content.
49+
- If you add more code paths that build shell commands with the password, consistently use the same escaping helper and avoid building commands via string concatenation with user input.
50+
51+
### 2.3 Remove always requires password
52+
53+
**Location:** `src/install/direct.rs``start_integrated_remove_all()`.
54+
55+
**Finding:**
56+
Remove operations always show `PasswordPrompt`; there is no branch that skips it based on passwordless sudo. This matches the design (remove always requires authentication).
57+
58+
**Suggestion:**
59+
None; behavior is correct. Optionally add a short comment in code that remove is intentionally excluded from passwordless sudo for safety.
60+
61+
### 2.4 CLI update vs settings
62+
63+
**Location:** `src/args/update.rs``prompt_and_validate_password()`.
64+
65+
**Finding:**
66+
The CLI update path checks passwordless sudo with `sudo -n true` and skips the password prompt if that succeeds. It does **not** read `use_passwordless_sudo` from settings. So:
67+
68+
- **TUI:** Respects `use_passwordless_sudo` (opt-in).
69+
- **CLI update:** Uses passwordless sudo whenever the system allows it, regardless of config.
70+
71+
**Suggestion:**
72+
- Decide intended behavior: either (a) CLI update should also respect `use_passwordless_sudo` for consistency, or (b) document that CLI update always tries passwordless sudo when available.
73+
- If (a): load settings (or at least the flag) in the CLI update path and only skip the password prompt when both `sudo -n true` succeeds and `use_passwordless_sudo` is true.
74+
75+
---
76+
77+
## 3. Code quality and project standards
78+
79+
### 3.1 CONTRIBUTING.md / AGENTS.md
80+
81+
- **Rust docs (What, Inputs, Output, Details):** Present and consistent in `password.rs`, `direct.rs`, theme types, and parse_settings.
82+
- **No `unwrap()` / `expect()` in non-test code:** The reviewed code uses `Result` and `unwrap_or_else` for defaults (e.g. `USER`); no inappropriate unwraps.
83+
- **Clippy:** Not re-run as part of this review; the PR checklist states it was run.
84+
- **Tests:** Integration tests in `tests/passwordless_sudo/` cover install (single/multiple, official/AUR), remove (always password), update, downgrade, filesync, and env var behavior.
85+
- **Complexity:** New functions in `password.rs` and `direct.rs` are short and linear; no obvious cyclomatic/complexity concerns.
86+
87+
### 3.2 Configuration
88+
89+
- **Default:** `use_passwordless_sudo: false` in `Settings::default()` — correct.
90+
- **Parsing:** `use_passwordless_sudo` and aliases (`passwordless_sudo`, `allow_passwordless_sudo`) in `parse_misc_settings` — consistent.
91+
- **Example config:** `config/settings.conf` documents the option and safety implications.
92+
93+
### 3.3 Minor documentation improvements
94+
95+
- In `password.rs`, the **Testing** paragraphs for the env var could state explicitly that this override must not be honored in production builds (once you restrict it as in 2.1).
96+
- In `direct.rs`, the docstrings for install flows already mention passwordless sudo; you could add one sentence that remove is intentionally always gated by password prompt.
97+
98+
---
99+
100+
## 4. Suggestions for improvements (no code changes applied)
101+
102+
### 4.1 Security
103+
104+
| # | Suggestion | Priority |
105+
|---|------------|----------|
106+
| 1 | Restrict `PACSEA_TEST_SUDO_PASSWORDLESS` to test-only contexts (e.g. only when another test-only env var is set) so production builds never honor it. | High |
107+
| 2 | Align CLI update with TUI: either make CLI update respect `use_passwordless_sudo`, or document that CLI update always uses passwordless sudo when available. | Medium |
108+
109+
### 4.2 Robustness and clarity
110+
111+
| # | Suggestion | Priority |
112+
|---|------------|----------|
113+
| 3 | Add a one-line comment in `start_integrated_remove_all` that remove is intentionally never passwordless for safety. | Low |
114+
| 4 | In rustdoc for the test env var, clarify that the override is (or will be) disabled in production. | Low |
115+
116+
### 4.3 Tests
117+
118+
| # | Suggestion | Priority |
119+
|---|------------|----------|
120+
| 5 | Add an integration test that, when `PACSEA_TEST_SUDO_PASSWORDLESS` is unset (or not honored), install path shows password prompt when `use_passwordless_sudo` is false, even if the system has passwordless sudo. | Medium |
121+
| 6 | If CLI update is changed to respect settings, add a test (or doc example) that CLI update still prompts when `use_passwordless_sudo` is false. | Low |
122+
123+
### 4.4 Documentation and PR
124+
125+
| # | Suggestion | Priority |
126+
|---|------------|----------|
127+
| 7 | In the PR description or wiki, briefly document that remove operations always require a password, regardless of `use_passwordless_sudo`. | Low |
128+
| 8 | If you keep the test env var for integration tests, add a note in CONTRIBUTING or the test README that `PACSEA_TEST_SUDO_PASSWORDLESS` is for tests only and must not be set in production. | Low |
129+
130+
---
131+
132+
## 5. Checklist vs review
133+
134+
| PR checklist item | Review note |
135+
|-------------------|------------|
136+
| Code compiles, fmt, clippy, tests | Not re-run; PR states they pass. |
137+
| Complexity checks | New code appears within limits. |
138+
| Rust docs (What, Inputs, Output, Details) | Present on new/updated public API. |
139+
| No `unwrap()`/`expect()` in non-test code | Confirmed in reviewed files. |
140+
| Integration tests | 34 tests; cover main flows and remove-always-password. |
141+
| Config examples updated | `config/settings.conf` updated. |
142+
| Respects `--dry-run` | Not re-verified; PR states yes. |
143+
| Graceful degradation | Passwordless check failures fall back to password prompt. |
144+
| No breaking changes | Opt-in, default off; no breaking change. |
145+
146+
---
147+
148+
## 6. Conclusion
149+
150+
The feature is implemented in line with the plan: opt-in, default off, install/update can use passwordless sudo when enabled and available, remove always requires a password. The main improvement is to ensure the test-only env var cannot affect production behavior. Aligning CLI update with the TUI setting (or documenting the difference) will make behavior clearer and more consistent.
151+
152+
**Recommended before merge:** Address the high-priority item (restrict `PACSEA_TEST_SUDO_PASSWORDLESS` to test context). The rest can be done in this PR or in follow-ups.

0 commit comments

Comments
 (0)