20 #include <freerdp/config.h>
22 #include "../settings.h"
23 #include "ncacn_http.h"
25 #include <winpr/crt.h>
26 #include <winpr/tchar.h>
27 #include <winpr/stream.h>
28 #include <winpr/dsparse.h>
32 #define TAG FREERDP_TAG("core.gateway.ntlm")
34 #define AUTH_PKG NTLM_SSP_NAME
36 static wStream* rpc_auth_http_request(HttpContext* http,
const char* method,
size_t contentLength,
37 const SecBuffer* authToken,
const char* auth_scheme)
40 HttpRequest* request = NULL;
41 char* base64AuthToken = NULL;
42 const char* uri = NULL;
47 request = http_request_new();
53 base64AuthToken = crypto_base64_encode(authToken->pvBuffer, authToken->cbBuffer);
55 uri = http_context_get_uri(http);
57 if (!http_request_set_method(request, method) ||
58 !http_request_set_content_length(request, contentLength) ||
59 !http_request_set_uri(request, uri))
64 if (!http_request_set_auth_scheme(request, auth_scheme) ||
65 !http_request_set_auth_param(request, base64AuthToken))
69 s = http_request_write(http, request);
71 http_request_free(request);
72 free(base64AuthToken);
76 BOOL rpc_ncacn_http_send_in_channel_request(
RpcChannel* inChannel)
80 rdpCredsspAuth* auth = NULL;
81 HttpContext* http = NULL;
85 if (!inChannel || !inChannel->auth || !inChannel->http)
88 auth = inChannel->auth;
89 http = inChannel->http;
91 rc = credssp_auth_authenticate(auth);
95 const size_t contentLength = (rc == 0) ? 0 : 0x40000000;
96 buffer = credssp_auth_have_output_token(auth) ? credssp_auth_get_output_buffer(auth) : NULL;
97 s = rpc_auth_http_request(http,
"RPC_IN_DATA", contentLength, buffer,
98 credssp_auth_pkg_name(auth));
103 status = rpc_channel_write(inChannel, Stream_Buffer(s), Stream_Length(s));
104 Stream_Free(s, TRUE);
105 return (status > 0) ? 1 : -1;
108 BOOL rpc_ncacn_http_recv_in_channel_response(
RpcChannel* inChannel, HttpResponse* response)
110 size_t authTokenLength = 0;
111 BYTE* authTokenData = NULL;
113 if (!inChannel || !response || !inChannel->auth)
116 rdpCredsspAuth* auth = inChannel->auth;
117 const char* token64 = http_response_get_auth_token(response, credssp_auth_pkg_name(auth));
120 crypto_base64_decode(token64, strlen(token64), &authTokenData, &authTokenLength);
122 if (authTokenLength > UINT32_MAX)
128 SecBuffer buffer = { .pvBuffer = authTokenData, .cbBuffer = (UINT32)authTokenLength };
130 if (authTokenData && authTokenLength)
132 credssp_auth_take_input_buffer(auth, &buffer);
136 sspi_SecBufferFree(&buffer);
140 BOOL rpc_ncacn_http_auth_init(rdpContext* context,
RpcChannel* channel)
143 rdpCredsspAuth* auth = NULL;
144 rdpSettings* settings = NULL;
145 freerdp* instance = NULL;
146 auth_status rc = AUTH_FAILED;
147 SEC_WINNT_AUTH_IDENTITY identity = { 0 };
149 if (!context || !channel)
153 auth = channel->auth;
154 settings = context->settings;
155 instance = context->instance;
157 if (!tls || !auth || !instance || !settings)
160 rc = utils_authenticate_gateway(instance, GW_AUTH_HTTP);
167 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
169 case AUTH_NO_CREDENTIALS:
170 WLog_INFO(TAG,
"No credentials provided - using NULL identity");
177 if (!credssp_auth_init(auth, AUTH_PKG, tls->Bindings))
180 if (!identity_set_from_settings(&identity, settings, FreeRDP_GatewayUsername,
181 FreeRDP_GatewayDomain, FreeRDP_GatewayPassword))
184 SEC_WINNT_AUTH_IDENTITY* identityArg = (settings->GatewayUsername ? &identity : NULL);
186 credssp_auth_setup_client(auth,
"HTTP", settings->GatewayHostname, identityArg, NULL);
188 sspi_FreeAuthIdentity(&identity);
190 credssp_auth_set_flags(auth, ISC_REQ_CONFIDENTIALITY);
195 void rpc_ncacn_http_auth_uninit(
RpcChannel* channel)
200 credssp_auth_free(channel->auth);
201 channel->auth = NULL;
204 BOOL rpc_ncacn_http_send_out_channel_request(
RpcChannel* outChannel, BOOL replacement)
208 size_t contentLength = 0;
209 rdpCredsspAuth* auth = NULL;
210 HttpContext* http = NULL;
214 if (!outChannel || !outChannel->auth || !outChannel->http)
217 auth = outChannel->auth;
218 http = outChannel->http;
220 rc = credssp_auth_authenticate(auth);
225 contentLength = (rc == 0) ? 0 : 76;
227 contentLength = (rc == 0) ? 0 : 120;
229 buffer = credssp_auth_have_output_token(auth) ? credssp_auth_get_output_buffer(auth) : NULL;
230 s = rpc_auth_http_request(http,
"RPC_OUT_DATA", contentLength, buffer,
231 credssp_auth_pkg_name(auth));
236 if (rpc_channel_write(outChannel, Stream_Buffer(s), Stream_Length(s)) < 0)
239 Stream_Free(s, TRUE);
243 BOOL rpc_ncacn_http_recv_out_channel_response(
RpcChannel* outChannel, HttpResponse* response)
245 size_t authTokenLength = 0;
246 BYTE* authTokenData = NULL;
248 if (!outChannel || !response || !outChannel->auth)
251 rdpCredsspAuth* auth = outChannel->auth;
252 const char* token64 = http_response_get_auth_token(response, credssp_auth_pkg_name(auth));
255 crypto_base64_decode(token64, strlen(token64), &authTokenData, &authTokenLength);
257 if (authTokenLength > UINT32_MAX)
262 SecBuffer buffer = { .pvBuffer = authTokenData, .cbBuffer = (UINT32)authTokenLength };
264 if (authTokenData && authTokenLength)
266 credssp_auth_take_input_buffer(auth, &buffer);
270 sspi_SecBufferFree(&buffer);
274 BOOL rpc_ncacn_http_is_final_request(
RpcChannel* channel)
276 WINPR_ASSERT(channel);
277 return credssp_auth_is_complete(channel->auth);