| 302 | } |
| 303 | |
| 304 | fn tls_paths(&self) -> Result<Option<VmDriverTlsPaths>, String> { |
| 305 | let provided = [ |
| 306 | self.guest_tls_ca.as_ref(), |
| 307 | self.guest_tls_cert.as_ref(), |
| 308 | self.guest_tls_key.as_ref(), |
| 309 | ]; |
| 310 | if provided.iter().all(Option::is_none) { |
| 311 | return if self.requires_tls_materials() { |
| 312 | Err( |
| 313 | "https:// openshell endpoint requires OPENSHELL_VM_TLS_CA, OPENSHELL_VM_TLS_CERT, and OPENSHELL_VM_TLS_KEY so sandbox VMs can authenticate to the gateway" |
| 314 | .to_string(), |
| 315 | ) |
| 316 | } else { |
| 317 | Ok(None) |
| 318 | }; |
| 319 | } |
| 320 | |
| 321 | let Some(ca) = self.guest_tls_ca.clone() else { |
| 322 | return Err( |
| 323 | "OPENSHELL_VM_TLS_CA is required when TLS materials are configured".to_string(), |
| 324 | ); |
| 325 | }; |
| 326 | let Some(cert) = self.guest_tls_cert.clone() else { |
| 327 | return Err( |
| 328 | "OPENSHELL_VM_TLS_CERT is required when TLS materials are configured".to_string(), |
| 329 | ); |
| 330 | }; |
| 331 | let Some(key) = self.guest_tls_key.clone() else { |
| 332 | return Err( |
| 333 | "OPENSHELL_VM_TLS_KEY is required when TLS materials are configured".to_string(), |
| 334 | ); |
| 335 | }; |
| 336 | |
| 337 | for path in [&ca, &cert, &key] { |
| 338 | if !path.is_file() { |
| 339 | return Err(format!( |
| 340 | "TLS material '{}' does not exist or is not a file", |
| 341 | path.display() |
| 342 | )); |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | Ok(Some(VmDriverTlsPaths { ca, cert, key })) |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | fn validate_openshell_endpoint(endpoint: &str) -> Result<(), String> { |