Skip to content

Commit d60b303

Browse files
feat(devolutions-gateway): remove domain from credentials and update Kerberos server config;
1 parent c4adbb1 commit d60b303

3 files changed

Lines changed: 35 additions & 27 deletions

File tree

devolutions-gateway/src/config.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,20 +1133,35 @@ pub mod dto {
11331133
/// Domain user credentials.
11341134
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
11351135
pub struct DomainUser {
1136+
/// Username in FQDN format (e.g. "pw13@example.com").
11361137
pub username: String,
1137-
pub domain: String,
1138+
// User password.
11381139
pub password: String,
1140+
/// Salt for generating the user's key.
1141+
///
1142+
/// Usually, it is equal to `{REALM}{username}` (e.g. "EXAMPLEpw13").
1143+
pub salt: String,
11391144
}
11401145

11411146
/// Kerberos server config
11421147
///
11431148
/// This config is used to configure the Kerberos server during RDP proxying.
11441149
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
11451150
pub struct KerberosServer {
1151+
/// KDC and Kerberos Application Server realm.
1152+
///
1153+
/// For example, `cd9bee03-b0aa-49dd-bad7-568b595c8024.jet`.
1154+
pub realm: String,
1155+
/// Users credentials inside fake KDC.
1156+
pub users: Vec<DomainUser>,
11461157
/// The maximum allowed time difference between client and proxy clocks
11471158
///
11481159
/// The value must be in seconds.
11491160
pub max_time_skew: u64,
1161+
/// krbtgt service key.
1162+
///
1163+
/// This key is used to encrypt/decrypt TGT tickets.
1164+
pub krbtgt_key: Vec<u8>,
11501165
/// Ticket decryption key
11511166
///
11521167
/// This key is used to decrypt the TGS ticket sent by the client. If you do not plan

devolutions-gateway/src/credential.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ use uuid::Uuid;
1414
#[serde(tag = "kind")]
1515
pub enum AppCredential {
1616
#[serde(rename = "username-password")]
17-
UsernamePassword {
18-
username: String,
19-
domain: Option<String>,
20-
password: Password,
21-
},
17+
UsernamePassword { username: String, password: Password },
2218
}
2319

2420
/// Application protocol level credential mapping

devolutions-gateway/src/rdp_proxy.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::net::{IpAddr, SocketAddr};
22
use std::sync::Arc;
33
use std::time::Duration;
44

5-
use crate::config::dto::{DomainUser, KerberosServer};
65
use crate::config::Conf;
6+
use crate::config::dto::{DomainUser, KerberosServer};
77
use crate::credential::{AppCredentialMapping, ArcCredentialEntry};
88
use crate::proxy::Proxy;
99
use crate::session::{DisconnectInterest, SessionInfo, SessionMessageSender};
@@ -117,6 +117,9 @@ where
117117

118118
let krb_server_config = if conf.debug.enable_unstable {
119119
if let Some(KerberosServer {
120+
realm: _,
121+
users: _,
122+
krbtgt_key: _,
120123
max_time_skew,
121124
ticket_decryption_key,
122125
service_user,
@@ -125,10 +128,13 @@ where
125128
let user = service_user.as_ref().map(|user| {
126129
let DomainUser {
127130
username,
128-
domain,
129131
password,
132+
salt: _,
130133
} = user;
131-
CredentialsBuffers::AuthIdentity(AuthIdentityBuffers::from_utf8(username, domain, password))
134+
CredentialsBuffers::AuthIdentity(AuthIdentityBuffers::from_utf8(
135+
username, // The username is in the FQDN format. Thus, the domain field can be empty.
136+
"", password,
137+
))
132138
});
133139

134140
Some(KerberosServerConfig {
@@ -383,23 +389,18 @@ where
383389
{
384390
use ironrdp_tokio::FramedWrite as _;
385391

386-
let (credentials, domain) = match credentials {
387-
crate::credential::AppCredential::UsernamePassword {
388-
username,
389-
domain,
390-
password,
391-
} => (
392+
let credentials = match credentials {
393+
crate::credential::AppCredential::UsernamePassword { username, password } => {
392394
ironrdp_connector::Credentials::UsernamePassword {
393395
username: username.clone(),
394396
password: password.expose_secret().to_owned(),
395-
},
396-
domain.as_deref(),
397-
),
397+
}
398+
}
398399
};
399400

400401
let (mut sequence, mut ts_request) = ironrdp_connector::credssp::CredsspSequence::init(
401402
credentials,
402-
domain,
403+
None,
403404
security_protocol,
404405
ironrdp_connector::ServerName::new(server_name),
405406
server_public_key,
@@ -484,9 +485,9 @@ async fn resolve_client_generator(
484485
GeneratorState::Completed(client_state) => {
485486
break client_state.map_err(|e| {
486487
ironrdp_connector::ConnectorError::new("CredSSP", ironrdp_connector::ConnectorErrorKind::Credssp(e))
487-
})
488+
});
488489
}
489-
}
490+
};
490491
}
491492
}
492493

@@ -552,13 +553,9 @@ where
552553
where
553554
S: ironrdp_tokio::FramedRead + ironrdp_tokio::FramedWrite,
554555
{
555-
let crate::credential::AppCredential::UsernamePassword {
556-
username,
557-
domain,
558-
password,
559-
} = credentials;
556+
let crate::credential::AppCredential::UsernamePassword { username, password } = credentials;
560557

561-
let username = sspi::Username::new(username, domain.as_deref()).context("invalid username")?;
558+
let username = sspi::Username::new(username, None).context("invalid username")?;
562559

563560
let identity = sspi::AuthIdentity {
564561
username,

0 commit comments

Comments
 (0)