- SSL verification callback: send correct hostname and port

- Gateway Authentication callback.
- Handling “use same credentials”
This commit is contained in:
Benoît LeBlanc 2013-12-06 22:15:45 -05:00
parent 153bcbfa7c
commit 8c1f836ac8
7 changed files with 103 additions and 22 deletions

View File

@ -49,6 +49,8 @@ struct rdp_tls
rdpSettings* settings;
SecPkgContext_Bindings* Bindings;
rdpCertificateStore* certificate_store;
char* hostname;
int port;
};
FREERDP_API BOOL tls_connect(rdpTls* tls);

View File

@ -204,7 +204,11 @@ struct rdp_freerdp
Callback for cleaning up resources allocated
by connect callbacks. */
UINT64 paddingD[64 - 56]; /* 56 */
ALIGN64 pAuthenticate GatewayAuthenticate; /**< (offset 56)
Callback for gateway authentication.
It is used to get the username/password when it was not provided at connection time. */
UINT64 paddingD[64 - 57]; /* 57 */
ALIGN64 pSendChannelData SendChannelData; /* (offset 64)
Callback for sending data to a channel.

View File

@ -113,15 +113,40 @@ int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
{
rdpNtlm* ntlm = NULL;
rdpSettings* settings;
settings = rpc->settings;
rdpSettings* settings = rpc->settings;
freerdp* instance = (freerdp*) rpc->settings->instance;
BOOL promptPassword = FALSE;
if (channel == TSG_CHANNEL_IN)
ntlm = rpc->NtlmHttpIn->ntlm;
else if (channel == TSG_CHANNEL_OUT)
ntlm = rpc->NtlmHttpOut->ntlm;
if ((!settings->GatewayPassword) || (!settings->GatewayUsername)
|| (!strlen(settings->GatewayPassword)) || (!strlen(settings->GatewayUsername)))
{
promptPassword = TRUE;
}
if (promptPassword)
{
if (instance->GatewayAuthenticate)
{
BOOL proceed = instance->GatewayAuthenticate(instance,
&settings->GatewayUsername, &settings->GatewayPassword, &settings->GatewayDomain);
if (!proceed)
return 0;
if (settings->GatewayUseSameCredentials)
{
settings->Username = _strdup(settings->GatewayUsername);
settings->Domain = _strdup(settings->GatewayDomain);
settings->Password = _strdup(settings->GatewayPassword);
}
}
}
ntlm_client_init(ntlm, TRUE, settings->GatewayUsername,
settings->GatewayDomain, settings->GatewayPassword,
rpc->TlsIn->Bindings);
@ -180,7 +205,7 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc)
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
{
int ntlm_token_length;
int ntlm_token_length = 0;
BYTE* ntlm_token_data;
HttpResponse* http_response;
rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm;
@ -188,8 +213,11 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
http_response = http_response_recv(rpc->TlsOut);
ntlm_token_data = NULL;
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
if (http_response && http_response->AuthParam)
{
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
}
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;

View File

@ -227,6 +227,12 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
}
}
if ((!ntlm) || (!ntlm->table))
{
fprintf(stderr, "rpc_write: invalid ntlm context\n");
return FALSE;
}
status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
(ntlm->haveContext) ? &ntlm->context : NULL,
(ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
@ -270,9 +276,12 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
free(ntlm->identity.Password);
free(ntlm->ServicePrincipalName);
ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
ntlm->table->DeleteSecurityContext(&ntlm->context);
if (ntlm->table)
{
ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
ntlm->table->DeleteSecurityContext(&ntlm->context);
}
}
rdpNtlm* ntlm_new()

View File

@ -97,11 +97,38 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
p_cont_elem_t* p_cont_elem;
rpcconn_bind_hdr_t* bind_pdu;
rdpSettings* settings = rpc->settings;
BOOL promptPassword = FALSE;
freerdp* instance = (freerdp*) settings->instance;
DEBUG_RPC("Sending bind PDU");
rpc->ntlm = ntlm_new();
if ((!settings->GatewayPassword) || (!settings->GatewayUsername)
|| (!strlen(settings->GatewayPassword)) || (!strlen(settings->GatewayUsername)))
{
promptPassword = TRUE;
}
if (promptPassword)
{
if (instance->GatewayAuthenticate)
{
BOOL proceed = instance->GatewayAuthenticate(instance,
&settings->GatewayUsername, &settings->GatewayPassword, &settings->GatewayDomain);
if (!proceed)
return 0;
if (settings->GatewayUseSameCredentials)
{
settings->Username = _strdup(settings->GatewayUsername);
settings->Domain = _strdup(settings->GatewayDomain);
settings->Password = _strdup(settings->GatewayPassword);
}
}
}
ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword, NULL);
ntlm_client_make_spn(rpc->ntlm, NULL, settings->GatewayHostname);

View File

@ -222,6 +222,12 @@ BOOL transport_connect_tls(rdpTransport* transport)
transport->layer = TRANSPORT_LAYER_TSG_TLS;
transport->TsgTls->hostname = transport->settings->ServerHostname;
transport->TsgTls->port = transport->settings->ServerPort;
if (transport->TsgTls->port == 0)
transport->TsgTls->port = 3389;
if (!tls_connect(transport->TsgTls))
{
if (!connectErrorCode)
@ -245,6 +251,12 @@ BOOL transport_connect_tls(rdpTransport* transport)
transport->layer = TRANSPORT_LAYER_TLS;
transport->TlsIn->sockfd = transport->TcpIn->sockfd;
transport->TlsIn->hostname = transport->settings->ServerHostname;
transport->TlsIn->port = transport->settings->ServerPort;
if (transport->TlsIn->port == 0)
transport->TlsIn->port = 3389;
if (!tls_connect(transport->TlsIn))
{
if (!connectErrorCode)
@ -313,11 +325,21 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
transport->TlsIn = tls_new(transport->settings);
transport->TlsIn->sockfd = transport->TcpIn->sockfd;
transport->TlsIn->hostname = transport->settings->GatewayHostname;
transport->TlsIn->port = transport->settings->GatewayPort;
if (transport->TlsIn->port == 0)
transport->TlsIn->port = 443;
if (!transport->TlsOut)
transport->TlsOut = tls_new(transport->settings);
transport->TlsOut->sockfd = transport->TcpOut->sockfd;
transport->TlsOut->hostname = transport->settings->GatewayHostname;
transport->TlsOut->port = transport->settings->GatewayPort;
if (transport->TlsOut->port == 0)
transport->TlsOut->port = 443;
if (!tls_connect(transport->TlsIn))
return FALSE;

View File

@ -214,18 +214,7 @@ BOOL tls_connect(rdpTls* tls)
return FALSE;
}
if (tls->settings->GatewayEnabled)
{
hostname = tls->settings->GatewayHostname;
port = tls->settings->GatewayPort;
}
else
{
hostname = tls->settings->ServerHostname;
port = tls->settings->ServerPort;
}
if (!tls_verify_certificate(tls, cert, hostname, port))
if (!tls_verify_certificate(tls, cert, tls->hostname, tls->port))
{
fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n");
tls_disconnect(tls);