Use Windows username in client auth paths
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s

This commit is contained in:
DuProcess
2026-07-16 20:43:34 -04:00
parent b6d8c83fc9
commit 8644c22554
+66 -33
View File
@@ -4953,7 +4953,7 @@ fn local_bootstrap(
let mut server_config = load_server_config(None)?; let mut server_config = load_server_config(None)?;
server_config.port = port; server_config.port = port;
let secret = load_or_create_server_secret(&server_config)?; let secret = load_or_create_server_secret(&server_config)?;
let user = std::env::var("USER").unwrap_or_else(|_| "unknown".to_string()); let user = local_username();
let nonce = crypto::random_12(); let nonce = crypto::random_12();
build_bootstrap( build_bootstrap(
&server_config, &server_config,
@@ -5393,7 +5393,7 @@ async fn try_native_auth(
}; };
let requested_user = ssh_username(server) let requested_user = ssh_username(server)
.or(ssh_config.user.clone()) .or(ssh_config.user.clone())
.unwrap_or_else(|| std::env::var("USER").unwrap_or_else(|_| "unknown".to_string())); .unwrap_or_else(local_username);
let (client_secret, client_public) = generate_native_ephemeral(); let (client_secret, client_public) = generate_native_ephemeral();
let hello = dosh::native::NativeClientHello { let hello = dosh::native::NativeClientHello {
protocol_version: dosh::native::NATIVE_PROTOCOL_VERSION, protocol_version: dosh::native::NATIVE_PROTOCOL_VERSION,
@@ -5544,7 +5544,7 @@ async fn try_native_auth_check(
}; };
let requested_user = ssh_username(server) let requested_user = ssh_username(server)
.or(ssh_config.user.clone()) .or(ssh_config.user.clone())
.unwrap_or_else(|| std::env::var("USER").unwrap_or_else(|_| "unknown".to_string())); .unwrap_or_else(local_username);
let (client_secret, client_public) = generate_native_ephemeral(); let (client_secret, client_public) = generate_native_ephemeral();
let hello = dosh::native::NativeClientHello { let hello = dosh::native::NativeClientHello {
protocol_version: dosh::native::NATIVE_PROTOCOL_VERSION, protocol_version: dosh::native::NATIVE_PROTOCOL_VERSION,
@@ -5835,9 +5835,15 @@ fn ssh_path_token_context(
} }
fn local_username() -> String { fn local_username() -> String {
std::env::var("USER") local_username_from_env(|name| std::env::var(name).ok())
.or_else(|_| std::env::var("USERNAME")) }
.unwrap_or_else(|_| "unknown".to_string())
fn local_username_from_env(mut get: impl FnMut(&str) -> Option<String>) -> String {
["USER", "USERNAME"]
.into_iter()
.filter_map(|name| get(name))
.find(|value| !value.is_empty())
.unwrap_or_else(|| "unknown".to_string())
} }
fn expand_ssh_path_tokens(path: &str, context: &SshPathTokenContext) -> String { fn expand_ssh_path_tokens(path: &str, context: &SshPathTokenContext) -> String {
@@ -10401,33 +10407,33 @@ mod tests {
expand_ssh_path_tokens, input_contains_focus_in, input_matches_escape, expand_ssh_path_tokens, input_contains_focus_in, input_matches_escape,
is_local_status_target, is_resume_response_for_client, latest_release_download_url, is_local_status_target, is_resume_response_for_client, latest_release_download_url,
load_first_native_identity_with_prompt, local_symlink_target_is_dir, load_first_native_identity_with_prompt, local_symlink_target_is_dir,
native_proxy_udp_warning, newest_client_trace_path_from, parse_dynamic_forward, local_username_from_env, native_proxy_udp_warning, newest_client_trace_path_from,
parse_escape_key, parse_local_forward, parse_remote_forward, parse_single_remote_path, parse_dynamic_forward, parse_escape_key, parse_local_forward, parse_remote_forward,
parse_ssh_config, parse_trace_line, parse_trace_options, parse_trace_report_options, parse_single_remote_path, parse_ssh_config, parse_trace_line, parse_trace_options,
parse_trace_summary, parse_update_options, post_submit_hold_duration, parse_trace_report_options, parse_trace_summary, parse_update_options,
queue_or_send_stream_data, queue_pending_user_input, queue_stale_pending_user_input, post_submit_hold_duration, queue_or_send_stream_data, queue_pending_user_input,
raw_contains_host_table, recv_response_until, refresh_live_addr, release_artifact_name_for, queue_stale_pending_user_input, raw_contains_host_table, recv_response_until,
release_tag_download_url, release_tag_from_effective_url, release_version_from_tag, refresh_live_addr, release_artifact_name_for, release_tag_download_url,
remote_unix_server_update_script, render_frame_bytes, render_status_clear, release_tag_from_effective_url, release_version_from_tag, remote_unix_server_update_script,
render_status_overlay, requested_env, resolve_forward_agent_endpoint, render_frame_bytes, render_status_clear, render_status_overlay, requested_env,
resolved_startup_command, retire_stream_state, retransmit_stream_closes, resolve_forward_agent_endpoint, resolved_startup_command, retire_stream_state,
retransmit_stream_eofs, retransmit_stream_opens, retransmit_stream_window_adjusts, retransmit_stream_closes, retransmit_stream_eofs, retransmit_stream_opens,
rewrite_forward_command, sanitize_trace_name, selected_predict_mode, selected_udp_host, retransmit_stream_window_adjusts, rewrite_forward_command, sanitize_trace_name,
send_stream_eof, server_version_mismatch, should_flush_terminal_input_after_contact, selected_predict_mode, selected_udp_host, send_stream_eof, server_version_mismatch,
should_health_log_client_start, should_hold_during_startup_gate, should_flush_terminal_input_after_contact, should_health_log_client_start,
should_hold_post_submit_input, should_reconnect_before_input_for_local_sleep, should_hold_during_startup_gate, should_hold_post_submit_input,
should_repaint_idle_terminal, should_strip_unowned_terminal_reports, should_reconnect_before_input_for_local_sleep, should_repaint_idle_terminal,
split_after_command_submit, split_trace_tokens, ssh_command_target, ssh_config_uses_proxy, should_strip_unowned_terminal_reports, split_after_command_submit, split_trace_tokens,
ssh_config_word_for_os, ssh_destination_host, ssh_username, ssh_with_user, startup_command, ssh_command_target, ssh_config_uses_proxy, ssh_config_word_for_os, ssh_destination_host,
status_ssh_target, strip_stale_mouse_reports, strip_terminal_focus_reports, ssh_username, ssh_with_user, startup_command, status_ssh_target, strip_stale_mouse_reports,
strip_unowned_terminal_reports, summarize_trace_file, summarize_trace_file_with_mode, strip_terminal_focus_reports, strip_unowned_terminal_reports, summarize_trace_file,
terminal_private_mode_transition, toml_bare_key_or_quoted, top_trace_events, summarize_trace_file_with_mode, terminal_private_mode_transition, toml_bare_key_or_quoted,
trace_report_warnings, unix_update_script, update_binary_version_for_installer, top_trace_events, trace_report_warnings, unix_update_script,
update_installer_url, update_version_status, upsert_managed_block, valid_forward_host, update_binary_version_for_installer, update_installer_url, update_version_status,
vscode_command_candidates, vscode_safe_alias, wake_repaint_retry_deadline, upsert_managed_block, valid_forward_host, vscode_command_candidates, vscode_safe_alias,
windows_command_word, windows_deferred_update_script, windows_effective_url_script, wake_repaint_retry_deadline, windows_command_word, windows_deferred_update_script,
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script, windows_effective_url_script, windows_mode_from_readonly, windows_readonly_from_mode,
windows_url_reachable_script, windows_vt_output_mode, windows_update_script, windows_url_reachable_script, windows_vt_output_mode,
}; };
use dosh::config::{ClientConfig, CommandExtension, HostConfig}; use dosh::config::{ClientConfig, CommandExtension, HostConfig};
use dosh::native::EnvVar; use dosh::native::EnvVar;
@@ -10982,6 +10988,33 @@ mod tests {
); );
} }
#[test]
fn local_username_uses_unix_or_windows_environment_names() {
assert_eq!(
local_username_from_env(|name| match name {
"USER" => Some("palav".to_string()),
_ => None,
}),
"palav"
);
assert_eq!(
local_username_from_env(|name| match name {
"USERNAME" => Some("palav-win".to_string()),
_ => None,
}),
"palav-win"
);
assert_eq!(
local_username_from_env(|name| match name {
"USER" => Some(String::new()),
"USERNAME" => Some("palav-win".to_string()),
_ => None,
}),
"palav-win"
);
assert_eq!(local_username_from_env(|_| None), "unknown");
}
#[test] #[test]
fn native_proxy_udp_warning_requires_missing_explicit_dosh_host() { fn native_proxy_udp_warning_requires_missing_explicit_dosh_host() {
let proxied = SshConfig { let proxied = SshConfig {