Skip to content

Commit 3a33c93

Browse files
committed
fix(auth): sanitize os keyring error strings and handle missing file fallbacks
This commit removes the inadvertently included skills, uses output::sanitize_for_terminal to protect the user from escape sequence injection via keyring errors, and ensures removal of the fallback file properly alerts the user when an io error occurs.
1 parent af67473 commit 3a33c93

4 files changed

Lines changed: 23 additions & 120 deletions

File tree

crates/google-workspace-cli/src/credential_store.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,15 @@ fn resolve_key(
212212
arr.copy_from_slice(&decoded);
213213
// Cleanup insecure file fallback if it still exists.
214214
// TOCTOU race condition is a known limitation.
215-
let _ = std::fs::remove_file(key_file);
215+
if let Err(e) = std::fs::remove_file(key_file) {
216+
if e.kind() != std::io::ErrorKind::NotFound {
217+
eprintln!(
218+
"Warning: failed to remove legacy key file at '{}': {}",
219+
key_file.display(),
220+
e
221+
);
222+
}
223+
}
216224
return Ok(arr);
217225
}
218226
}
@@ -222,17 +230,28 @@ fn resolve_key(
222230
// Keyring is empty — fall through to generate new.
223231
}
224232
Err(e) => {
225-
anyhow::bail!("OS keyring failed: {e}. Set GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file to use file storage.");
233+
anyhow::bail!("OS keyring failed: {}. Set GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file to use file storage.", sanitize_for_terminal(&e.to_string()));
226234
}
227235
}
228236

229237
// Generate a new key if keyring was empty or contained invalid data.
230238
let key = generate_random_key();
231239
let b64_key = STANDARD.encode(key);
232240
if let Err(e) = provider.set_password(&b64_key) {
233-
anyhow::bail!("Failed to set key in OS keyring: {e}");
241+
anyhow::bail!(
242+
"Failed to set key in OS keyring: {}",
243+
sanitize_for_terminal(&e.to_string())
244+
);
245+
}
246+
if let Err(e) = std::fs::remove_file(key_file) {
247+
if e.kind() != std::io::ErrorKind::NotFound {
248+
eprintln!(
249+
"Warning: failed to remove legacy key file at '{}': {}",
250+
key_file.display(),
251+
e
252+
);
253+
}
234254
}
235-
let _ = std::fs::remove_file(key_file);
236255
return Ok(key);
237256
}
238257

docs/skills.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ Core Google Workspace API skills.
2626
| [gws-events](../skills/gws-events/SKILL.md) | Subscribe to Google Workspace events. |
2727
| [gws-modelarmor](../skills/gws-modelarmor/SKILL.md) | Google Model Armor: Filter user-generated content for safety. |
2828
| [gws-workflow](../skills/gws-workflow/SKILL.md) | Google Workflow: Cross-service productivity workflows. |
29-
| [gws-script](../skills/gws-script/SKILL.md) | Manage Google Apps Script projects. |
3029

3130
## Helpers
3231

@@ -58,7 +57,6 @@ Shortcut commands for common operations.
5857
| [gws-workflow-email-to-task](../skills/gws-workflow-email-to-task/SKILL.md) | Google Workflow: Convert a Gmail message into a Google Tasks entry. |
5958
| [gws-workflow-weekly-digest](../skills/gws-workflow-weekly-digest/SKILL.md) | Google Workflow: Weekly summary: this week's meetings + unread email count. |
6059
| [gws-workflow-file-announce](../skills/gws-workflow-file-announce/SKILL.md) | Google Workflow: Announce a Drive file in a Chat space. |
61-
| [gws-script-push](../skills/gws-script-push/SKILL.md) | Google Apps Script: Upload local files to an Apps Script project. |
6260

6361
## Personas
6462

skills/gws-script-push/SKILL.md

Lines changed: 0 additions & 52 deletions
This file was deleted.

skills/gws-script/SKILL.md

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)