(
listen_path: PathBuf,
ready_tx: tokio::sync::oneshot::Sender<Result<()>>,
policy: SandboxPolicy,
workdir: Option<String>,
netns_fd: Option<RawFd>,
proxy_url: Option<String>,
| 99 | |
| 100 | #[allow(clippy::too_many_arguments, clippy::implicit_hasher)] |
| 101 | pub async fn run_ssh_server( |
| 102 | listen_path: PathBuf, |
| 103 | ready_tx: tokio::sync::oneshot::Sender<Result<()>>, |
| 104 | policy: SandboxPolicy, |
| 105 | workdir: Option<String>, |
| 106 | netns_fd: Option<RawFd>, |
| 107 | proxy_url: Option<String>, |
| 108 | ca_file_paths: Option<(PathBuf, PathBuf)>, |
| 109 | provider_credentials: ProviderCredentialState, |
| 110 | user_environment: HashMap<String, String>, |
| 111 | ) -> Result<()> { |
| 112 | let (listener, config, ca_paths) = match ssh_server_init(&listen_path, &ca_file_paths) { |
| 113 | Ok(v) => { |
| 114 | // Signal that the SSH server has bound the socket and is ready to |
| 115 | // accept connections. The parent task awaits this before spawning |
| 116 | // the entrypoint process, ensuring exec requests won't race |
| 117 | // against server startup. |
| 118 | let _ = ready_tx.send(Ok(())); |
| 119 | v |
| 120 | } |
| 121 | Err(err) => { |
| 122 | let _ = ready_tx.send(Err(err)); |
| 123 | return Ok(()); |
| 124 | } |
| 125 | }; |
| 126 | |
| 127 | loop { |
| 128 | let (stream, _peer) = listener.accept().await.into_diagnostic()?; |
| 129 | let config = config.clone(); |
| 130 | let policy = policy.clone(); |
| 131 | let workdir = workdir.clone(); |
| 132 | let proxy_url = proxy_url.clone(); |
| 133 | let ca_paths = ca_paths.clone(); |
| 134 | let provider_credentials = provider_credentials.clone(); |
| 135 | let user_environment = user_environment.clone(); |
| 136 | |
| 137 | tokio::spawn(async move { |
| 138 | if let Err(err) = handle_connection( |
| 139 | stream, |
| 140 | config, |
| 141 | policy, |
| 142 | workdir, |
| 143 | netns_fd, |
| 144 | proxy_url, |
| 145 | ca_paths, |
| 146 | provider_credentials, |
| 147 | user_environment, |
| 148 | ) |
| 149 | .await |
| 150 | { |
| 151 | ocsf_emit!( |
| 152 | SshActivityBuilder::new(openshell_ocsf::ctx::ctx()) |
| 153 | .activity(ActivityId::Fail) |
| 154 | .severity(SeverityId::Low) |
| 155 | .status(StatusId::Failure) |
| 156 | .message(format!("SSH connection failed: {err}")) |
| 157 | .build() |
| 158 | ); |
no test coverage detected