Merge pull request #885 from awakecoding/master
SSPI NTLMv2 Fixes and Improvements
This commit is contained in:
commit
4c31e4efaf
@ -96,6 +96,9 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "nla extended protocol security" },
|
||||
{ "cert-name", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL, "certificate name" },
|
||||
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" },
|
||||
{ "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" },
|
||||
{ "pcid", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL, "Preconnection Id" },
|
||||
{ "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "<vmid>", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" },
|
||||
{ "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" },
|
||||
{ "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" },
|
||||
{ "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "grab keyboard" },
|
||||
@ -189,6 +192,7 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
|
||||
printf(" xfreerdp connection.rdp /p:Pwd123! /f\n");
|
||||
printf(" xfreerdp /u:CONTOSO\\JohnDoe /p:Pwd123! /v:rdp.contoso.com\n");
|
||||
printf(" xfreerdp /u:JohnDoe /p:Pwd123! /w:1366 /h:768 /v:192.168.1.100:4489\n");
|
||||
printf(" xfreerdp /u:JohnDoe /p:Pwd123! /vmconnect:C824F53E-95D2-46C6-9A18-23A5BB403532 /v:192.168.1.100\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Clipboard Redirection: +clipboard\n");
|
||||
@ -832,6 +836,17 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
settings->ServerHostname = _strdup(arg->Value);
|
||||
}
|
||||
}
|
||||
CommandLineSwitchCase(arg, "vmconnect")
|
||||
{
|
||||
settings->ServerPort = 2179;
|
||||
settings->NegotiateSecurityLayer = FALSE;
|
||||
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
{
|
||||
settings->SendPreconnectionPdu = TRUE;
|
||||
settings->PreconnectionBlob = _strdup(arg->Value);
|
||||
}
|
||||
}
|
||||
CommandLineSwitchCase(arg, "port")
|
||||
{
|
||||
settings->ServerPort = atoi(arg->Value);
|
||||
@ -1161,16 +1176,16 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
{
|
||||
settings->NegotiateSecurityLayer = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "pcid")
|
||||
{
|
||||
settings->SendPreconnectionPdu = TRUE;
|
||||
settings->PreconnectionId = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "pcb")
|
||||
{
|
||||
settings->SendPreconnectionPdu = TRUE;
|
||||
settings->PreconnectionBlob = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "pcid")
|
||||
{
|
||||
settings->SendPreconnectionPdu = TRUE;
|
||||
settings->PreconnectionId = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "sec")
|
||||
{
|
||||
if (strcmp("rdp", arg->Value) == 0) /* Standard RDP */
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "crypto.h"
|
||||
#include "certificate.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@ -40,6 +43,7 @@ struct rdp_tls
|
||||
BYTE* PublicKey;
|
||||
DWORD PublicKeyLength;
|
||||
rdpSettings* settings;
|
||||
SecPkgContext_Bindings* Bindings;
|
||||
rdpCertificateStore* certificate_store;
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
typedef struct rdp_update rdpUpdate;
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
@ -191,6 +196,9 @@ struct rdp_update
|
||||
|
||||
SURFACE_BITS_COMMAND surface_bits_command;
|
||||
SURFACE_FRAME_MARKER surface_frame_marker;
|
||||
|
||||
HANDLE thread;
|
||||
wQueue* queue;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_UPDATE_H */
|
||||
|
@ -340,7 +340,7 @@ static BOOL fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
int fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
|
||||
@ -349,15 +349,12 @@ BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
while (stream_get_left(s) >= 3)
|
||||
{
|
||||
if (!fastpath_recv_update_data(fastpath, s))
|
||||
{
|
||||
/* XXX: Do we need to call EndPaint? */
|
||||
return FALSE;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFCALL(update->EndPaint, update->context);
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL fastpath_read_input_event_header(STREAM* s, BYTE* eventFlags, BYTE* eventCode)
|
||||
@ -506,7 +503,7 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, STREAM* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
int fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
BYTE i;
|
||||
|
||||
@ -518,7 +515,7 @@ BOOL fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
*/
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
stream_read_BYTE(s, fastpath->numberEvents); /* eventHeader (1 byte) */
|
||||
}
|
||||
@ -526,10 +523,10 @@ BOOL fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
for (i = 0; i < fastpath->numberEvents; i++)
|
||||
{
|
||||
if (!fastpath_recv_input_event(fastpath, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp)
|
||||
|
@ -80,7 +80,7 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc)
|
||||
|
||||
content_length = (continue_needed) ? 0 : 0x40000000;
|
||||
|
||||
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_IN);
|
||||
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], content_length, TSG_CHANNEL_IN);
|
||||
|
||||
DEBUG_RPC("\n%s", Stream_Buffer(s));
|
||||
rpc_in_write(rpc, Stream_Buffer(s), Stream_Length(s));
|
||||
@ -102,8 +102,8 @@ int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
|
||||
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
|
||||
&ntlm_token_data, &ntlm_token_length);
|
||||
|
||||
ntlm->inputBuffer.pvBuffer = ntlm_token_data;
|
||||
ntlm->inputBuffer.cbBuffer = ntlm_token_length;
|
||||
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
|
||||
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
|
||||
|
||||
http_response_free(http_response);
|
||||
|
||||
@ -123,7 +123,8 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
|
||||
ntlm = rpc->NtlmHttpOut->ntlm;
|
||||
|
||||
ntlm_client_init(ntlm, TRUE, settings->GatewayUsername,
|
||||
settings->GatewayDomain, settings->GatewayPassword);
|
||||
settings->GatewayDomain, settings->GatewayPassword,
|
||||
rpc->TlsIn->Bindings);
|
||||
|
||||
//ntlm_client_make_spn(ntlm, NULL, settings->GatewayHostname);
|
||||
ntlm_client_make_spn(ntlm, _T("HTTP"), settings->GatewayHostname);
|
||||
@ -168,7 +169,7 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc)
|
||||
|
||||
content_length = (continue_needed) ? 0 : 76;
|
||||
|
||||
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_OUT);
|
||||
s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], content_length, TSG_CHANNEL_OUT);
|
||||
|
||||
DEBUG_RPC("\n%s", Stream_Buffer(s));
|
||||
rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s));
|
||||
@ -190,8 +191,8 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
|
||||
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
|
||||
&ntlm_token_data, &ntlm_token_length);
|
||||
|
||||
ntlm->inputBuffer.pvBuffer = ntlm_token_data;
|
||||
ntlm->inputBuffer.cbBuffer = ntlm_token_length;
|
||||
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
|
||||
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
|
||||
|
||||
http_response_free(http_response);
|
||||
|
||||
|
@ -37,12 +37,15 @@
|
||||
|
||||
#include "ntlm.h"
|
||||
|
||||
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password)
|
||||
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password, SecPkgContext_Bindings* Bindings)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
sspi_GlobalInit();
|
||||
|
||||
ntlm->http = http;
|
||||
ntlm->Bindings = Bindings;
|
||||
|
||||
#ifdef WITH_NATIVE_SSPI
|
||||
{
|
||||
HMODULE hSSPI;
|
||||
@ -91,7 +94,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char*
|
||||
|
||||
ntlm->fContextReq = 0;
|
||||
|
||||
if (http)
|
||||
if (ntlm->http)
|
||||
{
|
||||
/* flags for HTTP authentication */
|
||||
ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY;
|
||||
@ -195,25 +198,33 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
if (ntlm->outputBuffer.pvBuffer)
|
||||
if (ntlm->outputBuffer[0].pvBuffer)
|
||||
{
|
||||
free(ntlm->outputBuffer.pvBuffer);
|
||||
ntlm->outputBuffer.pvBuffer = NULL;
|
||||
free(ntlm->outputBuffer[0].pvBuffer);
|
||||
ntlm->outputBuffer[0].pvBuffer = NULL;
|
||||
}
|
||||
|
||||
ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
ntlm->outputBufferDesc.cBuffers = 1;
|
||||
ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer;
|
||||
ntlm->outputBuffer.BufferType = SECBUFFER_TOKEN;
|
||||
ntlm->outputBuffer.cbBuffer = ntlm->cbMaxToken;
|
||||
ntlm->outputBuffer.pvBuffer = malloc(ntlm->outputBuffer.cbBuffer);
|
||||
ntlm->outputBufferDesc.pBuffers = ntlm->outputBuffer;
|
||||
ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
|
||||
ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
|
||||
ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
|
||||
|
||||
if (ntlm->haveInputBuffer)
|
||||
{
|
||||
ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
ntlm->inputBufferDesc.cBuffers = 1;
|
||||
ntlm->inputBufferDesc.pBuffers = &ntlm->inputBuffer;
|
||||
ntlm->inputBuffer.BufferType = SECBUFFER_TOKEN;
|
||||
ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer;
|
||||
ntlm->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
|
||||
|
||||
if (ntlm->Bindings)
|
||||
{
|
||||
ntlm->inputBufferDesc.cBuffers++;
|
||||
ntlm->inputBuffer[1].BufferType = SECBUFFER_CHANNEL_BINDINGS;
|
||||
ntlm->inputBuffer[1].cbBuffer = ntlm->Bindings->BindingsLength;
|
||||
ntlm->inputBuffer[1].pvBuffer = (void*) ntlm->Bindings->Bindings;
|
||||
}
|
||||
}
|
||||
|
||||
status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
|
||||
@ -243,7 +254,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
|
||||
|
||||
if (ntlm->haveInputBuffer)
|
||||
{
|
||||
free(ntlm->inputBuffer.pvBuffer);
|
||||
free(ntlm->inputBuffer[0].pvBuffer);
|
||||
}
|
||||
|
||||
ntlm->haveInputBuffer = TRUE;
|
||||
|
@ -43,14 +43,15 @@ typedef struct rdp_ntlm_http rdpNtlmHttp;
|
||||
|
||||
struct rdp_ntlm
|
||||
{
|
||||
BOOL http;
|
||||
CtxtHandle context;
|
||||
ULONG cbMaxToken;
|
||||
ULONG fContextReq;
|
||||
ULONG pfContextAttr;
|
||||
TimeStamp expiration;
|
||||
PSecBuffer pBuffer;
|
||||
SecBuffer inputBuffer;
|
||||
SecBuffer outputBuffer;
|
||||
SecBuffer inputBuffer[2];
|
||||
SecBuffer outputBuffer[2];
|
||||
BOOL haveContext;
|
||||
BOOL haveInputBuffer;
|
||||
LPTSTR ServicePrincipalName;
|
||||
@ -62,6 +63,7 @@ struct rdp_ntlm
|
||||
SecurityFunctionTable* table;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SecPkgContext_Sizes ContextSizes;
|
||||
SecPkgContext_Bindings* Bindings;
|
||||
};
|
||||
|
||||
struct rdp_ntlm_http
|
||||
@ -72,7 +74,8 @@ struct rdp_ntlm_http
|
||||
|
||||
BOOL ntlm_authenticate(rdpNtlm* ntlm);
|
||||
|
||||
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* domain, char* password);
|
||||
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user,
|
||||
char* domain, char* password, SecPkgContext_Bindings* Bindings);
|
||||
void ntlm_client_uninit(rdpNtlm* ntlm);
|
||||
|
||||
BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname);
|
||||
|
@ -102,7 +102,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
|
||||
|
||||
rpc->ntlm = ntlm_new();
|
||||
|
||||
ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword);
|
||||
ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword, NULL);
|
||||
ntlm_client_make_spn(rpc->ntlm, NULL, settings->GatewayHostname);
|
||||
|
||||
ntlm_authenticate(rpc->ntlm);
|
||||
@ -112,8 +112,8 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
|
||||
|
||||
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) bind_pdu);
|
||||
|
||||
bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
|
||||
bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
|
||||
bind_pdu->auth_length = rpc->ntlm->outputBuffer[0].cbBuffer;
|
||||
bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].pvBuffer;
|
||||
|
||||
bind_pdu->ptype = PTYPE_BIND;
|
||||
bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_SUPPORT_HEADER_SIGN | PFC_CONC_MPX;
|
||||
@ -228,11 +228,11 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
rpc->max_recv_frag = header->bind_ack.max_xmit_frag;
|
||||
rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
|
||||
|
||||
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
|
||||
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length);
|
||||
rpc->ntlm->inputBuffer[0].cbBuffer = header->common.auth_length;
|
||||
rpc->ntlm->inputBuffer[0].pvBuffer = malloc(header->common.auth_length);
|
||||
|
||||
auth_data = buffer + (header->common.frag_length - header->common.auth_length);
|
||||
CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length);
|
||||
CopyMemory(rpc->ntlm->inputBuffer[0].pvBuffer, auth_data, header->common.auth_length);
|
||||
|
||||
ntlm_authenticate(rpc->ntlm);
|
||||
|
||||
@ -261,8 +261,8 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
|
||||
|
||||
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) auth_3_pdu);
|
||||
|
||||
auth_3_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
|
||||
auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
|
||||
auth_3_pdu->auth_length = rpc->ntlm->outputBuffer[0].cbBuffer;
|
||||
auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].pvBuffer;
|
||||
|
||||
auth_3_pdu->ptype = PTYPE_RPC_AUTH_3;
|
||||
auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX;
|
||||
|
@ -465,9 +465,9 @@ BOOL nego_recv_response(rdpNego* nego)
|
||||
STREAM* s = transport_recv_stream_init(nego->transport, 1024);
|
||||
|
||||
if (transport_read(nego->transport, s) < 0)
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
return nego_recv(nego->transport, s, nego);
|
||||
return ((nego_recv(nego->transport, s, nego) < 0) ? FALSE : TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -478,7 +478,7 @@ BOOL nego_recv_response(rdpNego* nego)
|
||||
* @param extra nego pointer
|
||||
*/
|
||||
|
||||
BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra)
|
||||
int nego_recv(rdpTransport* transport, STREAM* s, void* extra)
|
||||
{
|
||||
BYTE li;
|
||||
BYTE type;
|
||||
@ -488,7 +488,7 @@ BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra)
|
||||
length = tpkt_read_header(s);
|
||||
|
||||
if (length == 0)
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
li = tpdu_read_connection_confirm(s);
|
||||
|
||||
@ -546,7 +546,7 @@ BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra)
|
||||
nego->state = NEGO_STATE_FAIL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,7 +117,7 @@ void nego_attempt_tls(rdpNego* nego);
|
||||
void nego_attempt_rdp(rdpNego* nego);
|
||||
|
||||
void nego_send(rdpNego* nego);
|
||||
BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra);
|
||||
int nego_recv(rdpTransport* transport, STREAM* s, void* extra);
|
||||
BOOL nego_recv_response(rdpNego* nego);
|
||||
BOOL nego_read_request(rdpNego* nego, STREAM* s);
|
||||
|
||||
|
@ -156,7 +156,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
static int peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
UINT16 length;
|
||||
@ -171,7 +171,7 @@ static BOOL peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
{
|
||||
printf("Incorrect RDP header.\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rdp->settings->DisableEncryption)
|
||||
@ -183,7 +183,7 @@ static BOOL peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
{
|
||||
printf("rdp_decrypt failed\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,7 @@ static BOOL peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
else
|
||||
{
|
||||
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
client->settings->PduSource = pduSource;
|
||||
|
||||
@ -203,19 +203,19 @@ static BOOL peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
|
||||
{
|
||||
case PDU_TYPE_DATA:
|
||||
if (!peer_recv_data_pdu(client, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Client sent pduType %d\n", pduType);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
|
||||
static int peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
UINT16 length;
|
||||
@ -225,10 +225,10 @@ static BOOL peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
|
||||
fastpath = rdp->fastpath;
|
||||
length = fastpath_read_header_rdp(fastpath, s);
|
||||
|
||||
if (length == 0 || length > stream_get_left(s))
|
||||
if ((length == 0) || (length > stream_get_left(s)))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
@ -239,7 +239,7 @@ static BOOL peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
|
||||
return fastpath_recv_inputs(fastpath, s);
|
||||
}
|
||||
|
||||
static BOOL peer_recv_pdu(freerdp_peer* client, STREAM* s)
|
||||
static int peer_recv_pdu(freerdp_peer* client, STREAM* s)
|
||||
{
|
||||
if (tpkt_verify_header(s))
|
||||
return peer_recv_tpkt_pdu(client, s);
|
||||
@ -256,7 +256,7 @@ static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
{
|
||||
case CONNECTION_STATE_INITIAL:
|
||||
if (!rdp_server_accept_nego(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
if (rdp->nego->selected_protocol & PROTOCOL_NLA)
|
||||
{
|
||||
@ -273,29 +273,29 @@ static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
||||
case CONNECTION_STATE_NEGO:
|
||||
if (!rdp_server_accept_mcs_connect_initial(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CONNECT:
|
||||
if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ERECT_DOMAIN:
|
||||
if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ATTACH_USER:
|
||||
if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
|
||||
if (rdp->settings->DisableEncryption)
|
||||
{
|
||||
if (!rdp_server_accept_client_keys(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
rdp->state = CONNECTION_STATE_ESTABLISH_KEYS;
|
||||
@ -303,12 +303,12 @@ static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
||||
case CONNECTION_STATE_ESTABLISH_KEYS:
|
||||
if (!rdp_server_accept_client_info(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
|
||||
IFCALL(client->Capabilities, client);
|
||||
|
||||
if (!rdp_send_demand_active(rdp))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_LICENSE:
|
||||
@ -325,15 +325,15 @@ static BOOL peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
if (!peer_recv_pdu(client, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Invalid state %d\n", rdp->state);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL freerdp_peer_close(freerdp_peer* client)
|
||||
|
@ -480,7 +480,7 @@ void rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
rdp_print_errinfo(rdp->errorInfo);
|
||||
}
|
||||
|
||||
BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
BYTE type;
|
||||
UINT16 length;
|
||||
@ -507,7 +507,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
else
|
||||
{
|
||||
printf("decompress_rdp() failed\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
stream_seek(s, compressed_len - 18);
|
||||
}
|
||||
@ -522,7 +522,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
case DATA_PDU_TYPE_UPDATE:
|
||||
if (!update_recv(rdp->update, comp_stream))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_CONTROL:
|
||||
@ -611,7 +611,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
stream_free(comp_stream);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
|
||||
@ -624,7 +624,7 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
|
||||
|
||||
if (type == PDU_TYPE_DATA)
|
||||
{
|
||||
return rdp_recv_data_pdu(rdp, s);
|
||||
return (rdp_recv_data_pdu(rdp, s) < 0) ? FALSE : TRUE;
|
||||
}
|
||||
else if (type == PDU_TYPE_SERVER_REDIRECTION)
|
||||
{
|
||||
@ -712,7 +712,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, UINT16 securityFlags)
|
||||
* @param s stream
|
||||
*/
|
||||
|
||||
static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static int rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT16 length;
|
||||
UINT16 pduType;
|
||||
@ -725,7 +725,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
{
|
||||
printf("Incorrect RDP header.\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rdp->settings->DisableEncryption)
|
||||
@ -737,7 +737,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
{
|
||||
printf("rdp_decrypt failed\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,7 +749,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
*/
|
||||
s->p -= 2;
|
||||
rdp_recv_enhanced_security_redirection_packet(rdp, s);
|
||||
return TRUE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,16 +770,16 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
switch (pduType)
|
||||
{
|
||||
case PDU_TYPE_DATA:
|
||||
if (!rdp_recv_data_pdu(rdp, s))
|
||||
if (rdp_recv_data_pdu(rdp, s) < 0)
|
||||
{
|
||||
printf("rdp_recv_data_pdu failed\n");
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDU_TYPE_DEACTIVATE_ALL:
|
||||
if (!rdp_recv_deactivate_all(rdp, s))
|
||||
return FALSE;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case PDU_TYPE_SERVER_REDIRECTION:
|
||||
@ -794,10 +794,10 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static int rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
UINT16 length;
|
||||
rdpFastPath* fastpath;
|
||||
@ -808,7 +808,7 @@ static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
if ((length == 0) || (length > stream_get_left(s)))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
|
||||
@ -819,7 +819,7 @@ static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
return fastpath_recv_updates(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static BOOL rdp_recv_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static int rdp_recv_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (tpkt_verify_header(s))
|
||||
return rdp_recv_tpkt_pdu(rdp, s);
|
||||
@ -842,58 +842,58 @@ void rdp_recv(rdpRdp* rdp)
|
||||
rdp_recv_pdu(rdp, s);
|
||||
}
|
||||
|
||||
static BOOL rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
{
|
||||
int status = 0;
|
||||
rdpRdp* rdp = (rdpRdp*) extra;
|
||||
|
||||
switch (rdp->state)
|
||||
{
|
||||
case CONNECTION_STATE_NEGO:
|
||||
if (!rdp_client_connect_mcs_connect_response(rdp, s))
|
||||
return FALSE;
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ATTACH_USER:
|
||||
if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
|
||||
return FALSE;
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
|
||||
if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
|
||||
return FALSE;
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_LICENSE:
|
||||
if (!rdp_client_connect_license(rdp, s))
|
||||
return FALSE;
|
||||
status = -1;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_CAPABILITY:
|
||||
if (!rdp_client_connect_demand_active(rdp, s))
|
||||
{
|
||||
printf("rdp_client_connect_demand_active failed\n");
|
||||
return FALSE;
|
||||
status = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_FINALIZATION:
|
||||
if (!rdp_recv_pdu(rdp, s))
|
||||
return FALSE;
|
||||
if (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE)
|
||||
status = rdp_recv_pdu(rdp, s);
|
||||
if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
|
||||
rdp->state = CONNECTION_STATE_ACTIVE;
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
if (!rdp_recv_pdu(rdp, s))
|
||||
return FALSE;
|
||||
status = rdp_recv_pdu(rdp, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Invalid state %d\n", rdp->state);
|
||||
return FALSE;
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
int rdp_send_channel_data(rdpRdp* rdp, int channel_id, BYTE* data, int size)
|
||||
|
@ -76,7 +76,7 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
|
||||
return 6;
|
||||
}
|
||||
|
||||
BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
|
||||
int update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
|
||||
{
|
||||
BYTE* mark;
|
||||
UINT16 cmdType;
|
||||
@ -102,7 +102,7 @@ BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unknown cmdType 0x%X", cmdType);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
size -= cmdLength;
|
||||
@ -113,7 +113,8 @@ BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
|
||||
pcap_flush(update->pcap_rfx);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd)
|
||||
|
@ -33,7 +33,7 @@ enum SURFCMD_CMDTYPE
|
||||
CMDTYPE_STREAM_SURFACE_BITS = 0x0006
|
||||
};
|
||||
|
||||
BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s);
|
||||
int update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s);
|
||||
|
||||
void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
|
||||
void update_write_surfcmd_frame_marker(STREAM* s, UINT16 frameAction, UINT32 frameId);
|
||||
|
@ -589,6 +589,7 @@ int transport_check_fds(rdpTransport** ptransport)
|
||||
int pos;
|
||||
int status;
|
||||
UINT16 length;
|
||||
int recv_status;
|
||||
STREAM* received;
|
||||
rdpTransport* transport = *ptransport;
|
||||
|
||||
@ -684,10 +685,21 @@ int transport_check_fds(rdpTransport** ptransport)
|
||||
stream_seal(received);
|
||||
stream_set_pos(received, 0);
|
||||
|
||||
if (transport->ReceiveCallback(transport, received, transport->ReceiveExtra) == FALSE)
|
||||
/**
|
||||
* ReceiveCallback return values:
|
||||
*
|
||||
* -1: synchronous failure
|
||||
* 0: synchronous success
|
||||
* 1: asynchronous return
|
||||
*/
|
||||
|
||||
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
|
||||
|
||||
if (recv_status < 0)
|
||||
status = -1;
|
||||
|
||||
transport_receive_pool_return(transport, received);
|
||||
if (recv_status == 0)
|
||||
transport_receive_pool_return(transport, received);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/thread.h>
|
||||
|
||||
#include "update.h"
|
||||
#include "surface.h"
|
||||
@ -620,6 +621,20 @@ void update_register_client_callbacks(rdpUpdate* update)
|
||||
update->SuppressOutput = update_send_suppress_output;
|
||||
}
|
||||
|
||||
static void* update_thread(void* arg)
|
||||
{
|
||||
rdpUpdate* update;
|
||||
|
||||
update = (rdpUpdate*) arg;
|
||||
|
||||
while (WaitForSingleObject(Queue_Event(update->queue), INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdpUpdate* update_new(rdpRdp* rdp)
|
||||
{
|
||||
rdpUpdate* update;
|
||||
@ -657,6 +672,10 @@ rdpUpdate* update_new(rdpRdp* rdp)
|
||||
deleteList->cIndices = 0;
|
||||
|
||||
update->SuppressOutput = update_send_suppress_output;
|
||||
|
||||
update->queue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
update->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_thread, update, 0, NULL);
|
||||
}
|
||||
|
||||
return update;
|
||||
@ -679,7 +698,9 @@ void update_free(rdpUpdate* update)
|
||||
free(update->secondary);
|
||||
free(update->altsec);
|
||||
free(update->window);
|
||||
|
||||
CloseHandle(update->thread);
|
||||
|
||||
free(update);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/tcp.h>
|
||||
@ -58,6 +59,86 @@ static void tls_free_certificate(CryptoCert cert)
|
||||
free(cert);
|
||||
}
|
||||
|
||||
static void tls_md5_update_uint32_be(MD5_CTX* md5, UINT32 num)
|
||||
{
|
||||
BYTE be32[4];
|
||||
|
||||
be32[0] = (num >> 0) & 0xFF;
|
||||
be32[1] = (num >> 8) & 0xFF;
|
||||
be32[2] = (num >> 16) & 0xFF;
|
||||
be32[3] = (num >> 24) & 0xFF;
|
||||
|
||||
MD5_Update(md5, be32, 4);
|
||||
}
|
||||
|
||||
BYTE* tls_get_channel_bindings_hash(SecPkgContext_Bindings* Bindings)
|
||||
{
|
||||
MD5_CTX md5;
|
||||
BYTE* ChannelBindingToken;
|
||||
UINT32 ChannelBindingTokenLength;
|
||||
BYTE* ChannelBindingsHash;
|
||||
UINT32 ChannelBindingsHashLength;
|
||||
SEC_CHANNEL_BINDINGS* ChannelBindings;
|
||||
|
||||
ChannelBindings = Bindings->Bindings;
|
||||
ChannelBindingTokenLength = Bindings->BindingsLength - sizeof(SEC_CHANNEL_BINDINGS);
|
||||
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
|
||||
|
||||
ChannelBindingsHashLength = 16;
|
||||
ChannelBindingsHash = (BYTE*) malloc(ChannelBindingsHashLength);
|
||||
ZeroMemory(ChannelBindingsHash, ChannelBindingsHashLength);
|
||||
|
||||
MD5_Init(&md5);
|
||||
|
||||
tls_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType);
|
||||
tls_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength);
|
||||
tls_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType);
|
||||
tls_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength);
|
||||
tls_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength);
|
||||
|
||||
MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
|
||||
|
||||
MD5_Final(ChannelBindingsHash, &md5);
|
||||
|
||||
return ChannelBindingsHash;
|
||||
}
|
||||
|
||||
#define TLS_SERVER_END_POINT "tls-server-end-point:"
|
||||
|
||||
SecPkgContext_Bindings* tls_get_channel_bindings(X509* cert)
|
||||
{
|
||||
int PrefixLength;
|
||||
BYTE CertificateHash[32];
|
||||
UINT32 CertificateHashLength;
|
||||
BYTE* ChannelBindingToken;
|
||||
UINT32 ChannelBindingTokenLength;
|
||||
SEC_CHANNEL_BINDINGS* ChannelBindings;
|
||||
SecPkgContext_Bindings* ContextBindings;
|
||||
|
||||
ZeroMemory(CertificateHash, sizeof(CertificateHash));
|
||||
X509_digest(cert, EVP_sha256(), CertificateHash, &CertificateHashLength);
|
||||
|
||||
PrefixLength = strlen(TLS_SERVER_END_POINT);
|
||||
ChannelBindingTokenLength = PrefixLength + CertificateHashLength;
|
||||
|
||||
ContextBindings = (SecPkgContext_Bindings*) malloc(sizeof(SecPkgContext_Bindings));
|
||||
ZeroMemory(ContextBindings, sizeof(SecPkgContext_Bindings));
|
||||
|
||||
ContextBindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + ChannelBindingTokenLength;
|
||||
ChannelBindings = (SEC_CHANNEL_BINDINGS*) malloc(ContextBindings->BindingsLength);
|
||||
ZeroMemory(ChannelBindings, ContextBindings->BindingsLength);
|
||||
ContextBindings->Bindings = ChannelBindings;
|
||||
|
||||
ChannelBindings->cbApplicationDataLength = ChannelBindingTokenLength;
|
||||
ChannelBindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS);
|
||||
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
|
||||
|
||||
strcpy((char*) ChannelBindingToken, TLS_SERVER_END_POINT);
|
||||
CopyMemory(&ChannelBindingToken[PrefixLength], CertificateHash, CertificateHashLength);
|
||||
|
||||
return ContextBindings;
|
||||
}
|
||||
|
||||
BOOL tls_connect(rdpTls* tls)
|
||||
{
|
||||
CryptoCert cert;
|
||||
@ -135,6 +216,8 @@ BOOL tls_connect(rdpTls* tls)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tls->Bindings = tls_get_channel_bindings(cert->px509);
|
||||
|
||||
if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
|
||||
{
|
||||
printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n");
|
||||
|
@ -54,7 +54,6 @@ if(WITH_WIN8)
|
||||
endif()
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} dsound)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-server)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
@ -24,7 +24,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr\windows.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#define INITGUID
|
||||
#include <initguid.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#define CINTERFACE
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
@ -38,7 +43,7 @@
|
||||
* Here are some temp things that shall be moved
|
||||
*
|
||||
*/
|
||||
IDirectSoundCapture8 * cap;
|
||||
IDirectSoundCapture8* cap;
|
||||
IDirectSoundCaptureBuffer8* capBuf;
|
||||
DSCBUFFERDESC dscbd;
|
||||
DWORD capturePos;
|
||||
|
387
winpr/include/winpr/crypto.h
Normal file
387
winpr/include/winpr/crypto.h
Normal file
@ -0,0 +1,387 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Cryptography API (CryptoAPI)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 WINPR_CRYPTO_H
|
||||
#define WINPR_CRYPTO_H
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
#else
|
||||
|
||||
#define GET_ALG_CLASS(x) (x & (7 << 13))
|
||||
#define GET_ALG_TYPE(x) (x & (15 << 9))
|
||||
#define GET_ALG_SID(x) (x & (511))
|
||||
|
||||
#define ALG_CLASS_ANY (0)
|
||||
#define ALG_CLASS_SIGNATURE (1 << 13)
|
||||
#define ALG_CLASS_MSG_ENCRYPT (2 << 13)
|
||||
#define ALG_CLASS_DATA_ENCRYPT (3 << 13)
|
||||
#define ALG_CLASS_HASH (4 << 13)
|
||||
#define ALG_CLASS_KEY_EXCHANGE (5 << 13)
|
||||
#define ALG_CLASS_ALL (7 << 13)
|
||||
|
||||
#define ALG_TYPE_ANY (0)
|
||||
#define ALG_TYPE_DSS (1 << 9)
|
||||
#define ALG_TYPE_RSA (2 << 9)
|
||||
#define ALG_TYPE_BLOCK (3 << 9)
|
||||
#define ALG_TYPE_STREAM (4 << 9)
|
||||
#define ALG_TYPE_DH (5 << 9)
|
||||
#define ALG_TYPE_SECURECHANNEL (6 << 9)
|
||||
#define ALG_TYPE_RESERVED7 (7 << 9)
|
||||
|
||||
#define ALG_SID_ANY (0)
|
||||
|
||||
#define ALG_SID_RSA_ANY 0
|
||||
#define ALG_SID_RSA_PKCS 1
|
||||
#define ALG_SID_RSA_MSATWORK 2
|
||||
#define ALG_SID_RSA_ENTRUST 3
|
||||
#define ALG_SID_RSA_PGP 4
|
||||
|
||||
#define ALG_SID_DSS_ANY 0
|
||||
#define ALG_SID_DSS_PKCS 1
|
||||
#define ALG_SID_DSS_DMS 2
|
||||
|
||||
#define ALG_SID_ECDSA 3
|
||||
|
||||
#define ALG_SID_DES 1
|
||||
#define ALG_SID_3DES 3
|
||||
#define ALG_SID_DESX 4
|
||||
#define ALG_SID_IDEA 5
|
||||
#define ALG_SID_CAST 6
|
||||
#define ALG_SID_SAFERSK64 7
|
||||
#define ALG_SID_SAFERSK128 8
|
||||
#define ALG_SID_3DES_112 9
|
||||
#define ALG_SID_CYLINK_MEK 12
|
||||
#define ALG_SID_RC5 13
|
||||
|
||||
#define ALG_SID_AES_128 14
|
||||
#define ALG_SID_AES_192 15
|
||||
#define ALG_SID_AES_256 16
|
||||
#define ALG_SID_AES 17
|
||||
|
||||
#define ALG_SID_SKIPJACK 10
|
||||
#define ALG_SID_TEK 11
|
||||
|
||||
#define CRYPT_MODE_CBCI 6
|
||||
#define CRYPT_MODE_CFBP 7
|
||||
#define CRYPT_MODE_OFBP 8
|
||||
#define CRYPT_MODE_CBCOFM 9
|
||||
#define CRYPT_MODE_CBCOFMI 10
|
||||
|
||||
#define ALG_SID_RC2 2
|
||||
|
||||
#define ALG_SID_RC4 1
|
||||
#define ALG_SID_SEAL 2
|
||||
|
||||
#define ALG_SID_DH_SANDF 1
|
||||
#define ALG_SID_DH_EPHEM 2
|
||||
#define ALG_SID_AGREED_KEY_ANY 3
|
||||
#define ALG_SID_KEA 4
|
||||
|
||||
#define ALG_SID_ECDH 5
|
||||
|
||||
#define ALG_SID_MD2 1
|
||||
#define ALG_SID_MD4 2
|
||||
#define ALG_SID_MD5 3
|
||||
#define ALG_SID_SHA 4
|
||||
#define ALG_SID_SHA1 4
|
||||
#define ALG_SID_MAC 5
|
||||
#define ALG_SID_RIPEMD 6
|
||||
#define ALG_SID_RIPEMD160 7
|
||||
#define ALG_SID_SSL3SHAMD5 8
|
||||
#define ALG_SID_HMAC 9
|
||||
#define ALG_SID_TLS1PRF 10
|
||||
|
||||
#define ALG_SID_HASH_REPLACE_OWF 11
|
||||
|
||||
#define ALG_SID_SHA_256 12
|
||||
#define ALG_SID_SHA_384 13
|
||||
#define ALG_SID_SHA_512 14
|
||||
|
||||
#define ALG_SID_SSL3_MASTER 1
|
||||
#define ALG_SID_SCHANNEL_MASTER_HASH 2
|
||||
#define ALG_SID_SCHANNEL_MAC_KEY 3
|
||||
#define ALG_SID_PCT1_MASTER 4
|
||||
#define ALG_SID_SSL2_MASTER 5
|
||||
#define ALG_SID_TLS1_MASTER 6
|
||||
#define ALG_SID_SCHANNEL_ENC_KEY 7
|
||||
|
||||
#define ALG_SID_ECMQV 1
|
||||
|
||||
#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2)
|
||||
#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4)
|
||||
#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
|
||||
#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA)
|
||||
#define CALG_SHA1 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
|
||||
#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC)
|
||||
#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
|
||||
#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY)
|
||||
|
||||
#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)
|
||||
|
||||
#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
|
||||
#define CALG_DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES)
|
||||
#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES_112)
|
||||
#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES)
|
||||
#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX)
|
||||
#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2)
|
||||
#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4)
|
||||
#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL)
|
||||
#define CALG_DH_SF (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_SANDF)
|
||||
#define CALG_DH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EPHEM)
|
||||
#define CALG_AGREEDKEY_ANY (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_AGREED_KEY_ANY)
|
||||
#define CALG_KEA_KEYX (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_KEA)
|
||||
#define CALG_HUGHES_MD5 (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_MD5)
|
||||
#define CALG_SKIPJACK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_SKIPJACK)
|
||||
#define CALG_TEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_TEK)
|
||||
#define CALG_CYLINK_MEK (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_CYLINK_MEK)
|
||||
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
|
||||
#define CALG_SSL3_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL3_MASTER)
|
||||
#define CALG_SCHANNEL_MASTER_HASH (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MASTER_HASH)
|
||||
#define CALG_SCHANNEL_MAC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MAC_KEY)
|
||||
#define CALG_SCHANNEL_ENC_KEY (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_ENC_KEY)
|
||||
#define CALG_PCT1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_PCT1_MASTER)
|
||||
#define CALG_SSL2_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL2_MASTER)
|
||||
#define CALG_TLS1_MASTER (ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_TLS1_MASTER)
|
||||
#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC5)
|
||||
#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
|
||||
#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)
|
||||
|
||||
#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
|
||||
#define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128)
|
||||
#define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192)
|
||||
#define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256)
|
||||
#define CALG_AES (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES)
|
||||
|
||||
#define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
|
||||
#define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
|
||||
#define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)
|
||||
|
||||
#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)
|
||||
#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
|
||||
#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)
|
||||
|
||||
typedef struct _CRYPTOAPI_BLOB
|
||||
{
|
||||
DWORD cbData;
|
||||
BYTE* pbData;
|
||||
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
|
||||
CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
|
||||
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
|
||||
CERT_NAME_BLOB, *PCERT_NAME_BLOB,
|
||||
CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
|
||||
CERT_BLOB, *PCERT_BLOB,
|
||||
CRL_BLOB, *PCRL_BLOB,
|
||||
DATA_BLOB, *PDATA_BLOB,
|
||||
CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
|
||||
CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
|
||||
CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
|
||||
CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
|
||||
CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;
|
||||
|
||||
typedef struct _CRYPT_ALGORITHM_IDENTIFIER
|
||||
{
|
||||
LPSTR pszObjId;
|
||||
CRYPT_OBJID_BLOB Parameters;
|
||||
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;
|
||||
|
||||
typedef struct _CRYPT_BIT_BLOB
|
||||
{
|
||||
DWORD cbData;
|
||||
BYTE* pbData;
|
||||
DWORD cUnusedBits;
|
||||
} CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;
|
||||
|
||||
typedef struct _CERT_PUBLIC_KEY_INFO
|
||||
{
|
||||
CRYPT_ALGORITHM_IDENTIFIER Algorithm;
|
||||
CRYPT_BIT_BLOB PublicKey;
|
||||
} CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;
|
||||
|
||||
typedef struct _CERT_EXTENSION
|
||||
{
|
||||
LPSTR pszObjId;
|
||||
BOOL fCritical;
|
||||
CRYPT_OBJID_BLOB Value;
|
||||
} CERT_EXTENSION, *PCERT_EXTENSION;
|
||||
typedef const CERT_EXTENSION* PCCERT_EXTENSION;
|
||||
|
||||
typedef struct _CERT_INFO
|
||||
{
|
||||
DWORD dwVersion;
|
||||
CRYPT_INTEGER_BLOB SerialNumber;
|
||||
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
|
||||
CERT_NAME_BLOB Issuer;
|
||||
FILETIME NotBefore;
|
||||
FILETIME NotAfter;
|
||||
CERT_NAME_BLOB Subject;
|
||||
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
|
||||
CRYPT_BIT_BLOB IssuerUniqueId;
|
||||
CRYPT_BIT_BLOB SubjectUniqueId;
|
||||
DWORD cExtension;
|
||||
PCERT_EXTENSION rgExtension;
|
||||
} CERT_INFO, *PCERT_INFO;
|
||||
|
||||
typedef void *HCERTSTORE;
|
||||
typedef ULONG_PTR HCRYPTPROV;
|
||||
typedef ULONG_PTR HCRYPTPROV_LEGACY;
|
||||
|
||||
typedef struct _CERT_CONTEXT
|
||||
{
|
||||
DWORD dwCertEncodingType;
|
||||
BYTE* pbCertEncoded;
|
||||
DWORD cbCertEncoded;
|
||||
PCERT_INFO pCertInfo;
|
||||
HCERTSTORE hCertStore;
|
||||
} CERT_CONTEXT, *PCERT_CONTEXT;
|
||||
typedef const CERT_CONTEXT *PCCERT_CONTEXT;
|
||||
|
||||
#define CERT_ENCODING_TYPE_MASK 0x0000FFFF
|
||||
#define CMSG_ENCODING_TYPE_MASK 0xFFFF0000
|
||||
#define GET_CERT_ENCODING_TYPE(x) (x & CERT_ENCODING_TYPE_MASK)
|
||||
#define GET_CMSG_ENCODING_TYPE(x) (x & CMSG_ENCODING_TYPE_MASK)
|
||||
|
||||
#define CRYPT_ASN_ENCODING 0x00000001
|
||||
#define CRYPT_NDR_ENCODING 0x00000002
|
||||
#define X509_ASN_ENCODING 0x00000001
|
||||
#define X509_NDR_ENCODING 0x00000002
|
||||
#define PKCS_7_ASN_ENCODING 0x00010000
|
||||
#define PKCS_7_NDR_ENCODING 0x00020000
|
||||
|
||||
#define CERT_COMPARE_MASK 0xFFFF
|
||||
#define CERT_COMPARE_SHIFT 16
|
||||
#define CERT_COMPARE_ANY 0
|
||||
#define CERT_COMPARE_SHA1_HASH 1
|
||||
#define CERT_COMPARE_NAME 2
|
||||
#define CERT_COMPARE_ATTR 3
|
||||
#define CERT_COMPARE_MD5_HASH 4
|
||||
#define CERT_COMPARE_PROPERTY 5
|
||||
#define CERT_COMPARE_PUBLIC_KEY 6
|
||||
#define CERT_COMPARE_HASH CERT_COMPARE_SHA1_HASH
|
||||
#define CERT_COMPARE_NAME_STR_A 7
|
||||
#define CERT_COMPARE_NAME_STR_W 8
|
||||
#define CERT_COMPARE_KEY_SPEC 9
|
||||
#define CERT_COMPARE_ENHKEY_USAGE 10
|
||||
#define CERT_COMPARE_CTL_USAGE CERT_COMPARE_ENHKEY_USAGE
|
||||
#define CERT_COMPARE_SUBJECT_CERT 11
|
||||
#define CERT_COMPARE_ISSUER_OF 12
|
||||
#define CERT_COMPARE_EXISTING 13
|
||||
#define CERT_COMPARE_SIGNATURE_HASH 14
|
||||
#define CERT_COMPARE_KEY_IDENTIFIER 15
|
||||
#define CERT_COMPARE_CERT_ID 16
|
||||
#define CERT_COMPARE_CROSS_CERT_DIST_POINTS 17
|
||||
#define CERT_COMPARE_PUBKEY_MD5_HASH 18
|
||||
#define CERT_COMPARE_SUBJECT_INFO_ACCESS 19
|
||||
#define CERT_COMPARE_HASH_STR 20
|
||||
#define CERT_COMPARE_HAS_PRIVATE_KEY 21
|
||||
|
||||
#define CERT_FIND_ANY (CERT_COMPARE_ANY << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_SHA1_HASH (CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_MD5_HASH (CERT_COMPARE_MD5_HASH << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_SIGNATURE_HASH (CERT_COMPARE_SIGNATURE_HASH << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_KEY_IDENTIFIER (CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_HASH CERT_FIND_SHA1_HASH
|
||||
#define CERT_FIND_PROPERTY (CERT_COMPARE_PROPERTY << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_PUBLIC_KEY (CERT_COMPARE_PUBLIC_KEY << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_SUBJECT_NAME (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
|
||||
#define CERT_FIND_SUBJECT_ATTR (CERT_COMPARE_ATTR << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
|
||||
#define CERT_FIND_ISSUER_NAME (CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
|
||||
#define CERT_FIND_ISSUER_ATTR (CERT_COMPARE_ATTR << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
|
||||
#define CERT_FIND_SUBJECT_STR_A (CERT_COMPARE_NAME_STR_A << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
|
||||
#define CERT_FIND_SUBJECT_STR_W (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
|
||||
#define CERT_FIND_SUBJECT_STR CERT_FIND_SUBJECT_STR_W
|
||||
#define CERT_FIND_ISSUER_STR_A (CERT_COMPARE_NAME_STR_A << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
|
||||
#define CERT_FIND_ISSUER_STR_W (CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
|
||||
#define CERT_FIND_ISSUER_STR CERT_FIND_ISSUER_STR_W
|
||||
#define CERT_FIND_KEY_SPEC (CERT_COMPARE_KEY_SPEC << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_ENHKEY_USAGE (CERT_COMPARE_ENHKEY_USAGE << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_CTL_USAGE CERT_FIND_ENHKEY_USAGE
|
||||
#define CERT_FIND_SUBJECT_CERT (CERT_COMPARE_SUBJECT_CERT << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_ISSUER_OF (CERT_COMPARE_ISSUER_OF << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_EXISTING (CERT_COMPARE_EXISTING << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_CERT_ID (CERT_COMPARE_CERT_ID << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_CROSS_CERT_DIST_POINTS (CERT_COMPARE_CROSS_CERT_DIST_POINTS << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_PUBKEY_MD5_HASH (CERT_COMPARE_PUBKEY_MD5_HASH << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_SUBJECT_INFO_ACCESS (CERT_COMPARE_SUBJECT_INFO_ACCESS << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_HASH_STR (CERT_COMPARE_HASH_STR << CERT_COMPARE_SHIFT)
|
||||
#define CERT_FIND_HAS_PRIVATE_KEY (CERT_COMPARE_HAS_PRIVATE_KEY << CERT_COMPARE_SHIFT)
|
||||
|
||||
#define CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG 0x1
|
||||
#define CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG 0x2
|
||||
#define CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG 0x4
|
||||
#define CERT_FIND_NO_ENHKEY_USAGE_FLAG 0x8
|
||||
#define CERT_FIND_OR_ENHKEY_USAGE_FLAG 0x10
|
||||
#define CERT_FIND_VALID_ENHKEY_USAGE_FLAG 0x20
|
||||
#define CERT_FIND_OPTIONAL_CTL_USAGE_FLAG CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG
|
||||
#define CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
|
||||
#define CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG
|
||||
#define CERT_FIND_NO_CTL_USAGE_FLAG CERT_FIND_NO_ENHKEY_USAGE_FLAG
|
||||
#define CERT_FIND_OR_CTL_USAGE_FLAG CERT_FIND_OR_ENHKEY_USAGE_FLAG
|
||||
#define CERT_FIND_VALID_CTL_USAGE_FLAG CERT_FIND_VALID_ENHKEY_USAGE_FLAG
|
||||
|
||||
#define CERT_NAME_EMAIL_TYPE 1
|
||||
#define CERT_NAME_RDN_TYPE 2
|
||||
#define CERT_NAME_ATTR_TYPE 3
|
||||
#define CERT_NAME_SIMPLE_DISPLAY_TYPE 4
|
||||
#define CERT_NAME_FRIENDLY_DISPLAY_TYPE 5
|
||||
#define CERT_NAME_DNS_TYPE 6
|
||||
#define CERT_NAME_URL_TYPE 7
|
||||
#define CERT_NAME_UPN_TYPE 8
|
||||
|
||||
#define CERT_NAME_ISSUER_FLAG 0x1
|
||||
#define CERT_NAME_DISABLE_IE4_UTF8_FLAG 0x00010000
|
||||
|
||||
#define CERT_NAME_SEARCH_ALL_NAMES_FLAG 0x2
|
||||
|
||||
WINPR_API HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubsystemProtocol);
|
||||
WINPR_API HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubsystemProtocol);
|
||||
|
||||
WINPR_API BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CertOpenSystemStore CertOpenSystemStoreW
|
||||
#else
|
||||
#define CertOpenSystemStore CertOpenSystemStoreA
|
||||
#endif
|
||||
|
||||
WINPR_API PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType,
|
||||
DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext);
|
||||
|
||||
WINPR_API PCCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
|
||||
|
||||
DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, void* pvTypePara, LPWSTR pszNameString, DWORD cchNameString);
|
||||
DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, void* pvTypePara, LPSTR pszNameString, DWORD cchNameString);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CertGetNameString CertGetNameStringW
|
||||
#else
|
||||
#define CertGetNameString CertGetNameStringA
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_CRYPTO_H */
|
||||
|
287
winpr/include/winpr/schannel.h
Normal file
287
winpr/include/winpr/schannel.h
Normal file
@ -0,0 +1,287 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Schannel Security Package
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 WINPR_SSPI_SCHANNEL_H
|
||||
#define WINPR_SSPI_SCHANNEL_H
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <schannel.h>
|
||||
|
||||
#else
|
||||
|
||||
#define SCHANNEL_NAME_A "Schannel"
|
||||
#define SCHANNEL_NAME_W L"Schannel"
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define SCHANNEL_NAME SCHANNEL_NAME_W
|
||||
#else
|
||||
#define SCHANNEL_NAME SCHANNEL_NAME_A
|
||||
#endif
|
||||
|
||||
#define SECPKG_ATTR_SUPPORTED_ALGS 86
|
||||
#define SECPKG_ATTR_CIPHER_STRENGTHS 87
|
||||
#define SECPKG_ATTR_SUPPORTED_PROTOCOLS 88
|
||||
|
||||
typedef struct _SecPkgCred_SupportedAlgs
|
||||
{
|
||||
DWORD cSupportedAlgs;
|
||||
ALG_ID* palgSupportedAlgs;
|
||||
} SecPkgCred_SupportedAlgs, *PSecPkgCred_SupportedAlgs;
|
||||
|
||||
typedef struct _SecPkgCred_CipherStrengths
|
||||
{
|
||||
DWORD dwMinimumCipherStrength;
|
||||
DWORD dwMaximumCipherStrength;
|
||||
} SecPkgCred_CipherStrengths, *PSecPkgCred_CipherStrengths;
|
||||
|
||||
typedef struct _SecPkgCred_SupportedProtocols
|
||||
{
|
||||
DWORD grbitProtocol;
|
||||
} SecPkgCred_SupportedProtocols, *PSecPkgCred_SupportedProtocols;
|
||||
|
||||
enum eTlsSignatureAlgorithm
|
||||
{
|
||||
TlsSignatureAlgorithm_Anonymous = 0,
|
||||
TlsSignatureAlgorithm_Rsa = 1,
|
||||
TlsSignatureAlgorithm_Dsa = 2,
|
||||
TlsSignatureAlgorithm_Ecdsa = 3
|
||||
};
|
||||
|
||||
enum eTlsHashAlgorithm
|
||||
{
|
||||
TlsHashAlgorithm_None = 0,
|
||||
TlsHashAlgorithm_Md5 = 1,
|
||||
TlsHashAlgorithm_Sha1 = 2,
|
||||
TlsHashAlgorithm_Sha224 = 3,
|
||||
TlsHashAlgorithm_Sha256 = 4,
|
||||
TlsHashAlgorithm_Sha384 = 5,
|
||||
TlsHashAlgorithm_Sha512 = 6
|
||||
};
|
||||
|
||||
#define SCH_CRED_V1 0x00000001
|
||||
#define SCH_CRED_V2 0x00000002
|
||||
#define SCH_CRED_VERSION 0x00000002
|
||||
#define SCH_CRED_V3 0x00000003
|
||||
#define SCHANNEL_CRED_VERSION 0x00000004
|
||||
|
||||
struct _HMAPPER;
|
||||
|
||||
typedef struct _SCHANNEL_CRED
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD cCreds;
|
||||
PCCERT_CONTEXT* paCred;
|
||||
HCERTSTORE hRootStore;
|
||||
|
||||
DWORD cMappers;
|
||||
struct _HMAPPER **aphMappers;
|
||||
|
||||
DWORD cSupportedAlgs;
|
||||
ALG_ID* palgSupportedAlgs;
|
||||
|
||||
DWORD grbitEnabledProtocols;
|
||||
DWORD dwMinimumCipherStrength;
|
||||
DWORD dwMaximumCipherStrength;
|
||||
DWORD dwSessionLifespan;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCredFormat;
|
||||
} SCHANNEL_CRED, *PSCHANNEL_CRED;
|
||||
|
||||
#define SCH_CRED_FORMAT_CERT_CONTEXT 0x00000000
|
||||
#define SCH_CRED_FORMAT_CERT_HASH 0x00000001
|
||||
#define SCH_CRED_FORMAT_CERT_HASH_STORE 0x00000002
|
||||
|
||||
#define SCH_CRED_MAX_STORE_NAME_SIZE 128
|
||||
#define SCH_CRED_MAX_SUPPORTED_ALGS 256
|
||||
#define SCH_CRED_MAX_SUPPORTED_CERTS 100
|
||||
|
||||
typedef struct _SCHANNEL_CERT_HASH
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwFlags;
|
||||
HCRYPTPROV hProv;
|
||||
BYTE ShaHash[20];
|
||||
} SCHANNEL_CERT_HASH, *PSCHANNEL_CERT_HASH;
|
||||
|
||||
typedef struct _SCHANNEL_CERT_HASH_STORE
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwFlags;
|
||||
HCRYPTPROV hProv;
|
||||
BYTE ShaHash[20];
|
||||
WCHAR pwszStoreName[SCH_CRED_MAX_STORE_NAME_SIZE];
|
||||
} SCHANNEL_CERT_HASH_STORE, *PSCHANNEL_CERT_HASH_STORE;
|
||||
|
||||
#define SCH_MACHINE_CERT_HASH 0x00000001
|
||||
|
||||
#define SCH_CRED_NO_SYSTEM_MAPPER 0x00000002
|
||||
#define SCH_CRED_NO_SERVERNAME_CHECK 0x00000004
|
||||
#define SCH_CRED_MANUAL_CRED_VALIDATION 0x00000008
|
||||
#define SCH_CRED_NO_DEFAULT_CREDS 0x00000010
|
||||
#define SCH_CRED_AUTO_CRED_VALIDATION 0x00000020
|
||||
#define SCH_CRED_USE_DEFAULT_CREDS 0x00000040
|
||||
#define SCH_CRED_DISABLE_RECONNECTS 0x00000080
|
||||
|
||||
#define SCH_CRED_REVOCATION_CHECK_END_CERT 0x00000100
|
||||
#define SCH_CRED_REVOCATION_CHECK_CHAIN 0x00000200
|
||||
#define SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x00000400
|
||||
#define SCH_CRED_IGNORE_NO_REVOCATION_CHECK 0x00000800
|
||||
#define SCH_CRED_IGNORE_REVOCATION_OFFLINE 0x00001000
|
||||
|
||||
#define SCH_CRED_RESTRICTED_ROOTS 0x00002000
|
||||
#define SCH_CRED_REVOCATION_CHECK_CACHE_ONLY 0x00004000
|
||||
#define SCH_CRED_CACHE_ONLY_URL_RETRIEVAL 0x00008000
|
||||
|
||||
#define SCH_CRED_MEMORY_STORE_CERT 0x00010000
|
||||
|
||||
#define SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE 0x00020000
|
||||
|
||||
#define SCH_SEND_ROOT_CERT 0x00040000
|
||||
#define SCH_CRED_SNI_CREDENTIAL 0x00080000
|
||||
#define SCH_CRED_SNI_ENABLE_OCSP 0x00100000
|
||||
#define SCH_SEND_AUX_RECORD 0x00200000
|
||||
|
||||
#define SCHANNEL_RENEGOTIATE 0
|
||||
#define SCHANNEL_SHUTDOWN 1
|
||||
#define SCHANNEL_ALERT 2
|
||||
#define SCHANNEL_SESSION 3
|
||||
|
||||
typedef struct _SCHANNEL_ALERT_TOKEN
|
||||
{
|
||||
DWORD dwTokenType;
|
||||
DWORD dwAlertType;
|
||||
DWORD dwAlertNumber;
|
||||
} SCHANNEL_ALERT_TOKEN;
|
||||
|
||||
#define TLS1_ALERT_WARNING 1
|
||||
#define TLS1_ALERT_FATAL 2
|
||||
|
||||
#define TLS1_ALERT_CLOSE_NOTIFY 0
|
||||
#define TLS1_ALERT_UNEXPECTED_MESSAGE 10
|
||||
#define TLS1_ALERT_BAD_RECORD_MAC 20
|
||||
#define TLS1_ALERT_DECRYPTION_FAILED 21
|
||||
#define TLS1_ALERT_RECORD_OVERFLOW 22
|
||||
#define TLS1_ALERT_DECOMPRESSION_FAIL 30
|
||||
#define TLS1_ALERT_HANDSHAKE_FAILURE 40
|
||||
#define TLS1_ALERT_BAD_CERTIFICATE 42
|
||||
#define TLS1_ALERT_UNSUPPORTED_CERT 43
|
||||
#define TLS1_ALERT_CERTIFICATE_REVOKED 44
|
||||
#define TLS1_ALERT_CERTIFICATE_EXPIRED 45
|
||||
#define TLS1_ALERT_CERTIFICATE_UNKNOWN 46
|
||||
#define TLS1_ALERT_ILLEGAL_PARAMETER 47
|
||||
#define TLS1_ALERT_UNKNOWN_CA 48
|
||||
#define TLS1_ALERT_ACCESS_DENIED 49
|
||||
#define TLS1_ALERT_DECODE_ERROR 50
|
||||
#define TLS1_ALERT_DECRYPT_ERROR 51
|
||||
#define TLS1_ALERT_EXPORT_RESTRICTION 60
|
||||
#define TLS1_ALERT_PROTOCOL_VERSION 70
|
||||
#define TLS1_ALERT_INSUFFIENT_SECURITY 71
|
||||
#define TLS1_ALERT_INTERNAL_ERROR 80
|
||||
#define TLS1_ALERT_USER_CANCELED 90
|
||||
#define TLS1_ALERT_NO_RENEGOTIATION 100
|
||||
#define TLS1_ALERT_UNSUPPORTED_EXT 110
|
||||
|
||||
#define SSL_SESSION_ENABLE_RECONNECTS 1
|
||||
#define SSL_SESSION_DISABLE_RECONNECTS 2
|
||||
|
||||
typedef struct _SCHANNEL_SESSION_TOKEN
|
||||
{
|
||||
DWORD dwTokenType;
|
||||
DWORD dwFlags;
|
||||
} SCHANNEL_SESSION_TOKEN;
|
||||
|
||||
typedef struct _SCHANNEL_CLIENT_SIGNATURE
|
||||
{
|
||||
DWORD cbLength;
|
||||
ALG_ID aiHash;
|
||||
DWORD cbHash;
|
||||
BYTE HashValue[36];
|
||||
BYTE CertThumbprint[20];
|
||||
} SCHANNEL_CLIENT_SIGNATURE, *PSCHANNEL_CLIENT_SIGNATURE;
|
||||
|
||||
#define SP_PROT_SSL3_SERVER 0x00000010
|
||||
#define SP_PROT_SSL3_CLIENT 0x00000020
|
||||
#define SP_PROT_SSL3 (SP_PROT_SSL3_SERVER | SP_PROT_SSL3_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_SERVER 0x00000040
|
||||
#define SP_PROT_TLS1_CLIENT 0x00000080
|
||||
#define SP_PROT_TLS1 (SP_PROT_TLS1_SERVER | SP_PROT_TLS1_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL3TLS1_CLIENTS (SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT)
|
||||
#define SP_PROT_SSL3TLS1_SERVERS (SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER)
|
||||
#define SP_PROT_SSL3TLS1 (SP_PROT_SSL3 | SP_PROT_TLS1)
|
||||
|
||||
#define SP_PROT_UNI_SERVER 0x40000000
|
||||
#define SP_PROT_UNI_CLIENT 0x80000000
|
||||
#define SP_PROT_UNI (SP_PROT_UNI_SERVER | SP_PROT_UNI_CLIENT)
|
||||
|
||||
#define SP_PROT_ALL 0xFFFFFFFF
|
||||
#define SP_PROT_NONE 0
|
||||
#define SP_PROT_CLIENTS (SP_PROT_SSL3_CLIENT | SP_PROT_UNI_CLIENT | SP_PROT_TLS1_CLIENT)
|
||||
#define SP_PROT_SERVERS (SP_PROT_SSL3_SERVER | SP_PROT_UNI_SERVER | SP_PROT_TLS1_SERVER)
|
||||
|
||||
#define SP_PROT_TLS1_0_SERVER SP_PROT_TLS1_SERVER
|
||||
#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
|
||||
#define SP_PROT_TLS1_0 (SP_PROT_TLS1_0_SERVER | SP_PROT_TLS1_0_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_1_SERVER 0x00000100
|
||||
#define SP_PROT_TLS1_1_CLIENT 0x00000200
|
||||
#define SP_PROT_TLS1_1 (SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_1_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_2_SERVER 0x00000400
|
||||
#define SP_PROT_TLS1_2_CLIENT 0x00000800
|
||||
#define SP_PROT_TLS1_2 (SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_2_CLIENT)
|
||||
|
||||
#define SP_PROT_DTLS_SERVER 0x00010000
|
||||
#define SP_PROT_DTLS_CLIENT 0x00020000
|
||||
#define SP_PROT_DTLS (SP_PROT_DTLS_SERVER | SP_PROT_DTLS_CLIENT)
|
||||
|
||||
#define SP_PROT_DTLS1_0_SERVER SP_PROT_DTLS_SERVER
|
||||
#define SP_PROT_DTLS1_0_CLIENT SP_PROT_DTLS_CLIENT
|
||||
#define SP_PROT_DTLS1_0 (SP_PROT_DTLS1_0_SERVER | SP_PROT_DTLS1_0_CLIENT)
|
||||
|
||||
#define SP_PROT_DTLS1_X_SERVER SP_PROT_DTLS1_0_SERVER
|
||||
|
||||
#define SP_PROT_DTLS1_X_CLIENT SP_PROT_DTLS1_0_CLIENT
|
||||
|
||||
#define SP_PROT_DTLS1_X (SP_PROT_DTLS1_X_SERVER | SP_PROT_DTLS1_X_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_1PLUS_SERVER (SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER)
|
||||
#define SP_PROT_TLS1_1PLUS_CLIENT (SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_1PLUS (SP_PROT_TLS1_1PLUS_SERVER | SP_PROT_TLS1_1PLUS_CLIENT)
|
||||
|
||||
#define SP_PROT_TLS1_X_SERVER (SP_PROT_TLS1_0_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_2_SERVER)
|
||||
#define SP_PROT_TLS1_X_CLIENT (SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT)
|
||||
#define SP_PROT_TLS1_X (SP_PROT_TLS1_X_SERVER | SP_PROT_TLS1_X_CLIENT)
|
||||
|
||||
#define SP_PROT_SSL3TLS1_X_CLIENTS (SP_PROT_TLS1_X_CLIENT | SP_PROT_SSL3_CLIENT)
|
||||
#define SP_PROT_SSL3TLS1_X_SERVERS (SP_PROT_TLS1_X_SERVER | SP_PROT_SSL3_SERVER)
|
||||
#define SP_PROT_SSL3TLS1_X (SP_PROT_SSL3 | SP_PROT_TLS1_X)
|
||||
|
||||
#define SP_PROT_X_CLIENTS (SP_PROT_CLIENTS | SP_PROT_TLS1_X_CLIENT | SP_PROT_DTLS1_X_CLIENT)
|
||||
#define SP_PROT_X_SERVERS (SP_PROT_SERVERS | SP_PROT_TLS1_X_SERVER | SP_PROT_DTLS1_X_SERVER )
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_SSPI_SCHANNEL_H */
|
@ -635,12 +635,20 @@ struct _SecHandle
|
||||
ULONG_PTR dwUpper;
|
||||
};
|
||||
typedef struct _SecHandle SecHandle;
|
||||
typedef SecHandle* PSecHandle;
|
||||
|
||||
typedef SecHandle CredHandle;
|
||||
typedef CredHandle* PCredHandle;
|
||||
typedef SecHandle CtxtHandle;
|
||||
typedef CtxtHandle* PCtxtHandle;
|
||||
|
||||
#define SecInvalidateHandle(x) \
|
||||
((PSecHandle)(x))->dwLower = ((PSecHandle)(x))->dwUpper = ((ULONG_PTR)((INT_PTR) - 1));
|
||||
|
||||
#define SecIsValidHandle(x) \
|
||||
((((PSecHandle)(x))->dwLower != ((ULONG_PTR)((INT_PTR) - 1))) && \
|
||||
(((PSecHandle) (x))->dwUpper != ((ULONG_PTR)((INT_PTR) - 1))))
|
||||
|
||||
#endif
|
||||
|
||||
#define SECBUFFER_VERSION 0
|
||||
|
49
winpr/libwinpr/crypto/CMakeLists.txt
Normal file
49
winpr/libwinpr/crypto/CMakeLists.txt
Normal file
@ -0,0 +1,49 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-crypto cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
set(MODULE_NAME "winpr-crypto")
|
||||
set(MODULE_PREFIX "WINPR_CRYPTO")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
crypto.c
|
||||
cert.c)
|
||||
|
||||
if(MSVC AND (NOT MONOLITHIC_BUILD))
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)
|
||||
endif()
|
||||
|
||||
add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT"
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
SOURCES ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib")
|
||||
|
||||
if(WIN32)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} crypt32)
|
||||
endif()
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
|
||||
else()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
9
winpr/libwinpr/crypto/ModuleOptions.cmake
Normal file
9
winpr/libwinpr/crypto/ModuleOptions.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
set(MINWIN_LAYER "1")
|
||||
set(MINWIN_GROUP "core")
|
||||
set(MINWIN_MAJOR_VERSION "1")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "crypto")
|
||||
set(MINWIN_LONG_NAME "Cryptography API (CryptoAPI)")
|
||||
set(MODULE_LIBRARY_NAME "crypt32")
|
||||
|
194
winpr/libwinpr/crypto/cert.c
Normal file
194
winpr/libwinpr/crypto/cert.c
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Cryptography API (CryptoAPI)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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/crypto.h>
|
||||
|
||||
/**
|
||||
* CertOpenStore
|
||||
* CertCloseStore
|
||||
* CertControlStore
|
||||
* CertDuplicateStore
|
||||
* CertSaveStore
|
||||
* CertRegisterPhysicalStore
|
||||
* CertRegisterSystemStore
|
||||
* CertAddStoreToCollection
|
||||
* CertRemoveStoreFromCollection
|
||||
* CertOpenSystemStoreA
|
||||
* CertOpenSystemStoreW
|
||||
* CertEnumPhysicalStore
|
||||
* CertEnumSystemStore
|
||||
* CertEnumSystemStoreLocation
|
||||
* CertSetStoreProperty
|
||||
* CertUnregisterPhysicalStore
|
||||
* CertUnregisterSystemStore
|
||||
*
|
||||
* CertAddCertificateContextToStore
|
||||
* CertAddCertificateLinkToStore
|
||||
* CertAddCRLContextToStore
|
||||
* CertAddCRLLinkToStore
|
||||
* CertAddCTLContextToStore
|
||||
* CertAddCTLLinkToStore
|
||||
* CertAddEncodedCertificateToStore
|
||||
* CertAddEncodedCertificateToSystemStoreA
|
||||
* CertAddEncodedCertificateToSystemStoreW
|
||||
* CertAddEncodedCRLToStore
|
||||
* CertAddEncodedCTLToStore
|
||||
* CertAddSerializedElementToStore
|
||||
* CertDeleteCertificateFromStore
|
||||
* CertDeleteCRLFromStore
|
||||
* CertDeleteCTLFromStore
|
||||
* CertGetCRLFromStore
|
||||
* CertEnumCertificatesInStore
|
||||
* CertEnumCRLsInStore
|
||||
* CertEnumCTLsInStore
|
||||
* CertFindCertificateInStore
|
||||
* CertFindChainInStore
|
||||
* CertFindCRLInStore
|
||||
* CertFindCTLInStore
|
||||
* CertGetIssuerCertificateFromStore
|
||||
* CertGetStoreProperty
|
||||
* CertGetSubjectCertificateFromStore
|
||||
* CertSerializeCertificateStoreElement
|
||||
* CertSerializeCRLStoreElement
|
||||
* CertSerializeCTLStoreElement
|
||||
*
|
||||
* CertAddEnhancedKeyUsageIdentifier
|
||||
* CertAddRefServerOcspResponse
|
||||
* CertAddRefServerOcspResponseContext
|
||||
* CertAlgIdToOID
|
||||
* CertCloseServerOcspResponse
|
||||
* CertCompareCertificate
|
||||
* CertCompareCertificateName
|
||||
* CertCompareIntegerBlob
|
||||
* CertComparePublicKeyInfo
|
||||
* CertCreateCertificateChainEngine
|
||||
* CertCreateCertificateContext
|
||||
* CertCreateContext
|
||||
* CertCreateCRLContext
|
||||
* CertCreateCTLContext
|
||||
* CertCreateCTLEntryFromCertificateContextProperties
|
||||
* CertCreateSelfSignCertificate
|
||||
* CertDuplicateCertificateChain
|
||||
* CertDuplicateCertificateContext
|
||||
* CertDuplicateCRLContext
|
||||
* CertDuplicateCTLContext
|
||||
* CertEnumCertificateContextProperties
|
||||
* CertEnumCRLContextProperties
|
||||
* CertEnumCTLContextProperties
|
||||
* CertEnumSubjectInSortedCTL
|
||||
* CertFindAttribute
|
||||
* CertFindCertificateInCRL
|
||||
* CertFindExtension
|
||||
* CertFindRDNAttr
|
||||
* CertFindSubjectInCTL
|
||||
* CertFindSubjectInSortedCTL
|
||||
* CertFreeCertificateChain
|
||||
* CertFreeCertificateChainEngine
|
||||
* CertFreeCertificateChainList
|
||||
* CertFreeCertificateContext
|
||||
* CertFreeCRLContext
|
||||
* CertFreeCTLContext
|
||||
* CertFreeServerOcspResponseContext
|
||||
* CertGetCertificateChain
|
||||
* CertGetCertificateContextProperty
|
||||
* CertGetCRLContextProperty
|
||||
* CertGetCTLContextProperty
|
||||
* CertGetEnhancedKeyUsage
|
||||
* CertGetIntendedKeyUsage
|
||||
* CertGetNameStringA
|
||||
* CertGetNameStringW
|
||||
* CertGetPublicKeyLength
|
||||
* CertGetServerOcspResponseContext
|
||||
* CertGetValidUsages
|
||||
* CertIsRDNAttrsInCertificateName
|
||||
* CertIsStrongHashToSign
|
||||
* CertIsValidCRLForCertificate
|
||||
* CertNameToStrA
|
||||
* CertNameToStrW
|
||||
* CertOIDToAlgId
|
||||
* CertOpenServerOcspResponse
|
||||
* CertRDNValueToStrA
|
||||
* CertRDNValueToStrW
|
||||
* CertRemoveEnhancedKeyUsageIdentifier
|
||||
* CertResyncCertificateChainEngine
|
||||
* CertRetrieveLogoOrBiometricInfo
|
||||
* CertSelectCertificateChains
|
||||
* CertSetCertificateContextPropertiesFromCTLEntry
|
||||
* CertSetCertificateContextProperty
|
||||
* CertSetCRLContextProperty
|
||||
* CertSetCTLContextProperty
|
||||
* CertSetEnhancedKeyUsage
|
||||
* CertStrToNameA
|
||||
* CertStrToNameW
|
||||
* CertVerifyCertificateChainPolicy
|
||||
* CertVerifyCRLRevocation
|
||||
* CertVerifyCRLTimeValidity
|
||||
* CertVerifyCTLUsage
|
||||
* CertVerifyRevocation
|
||||
* CertVerifySubjectCertificateContext
|
||||
* CertVerifyTimeValidity
|
||||
* CertVerifyValidityNesting
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubsystemProtocol)
|
||||
{
|
||||
return (HCERTSTORE) 1;
|
||||
}
|
||||
|
||||
HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubsystemProtocol)
|
||||
{
|
||||
return CertOpenSystemStoreW(hProv, NULL);
|
||||
}
|
||||
|
||||
BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType,
|
||||
DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext)
|
||||
{
|
||||
return (PCCERT_CONTEXT) 1;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext)
|
||||
{
|
||||
return (PCCERT_CONTEXT) NULL;
|
||||
}
|
||||
|
||||
DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, void* pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
||||
DWORD dwFlags, void* pvTypePara, LPSTR pszNameString, DWORD cchNameString)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
149
winpr/libwinpr/crypto/crypto.c
Normal file
149
winpr/libwinpr/crypto/crypto.c
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Cryptography API (CryptoAPI)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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/crypto.h>
|
||||
|
||||
/**
|
||||
* CryptAcquireCertificatePrivateKey
|
||||
* CryptBinaryToStringA
|
||||
* CryptBinaryToStringW
|
||||
* CryptCloseAsyncHandle
|
||||
* CryptCreateAsyncHandle
|
||||
* CryptCreateKeyIdentifierFromCSP
|
||||
* CryptDecodeMessage
|
||||
* CryptDecodeObject
|
||||
* CryptDecodeObjectEx
|
||||
* CryptDecryptAndVerifyMessageSignature
|
||||
* CryptDecryptMessage
|
||||
* CryptEncodeObject
|
||||
* CryptEncodeObjectEx
|
||||
* CryptEncryptMessage
|
||||
* CryptEnumKeyIdentifierProperties
|
||||
* CryptEnumOIDFunction
|
||||
* CryptEnumOIDInfo
|
||||
* CryptExportPKCS8
|
||||
* CryptExportPublicKeyInfo
|
||||
* CryptExportPublicKeyInfoEx
|
||||
* CryptExportPublicKeyInfoFromBCryptKeyHandle
|
||||
* CryptFindCertificateKeyProvInfo
|
||||
* CryptFindLocalizedName
|
||||
* CryptFindOIDInfo
|
||||
* CryptFormatObject
|
||||
* CryptFreeOIDFunctionAddress
|
||||
* CryptGetAsyncParam
|
||||
* CryptGetDefaultOIDDllList
|
||||
* CryptGetDefaultOIDFunctionAddress
|
||||
* CryptGetKeyIdentifierProperty
|
||||
* CryptGetMessageCertificates
|
||||
* CryptGetMessageSignerCount
|
||||
* CryptGetOIDFunctionAddress
|
||||
* CryptGetOIDFunctionValue
|
||||
* CryptHashCertificate
|
||||
* CryptHashCertificate2
|
||||
* CryptHashMessage
|
||||
* CryptHashPublicKeyInfo
|
||||
* CryptHashToBeSigned
|
||||
* CryptImportPKCS8
|
||||
* CryptImportPublicKeyInfo
|
||||
* CryptImportPublicKeyInfoEx
|
||||
* CryptImportPublicKeyInfoEx2
|
||||
* CryptInitOIDFunctionSet
|
||||
* CryptInstallDefaultContext
|
||||
* CryptInstallOIDFunctionAddress
|
||||
* CryptLoadSip
|
||||
* CryptMemAlloc
|
||||
* CryptMemFree
|
||||
* CryptMemRealloc
|
||||
* CryptMsgCalculateEncodedLength
|
||||
* CryptMsgClose
|
||||
* CryptMsgControl
|
||||
* CryptMsgCountersign
|
||||
* CryptMsgCountersignEncoded
|
||||
* CryptMsgDuplicate
|
||||
* CryptMsgEncodeAndSignCTL
|
||||
* CryptMsgGetAndVerifySigner
|
||||
* CryptMsgGetParam
|
||||
* CryptMsgOpenToDecode
|
||||
* CryptMsgOpenToEncode
|
||||
* CryptMsgSignCTL
|
||||
* CryptMsgUpdate
|
||||
* CryptMsgVerifyCountersignatureEncoded
|
||||
* CryptMsgVerifyCountersignatureEncodedEx
|
||||
* CryptProtectData
|
||||
* CryptProtectMemory
|
||||
* CryptQueryObject
|
||||
* CryptRegisterDefaultOIDFunction
|
||||
* CryptRegisterOIDFunction
|
||||
* CryptRegisterOIDInfo
|
||||
* CryptRetrieveTimeStamp
|
||||
* CryptSetAsyncParam
|
||||
* CryptSetKeyIdentifierProperty
|
||||
* CryptSetOIDFunctionValue
|
||||
* CryptSignAndEncodeCertificate
|
||||
* CryptSignAndEncryptMessage
|
||||
* CryptSignCertificate
|
||||
* CryptSignMessage
|
||||
* CryptSignMessageWithKey
|
||||
* CryptSIPAddProvider
|
||||
* CryptSIPCreateIndirectData
|
||||
* CryptSIPGetCaps
|
||||
* CryptSIPGetSignedDataMsg
|
||||
* CryptSIPLoad
|
||||
* CryptSIPPutSignedDataMsg
|
||||
* CryptSIPRemoveProvider
|
||||
* CryptSIPRemoveSignedDataMsg
|
||||
* CryptSIPRetrieveSubjectGuid
|
||||
* CryptSIPRetrieveSubjectGuidForCatalogFile
|
||||
* CryptSIPVerifyIndirectData
|
||||
* CryptStringToBinaryA
|
||||
* CryptStringToBinaryW
|
||||
* CryptUninstallDefaultContext
|
||||
* CryptUnprotectData
|
||||
* CryptUnprotectMemory
|
||||
* CryptUnregisterDefaultOIDFunction
|
||||
* CryptUnregisterOIDFunction
|
||||
* CryptUnregisterOIDInfo
|
||||
* CryptUpdateProtectedState
|
||||
* CryptVerifyCertificateSignature
|
||||
* CryptVerifyCertificateSignatureEx
|
||||
* CryptVerifyDetachedMessageHash
|
||||
* CryptVerifyDetachedMessageSignature
|
||||
* CryptVerifyMessageHash
|
||||
* CryptVerifyMessageSignature
|
||||
* CryptVerifyMessageSignatureWithKey
|
||||
* CryptVerifyTimeStampSignature
|
||||
* DbgInitOSS
|
||||
* DbgPrintf
|
||||
* PFXExportCertStore
|
||||
* PFXExportCertStore2
|
||||
* PFXExportCertStoreEx
|
||||
* PFXImportCertStore
|
||||
* PFXIsPFXBlob
|
||||
* PFXVerifyPassword
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
|
||||
|
||||
#endif
|
3
winpr/libwinpr/crypto/module.def
Normal file
3
winpr/libwinpr/crypto/module.def
Normal file
@ -0,0 +1,3 @@
|
||||
LIBRARY "libwinpr-crypto"
|
||||
EXPORTS
|
||||
|
3
winpr/libwinpr/crypto/test/.gitignore
vendored
Normal file
3
winpr/libwinpr/crypto/test/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
TestCrypto
|
||||
TestCrypto.c
|
||||
|
35
winpr/libwinpr/crypto/test/CMakeLists.txt
Normal file
35
winpr/libwinpr/crypto/test/CMakeLists.txt
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
set(MODULE_NAME "TestCrypto")
|
||||
set(MODULE_PREFIX "TEST_CRYPTO")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestCertEnumCertificatesInStore.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
if(WIN32)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} secur32 crypt32 cryptui)
|
||||
endif()
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-crypto winpr-utils)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
|
66
winpr/libwinpr/crypto/test/TestCertEnumCertificatesInStore.c
Normal file
66
winpr/libwinpr/crypto/test/TestCertEnumCertificatesInStore.c
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
//#define WITH_CRYPTUI 1
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CRYPTUI
|
||||
#include <cryptuiapi.h>
|
||||
#endif
|
||||
|
||||
int TestCertEnumCertificatesInStore(int argc, char* argv[])
|
||||
{
|
||||
int index;
|
||||
DWORD status;
|
||||
LPTSTR pszNameString;
|
||||
HCERTSTORE hCertStore = NULL;
|
||||
PCCERT_CONTEXT pCertContext = NULL;
|
||||
|
||||
/**
|
||||
* System Store Locations:
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa388136/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Requires elevated rights:
|
||||
* hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, _T("Remote Desktop"));
|
||||
*/
|
||||
|
||||
hCertStore = CertOpenSystemStore((HCRYPTPROV_LEGACY) NULL, _T("MY"));
|
||||
// hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("MY"));
|
||||
|
||||
if (!hCertStore)
|
||||
{
|
||||
printf("Failed to open system store\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
|
||||
while ((pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)))
|
||||
{
|
||||
status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
|
||||
|
||||
pszNameString = (LPTSTR) malloc(status * sizeof(TCHAR));
|
||||
status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, status);
|
||||
|
||||
_tprintf(_T("Certificate #%d: %s\n"), index++, pszNameString);
|
||||
|
||||
#ifdef WITH_CRYPTUI
|
||||
CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pCertContext, NULL, NULL, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!CertCloseStore(hCertStore, 0))
|
||||
{
|
||||
printf("Failed to close system store\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-thread cmake build script
|
||||
# libwinpr-pool cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
|
@ -33,6 +33,8 @@ set(${MODULE_PREFIX}_NEGOTIATE_SRCS
|
||||
Negotiate/negotiate.h)
|
||||
|
||||
set(${MODULE_PREFIX}_SCHANNEL_SRCS
|
||||
Schannel/schannel_openssl.c
|
||||
Schannel/schannel_openssl.h
|
||||
Schannel/schannel.c
|
||||
Schannel/schannel.h)
|
||||
|
||||
@ -79,7 +81,7 @@ endif()
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-sysinfo winpr-registry winpr-utils)
|
||||
MODULES winpr-crt winpr-sysinfo winpr-registry winpr-crypto winpr-utils)
|
||||
|
||||
if(MONOLITHIC_BUILD)
|
||||
set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
@ -133,7 +133,7 @@ NTLM_CONTEXT* ntlm_ContextNew()
|
||||
* Extended Protection is enabled by default in Windows 7,
|
||||
* but enabling it in WinPR breaks TS Gateway at this point
|
||||
*/
|
||||
context->SuppressExtendedProtection = TRUE;
|
||||
context->SuppressExtendedProtection = FALSE;
|
||||
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\LSA"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||
|
||||
@ -416,8 +416,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredenti
|
||||
NTLM_CONTEXT* context;
|
||||
SECURITY_STATUS status;
|
||||
CREDENTIALS* credentials;
|
||||
PSecBuffer input_buffer;
|
||||
PSecBuffer output_buffer;
|
||||
PSecBuffer input_buffer = NULL;
|
||||
PSecBuffer output_buffer = NULL;
|
||||
PSecBuffer channel_bindings = NULL;
|
||||
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
@ -478,6 +479,18 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredenti
|
||||
if (input_buffer->cbBuffer < 1)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (pInput->cBuffers > 1)
|
||||
{
|
||||
if (pInput->pBuffers[1].BufferType == SECBUFFER_CHANNEL_BINDINGS)
|
||||
channel_bindings = &pInput->pBuffers[1];
|
||||
}
|
||||
|
||||
if (channel_bindings)
|
||||
{
|
||||
context->Bindings.BindingsLength = channel_bindings->cbBuffer;
|
||||
context->Bindings.Bindings = (SEC_CHANNEL_BINDINGS*) channel_bindings->pvBuffer;
|
||||
}
|
||||
|
||||
if (context->state == NTLM_STATE_CHALLENGE)
|
||||
{
|
||||
status = ntlm_read_ChallengeMessage(context, input_buffer);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
@ -242,7 +243,7 @@ struct _NTLM_CONTEXT
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
BYTE* ChannelBindingToken;
|
||||
BYTE ChannelBindingsHash[16];
|
||||
SecPkgContext_Bindings EndpointBindings;
|
||||
SecPkgContext_Bindings Bindings;
|
||||
SecBuffer NegotiateMessage;
|
||||
SecBuffer ChallengeMessage;
|
||||
SecBuffer AuthenticateMessage;
|
||||
|
@ -228,124 +228,55 @@ void ntlm_free_unicode_string(PUNICODE_STRING string)
|
||||
* https://raw.github.com/mozilla/mozilla-central/master/extensions/auth/nsAuthSSPI.cpp
|
||||
*/
|
||||
|
||||
/* Certificate (TBSCertificate) */
|
||||
|
||||
BYTE test_Certificate[] =
|
||||
"\x30\x82\x02\xfa\xa0\x03\x02\x01\x02\x02\x10\x33\x1d\x91\x3b\x2b"
|
||||
"\x0a\xc8\x90\x4a\x19\x35\xed\x79\x65\xb8\xe3\x30\x09\x06\x05\x2b"
|
||||
"\x0e\x03\x02\x1d\x05\x00\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04"
|
||||
"\x03\x13\x0b\x4c\x41\x42\x33\x2d\x57\x32\x4b\x38\x52\x32\x30\x1e"
|
||||
"\x17\x0d\x31\x32\x31\x32\x31\x37\x31\x37\x33\x33\x31\x32\x5a\x17"
|
||||
"\x0d\x33\x39\x31\x32\x33\x31\x32\x33\x35\x39\x35\x39\x5a\x30\x16"
|
||||
"\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x4c\x41\x42\x33\x2d"
|
||||
"\x57\x32\x4b\x38\x52\x32\x30\x82\x02\x22\x30\x0d\x06\x09\x2a\x86"
|
||||
"\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x02\x0f\x00\x30\x82"
|
||||
"\x02\x0a\x02\x82\x02\x01\x00\xbf\x99\x68\x59\x41\x06\x5a\xd0\x3a"
|
||||
"\x38\x7a\xca\x7a\x1e\x85\xee\x21\x7e\xa3\x01\xca\xf5\xdd\x2f\xbc"
|
||||
"\xf7\x05\x87\x12\x89\x22\xd7\x37\xc1\xe1\x5d\x41\x02\xd8\x60\xc5"
|
||||
"\x07\xec\x26\x6f\x13\x48\xe1\xf3\xc3\x42\x1e\x71\x5d\x31\x8e\x83"
|
||||
"\x74\xac\x23\x84\x88\x02\xf4\xa2\x0a\xa8\x41\xfd\x16\x27\x31\x9c"
|
||||
"\xb6\x78\x08\x84\xfe\x5f\xa1\x9f\x9b\x5c\xe4\x41\xf0\x7f\xb2\x41"
|
||||
"\xe8\xd7\xf1\xcc\xb5\xd4\x38\x38\x5c\x0b\x64\x4b\x10\x6a\x62\x55"
|
||||
"\xc1\x4f\xa3\x22\x58\x01\x92\x1c\x09\x68\xec\xe4\xf1\x01\xda\xe3"
|
||||
"\x6d\x4b\xec\xc2\x9e\xc4\x8e\xc0\x00\x0f\x6e\x07\x7b\xec\x87\x0e"
|
||||
"\x17\x46\xc7\x84\x78\x78\xd0\x9b\xeb\x86\xca\xd4\x30\x09\xe4\xd5"
|
||||
"\xb7\x54\xab\xc0\x86\x2c\x7f\x0e\x8f\x00\xda\xd9\xdf\xb3\x56\xbe"
|
||||
"\xce\xd5\x65\x1b\xe0\xe2\x55\x5a\xd1\xef\xfc\xe6\x20\x3f\x22\xc0"
|
||||
"\xa6\x88\x63\x00\xa7\x0a\xcb\x73\xf1\x0d\x73\xba\x79\x39\x45\x8d"
|
||||
"\xa8\x1f\x32\x58\xb1\xb5\x23\xe7\x68\x7d\xc4\x3a\x8f\x44\xa8\x36"
|
||||
"\xc1\x5d\x0d\xcf\x4a\x21\x0f\x33\x8c\xb4\x57\x9a\x9f\xcb\xc6\xcb"
|
||||
"\x04\x25\x74\x3a\x91\xaf\xd6\xb5\x35\x94\xa5\xe3\xe1\xa4\x92\x87"
|
||||
"\xb5\xc7\xd9\x23\x07\xe2\x37\xf3\xb9\x6d\x01\x55\xa2\x39\x65\x8e"
|
||||
"\xee\xcc\x53\x29\xcb\x1f\x1c\x7e\x7d\x4e\xd6\xfc\xe7\x02\x0a\xba"
|
||||
"\xdb\xa9\x2d\x74\x9a\xeb\xe0\x95\x50\x23\xcd\xff\xe7\xc4\x47\xc2"
|
||||
"\x55\x08\xdb\x1b\x0f\xb8\xd4\x4d\x4f\xd7\xd7\x13\x4c\x66\xed\x0f"
|
||||
"\x78\x7d\x9a\xd5\xb5\xc0\x9e\xf3\xff\xe6\xef\xb7\xea\xd1\xff\xd4"
|
||||
"\xf7\x09\x92\x15\x3e\x44\xb4\x3e\x01\x29\x06\xf1\x73\xa3\x61\xe8"
|
||||
"\x84\x7b\x3e\x0d\x12\x44\x73\x4a\x29\x4b\x82\xe3\xac\x64\x81\xa5"
|
||||
"\xa5\x1d\xa6\xb5\xd6\xc2\xe5\x6f\x98\x3b\x7c\x70\x82\xda\xf9\xf1"
|
||||
"\xde\x46\x7b\xe8\x9e\x03\xbf\xc7\xb2\xe6\x26\x24\x21\x6c\xb3\x67"
|
||||
"\xde\xe0\x8c\x17\x93\xf2\x32\xe5\xae\x5e\xfd\x4f\x77\x40\x3e\x25"
|
||||
"\xfe\xfe\xc0\xd5\xc9\xcd\xff\x8b\xa2\x4e\xae\x89\x12\x0f\x05\xdb"
|
||||
"\xc5\xba\xc2\x02\x6f\x60\xf8\x91\x23\x99\x29\xb4\x22\x5e\x62\x43"
|
||||
"\x5e\xde\xb3\x56\x02\x3c\xa2\xf8\x2a\xbf\x82\xf7\x7a\xcc\x2c\x26"
|
||||
"\x96\x88\x0e\x8d\x65\xb6\x7f\xda\x3c\x52\x6a\x25\xc1\xb2\x89\x5e"
|
||||
"\x3d\x30\x39\x5f\x11\x74\x3c\x00\xa2\xef\x2c\xff\x3e\xaa\x04\x34"
|
||||
"\x93\xbd\x55\xc2\x8b\x98\x5b\x66\x9c\x53\x8b\x27\x7c\x4c\x87\x0b"
|
||||
"\x5b\x24\x72\x08\x06\xf9\x11\x02\x03\x01\x00\x01\xa3\x60\x30\x5e"
|
||||
"\x30\x13\x06\x03\x55\x1d\x25\x04\x0c\x30\x0a\x06\x08\x2b\x06\x01"
|
||||
"\x05\x05\x07\x03\x01\x30\x47\x06\x03\x55\x1d\x01\x04\x40\x30\x3e"
|
||||
"\x80\x10\x8c\x90\xe6\x16\x1e\x1e\xa9\xf3\xbf\x03\x93\x22\xe1\x0c"
|
||||
"\x3b\xfe\xa1\x18\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13"
|
||||
"\x0b\x4c\x41\x42\x33\x2d\x57\x32\x4b\x38\x52\x32\x82\x10\x33\x1d"
|
||||
"\x91\x3b\x2b\x0a\xc8\x90\x4a\x19\x35\xed\x79\x65\xb8\xe3";
|
||||
|
||||
/* 544D5750776A7533334736516B4D76694762777548516B41 (MD5 hash of SEC_CHANNEL_BINDINGS) */
|
||||
BYTE test_ChannelBindingsHash[] = "\x54\x4D\x57\x50\x77\x6A\x75\x33\x33\x47\x36\x51\x6B\x4D\x76\x69\x47\x62\x77\x75\x48\x51\x6B\x41";
|
||||
|
||||
/* 63d3533695bf1bd0de203fee9691a2515e2e7bfe75bb8ab09da08911e157847c (SHA-256 hash of Certificate, length = 32) */
|
||||
BYTE test_CertificateHash_SHA256[] = "\x63\xd3\x53\x36\x95\xbf\x1b\xd0\xde\x20\x3f\xee\x96\x91\xa2\x51\x5e\x2e\x7b\xfe\x75\xbb\x8a\xb0\x9d\xa0\x89\x11\xe1\x57\x84\x7c";
|
||||
|
||||
/* c0ef35911b5ba641c4b67f4b32c7efc4c1d82e2b (SHA1 hash of Certificate, length = 20) */
|
||||
BYTE test_CertificateHash_SHA1[] = "\xc0\xef\x35\x91\x1b\x5b\xa6\x41\xc4\xb6\x7f\x4b\x32\xc7\xef\xc4\xc1\xd8\x2e\x2b";
|
||||
|
||||
/* d2b4df88a54faf95590cd336987a97a5 (MD5 hash of Certificate, length = 16) */
|
||||
BYTE test_CertificateHash_MD5[] = "\xd2\xb4\xdf\x88\xa5\x4f\xaf\x95\x59\x0c\xd3\x36\x98\x7a\x97\xa5";
|
||||
|
||||
BYTE* test_CertificateHash = test_CertificateHash_SHA256;
|
||||
int test_CertificateHashLength = 32;
|
||||
|
||||
/*
|
||||
* Channel Bindings Data:
|
||||
*
|
||||
* tls-server-end-point:<binary hash>
|
||||
typedef struct gss_channel_bindings_struct {
|
||||
OM_uint32 initiator_addrtype;
|
||||
gss_buffer_desc initiator_address;
|
||||
OM_uint32 acceptor_addrtype;
|
||||
gss_buffer_desc acceptor_address;
|
||||
gss_buffer_desc application_data;
|
||||
} *gss_channel_bindings_t;
|
||||
*/
|
||||
|
||||
char TlsServerEndPointPrefix[] = "tls-server-end-point:";
|
||||
static void ntlm_md5_update_uint32_be(MD5_CTX* md5, UINT32 num)
|
||||
{
|
||||
BYTE be32[4];
|
||||
|
||||
be32[0] = (num >> 0) & 0xFF;
|
||||
be32[1] = (num >> 8) & 0xFF;
|
||||
be32[2] = (num >> 16) & 0xFF;
|
||||
be32[3] = (num >> 24) & 0xFF;
|
||||
|
||||
MD5_Update(md5, be32, 4);
|
||||
}
|
||||
|
||||
void ntlm_compute_channel_bindings(NTLM_CONTEXT* context)
|
||||
{
|
||||
#if 0
|
||||
MD5_CTX md5;
|
||||
int HashLength;
|
||||
int PrefixLength;
|
||||
BYTE* pChannelBindingToken;
|
||||
int ChannelBindingTokenLength;
|
||||
BYTE* ChannelBindingToken;
|
||||
UINT32 ChannelBindingTokenLength;
|
||||
SEC_CHANNEL_BINDINGS* ChannelBindings;
|
||||
|
||||
ZeroMemory(context->ChannelBindingsHash, 16);
|
||||
ChannelBindings = context->Bindings.Bindings;
|
||||
|
||||
HashLength = test_CertificateHashLength;
|
||||
PrefixLength = strlen(TlsServerEndPointPrefix);
|
||||
ChannelBindingTokenLength = PrefixLength + HashLength;
|
||||
context->ChannelBindingToken = (BYTE*) malloc(ChannelBindingTokenLength + 1);
|
||||
strcpy((char*) context->ChannelBindingToken, TlsServerEndPointPrefix);
|
||||
CopyMemory(&context->ChannelBindingToken[PrefixLength], test_CertificateHash, HashLength);
|
||||
if (!ChannelBindings)
|
||||
return;
|
||||
|
||||
printf("ChannelBindingToken:\n");
|
||||
winpr_HexDump(context->ChannelBindingToken, ChannelBindingTokenLength);
|
||||
|
||||
context->EndpointBindings.BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + ChannelBindingTokenLength;
|
||||
context->EndpointBindings.Bindings = (SEC_CHANNEL_BINDINGS*) malloc(context->EndpointBindings.BindingsLength);
|
||||
ZeroMemory(context->EndpointBindings.Bindings, context->EndpointBindings.BindingsLength);
|
||||
|
||||
ChannelBindings = context->EndpointBindings.Bindings;
|
||||
ChannelBindings->cbApplicationDataLength = ChannelBindingTokenLength;
|
||||
ChannelBindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS);
|
||||
|
||||
pChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
|
||||
CopyMemory(pChannelBindingToken, context->ChannelBindingToken, ChannelBindingTokenLength);
|
||||
|
||||
printf("ChannelBindings\n");
|
||||
winpr_HexDump((BYTE*) ChannelBindings, context->EndpointBindings.BindingsLength);
|
||||
ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS);
|
||||
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
|
||||
|
||||
MD5_Init(&md5);
|
||||
MD5_Update(&md5, (void*) context->EndpointBindings.Bindings, context->EndpointBindings.BindingsLength);
|
||||
MD5_Final(context->ChannelBindingsHash, &md5);
|
||||
|
||||
printf("ChannelBindingsHash:\n");
|
||||
winpr_HexDump(context->ChannelBindingsHash, 16);
|
||||
#endif
|
||||
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType);
|
||||
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength);
|
||||
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType);
|
||||
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength);
|
||||
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength);
|
||||
|
||||
MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
|
||||
|
||||
MD5_Final(context->ChannelBindingsHash, &md5);
|
||||
}
|
||||
|
||||
void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context)
|
||||
|
@ -30,47 +30,17 @@
|
||||
|
||||
char* SCHANNEL_PACKAGE_NAME = "Schannel";
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
SCHANNEL_CONTEXT* context;
|
||||
CREDENTIALS* credentials;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
context = schannel_ContextNew();
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phNewContext, context);
|
||||
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME);
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
|
||||
}
|
||||
|
||||
SCHANNEL_CONTEXT* schannel_ContextNew()
|
||||
{
|
||||
SCHANNEL_CONTEXT* context;
|
||||
|
||||
context = (SCHANNEL_CONTEXT*) calloc(1, sizeof(SCHANNEL_CONTEXT));
|
||||
context = (SCHANNEL_CONTEXT*) malloc(sizeof(SCHANNEL_CONTEXT));
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
ZeroMemory(context, sizeof(SCHANNEL_CONTEXT));
|
||||
|
||||
context->openssl = schannel_openssl_new();
|
||||
}
|
||||
|
||||
return context;
|
||||
@ -81,40 +51,109 @@ void schannel_ContextFree(SCHANNEL_CONTEXT* context)
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
schannel_openssl_free(context->openssl);
|
||||
|
||||
free(context);
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
SCHANNEL_CREDENTIALS* schannel_CredentialsNew()
|
||||
{
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
SCHANNEL_CREDENTIALS* credentials;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
credentials = (SCHANNEL_CREDENTIALS*) malloc(sizeof(SCHANNEL_CREDENTIALS));
|
||||
|
||||
if (credentials != NULL)
|
||||
{
|
||||
ZeroMemory(credentials, sizeof(SCHANNEL_CREDENTIALS));
|
||||
}
|
||||
|
||||
return credentials;
|
||||
}
|
||||
|
||||
void schannel_CredentialsFree(SCHANNEL_CREDENTIALS* credentials)
|
||||
{
|
||||
if (!credentials)
|
||||
return;
|
||||
|
||||
free(credentials);
|
||||
}
|
||||
|
||||
static ALG_ID schannel_SupportedAlgs[] =
|
||||
{
|
||||
CALG_AES_128, CALG_AES_256, CALG_RC4, CALG_DES, CALG_3DES,
|
||||
CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512,
|
||||
CALG_RSA_SIGN, CALG_DH_EPHEM,
|
||||
(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RESERVED7 | 6), /* what is this? */
|
||||
CALG_DSS_SIGN, CALG_ECDSA
|
||||
};
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
if (ulAttribute == SECPKG_ATTR_SUPPORTED_ALGS)
|
||||
{
|
||||
PSecPkgCred_SupportedAlgs SupportedAlgs = (PSecPkgCred_SupportedAlgs) pBuffer;
|
||||
|
||||
SupportedAlgs->cSupportedAlgs = sizeof(schannel_SupportedAlgs) / sizeof(ALG_ID);
|
||||
SupportedAlgs->palgSupportedAlgs = (ALG_ID*) schannel_SupportedAlgs;
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
else if (ulAttribute == SECPKG_ATTR_CIPHER_STRENGTHS)
|
||||
{
|
||||
PSecPkgCred_CipherStrengths CipherStrengths = (PSecPkgCred_CipherStrengths) pBuffer;
|
||||
|
||||
CipherStrengths->dwMinimumCipherStrength = 40;
|
||||
CipherStrengths->dwMaximumCipherStrength = 256;
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
else if (ulAttribute == SECPKG_ATTR_SUPPORTED_PROTOCOLS)
|
||||
{
|
||||
PSecPkgCred_SupportedProtocols SupportedProtocols = (PSecPkgCred_SupportedProtocols) pBuffer;
|
||||
|
||||
/* Observed SupportedProtocols: 0x208A0 */
|
||||
SupportedProtocols->grbitProtocol = (SP_PROT_CLIENTS | SP_PROT_SERVERS);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
return schannel_QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
{
|
||||
CREDENTIALS* credentials;
|
||||
SEC_WINNT_AUTH_IDENTITY* identity;
|
||||
SCHANNEL_CREDENTIALS* credentials;
|
||||
|
||||
if (fCredentialUse == SECPKG_CRED_OUTBOUND)
|
||||
{
|
||||
credentials = sspi_CredentialsNew();
|
||||
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
|
||||
SCHANNEL_CRED* cred;
|
||||
|
||||
//CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY));
|
||||
credentials = schannel_CredentialsNew();
|
||||
credentials->fCredentialUse = fCredentialUse;
|
||||
|
||||
cred = (SCHANNEL_CRED*) pAuthData;
|
||||
|
||||
if (cred)
|
||||
{
|
||||
CopyMemory(&credentials->cred, cred, sizeof(SCHANNEL_CRED));
|
||||
}
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
|
||||
sspi_SecureHandleSetUpperPointer(phCredential, (void*) SCHANNEL_PACKAGE_NAME);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
else if (fCredentialUse == SECPKG_CRED_INBOUND)
|
||||
{
|
||||
credentials = schannel_CredentialsNew();
|
||||
credentials->fCredentialUse = fCredentialUse;
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
|
||||
sspi_SecureHandleSetUpperPointer(phCredential, (void*) SCHANNEL_PACKAGE_NAME);
|
||||
@ -125,18 +164,165 @@ SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA(SEC_CHAR* pszPrinci
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
SEC_WCHAR* pszPrincipalW = NULL;
|
||||
SEC_WCHAR* pszPackageW = NULL;
|
||||
|
||||
ConvertToUnicode(CP_UTF8, 0, pszPrincipal, -1, &pszPrincipalW, 0);
|
||||
ConvertToUnicode(CP_UTF8, 0, pszPackage, -1, &pszPackageW, 0);
|
||||
|
||||
status = schannel_AcquireCredentialsHandleW(pszPrincipalW, pszPackageW, fCredentialUse, pvLogonID,
|
||||
pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
|
||||
|
||||
free(pszPrincipalW);
|
||||
free(pszPackageW);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
SECURITY_STATUS SEC_ENTRY schannel_FreeCredentialsHandle(PCredHandle phCredential)
|
||||
{
|
||||
if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
|
||||
{
|
||||
CREDENTIALS* credentials;
|
||||
SCHANNEL_CREDENTIALS* credentials;
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
if (!phCredential)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
credentials = (SCHANNEL_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
if (!credentials)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
schannel_CredentialsFree(credentials);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
SCHANNEL_CONTEXT* context;
|
||||
SCHANNEL_CREDENTIALS* credentials;
|
||||
|
||||
context = sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
context = schannel_ContextNew();
|
||||
|
||||
if (!context)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
credentials = (SCHANNEL_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
context->server = FALSE;
|
||||
CopyMemory(&context->cred, &credentials->cred, sizeof(SCHANNEL_CRED));
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phNewContext, context);
|
||||
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME);
|
||||
|
||||
schannel_openssl_client_init(context->openssl);
|
||||
|
||||
status = schannel_openssl_client_process_tokens(context->openssl, pInput, pOutput);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
SEC_WCHAR* pszTargetNameW = NULL;
|
||||
|
||||
if (pszTargetName != NULL)
|
||||
{
|
||||
ConvertToUnicode(CP_UTF8, 0, pszTargetName, -1, &pszTargetNameW, 0);
|
||||
}
|
||||
|
||||
status = schannel_InitializeSecurityContextW(phCredential, phContext, pszTargetNameW, fContextReq,
|
||||
Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
|
||||
|
||||
if (pszTargetNameW != NULL)
|
||||
free(pszTargetNameW);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
SCHANNEL_CONTEXT* context;
|
||||
SCHANNEL_CREDENTIALS* credentials;
|
||||
|
||||
context = (SCHANNEL_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
context = schannel_ContextNew();
|
||||
|
||||
if (!context)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
credentials = (SCHANNEL_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
context->server = TRUE;
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phNewContext, context);
|
||||
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME);
|
||||
|
||||
schannel_openssl_server_init(context->openssl);
|
||||
|
||||
status = schannel_openssl_server_process_tokens(context->openssl, pInput, pOutput);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_DeleteSecurityContext(PCtxtHandle phContext)
|
||||
{
|
||||
SCHANNEL_CONTEXT* context;
|
||||
|
||||
context = (SCHANNEL_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
schannel_ContextFree(context);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (ulAttribute == SECPKG_ATTR_SIZES)
|
||||
{
|
||||
SecPkgContext_Sizes* ContextSizes = (SecPkgContext_Sizes*) pBuffer;
|
||||
|
||||
ContextSizes->cbMaxToken = 0x6000;
|
||||
ContextSizes->cbMaxSignature = 16;
|
||||
ContextSizes->cbBlockSize = 0;
|
||||
ContextSizes->cbSecurityTrailer = 16;
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
@ -144,20 +330,13 @@ SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesA(PCredHandle phCre
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_FreeCredentialsHandle(PCredHandle phCredential)
|
||||
SECURITY_STATUS SEC_ENTRY schannel_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
{
|
||||
CREDENTIALS* credentials;
|
||||
|
||||
if (!phCredential)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
if (!credentials)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
sspi_CredentialsFree(credentials);
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
@ -171,16 +350,6 @@ SECURITY_STATUS SEC_ENTRY schannel_DecryptMessage(PCtxtHandle phContext, PSecBuf
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY schannel_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA =
|
||||
{
|
||||
1, /* dwVersion */
|
||||
@ -190,9 +359,9 @@ const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA =
|
||||
schannel_FreeCredentialsHandle, /* FreeCredentialsHandle */
|
||||
NULL, /* Reserved2 */
|
||||
schannel_InitializeSecurityContextA, /* InitializeSecurityContext */
|
||||
NULL, /* AcceptSecurityContext */
|
||||
schannel_AcceptSecurityContext, /* AcceptSecurityContext */
|
||||
NULL, /* CompleteAuthToken */
|
||||
NULL, /* DeleteSecurityContext */
|
||||
schannel_DeleteSecurityContext, /* DeleteSecurityContext */
|
||||
NULL, /* ApplyControlToken */
|
||||
schannel_QueryContextAttributes, /* QueryContextAttributes */
|
||||
NULL, /* ImpersonateSecurityContext */
|
||||
@ -222,9 +391,9 @@ const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW =
|
||||
schannel_FreeCredentialsHandle, /* FreeCredentialsHandle */
|
||||
NULL, /* Reserved2 */
|
||||
schannel_InitializeSecurityContextW, /* InitializeSecurityContext */
|
||||
NULL, /* AcceptSecurityContext */
|
||||
schannel_AcceptSecurityContext, /* AcceptSecurityContext */
|
||||
NULL, /* CompleteAuthToken */
|
||||
NULL, /* DeleteSecurityContext */
|
||||
schannel_DeleteSecurityContext, /* DeleteSecurityContext */
|
||||
NULL, /* ApplyControlToken */
|
||||
schannel_QueryContextAttributes, /* QueryContextAttributes */
|
||||
NULL, /* ImpersonateSecurityContext */
|
||||
@ -250,7 +419,7 @@ const SecPkgInfoA SCHANNEL_SecPkgInfoA =
|
||||
0x000107B3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x000E, /* wRPCID */
|
||||
0x00006000, /* cbMaxToken */
|
||||
SCHANNEL_CB_MAX_TOKEN, /* cbMaxToken */
|
||||
"Schannel", /* Name */
|
||||
"Schannel Security Package" /* Comment */
|
||||
};
|
||||
@ -269,7 +438,7 @@ const SecPkgInfoW SCHANNEL_SecPkgInfoW =
|
||||
0x000107B3, /* fCapabilities */
|
||||
1, /* wVersion */
|
||||
0x000E, /* wRPCID */
|
||||
0x00006000, /* cbMaxToken */
|
||||
SCHANNEL_CB_MAX_TOKEN, /* cbMaxToken */
|
||||
SCHANNEL_SecPkgInfoW_Name, /* Name */
|
||||
SCHANNEL_SecPkgInfoW_Comment /* Comment */
|
||||
};
|
||||
|
@ -21,12 +21,24 @@
|
||||
#define WINPR_SSPI_SCHANNEL_PRIVATE_H
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/schannel.h>
|
||||
|
||||
#include "../sspi.h"
|
||||
|
||||
#include "schannel_openssl.h"
|
||||
|
||||
struct _SCHANNEL_CREDENTIALS
|
||||
{
|
||||
SCHANNEL_CRED cred;
|
||||
ULONG fCredentialUse;
|
||||
};
|
||||
typedef struct _SCHANNEL_CREDENTIALS SCHANNEL_CREDENTIALS;
|
||||
|
||||
struct _SCHANNEL_CONTEXT
|
||||
{
|
||||
BOOL server;
|
||||
SCHANNEL_CRED cred;
|
||||
SCHANNEL_OPENSSL* openssl;
|
||||
};
|
||||
typedef struct _SCHANNEL_CONTEXT SCHANNEL_CONTEXT;
|
||||
|
||||
|
376
winpr/libwinpr/sspi/Schannel/schannel_openssl.c
Normal file
376
winpr/libwinpr/sspi/Schannel/schannel_openssl.c
Normal file
@ -0,0 +1,376 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Schannel Security Package (OpenSSL)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "schannel_openssl.h"
|
||||
|
||||
char* openssl_get_ssl_error_string(int ssl_error)
|
||||
{
|
||||
switch (ssl_error)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return "SSL_ERROR_ZERO_RETURN";
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return "SSL_ERROR_WANT_READ";
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return "SSL_ERROR_WANT_WRITE";
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
return "SSL_ERROR_SYSCALL";
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
ERR_print_errors_fp(stdout);
|
||||
return "SSL_ERROR_SSL";
|
||||
}
|
||||
|
||||
return "SSL_ERROR_UNKNOWN";
|
||||
}
|
||||
|
||||
int schannel_openssl_client_init(SCHANNEL_OPENSSL* context)
|
||||
{
|
||||
int status;
|
||||
long options = 0;
|
||||
|
||||
context->ctx = SSL_CTX_new(TLSv1_client_method());
|
||||
|
||||
if (!context->ctx)
|
||||
{
|
||||
printf("SSL_CTX_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* SSL_OP_NO_COMPRESSION:
|
||||
*
|
||||
* The Microsoft RDP server does not advertise support
|
||||
* for TLS compression, but alternative servers may support it.
|
||||
* This was observed between early versions of the FreeRDP server
|
||||
* and the FreeRDP client, and caused major performance issues,
|
||||
* which is why we're disabling it.
|
||||
*/
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
options |= SSL_OP_NO_COMPRESSION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SSL_OP_TLS_BLOCK_PADDING_BUG:
|
||||
*
|
||||
* The Microsoft RDP server does *not* support TLS padding.
|
||||
* It absolutely needs to be disabled otherwise it won't work.
|
||||
*/
|
||||
options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
|
||||
|
||||
/**
|
||||
* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
|
||||
*
|
||||
* Just like TLS padding, the Microsoft RDP server does not
|
||||
* support empty fragments. This needs to be disabled.
|
||||
*/
|
||||
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
|
||||
SSL_CTX_set_options(context->ctx, options);
|
||||
|
||||
context->ssl = SSL_new(context->ctx);
|
||||
|
||||
if (!context->ssl)
|
||||
{
|
||||
printf("SSL_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->bioRead = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!context->bioRead)
|
||||
{
|
||||
printf("BIO_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
context->bioWrite = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!context->bioWrite)
|
||||
{
|
||||
printf("BIO_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
|
||||
|
||||
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
|
||||
|
||||
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
|
||||
{
|
||||
int status;
|
||||
long options = 0;
|
||||
|
||||
context->ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
|
||||
if (!context->ctx)
|
||||
{
|
||||
printf("SSL_CTX_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* SSL_OP_NO_SSLv2:
|
||||
*
|
||||
* We only want SSLv3 and TLSv1, so disable SSLv2.
|
||||
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
|
||||
*/
|
||||
options |= SSL_OP_NO_SSLv2;
|
||||
|
||||
/**
|
||||
* SSL_OP_NO_COMPRESSION:
|
||||
*
|
||||
* The Microsoft RDP server does not advertise support
|
||||
* for TLS compression, but alternative servers may support it.
|
||||
* This was observed between early versions of the FreeRDP server
|
||||
* and the FreeRDP client, and caused major performance issues,
|
||||
* which is why we're disabling it.
|
||||
*/
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
options |= SSL_OP_NO_COMPRESSION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SSL_OP_TLS_BLOCK_PADDING_BUG:
|
||||
*
|
||||
* The Microsoft RDP server does *not* support TLS padding.
|
||||
* It absolutely needs to be disabled otherwise it won't work.
|
||||
*/
|
||||
options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
|
||||
|
||||
/**
|
||||
* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
|
||||
*
|
||||
* Just like TLS padding, the Microsoft RDP server does not
|
||||
* support empty fragments. This needs to be disabled.
|
||||
*/
|
||||
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
|
||||
SSL_CTX_set_options(context->ctx, options);
|
||||
|
||||
context->ssl = SSL_new(context->ctx);
|
||||
|
||||
if (!context->ssl)
|
||||
{
|
||||
printf("SSL_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_RSAPrivateKey_file(context->ctx, "/tmp/localhost.key", SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
printf("SSL_CTX_use_RSAPrivateKey_file failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SSL_use_certificate_file(context->ssl, "/tmp/localhost.crt", SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
printf("SSL_use_certificate_file failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->bioRead = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!context->bioRead)
|
||||
{
|
||||
printf("BIO_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
context->bioWrite = BIO_new(BIO_s_mem());
|
||||
|
||||
if (!context->bioWrite)
|
||||
{
|
||||
printf("BIO_new failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
|
||||
|
||||
SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
|
||||
|
||||
context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
int status;
|
||||
int ssl_error;
|
||||
PSecBuffer pBuffer;
|
||||
|
||||
if (!context->connected)
|
||||
{
|
||||
if (pInput)
|
||||
{
|
||||
if (pInput->cBuffers < 1)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
pBuffer = &pInput->pBuffers[0];
|
||||
|
||||
if (pBuffer->BufferType != SECBUFFER_TOKEN)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
|
||||
}
|
||||
|
||||
status = SSL_connect(context->ssl);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
ssl_error = SSL_get_error(context->ssl, status);
|
||||
printf("SSL_connect error: %s\n", openssl_get_ssl_error_string(ssl_error));
|
||||
}
|
||||
|
||||
status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status >= 0)
|
||||
{
|
||||
winpr_HexDump(context->ReadBuffer, status);
|
||||
}
|
||||
|
||||
if (pOutput->cBuffers < 1)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
pBuffer = &pOutput->pBuffers[0];
|
||||
|
||||
if (pBuffer->BufferType != SECBUFFER_TOKEN)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (pBuffer->cbBuffer < status)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status);
|
||||
pBuffer->cbBuffer = status;
|
||||
|
||||
return SEC_I_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput)
|
||||
{
|
||||
int status;
|
||||
int ssl_error;
|
||||
PSecBuffer pBuffer;
|
||||
|
||||
if (!context->connected)
|
||||
{
|
||||
if (pInput->cBuffers < 1)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
pBuffer = &pInput->pBuffers[0];
|
||||
|
||||
if (pBuffer->BufferType != SECBUFFER_TOKEN)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
printf("Server input: %d\n", pBuffer->cbBuffer);
|
||||
status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer);
|
||||
|
||||
status = SSL_accept(context->ssl);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
ssl_error = SSL_get_error(context->ssl, status);
|
||||
printf("SSL_accept error: %s\n", openssl_get_ssl_error_string(ssl_error));
|
||||
}
|
||||
|
||||
status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN);
|
||||
|
||||
if (status >= 0)
|
||||
{
|
||||
winpr_HexDump(context->ReadBuffer, status);
|
||||
}
|
||||
|
||||
if (pOutput->cBuffers < 1)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
pBuffer = &pOutput->pBuffers[0];
|
||||
|
||||
if (pBuffer->BufferType != SECBUFFER_TOKEN)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
if (pBuffer->cbBuffer < status)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status);
|
||||
pBuffer->cbBuffer = status;
|
||||
|
||||
return SEC_I_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SCHANNEL_OPENSSL* schannel_openssl_new()
|
||||
{
|
||||
SCHANNEL_OPENSSL* context;
|
||||
|
||||
context = (SCHANNEL_OPENSSL*) malloc(sizeof(SCHANNEL_OPENSSL));
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
ZeroMemory(context, sizeof(SCHANNEL_OPENSSL));
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
context->connected = FALSE;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void schannel_openssl_free(SCHANNEL_OPENSSL* context)
|
||||
{
|
||||
if (context)
|
||||
{
|
||||
free(context->ReadBuffer);
|
||||
free(context->WriteBuffer);
|
||||
|
||||
free(context);
|
||||
}
|
||||
}
|
55
winpr/libwinpr/sspi/Schannel/schannel_openssl.h
Normal file
55
winpr/libwinpr/sspi/Schannel/schannel_openssl.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Schannel Security Package (OpenSSL)
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 WINPR_SSPI_SCHANNEL_OPENSSL_H
|
||||
#define WINPR_SSPI_SCHANNEL_OPENSSL_H
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
#include "../sspi.h"
|
||||
|
||||
/* OpenSSL includes windows.h */
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
struct _SCHANNEL_OPENSSL
|
||||
{
|
||||
SSL* ssl;
|
||||
SSL_CTX* ctx;
|
||||
BOOL connected;
|
||||
BIO* bioRead;
|
||||
BIO* bioWrite;
|
||||
BYTE* ReadBuffer;
|
||||
BYTE* WriteBuffer;
|
||||
};
|
||||
typedef struct _SCHANNEL_OPENSSL SCHANNEL_OPENSSL;
|
||||
|
||||
int schannel_openssl_client_init(SCHANNEL_OPENSSL* context);
|
||||
int schannel_openssl_server_init(SCHANNEL_OPENSSL* context);
|
||||
|
||||
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput);
|
||||
SECURITY_STATUS schannel_openssl_server_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput);
|
||||
|
||||
SCHANNEL_OPENSSL* schannel_openssl_new();
|
||||
void schannel_openssl_free(SCHANNEL_OPENSSL* context);
|
||||
|
||||
#endif /* WINPR_SSPI_SCHANNEL_OPENSSL_H */
|
@ -40,24 +40,31 @@
|
||||
|
||||
extern const SecPkgInfoA NTLM_SecPkgInfoA;
|
||||
extern const SecPkgInfoW NTLM_SecPkgInfoW;
|
||||
extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
|
||||
extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
|
||||
|
||||
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
|
||||
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
|
||||
|
||||
extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
|
||||
extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
|
||||
extern const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA;
|
||||
extern const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW;
|
||||
|
||||
extern const SecPkgInfoA SCHANNEL_SecPkgInfoA;
|
||||
extern const SecPkgInfoW SCHANNEL_SecPkgInfoW;
|
||||
extern const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA;
|
||||
extern const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW;
|
||||
|
||||
const SecPkgInfoA* SecPkgInfoA_LIST[] =
|
||||
{
|
||||
&NTLM_SecPkgInfoA,
|
||||
&CREDSSP_SecPkgInfoA
|
||||
&CREDSSP_SecPkgInfoA,
|
||||
&SCHANNEL_SecPkgInfoA
|
||||
};
|
||||
|
||||
const SecPkgInfoW* SecPkgInfoW_LIST[] =
|
||||
{
|
||||
&NTLM_SecPkgInfoW,
|
||||
&CREDSSP_SecPkgInfoW
|
||||
&CREDSSP_SecPkgInfoW,
|
||||
&SCHANNEL_SecPkgInfoW
|
||||
};
|
||||
|
||||
SecurityFunctionTableA SSPI_SecurityFunctionTableA;
|
||||
@ -80,16 +87,19 @@ typedef struct _SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME;
|
||||
const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] =
|
||||
{
|
||||
{ "NTLM", &NTLM_SecurityFunctionTableA },
|
||||
{ "CREDSSP", &CREDSSP_SecurityFunctionTableA }
|
||||
{ "CREDSSP", &CREDSSP_SecurityFunctionTableA },
|
||||
{ "Schannel", &SCHANNEL_SecurityFunctionTableA }
|
||||
};
|
||||
|
||||
WCHAR NTLM_NAME_W[] = { 'N','T','L','M','\0' };
|
||||
WCHAR CREDSSP_NAME_W[] = { 'C','r','e','d','S','S','P','\0' };
|
||||
WCHAR SCHANNEL_NAME_W[] = { 'S','c','h','a','n','n','e','l','\0' };
|
||||
|
||||
const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] =
|
||||
{
|
||||
{ NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
|
||||
{ CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW }
|
||||
{ CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW },
|
||||
{ SCHANNEL_NAME_W, &SCHANNEL_SecurityFunctionTableW }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
#define SCHANNEL_CB_MAX_TOKEN 0x00006000
|
||||
|
||||
struct _CREDENTIALS
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
|
@ -8,7 +8,9 @@ set(${MODULE_PREFIX}_TESTS
|
||||
TestQuerySecurityPackageInfo.c
|
||||
TestEnumerateSecurityPackages.c
|
||||
TestInitializeSecurityContext.c
|
||||
TestAcquireCredentialsHandle.c)
|
||||
TestAcquireCredentialsHandle.c
|
||||
TestSchannel.c
|
||||
TestNTLM.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
@ -17,13 +19,13 @@ create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
if(WIN32)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} secur32)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} secur32 crypt32)
|
||||
endif()
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-sspi)
|
||||
MODULES winpr-sspi winpr-thread winpr-pipe winpr-file winpr-crypto winpr-utils)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
59
winpr/libwinpr/sspi/test/TestNTLM.c
Normal file
59
winpr/libwinpr/sspi/test/TestNTLM.c
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
BYTE test_Certificate[] =
|
||||
"\x30\x82\x02\x09\x30\x82\x01\x76\xa0\x03\x02\x01\x02\x02\x10\xcb"
|
||||
"\x69\x79\xcd\x51\x75\xc5\xb7\x4b\x67\x30\x83\x6c\x78\x44\x27\x30"
|
||||
"\x09\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x30\x16\x31\x14\x30\x12"
|
||||
"\x06\x03\x55\x04\x03\x13\x0b\x44\x43\x2d\x57\x53\x32\x30\x30\x38"
|
||||
"\x52\x32\x30\x1e\x17\x0d\x31\x32\x31\x31\x31\x37\x30\x30\x35\x39"
|
||||
"\x32\x31\x5a\x17\x0d\x33\x39\x31\x32\x33\x31\x32\x33\x35\x39\x35"
|
||||
"\x39\x5a\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x44"
|
||||
"\x43\x2d\x57\x53\x32\x30\x30\x38\x52\x32\x30\x81\x9f\x30\x0d\x06"
|
||||
"\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00"
|
||||
"\x30\x81\x89\x02\x81\x81\x00\x9b\x00\xf8\x1a\x2d\x37\xc6\x8d\xa1"
|
||||
"\x39\x91\x46\xf3\x6a\x1b\xf9\x60\x6c\xb3\x6c\xa0\xac\xed\x85\xe0"
|
||||
"\x3f\xdc\x92\x86\x36\xbd\x64\xbf\x36\x51\xdb\x57\x3a\x8a\x82\x6b"
|
||||
"\xd8\x94\x17\x7b\xd3\x91\x11\x98\xef\x19\x06\x52\x30\x03\x73\x67"
|
||||
"\xc8\xed\x8e\xfa\x0b\x3d\x4c\xc9\x10\x63\x9f\xcf\xb4\xcf\x39\xd8"
|
||||
"\xfe\x99\xeb\x5b\x11\xf2\xfc\xfa\x86\x24\xd9\xff\xd9\x19\xf5\x69"
|
||||
"\xb4\xdf\x5a\x5a\xc4\x94\xb4\xb0\x07\x25\x97\x13\xad\x7e\x38\x14"
|
||||
"\xfb\xd6\x33\x65\x6f\xe6\xf7\x48\x4b\x2d\xb3\x51\x2e\x6d\xc7\xea"
|
||||
"\x11\x76\x9a\x2b\xf0\x00\x4d\x02\x03\x01\x00\x01\xa3\x60\x30\x5e"
|
||||
"\x30\x13\x06\x03\x55\x1d\x25\x04\x0c\x30\x0a\x06\x08\x2b\x06\x01"
|
||||
"\x05\x05\x07\x03\x01\x30\x47\x06\x03\x55\x1d\x01\x04\x40\x30\x3e"
|
||||
"\x80\x10\xeb\x65\x26\x03\x95\x4b\xd6\xc0\x54\x75\x78\x7c\xb6\x2a"
|
||||
"\xa1\xbb\xa1\x18\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13"
|
||||
"\x0b\x44\x43\x2d\x57\x53\x32\x30\x30\x38\x52\x32\x82\x10\xcb\x69"
|
||||
"\x79\xcd\x51\x75\xc5\xb7\x4b\x67\x30\x83\x6c\x78\x44\x27\x30\x09"
|
||||
"\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x03\x81\x81\x00\x7b\xfa\xfe"
|
||||
"\xee\x74\x05\xac\xbb\x79\xe9\xda\xca\x00\x44\x96\x94\x71\x92\xb1"
|
||||
"\xdb\xc9\x9b\x71\x29\xc0\xe4\x28\x5e\x6a\x50\x99\xcd\xa8\x17\xe4"
|
||||
"\x56\xb9\xef\x7f\x02\x7d\x96\xa3\x48\x14\x72\x75\x2f\xb0\xb5\x87"
|
||||
"\xee\x55\xe9\x6a\x6d\x28\x3c\xc1\xfd\x00\xe4\x76\xe3\x80\x88\x78"
|
||||
"\x26\x0d\x6c\x8c\xb8\x64\x61\x63\xb7\x13\x3a\xab\xc7\xdd\x1d\x0a"
|
||||
"\xd7\x15\x45\xa1\xd6\xd9\x34\xc7\x21\x48\xfb\x43\x87\x38\xda\x1f"
|
||||
"\x50\x47\xb1\xa5\x5c\x47\xed\x04\x44\x97\xd3\xac\x74\x2d\xeb\x09"
|
||||
"\x77\x59\xbf\xa3\x54\x5b\xde\x42\xd5\x23\x5a\x71\x9f";
|
||||
|
||||
BYTE test_Certificate_SHA256Hash[] =
|
||||
"\xea\x05\xfe\xfe\xcc\x6b\x0b\xd5\x71\xdb\xbc\x5b\xaa\x3e\xd4\x53"
|
||||
"\x86\xd0\x44\x68\x35\xf7\xb7\x4c\x85\x62\x1b\x99\x83\x47\x5f\x95";
|
||||
|
||||
BYTE test_ChannelBindings_MD5Hash[] =
|
||||
"\x65\x86\xE9\x9D\x81\xC2\xFC\x98\x4E\x47\x17\x2F\xD4\xDD\x03\x10";
|
||||
|
||||
int test_ntlm_channel_binding_token()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestNTLM(int argc, char* argv[])
|
||||
{
|
||||
if (test_ntlm_channel_binding_token() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
472
winpr/libwinpr/sspi/test/TestSchannel.c
Normal file
472
winpr/libwinpr/sspi/test/TestSchannel.c
Normal file
@ -0,0 +1,472 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/pipe.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/schannel.h>
|
||||
|
||||
HANDLE g_ClientEvent = NULL;
|
||||
HANDLE g_ServerEvent = NULL;
|
||||
BOOL g_ClientWait = FALSE;
|
||||
BOOL g_ServerWait = FALSE;
|
||||
|
||||
HANDLE g_ClientReadPipe = NULL;
|
||||
HANDLE g_ClientWritePipe = NULL;
|
||||
HANDLE g_ServerReadPipe = NULL;
|
||||
HANDLE g_ServerWritePipe = NULL;
|
||||
|
||||
static void* schannel_test_server_thread(void* arg)
|
||||
{
|
||||
BOOL extraData;
|
||||
BYTE* lpTokenIn;
|
||||
BYTE* lpTokenOut;
|
||||
TimeStamp expiry;
|
||||
UINT32 cbMaxToken;
|
||||
UINT32 fContextReq;
|
||||
ULONG fContextAttr;
|
||||
SCHANNEL_CRED cred;
|
||||
CtxtHandle context;
|
||||
CredHandle credentials;
|
||||
DWORD cchNameString;
|
||||
LPTSTR pszNameString;
|
||||
HCERTSTORE hCertStore;
|
||||
PCCERT_CONTEXT pCertContext;
|
||||
PSecBuffer pSecBuffer;
|
||||
SecBuffer SecBuffer_in[2];
|
||||
SecBuffer SecBuffer_out[2];
|
||||
SecBufferDesc SecBufferDesc_in;
|
||||
SecBufferDesc SecBufferDesc_out;
|
||||
DWORD NumberOfBytesRead;
|
||||
SECURITY_STATUS status;
|
||||
PSecPkgInfo pPackageInfo;
|
||||
PSecurityFunctionTable table;
|
||||
DWORD NumberOfBytesWritten;
|
||||
|
||||
printf("Starting Server\n");
|
||||
|
||||
SecInvalidateHandle(&context);
|
||||
SecInvalidateHandle(&credentials);
|
||||
|
||||
table = InitSecurityInterface();
|
||||
|
||||
status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("QuerySecurityPackageInfo failure: 0x%08X\n", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cbMaxToken = pPackageInfo->cbMaxToken;
|
||||
|
||||
hCertStore = CertOpenSystemStore(0, _T("MY"));
|
||||
|
||||
if (!hCertStore)
|
||||
{
|
||||
printf("Error opening system store\n");
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
|
||||
|
||||
if (!pCertContext)
|
||||
{
|
||||
printf("Error finding certificate in store\n");
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
cchNameString = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
|
||||
|
||||
pszNameString = (LPTSTR) malloc(status * sizeof(TCHAR));
|
||||
cchNameString = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString);
|
||||
|
||||
_tprintf(_T("Certificate Name: %s\n"), pszNameString);
|
||||
|
||||
ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
|
||||
cred.dwVersion = SCHANNEL_CRED_VERSION;
|
||||
|
||||
cred.cCreds = 1;
|
||||
cred.paCred = &pCertContext;
|
||||
|
||||
cred.cSupportedAlgs = 0;
|
||||
cred.palgSupportedAlgs = NULL;
|
||||
|
||||
cred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
|
||||
|
||||
cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER;
|
||||
|
||||
status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
|
||||
SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("AcquireCredentialsHandle failure: 0x%08X\n", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extraData = FALSE;
|
||||
lpTokenIn = (BYTE*) malloc(cbMaxToken);
|
||||
lpTokenOut = (BYTE*) malloc(cbMaxToken);
|
||||
|
||||
fContextReq = ASC_REQ_STREAM |
|
||||
ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
|
||||
ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
|
||||
|
||||
do
|
||||
{
|
||||
if (!extraData)
|
||||
{
|
||||
WaitForSingleObject(g_ServerEvent, INFINITE);
|
||||
ResetEvent(g_ServerEvent);
|
||||
|
||||
if (g_ServerWait)
|
||||
{
|
||||
if (!ReadFile(g_ServerReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
|
||||
{
|
||||
printf("Failed to read from server pipe\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NumberOfBytesRead = 0;
|
||||
}
|
||||
}
|
||||
extraData = FALSE;
|
||||
|
||||
printf("Server Received %d bytes:\n", NumberOfBytesRead);
|
||||
winpr_HexDump(lpTokenIn, NumberOfBytesRead);
|
||||
|
||||
SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
|
||||
SecBuffer_in[0].pvBuffer = lpTokenIn;
|
||||
SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
|
||||
|
||||
SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
|
||||
SecBuffer_in[1].pvBuffer = NULL;
|
||||
SecBuffer_in[1].cbBuffer = 0;
|
||||
|
||||
SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
|
||||
SecBufferDesc_in.cBuffers = 2;
|
||||
SecBufferDesc_in.pBuffers = SecBuffer_in;
|
||||
|
||||
SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
|
||||
SecBuffer_out[0].pvBuffer = lpTokenOut;
|
||||
SecBuffer_out[0].cbBuffer = cbMaxToken;
|
||||
|
||||
SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
|
||||
SecBufferDesc_out.cBuffers = 1;
|
||||
SecBufferDesc_out.pBuffers = SecBuffer_out;
|
||||
|
||||
status = table->AcceptSecurityContext(&credentials, SecIsValidHandle(&context) ? &context : NULL,
|
||||
&SecBufferDesc_in, fContextReq, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
|
||||
|
||||
if (status == SEC_E_OK)
|
||||
{
|
||||
printf("AcceptSecurityContext SEC_E_OK, TLS connection complete\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((status != SEC_I_CONTINUE_NEEDED) && (status != SEC_E_INCOMPLETE_MESSAGE))
|
||||
{
|
||||
printf("AcceptSecurityContext unexpected status: 0x%08X\n", status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NumberOfBytesWritten = 0;
|
||||
|
||||
if (status == SEC_I_CONTINUE_NEEDED)
|
||||
printf("AcceptSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
|
||||
else if (status == SEC_E_INCOMPLETE_MESSAGE)
|
||||
printf("AcceptSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
|
||||
|
||||
printf("Server cBuffers: %d pBuffers[0]: %d type: %d\n",
|
||||
SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
|
||||
printf("Server Input cBuffers: %d pBuffers[1]: %d type: %d\n",
|
||||
SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
|
||||
|
||||
if (SecBufferDesc_in.pBuffers[1].BufferType == SECBUFFER_EXTRA)
|
||||
{
|
||||
printf("AcceptSecurityContext SECBUFFER_EXTRA\n");
|
||||
pSecBuffer = &SecBufferDesc_in.pBuffers[1];
|
||||
CopyMemory(lpTokenIn, &lpTokenIn[NumberOfBytesRead - pSecBuffer->cbBuffer], pSecBuffer->cbBuffer);
|
||||
NumberOfBytesRead = pSecBuffer->cbBuffer;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status != SEC_E_INCOMPLETE_MESSAGE)
|
||||
{
|
||||
pSecBuffer = &SecBufferDesc_out.pBuffers[0];
|
||||
winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
|
||||
|
||||
g_ClientWait = TRUE;
|
||||
SetEvent(g_ClientEvent);
|
||||
|
||||
if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
|
||||
{
|
||||
printf("failed to write to client pipe\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ClientWait = FALSE;
|
||||
SetEvent(g_ClientEvent);
|
||||
}
|
||||
|
||||
printf("Server wrote %d bytes\n", NumberOfBytesWritten);
|
||||
}
|
||||
while (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int TestSchannel(int argc, char* argv[])
|
||||
{
|
||||
int index;
|
||||
ALG_ID algId;
|
||||
HANDLE thread;
|
||||
BYTE* lpTokenIn;
|
||||
BYTE* lpTokenOut;
|
||||
TimeStamp expiry;
|
||||
UINT32 cbMaxToken;
|
||||
SCHANNEL_CRED cred;
|
||||
UINT32 fContextReq;
|
||||
ULONG fContextAttr;
|
||||
CtxtHandle context;
|
||||
CredHandle credentials;
|
||||
SECURITY_STATUS status;
|
||||
PSecPkgInfo pPackageInfo;
|
||||
PSecBuffer pSecBuffer;
|
||||
SecBuffer SecBuffer_in[2];
|
||||
SecBuffer SecBuffer_out[1];
|
||||
SecBufferDesc SecBufferDesc_in;
|
||||
SecBufferDesc SecBufferDesc_out;
|
||||
PSecurityFunctionTable table;
|
||||
DWORD NumberOfBytesRead;
|
||||
DWORD NumberOfBytesWritten;
|
||||
SecPkgCred_SupportedAlgs SupportedAlgs;
|
||||
SecPkgCred_CipherStrengths CipherStrengths;
|
||||
SecPkgCred_SupportedProtocols SupportedProtocols;
|
||||
|
||||
sspi_GlobalInit();
|
||||
|
||||
g_ClientEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
g_ServerEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
SecInvalidateHandle(&context);
|
||||
SecInvalidateHandle(&credentials);
|
||||
|
||||
if (!CreatePipe(&g_ClientReadPipe, &g_ClientWritePipe, NULL, 0))
|
||||
{
|
||||
printf("Failed to create client pipe\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!CreatePipe(&g_ServerReadPipe, &g_ServerWritePipe, NULL, 0))
|
||||
{
|
||||
printf("Failed to create server pipe\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) schannel_test_server_thread, NULL, 0, NULL);
|
||||
|
||||
table = InitSecurityInterface();
|
||||
|
||||
status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("QuerySecurityPackageInfo failure: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cbMaxToken = pPackageInfo->cbMaxToken;
|
||||
|
||||
ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
|
||||
cred.dwVersion = SCHANNEL_CRED_VERSION;
|
||||
|
||||
cred.cCreds = 0;
|
||||
cred.paCred = NULL;
|
||||
|
||||
cred.cSupportedAlgs = 0;
|
||||
cred.palgSupportedAlgs = NULL;
|
||||
|
||||
cred.grbitEnabledProtocols = SP_PROT_SSL3TLS1_CLIENTS;
|
||||
|
||||
cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
|
||||
cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
|
||||
cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
|
||||
|
||||
status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME,
|
||||
SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credentials, NULL);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("AcquireCredentialsHandle failure: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZeroMemory(&SupportedAlgs, sizeof(SecPkgCred_SupportedAlgs));
|
||||
status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_ALGS, &SupportedAlgs);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_ALGS failure: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* SupportedAlgs: 15
|
||||
* 0x660E 0x6610 0x6801 0x6603 0x6601 0x8003 0x8004
|
||||
* 0x800C 0x800D 0x800E 0x2400 0xAA02 0xAE06 0x2200 0x2203
|
||||
*/
|
||||
|
||||
printf("SupportedAlgs: %d\n", SupportedAlgs.cSupportedAlgs);
|
||||
|
||||
for (index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
|
||||
{
|
||||
algId = SupportedAlgs.palgSupportedAlgs[index];
|
||||
printf("\t0x%04X CLASS: %d TYPE: %d SID: %d\n", algId,
|
||||
((GET_ALG_CLASS(algId)) >> 13), ((GET_ALG_TYPE(algId)) >> 9), GET_ALG_SID(algId));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
ZeroMemory(&CipherStrengths, sizeof(SecPkgCred_CipherStrengths));
|
||||
status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS, &CipherStrengths);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("QueryCredentialsAttributes SECPKG_ATTR_CIPHER_STRENGTHS failure: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* CipherStrengths: Minimum: 40 Maximum: 256 */
|
||||
|
||||
printf("CipherStrengths: Minimum: %d Maximum: %d\n",
|
||||
CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
|
||||
|
||||
ZeroMemory(&SupportedProtocols, sizeof(SecPkgCred_SupportedProtocols));
|
||||
status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &SupportedProtocols);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_PROTOCOLS failure: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* SupportedProtocols: 0x208A0 */
|
||||
|
||||
printf("SupportedProtocols: 0x%04X\n", SupportedProtocols.grbitProtocol);
|
||||
|
||||
fContextReq = ISC_REQ_STREAM |
|
||||
ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
|
||||
ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
|
||||
|
||||
lpTokenIn = (BYTE*) malloc(cbMaxToken);
|
||||
lpTokenOut = (BYTE*) malloc(cbMaxToken);
|
||||
|
||||
ZeroMemory(&SecBuffer_in, sizeof(SecBuffer_in));
|
||||
ZeroMemory(&SecBuffer_out, sizeof(SecBuffer_out));
|
||||
ZeroMemory(&SecBufferDesc_in, sizeof(SecBufferDesc));
|
||||
ZeroMemory(&SecBufferDesc_out, sizeof(SecBufferDesc));
|
||||
|
||||
g_ClientWait = FALSE;
|
||||
SetEvent(g_ClientEvent);
|
||||
|
||||
do
|
||||
{
|
||||
WaitForSingleObject(g_ClientEvent, INFINITE);
|
||||
ResetEvent(g_ClientEvent);
|
||||
|
||||
if (g_ClientWait)
|
||||
{
|
||||
if (!ReadFile(g_ClientReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
|
||||
{
|
||||
printf("failed to read from server pipe\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NumberOfBytesRead = 0;
|
||||
}
|
||||
|
||||
printf("NumberOfBytesRead: %d\n", NumberOfBytesRead);
|
||||
|
||||
SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
|
||||
SecBuffer_in[0].pvBuffer = lpTokenIn;
|
||||
SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
|
||||
|
||||
SecBuffer_in[1].pvBuffer = NULL;
|
||||
SecBuffer_in[1].cbBuffer = 0;
|
||||
SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
|
||||
|
||||
SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
|
||||
SecBufferDesc_in.cBuffers = 2;
|
||||
SecBufferDesc_in.pBuffers = SecBuffer_in;
|
||||
|
||||
SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
|
||||
SecBuffer_out[0].pvBuffer = lpTokenOut;
|
||||
SecBuffer_out[0].cbBuffer = cbMaxToken;
|
||||
|
||||
SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
|
||||
SecBufferDesc_out.cBuffers = 1;
|
||||
SecBufferDesc_out.pBuffers = SecBuffer_out;
|
||||
|
||||
status = table->InitializeSecurityContext(&credentials, SecIsValidHandle(&context) ? &context : NULL, _T("localhost"),
|
||||
fContextReq, 0, 0, &SecBufferDesc_in, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
|
||||
|
||||
if ((status != SEC_I_CONTINUE_NEEDED) && (status != SEC_E_INCOMPLETE_MESSAGE))
|
||||
{
|
||||
printf("InitializeSecurityContext unexpected status: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NumberOfBytesWritten = 0;
|
||||
|
||||
if (status == SEC_I_CONTINUE_NEEDED)
|
||||
printf("InitializeSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
|
||||
else if (status == SEC_E_INCOMPLETE_MESSAGE)
|
||||
printf("InitializeSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
|
||||
|
||||
printf("Client Output cBuffers: %d pBuffers[0]: %d type: %d\n",
|
||||
SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
|
||||
printf("Client Input cBuffers: %d pBuffers[1]: %d type: %d\n",
|
||||
SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
|
||||
|
||||
if (status != SEC_E_INCOMPLETE_MESSAGE)
|
||||
{
|
||||
pSecBuffer = &SecBufferDesc_out.pBuffers[0];
|
||||
winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
|
||||
|
||||
g_ServerWait = TRUE;
|
||||
SetEvent(g_ServerEvent);
|
||||
|
||||
if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
|
||||
{
|
||||
printf("failed to write to server pipe\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ServerWait = FALSE;
|
||||
SetEvent(g_ServerEvent);
|
||||
}
|
||||
|
||||
printf("Client wrote %d bytes\n", NumberOfBytesWritten);
|
||||
}
|
||||
while(1);
|
||||
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
|
||||
sspi_GlobalFinish();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user