Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions src/protocols/rdp/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
"console-audio",
"server-layout",
"security",
"auth-pkg",
"kdc-url",
"kerberos-cache",
"ignore-cert",
"cert-tofu",
"cert-fingerprints",
Expand Down Expand Up @@ -296,6 +299,28 @@ enum RDP_ARGS_IDX {
*/
IDX_SECURITY,

/**
* The authentication package to use based on the underlying FreeRDP support
* for alternatives to NTML. Currently FreeRDP2 only supports NTLM, while
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a typo (NTML > NTLM)

* FreeRDP3 introduces support for Kerberos and continues to support NTLM.
* The default is to negotiate between guacd and the remote server.
*/
IDX_AUTH_PKG,

/**
* When kerberos authentication is in use, the URL of the KDC server to use
* for ticket validation. If not specified, guacd will use the underlying
* system's kerberos configuration.
*/
IDX_KDC_URL,

/**
* When kerberos authentication is in use, the path to the kerberos ticket
* cache, relative to GUACAMOLE_HOME. If not specified, the default system
* cache of the underlying system on which guacd is running will be used.
*/
IDX_KERBEROS_CACHE,

/**
* "true" if validity of the RDP server's certificate should be ignored,
* "false" or blank if invalid certificates should result in a failure to
Expand Down Expand Up @@ -832,6 +857,30 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
settings->security_mode = GUAC_SECURITY_ANY;
}

/* Use kerberos authentication */
if (strcmp(argv[IDX_AUTH_PKG], "kerberos") == 0) {
guac_user_log(user, GUAC_LOG_INFO, "Authentication package: Kerberos");
settings->auth_pkg = GUAC_AUTH_PKG_KERBEROS;
}

else if (strcmp(argv[IDX_AUTH_PKG], "ntlm") == 0) {
guac_user_log(user, GUAC_LOG_INFO, "Authentication package: NTLM");
settings->auth_pkg = GUAC_AUTH_PKG_NTLM;
}

else {
guac_user_log(user, GUAC_LOG_INFO, "No authentication package requested, defaulting to negotiate.");
settings->auth_pkg = GUAC_AUTH_PKG_ANY;
}

/* Set KDC URL */
settings->kdc_url = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS,
argv, IDX_KDC_URL, NULL);

/* Set Kerberos cache */
settings->kerberos_cache = guac_user_parse_args_string(user,
GUAC_RDP_CLIENT_ARGS, argv, IDX_KERBEROS_CACHE, NULL);

/* Set hostname */
settings->hostname =
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
Expand Down Expand Up @@ -1410,6 +1459,8 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
guac_mem_free(settings->timezone);
guac_mem_free(settings->username);
guac_mem_free(settings->printer_name);
guac_mem_free(settings->kdc_url);
guac_mem_free(settings->kerberos_cache);

/* Free channel name array */
if (settings->svc_names != NULL) {
Expand Down Expand Up @@ -1695,6 +1746,29 @@ void guac_rdp_push_settings(guac_client* client,

}

/* Set the authentication package to use. */
switch(guac_settings->auth_pkg) {

case GUAC_AUTH_PKG_NTLM:
freerdp_settings_set_string(rdp_settings, FreeRDP_AuthenticationPackageList, "ntlm,!kerberos");
break;

case GUAC_AUTH_PKG_KERBEROS:
freerdp_settings_set_string(rdp_settings, FreeRDP_AuthenticationPackageList, "!ntlm,kerberos");
break;

case GUAC_AUTH_PKG_ANY:
freerdp_settings_set_string(rdp_settings, FreeRDP_AuthenticationPackageList, "ntlm,kerberos");
break;

}

if (guac_settings->kdc_url != NULL)
freerdp_settings_set_string(rdp_settings, FreeRDP_KerberosKdcUrl, guac_strdup(guac_settings->kdc_url));

if (guac_settings->kerberos_cache != NULL)
freerdp_settings_set_string(rdp_settings, FreeRDP_KerberosCache, guac_strdup(guac_settings->kerberos_cache));

/* Security */
freerdp_settings_set_bool(rdp_settings, FreeRDP_Authentication, !guac_settings->disable_authentication);
freerdp_settings_set_bool(rdp_settings, FreeRDP_IgnoreCertificate, guac_settings->ignore_certificate);
Expand Down Expand Up @@ -1947,6 +2021,29 @@ void guac_rdp_push_settings(guac_client* client,

}

/* Set the authentication package preferences */
switch(guac_settings->auth_pkg) {

case GUAC_AUTH_PKG_NTLM:
rdp_settings->AuthenticationPackageList = "ntlm,!kerberos";
break;

case GUAC_AUTH_PKG_KERBEROS:
rdp_settings->AuthenticationPackageList = "!ntlm,kerberos";
break;

case GUAC_AUTH_PKG_ANY:
rdp_settings->AuthenticationPackageList = "ntlm,kerberos";
break;

}

/* Kerberos KDC URL */
rdp_settings->KerberosKdcUrl = guac_strdup(guac_settings->kdc_url);

/* Kerberos ticket cache */
rdp_settings->KerberosCache = guac_strdup(guac_settings->kerberos_cache);

/* Security */
rdp_settings->Authentication = !guac_settings->disable_authentication;
rdp_settings->IgnoreCertificate = guac_settings->ignore_certificate;
Expand Down
44 changes: 44 additions & 0 deletions src/protocols/rdp/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,32 @@ typedef enum guac_rdp_security {

} guac_rdp_security;

/**
* The authentication packages supported by freerdp and thus guacd.
*/
typedef enum guac_rdp_auth_package {

/**
* NTLM-based authentication, which is still the default for Windows, but
* is being phased out in favor of Kerberos due to security concerns.
*/
GUAC_AUTH_PKG_NTLM,

/**
* Kerberos-based authentication, which is supported by FreeRDP3 and is
* the new standard for RDP connections due to its superior security as
* compared with NTLM.
*/
GUAC_AUTH_PKG_KERBEROS,

/**
* Allow guacd and the server to negotiatoin without preferring one or the
* other.
*/
GUAC_AUTH_PKG_ANY

} guac_rdp_auth_package;

/**
* All supported combinations screen resize methods.
*/
Expand Down Expand Up @@ -296,6 +322,24 @@ typedef struct guac_rdp_settings {
*/
guac_rdp_security security_mode;

/**
* The authentication package to use.
*/
guac_rdp_auth_package auth_pkg;

/**
* When using kerberos-based authentication, the URL of the KDC, if something
* other than the system-level kerberos configuration should be used.
*/
char* kdc_url;

/**
* When using kerberos-based authentication, the location of the kerberos
* ticket cache to use, relative to GUACAMOLE_HOME, if the system-level
* cache file should not be used.
*/
char* kerberos_cache;

/**
* Whether bad server certificates should be ignored.
*/
Expand Down