feat(dgw): generate self-signed certificate when no TLS cert is configured for CredSSP#1682
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request enhances the Devolutions Gateway to automatically generate a self-signed TLS certificate for CredSSP credential injection when neither a CredSSP-specific certificate nor a main TLS certificate is configured. Previously, the gateway would fail with an error when attempting credential injection without a configured TLS certificate. Now, it gracefully handles this scenario by generating a minimal self-signed certificate on-the-fly.
Changes:
- Added automatic self-signed certificate generation for CredSSP when no TLS certificate is configured
- Replaced optional TLS requirement checks with a dedicated non-optional
credssp_tlsfield in the configuration - Implemented certificate generation using RSA 2048-bit keys with a 2-year validity period
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| devolutions-gateway/src/config.rs | Added credssp_tls field to Conf struct; implemented generate_self_signed_certificate() function; added logic to initialize credssp_tls by either cloning existing TLS config or generating a new self-signed certificate |
| devolutions-gateway/src/rdp_proxy.rs | Changed to use conf.credssp_tls instead of requiring main TLS configuration |
| devolutions-gateway/src/rd_clean_path.rs | Changed to use conf.credssp_tls instead of requiring main TLS configuration |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…gured for CredSSP When neither a CredSSP-specific certificate nor a main TLS certificate is configured, automatically generate a self-signed certificate for CredSSP credential injection.
b2f8388 to
0e72a4b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // and the client (e.g.: RDM) may automatically ignore the warnings. | ||
| info!("No TLS certificate configured; generating a self-signed certificate for CredSSP"); | ||
|
|
||
| let (certificates, private_key) = generate_self_signed_certificate(&hostname) | ||
| .context("generate self-signed CredSSP certificate")?; |
There was a problem hiding this comment.
A self-signed RSA keypair/certificate is generated during config loading when no TLS cert is configured. Since Conf is constructed on every startup (even if CredSSP injection is never used), this adds avoidable startup CPU/entropy cost and could slow/block startup on low-entropy systems. Consider lazy/on-demand generation (only when credential injection is invoked).
| let not_after = UtcDate::ymd( | ||
| (now.year() + 2).try_into().expect("valid year"), | ||
| now.month().into(), | ||
| now.day(), |
There was a problem hiding this comment.
Building not_after with (now.year() + 2, now.month(), now.day()) can fail on dates like Feb 29 (non-leap year two years later), causing config load/startup to error on those days. Consider computing the expiration by adding a duration to now (or clamping to a valid day) to avoid invalid calendar dates.
| let not_after = UtcDate::ymd( | |
| (now.year() + 2).try_into().expect("valid year"), | |
| now.month().into(), | |
| now.day(), | |
| let then = now + time::Duration::days(365_i64 * 2); | |
| let not_after = UtcDate::ymd( | |
| then.year().try_into().expect("valid year"), | |
| then.month().into(), | |
| then.day(), |
When neither a CredSSP-specific certificate nor a main TLS certificate is configured, automatically generate a self-signed certificate for CredSSP credential injection.