Implemented new AuthenticateEx callbacks.
This commit is contained in:
parent
bc9ef8327e
commit
50e9d3adf9
@ -76,6 +76,16 @@ extern "C"
|
|||||||
#define GATEWAY_MESSAGE_CONSENT 1
|
#define GATEWAY_MESSAGE_CONSENT 1
|
||||||
#define GATEWAY_MESSAGE_SERVICE 2
|
#define GATEWAY_MESSAGE_SERVICE 2
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AUTH_NLA,
|
||||||
|
AUTH_TLS,
|
||||||
|
AUTH_RDP,
|
||||||
|
GW_AUTH_HTTP,
|
||||||
|
GW_AUTH_RDG,
|
||||||
|
GW_AUTH_RPC
|
||||||
|
} rdp_auth_reason;
|
||||||
|
|
||||||
typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context);
|
typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context);
|
||||||
typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
|
typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
|
||||||
|
|
||||||
@ -84,6 +94,8 @@ extern "C"
|
|||||||
typedef void (*pPostDisconnect)(freerdp* instance);
|
typedef void (*pPostDisconnect)(freerdp* instance);
|
||||||
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password,
|
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password,
|
||||||
char** domain);
|
char** domain);
|
||||||
|
typedef BOOL (*pAuthenticateEx)(freerdp* instance, char** username, char** password,
|
||||||
|
char** domain, rdp_auth_reason reason);
|
||||||
|
|
||||||
/** @brief Callback used if user interaction is required to accept
|
/** @brief Callback used if user interaction is required to accept
|
||||||
* an unknown certificate.
|
* an unknown certificate.
|
||||||
@ -431,14 +443,17 @@ fingerprint. DEPRECATED: Use VerifyChangedCertificateEx */
|
|||||||
VerifyChangedCertificateEx; /**< (offset 67)
|
VerifyChangedCertificateEx; /**< (offset 67)
|
||||||
Callback for changed certificate validation.
|
Callback for changed certificate validation.
|
||||||
Used when a certificate differs from stored fingerprint. */
|
Used when a certificate differs from stored fingerprint. */
|
||||||
|
|
||||||
ALIGN64 pSendChannelPacket
|
ALIGN64 pSendChannelPacket
|
||||||
SendChannelPacket; /* (offset 68)
|
SendChannelPacket; /* (offset 68)
|
||||||
* Callback for sending RAW data to a channel. In contrast to
|
* Callback for sending RAW data to a channel. In contrast to
|
||||||
* SendChannelData data fragmentation is up to the user and this
|
* SendChannelData data fragmentation is up to the user and this
|
||||||
* function sends data as is with the provided flags.
|
* function sends data as is with the provided flags.
|
||||||
*/
|
*/
|
||||||
UINT64 paddingE[80 - 69]; /* 69 */
|
ALIGN64 pAuthenticateEx AuthenticateEx; /**< (offset 69)
|
||||||
|
Callback for authentication.
|
||||||
|
It is used to get the username/password. The reason
|
||||||
|
argument tells why it was called. */
|
||||||
|
UINT64 paddingE[80 - 70]; /* 70 */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rdp_channel_handles
|
struct rdp_channel_handles
|
||||||
|
@ -50,6 +50,8 @@ set(${MODULE_PREFIX}_GATEWAY_SRCS
|
|||||||
${${MODULE_PREFIX}_GATEWAY_DIR}/ncacn_http.h)
|
${${MODULE_PREFIX}_GATEWAY_DIR}/ncacn_http.h)
|
||||||
|
|
||||||
set(${MODULE_PREFIX}_SRCS
|
set(${MODULE_PREFIX}_SRCS
|
||||||
|
utils.c
|
||||||
|
utils.h
|
||||||
bulk.c
|
bulk.c
|
||||||
bulk.h
|
bulk.h
|
||||||
activation.c
|
activation.c
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <winpr/dsparse.h>
|
#include <winpr/dsparse.h>
|
||||||
#include <winpr/winhttp.h>
|
#include <winpr/winhttp.h>
|
||||||
|
|
||||||
|
#include "../utils.h"
|
||||||
|
|
||||||
#define TAG FREERDP_TAG("core.gateway.ntlm")
|
#define TAG FREERDP_TAG("core.gateway.ntlm")
|
||||||
|
|
||||||
static wStream* rpc_ntlm_http_request(HttpContext* http, const char* method, int contentLength,
|
static wStream* rpc_ntlm_http_request(HttpContext* http, const char* method, int contentLength,
|
||||||
@ -131,6 +133,7 @@ BOOL rpc_ncacn_http_ntlm_init(rdpContext* context, RpcChannel* channel)
|
|||||||
rdpNtlm* ntlm;
|
rdpNtlm* ntlm;
|
||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
freerdp* instance;
|
freerdp* instance;
|
||||||
|
auth_status rc;
|
||||||
|
|
||||||
if (!context || !channel)
|
if (!context || !channel)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -143,57 +146,18 @@ BOOL rpc_ncacn_http_ntlm_init(rdpContext* context, RpcChannel* channel)
|
|||||||
if (!tls || !ntlm || !instance || !settings)
|
if (!tls || !ntlm || !instance || !settings)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!settings->GatewayPassword || !settings->GatewayUsername ||
|
rc = utils_authenticate_gateway(instance, GW_AUTH_HTTP);
|
||||||
!strlen(settings->GatewayPassword) || !strlen(settings->GatewayUsername))
|
switch (rc)
|
||||||
{
|
{
|
||||||
if (freerdp_shall_disconnect(instance))
|
case AUTH_SUCCESS:
|
||||||
return FALSE;
|
case AUTH_SKIP:
|
||||||
|
break;
|
||||||
if (!instance->GatewayAuthenticate)
|
case AUTH_NO_CREDENTIALS:
|
||||||
{
|
freerdp_set_last_error_log(instance->context,
|
||||||
freerdp_set_last_error_log(context, FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
default:
|
||||||
else
|
return FALSE;
|
||||||
{
|
|
||||||
BOOL proceed =
|
|
||||||
instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
|
|
||||||
&settings->GatewayPassword, &settings->GatewayDomain);
|
|
||||||
|
|
||||||
if (!proceed)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(context,
|
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayUseSameCredentials)
|
|
||||||
{
|
|
||||||
if (settings->GatewayUsername)
|
|
||||||
{
|
|
||||||
free(settings->Username);
|
|
||||||
|
|
||||||
if (!(settings->Username = _strdup(settings->GatewayUsername)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayDomain)
|
|
||||||
{
|
|
||||||
free(settings->Domain);
|
|
||||||
|
|
||||||
if (!(settings->Domain = _strdup(settings->GatewayDomain)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayPassword)
|
|
||||||
{
|
|
||||||
free(settings->Password);
|
|
||||||
|
|
||||||
if (!(settings->Password = _strdup(settings->GatewayPassword)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ntlm_client_init(ntlm, TRUE, settings->GatewayUsername, settings->GatewayDomain,
|
if (!ntlm_client_init(ntlm, TRUE, settings->GatewayUsername, settings->GatewayDomain,
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "../rdp.h"
|
#include "../rdp.h"
|
||||||
#include "../../crypto/opensslcompat.h"
|
#include "../../crypto/opensslcompat.h"
|
||||||
#include "rpc_fault.h"
|
#include "rpc_fault.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
|
||||||
#define TAG FREERDP_TAG("core.gateway.rdg")
|
#define TAG FREERDP_TAG("core.gateway.rdg")
|
||||||
|
|
||||||
@ -1559,63 +1560,21 @@ DWORD rdg_get_event_handles(rdpRdg* rdg, HANDLE* events, DWORD count)
|
|||||||
|
|
||||||
static BOOL rdg_get_gateway_credentials(rdpContext* context)
|
static BOOL rdg_get_gateway_credentials(rdpContext* context)
|
||||||
{
|
{
|
||||||
rdpSettings* settings = context->settings;
|
|
||||||
freerdp* instance = context->instance;
|
freerdp* instance = context->instance;
|
||||||
|
|
||||||
if (!settings->GatewayPassword || !settings->GatewayUsername ||
|
auth_status rc = utils_authenticate_gateway(instance, GW_AUTH_RDG);
|
||||||
!strlen(settings->GatewayPassword) || !strlen(settings->GatewayUsername))
|
switch (rc)
|
||||||
{
|
{
|
||||||
if (freerdp_shall_disconnect(instance))
|
case AUTH_SUCCESS:
|
||||||
|
case AUTH_SKIP:
|
||||||
|
return TRUE;
|
||||||
|
case AUTH_NO_CREDENTIALS:
|
||||||
|
freerdp_set_last_error_log(instance->context,
|
||||||
|
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
default:
|
||||||
if (!instance->GatewayAuthenticate)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(context, FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOL proceed =
|
|
||||||
instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
|
|
||||||
&settings->GatewayPassword, &settings->GatewayDomain);
|
|
||||||
|
|
||||||
if (!proceed)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(context,
|
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayUseSameCredentials)
|
|
||||||
{
|
|
||||||
if (settings->GatewayUsername)
|
|
||||||
{
|
|
||||||
free(settings->Username);
|
|
||||||
|
|
||||||
if (!(settings->Username = _strdup(settings->GatewayUsername)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayDomain)
|
|
||||||
{
|
|
||||||
free(settings->Domain);
|
|
||||||
|
|
||||||
if (!(settings->Domain = _strdup(settings->GatewayDomain)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayPassword)
|
|
||||||
{
|
|
||||||
free(settings->Password);
|
|
||||||
|
|
||||||
if (!(settings->Password = _strdup(settings->GatewayPassword)))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL rdg_ntlm_init(rdpRdg* rdg, rdpTls* tls)
|
static BOOL rdg_ntlm_init(rdpRdg* rdg, rdpTls* tls)
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "rpc_client.h"
|
#include "rpc_client.h"
|
||||||
|
|
||||||
#include "rpc_bind.h"
|
#include "rpc_bind.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
|
||||||
#define TAG FREERDP_TAG("core.gateway.rpc")
|
#define TAG FREERDP_TAG("core.gateway.rpc")
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ const p_uuid_t BTFN_UUID = {
|
|||||||
|
|
||||||
int rpc_send_bind_pdu(rdpRpc* rpc)
|
int rpc_send_bind_pdu(rdpRpc* rpc)
|
||||||
{
|
{
|
||||||
|
auth_status rc;
|
||||||
BOOL continueNeeded = FALSE;
|
BOOL continueNeeded = FALSE;
|
||||||
int status = -1;
|
int status = -1;
|
||||||
BYTE* buffer = NULL;
|
BYTE* buffer = NULL;
|
||||||
@ -112,7 +114,6 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
|
|||||||
RpcClientCall* clientCall;
|
RpcClientCall* clientCall;
|
||||||
p_cont_elem_t* p_cont_elem;
|
p_cont_elem_t* p_cont_elem;
|
||||||
rpcconn_bind_hdr_t* bind_pdu = NULL;
|
rpcconn_bind_hdr_t* bind_pdu = NULL;
|
||||||
BOOL promptPassword = FALSE;
|
|
||||||
rdpSettings* settings = rpc->settings;
|
rdpSettings* settings = rpc->settings;
|
||||||
freerdp* instance = (freerdp*)settings->instance;
|
freerdp* instance = (freerdp*)settings->instance;
|
||||||
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
RpcVirtualConnection* connection = rpc->VirtualConnection;
|
||||||
@ -125,46 +126,18 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
|
|||||||
if (!rpc->ntlm)
|
if (!rpc->ntlm)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((!settings->GatewayPassword) || (!settings->GatewayUsername) ||
|
rc = utils_authenticate_gateway(instance, GW_AUTH_RPC);
|
||||||
(!strlen(settings->GatewayPassword)) || (!strlen(settings->GatewayUsername)))
|
switch (rc)
|
||||||
{
|
{
|
||||||
promptPassword = TRUE;
|
case AUTH_SUCCESS:
|
||||||
}
|
case AUTH_SKIP:
|
||||||
|
break;
|
||||||
if (promptPassword)
|
case AUTH_NO_CREDENTIALS:
|
||||||
{
|
|
||||||
if (freerdp_shall_disconnect(instance))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!instance->GatewayAuthenticate)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(instance->context,
|
freerdp_set_last_error_log(instance->context,
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
default:
|
||||||
else
|
return -1;
|
||||||
{
|
|
||||||
BOOL proceed =
|
|
||||||
instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
|
|
||||||
&settings->GatewayPassword, &settings->GatewayDomain);
|
|
||||||
|
|
||||||
if (!proceed)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(instance->context,
|
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings->GatewayUseSameCredentials)
|
|
||||||
{
|
|
||||||
settings->Username = _strdup(settings->GatewayUsername);
|
|
||||||
settings->Domain = _strdup(settings->GatewayDomain);
|
|
||||||
settings->Password = _strdup(settings->GatewayPassword);
|
|
||||||
|
|
||||||
if (!settings->Username || !settings->Domain || settings->Password)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain,
|
if (!ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain,
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <winpr/registry.h>
|
#include <winpr/registry.h>
|
||||||
|
|
||||||
#include "nla.h"
|
#include "nla.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#define TAG FREERDP_TAG("core.nla")
|
#define TAG FREERDP_TAG("core.nla")
|
||||||
|
|
||||||
@ -530,15 +531,6 @@ void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity)
|
|||||||
* @param credssp
|
* @param credssp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static BOOL is_empty(const char* str)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return TRUE;
|
|
||||||
if (strlen(str) == 0)
|
|
||||||
return TRUE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nla_client_init(rdpNla* nla)
|
static int nla_client_init(rdpNla* nla)
|
||||||
{
|
{
|
||||||
char* spn;
|
char* spn;
|
||||||
@ -554,13 +546,14 @@ static int nla_client_init(rdpNla* nla)
|
|||||||
if (settings->RestrictedAdminModeRequired)
|
if (settings->RestrictedAdminModeRequired)
|
||||||
settings->DisableCredentialsDelegation = TRUE;
|
settings->DisableCredentialsDelegation = TRUE;
|
||||||
|
|
||||||
if (is_empty(settings->Username) ||
|
if (utils_str_is_empty(settings->Username) ||
|
||||||
(is_empty(settings->Password) && is_empty((const char*)settings->RedirectionPassword)))
|
(utils_str_is_empty(settings->Password) &&
|
||||||
|
utils_str_is_empty((const char*)settings->RedirectionPassword)))
|
||||||
{
|
{
|
||||||
PromptPassword = TRUE;
|
PromptPassword = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PromptPassword && !is_empty(settings->Username))
|
if (PromptPassword && !utils_str_is_empty(settings->Username))
|
||||||
{
|
{
|
||||||
sam = SamOpen(NULL, TRUE);
|
sam = SamOpen(NULL, TRUE);
|
||||||
|
|
||||||
@ -597,25 +590,17 @@ static int nla_client_init(rdpNla* nla)
|
|||||||
|
|
||||||
if (PromptPassword)
|
if (PromptPassword)
|
||||||
{
|
{
|
||||||
if (freerdp_shall_disconnect(instance))
|
switch (utils_authenticate(instance, AUTH_NLA, TRUE))
|
||||||
return 0;
|
|
||||||
if (!instance->Authenticate)
|
|
||||||
{
|
{
|
||||||
freerdp_set_last_error_log(instance->context,
|
case AUTH_SKIP:
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
case AUTH_SUCCESS:
|
||||||
return 0;
|
break;
|
||||||
}
|
case AUTH_NO_CREDENTIALS:
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOL proceed = instance->Authenticate(instance, &settings->Username,
|
|
||||||
&settings->Password, &settings->Domain);
|
|
||||||
|
|
||||||
if (!proceed)
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(instance->context,
|
freerdp_set_last_error_log(instance->context,
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "rdp.h"
|
#include "rdp.h"
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#define TAG FREERDP_TAG("core.transport")
|
#define TAG FREERDP_TAG("core.transport")
|
||||||
|
|
||||||
@ -157,41 +158,20 @@ fail:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL transport_prompt_for_password(rdpTransport* transport)
|
|
||||||
{
|
|
||||||
rdpSettings* settings = transport->settings;
|
|
||||||
freerdp* instance = transport->context->instance;
|
|
||||||
|
|
||||||
/* Ask for auth data if no or an empty username was specified or no password was given */
|
|
||||||
if ((settings->Username == NULL || strlen(settings->Username) == 0) ||
|
|
||||||
(settings->Password == NULL && settings->RedirectionPassword == NULL))
|
|
||||||
{
|
|
||||||
/* If no callback is specified still continue connection */
|
|
||||||
if (!instance->Authenticate)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (!instance->Authenticate(instance, &settings->Username, &settings->Password,
|
|
||||||
&settings->Domain))
|
|
||||||
{
|
|
||||||
freerdp_set_last_error_log(instance->context,
|
|
||||||
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL transport_connect_rdp(rdpTransport* transport)
|
BOOL transport_connect_rdp(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
if (!transport)
|
if (!transport)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!transport_prompt_for_password(transport))
|
switch (utils_authenticate(transport->context->instance, AUTH_RDP, FALSE))
|
||||||
return FALSE;
|
{
|
||||||
|
case AUTH_SKIP:
|
||||||
/* RDP encryption */
|
case AUTH_SUCCESS:
|
||||||
return TRUE;
|
case AUTH_NO_CREDENTIALS:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL transport_connect_tls(rdpTransport* transport)
|
BOOL transport_connect_tls(rdpTransport* transport)
|
||||||
@ -202,8 +182,15 @@ BOOL transport_connect_tls(rdpTransport* transport)
|
|||||||
/* Only prompt for password if we use TLS (NLA also calls this function) */
|
/* Only prompt for password if we use TLS (NLA also calls this function) */
|
||||||
if (transport->settings->SelectedProtocol == PROTOCOL_SSL)
|
if (transport->settings->SelectedProtocol == PROTOCOL_SSL)
|
||||||
{
|
{
|
||||||
if (!transport_prompt_for_password(transport))
|
switch (utils_authenticate(transport->context->instance, AUTH_TLS, FALSE))
|
||||||
return FALSE;
|
{
|
||||||
|
case AUTH_SKIP:
|
||||||
|
case AUTH_SUCCESS:
|
||||||
|
case AUTH_NO_CREDENTIALS:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return IFCALLRESULT(FALSE, transport->io.TLSConnect, transport);
|
return IFCALLRESULT(FALSE, transport->io.TLSConnect, transport);
|
||||||
|
178
libfreerdp/core/utils.c
Normal file
178
libfreerdp/core/utils.c
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||||
|
* Terminal Server Gateway (utils)
|
||||||
|
*
|
||||||
|
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
|
||||||
|
* Copyright 2021 Thincast Technologies GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <winpr/assert.h>
|
||||||
|
|
||||||
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
|
#include <freerdp/log.h>
|
||||||
|
#define TAG FREERDP_TAG("core.gateway.utils")
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
BOOL utils_str_copy(const char* value, char** dst)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(dst);
|
||||||
|
|
||||||
|
free(*dst);
|
||||||
|
*dst = NULL;
|
||||||
|
if (!value)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
(*dst) = _strdup(value);
|
||||||
|
return (*dst) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason)
|
||||||
|
{
|
||||||
|
rdpSettings* settings;
|
||||||
|
rdpContext* context;
|
||||||
|
BOOL prompt = FALSE;
|
||||||
|
BOOL proceed;
|
||||||
|
|
||||||
|
WINPR_ASSERT(instance);
|
||||||
|
WINPR_ASSERT(instance->context);
|
||||||
|
WINPR_ASSERT(instance->settings);
|
||||||
|
|
||||||
|
settings = instance->settings;
|
||||||
|
context = instance->context;
|
||||||
|
|
||||||
|
if (freerdp_shall_disconnect(instance))
|
||||||
|
return AUTH_FAILED;
|
||||||
|
|
||||||
|
if (!settings->GatewayPassword || !settings->GatewayUsername ||
|
||||||
|
!strlen(settings->GatewayPassword) || !strlen(settings->GatewayUsername))
|
||||||
|
prompt = TRUE;
|
||||||
|
|
||||||
|
if (!prompt)
|
||||||
|
return AUTH_SKIP;
|
||||||
|
|
||||||
|
if (!instance->GatewayAuthenticate && !instance->AuthenticateEx)
|
||||||
|
return AUTH_NO_CREDENTIALS;
|
||||||
|
|
||||||
|
if (instance->AuthenticateEx)
|
||||||
|
proceed =
|
||||||
|
instance->AuthenticateEx(instance, &settings->GatewayUsername,
|
||||||
|
&settings->GatewayPassword, &settings->GatewayDomain, reason);
|
||||||
|
else
|
||||||
|
proceed =
|
||||||
|
instance->GatewayAuthenticate(instance, &settings->GatewayUsername,
|
||||||
|
&settings->GatewayPassword, &settings->GatewayDomain);
|
||||||
|
|
||||||
|
if (!proceed)
|
||||||
|
return AUTH_NO_CREDENTIALS;
|
||||||
|
|
||||||
|
if (!utils_sync_credentials(settings, FALSE))
|
||||||
|
return AUTH_FAILED;
|
||||||
|
return AUTH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL override)
|
||||||
|
{
|
||||||
|
rdpSettings* settings;
|
||||||
|
rdpContext* context;
|
||||||
|
BOOL prompt = !override;
|
||||||
|
BOOL proceed;
|
||||||
|
|
||||||
|
WINPR_ASSERT(instance);
|
||||||
|
WINPR_ASSERT(instance->context);
|
||||||
|
WINPR_ASSERT(instance->settings);
|
||||||
|
|
||||||
|
settings = instance->settings;
|
||||||
|
context = instance->context;
|
||||||
|
|
||||||
|
if (freerdp_shall_disconnect(instance))
|
||||||
|
return AUTH_FAILED;
|
||||||
|
|
||||||
|
/* Ask for auth data if no or an empty username was specified or no password was given */
|
||||||
|
if (utils_str_is_empty(settings->Username) ||
|
||||||
|
(settings->Password == NULL && settings->RedirectionPassword == NULL))
|
||||||
|
prompt = TRUE;
|
||||||
|
|
||||||
|
if (!prompt)
|
||||||
|
return AUTH_SKIP;
|
||||||
|
|
||||||
|
/* If no callback is specified still continue connection */
|
||||||
|
if (!instance->Authenticate && !instance->AuthenticateEx)
|
||||||
|
return AUTH_NO_CREDENTIALS;
|
||||||
|
|
||||||
|
if (instance->AuthenticateEx)
|
||||||
|
proceed =
|
||||||
|
instance->AuthenticateEx(instance, &settings->GatewayUsername,
|
||||||
|
&settings->GatewayPassword, &settings->GatewayDomain, reason);
|
||||||
|
else
|
||||||
|
proceed = instance->Authenticate(instance, &settings->GatewayUsername,
|
||||||
|
&settings->GatewayPassword, &settings->GatewayDomain);
|
||||||
|
|
||||||
|
if (!proceed)
|
||||||
|
return AUTH_NO_CREDENTIALS;
|
||||||
|
|
||||||
|
if (!instance->Authenticate(instance, &settings->Username, &settings->Password,
|
||||||
|
&settings->Domain))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error_log(instance->context,
|
||||||
|
FREERDP_ERROR_CONNECT_NO_OR_MISSING_CREDENTIALS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!utils_sync_credentials(settings, TRUE))
|
||||||
|
return AUTH_FAILED;
|
||||||
|
return AUTH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(settings);
|
||||||
|
if (!settings->GatewayUseSameCredentials)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (toGateway)
|
||||||
|
{
|
||||||
|
if (!utils_str_copy(settings->Username, &settings->GatewayUsername))
|
||||||
|
return FALSE;
|
||||||
|
if (!utils_str_copy(settings->Domain, &settings->GatewayDomain))
|
||||||
|
return FALSE;
|
||||||
|
if (!utils_str_copy(settings->Password, &settings->GatewayPassword))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!utils_str_copy(settings->GatewayUsername, &settings->Username))
|
||||||
|
return FALSE;
|
||||||
|
if (!utils_str_copy(settings->GatewayDomain, &settings->Domain))
|
||||||
|
return FALSE;
|
||||||
|
if (!utils_str_copy(settings->GatewayPassword, &settings->Password))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL utils_str_is_empty(const char* str)
|
||||||
|
{
|
||||||
|
if (!str)
|
||||||
|
return TRUE;
|
||||||
|
if (strlen(str) == 0)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
41
libfreerdp/core/utils.h
Normal file
41
libfreerdp/core/utils.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||||
|
* Terminal Server Gateway (utils)
|
||||||
|
*
|
||||||
|
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
|
||||||
|
* Copyright 2021 Thincast Technologies GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERDP_LIB_CORE_UTILS_H
|
||||||
|
#define FREERDP_LIB_CORE_UTILS_H
|
||||||
|
|
||||||
|
#include <winpr/winpr.h>
|
||||||
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AUTH_SUCCESS,
|
||||||
|
AUTH_SKIP,
|
||||||
|
AUTH_NO_CREDENTIALS,
|
||||||
|
AUTH_FAILED
|
||||||
|
} auth_status;
|
||||||
|
auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason);
|
||||||
|
auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL override);
|
||||||
|
BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway);
|
||||||
|
|
||||||
|
BOOL utils_str_is_empty(const char* str);
|
||||||
|
BOOL utils_str_copy(const char* value, char** dst);
|
||||||
|
|
||||||
|
#endif /* FREERDP_LIB_CORE_UTILS_H */
|
Loading…
Reference in New Issue
Block a user