Merge branch 'master' of github.com:FreeRDP/FreeRDP into winpr

This commit is contained in:
Marc-André Moreau 2012-07-26 12:41:49 -04:00
commit 984a8c97a3
14 changed files with 370 additions and 72 deletions

View File

@ -4,4 +4,8 @@ To create your own virtual channel plugin, copy this directory
then change all references of "skel" to your plugin name
remember, plugin name are 7 chars or less, no spaces or funny chars
server_chan_test.cpp is an example of how to open a channel to the client
this code needs to be compiled and run on the server in an rdp session
when connect with a client that has the "skel" plugin loaded
Jay

View File

@ -0,0 +1,60 @@
// xrdp_chan_test.cpp : Basic test for virtual channel use.
// These headers are required for the windows terminal service calls.
#include "windows.h"
#include "wtsapi32.h"
#include <string>
#define DSIZE 1024
int main()
{
// Initialize the data for send/receive
char* data;
char* data1;
data = (char*)malloc(DSIZE);
data1 = (char*)malloc(DSIZE);
memset(data, 0xca, DSIZE);
memset(data1, 0, DSIZE);
// Open the skel channel in current session
void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0);
unsigned long written = 0;
// Write the data to the channel
bool ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written);
if (!ret)
{
long err = GetLastError();
printf("error 0x%8.8x\n", err);
return 1;
}
ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written);
if (!ret)
{
long err = GetLastError();
printf("error 0x%8.8x\n", err);
return 1;
}
if (written != DSIZE)
{
printf("error read %d\n", written);
return 1;
}
ret = WTSVirtualChannelClose(channel);
if (memcmp(data, data1, DSIZE) == 0)
{
}
else
{
printf("error data no match\n");
return 1;
}
printf("Success!\n");
Sleep(2000);
return 0;
}

View File

@ -58,19 +58,25 @@ static void skel_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
if (skel == NULL)
{
printf("skel_process_receive: skel is nil\n");
return;
}
/* process data in(from server) here */
/* here we just send the same data back */
bytes = stream_get_length(data_in);
bytes = stream_get_size(data_in);
printf("skel_process_receive: got bytes %d\n", bytes);
if (bytes > 0)
{
data_out = stream_new(bytes);
stream_copy(data_out, data_in, bytes);
/* svc_plugin_send takes ownership of data_out, that is why
we do not free it */
bytes = stream_get_length(data_in);
printf("skel_process_receive: sending bytes %d\n", bytes);
svc_plugin_send(plugin, data_out);
}

View File

@ -329,13 +329,14 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
rdpBrush* brush;
uint32 foreColor;
uint32 backColor;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
foreColor = freerdp_color_convert_rgb(patblt->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(patblt->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_rgb(patblt->foreColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(patblt->backColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
if (brush->style == GDI_BS_SOLID)
{
@ -436,9 +437,10 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
{
uint32 color;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
color = freerdp_color_convert_var(opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
color = freerdp_color_convert_var(opaque_rect->color, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -466,9 +468,10 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
int i;
uint32 color;
DELTA_RECT* rectangle;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
color = freerdp_color_convert_var(multi_opaque_rect->color, xfi->srcBpp, xfi->bpp, xfi->clrconv);
color = freerdp_color_convert_var(multi_opaque_rect->color, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
@ -503,10 +506,11 @@ void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
{
uint32 color;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
xf_set_rop2(xfi, line_to->bRop2);
color = freerdp_color_convert_rgb(line_to->penColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
color = freerdp_color_convert_rgb(line_to->penColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
@ -550,10 +554,11 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
uint32 color;
XPoint* points;
int width, height;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
xf_set_rop2(xfi, polyline->bRop2);
color = freerdp_color_convert_var(polyline->penColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
color = freerdp_color_convert_var(polyline->penColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
@ -636,13 +641,14 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
uint32 foreColor;
uint32 backColor;
Pixmap pattern = 0;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
brush = &mem3blt->brush;
bitmap = (xfBitmap*) mem3blt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(mem3blt->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(mem3blt->backColor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
if (brush->style == GDI_BS_PATTERN)
{
@ -711,7 +717,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
xfInfo* xfi = ((xfContext*) context)->xfi;
xf_set_rop2(xfi, polygon_sc->bRop2);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv);
npoints = polygon_sc->numPoints + 1;
points = xmalloc(sizeof(XPoint) * npoints);
@ -768,8 +774,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
brush = &(polygon_cb->brush);
xf_set_rop2(xfi, polygon_cb->bRop2);
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv);
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, ((xfContext*)context)->settings->color_depth, xfi->bpp, xfi->clrconv);
npoints = polygon_cb->numPoints + 1;
points = xmalloc(sizeof(XPoint) * npoints);

View File

@ -35,7 +35,8 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
uint8* data;
Pixmap pixmap;
XImage* image;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
XSetFunction(xfi->display, xfi->gc, GXcopy);
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
@ -43,7 +44,7 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
if (bitmap->data != NULL)
{
data = freerdp_image_convert(bitmap->data, NULL,
bitmap->width, bitmap->height, xfi->srcBpp, xfi->bpp, xfi->clrconv);
bitmap->width, bitmap->height, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
if (bitmap->ephemeral != true)
{
@ -60,7 +61,7 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
if (data != bitmap->data)
xfree(bitmap->data);
bitmap->data = data;
}
}
@ -270,15 +271,16 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
bgcolor = (xfi->clrconv->invert)?
freerdp_color_convert_var_bgr(bgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(bgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
freerdp_color_convert_var_bgr(bgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(bgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
fgcolor = (xfi->clrconv->invert)?
freerdp_color_convert_var_bgr(fgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(fgcolor, xfi->srcBpp, xfi->bpp, xfi->clrconv);
freerdp_color_convert_var_bgr(fgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(fgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);

View File

@ -269,7 +269,8 @@ struct rdp_settings
ALIGN64 uint32 encryption_level; /* 28 */
ALIGN64 boolean authentication; /* 29 */
ALIGN64 uint32 negotiationFlags; /* 30 */
ALIGN64 uint64 paddingB[48 - 31]; /* 31 */
ALIGN64 boolean security_layer_negotiation; /* 31 */
ALIGN64 uint64 paddingB[48 - 32]; /* 32 */
/* Connection Settings */
ALIGN64 uint32 port; /* 48 */
@ -295,7 +296,10 @@ struct rdp_settings
ALIGN64 boolean local; /* 68 */
ALIGN64 boolean authentication_only; /* 69 */
ALIGN64 boolean from_stdin; /* 70 */
ALIGN64 uint64 paddingC[80 - 71]; /* 71 */
ALIGN64 boolean send_preconnection_pdu; /* 71 */
ALIGN64 uint32 preconnection_id; /* 72 */
ALIGN64 char* preconnection_blob; /* 73 */
ALIGN64 uint64 paddingC[80 - 74]; /* 74 */
/* User Interface Parameters */
ALIGN64 boolean sw_gdi; /* 80 */

View File

@ -21,6 +21,7 @@
#include "input.h"
#include "connection.h"
#include "transport.h"
#include <freerdp/errorcodes.h>
@ -63,13 +64,16 @@
boolean rdp_client_connect(rdpRdp* rdp)
{
boolean status;
uint32 selectedProtocol;
rdpSettings* settings = rdp->settings;
nego_init(rdp->nego);
nego_set_target(rdp->nego, settings->hostname, settings->port);
nego_set_cookie(rdp->nego, settings->username);
nego_set_send_preconnection_pdu(rdp->nego, settings->send_preconnection_pdu);
nego_set_preconnection_id(rdp->nego, settings->preconnection_id);
nego_set_preconnection_blob(rdp->nego, settings->preconnection_blob);
nego_set_negotiation_enabled(rdp->nego, settings->security_layer_negotiation);
nego_enable_rdp(rdp->nego, settings->rdp_security);
if (!settings->ts_gateway)
@ -78,36 +82,23 @@ boolean rdp_client_connect(rdpRdp* rdp)
nego_enable_tls(rdp->nego, settings->tls_security);
}
if (nego_connect(rdp->nego) != true)
if (!nego_connect(rdp->nego))
{
printf("Error: protocol security negotiation failure\n");
printf("Error: protocol security negotiation or connection failure\n");
return false;
}
selectedProtocol = rdp->nego->selected_protocol;
if ((selectedProtocol & PROTOCOL_TLS) || (selectedProtocol == PROTOCOL_RDP))
if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP))
{
if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0)))
settings->autologon = true;
}
status = false;
if (selectedProtocol & PROTOCOL_NLA)
status = transport_connect_nla(rdp->transport);
else if (selectedProtocol & PROTOCOL_TLS)
status = transport_connect_tls(rdp->transport);
else if (selectedProtocol == PROTOCOL_RDP) /* 0 */
status = transport_connect_rdp(rdp->transport);
if (status != true)
return false;
rdp_set_blocking_mode(rdp, false);
rdp->state = CONNECTION_STATE_NEGO;
rdp->finalize_sc_pdus = 0;
if (mcs_send_connect_initial(rdp->mcs) != true)
if (!mcs_send_connect_initial(rdp->mcs))
{
if (!connectErrorCode)
{

View File

@ -25,7 +25,6 @@
#include "tpdu.h"
#include "nego.h"
#include "mcs.h"
#include "transport.h"
#include "activation.h"
#include <freerdp/settings.h>

View File

@ -42,6 +42,24 @@
#define FASTPATH_MAX_PACKET_SIZE 0x3FFF
#ifdef WITH_DEBUG_RDP
static const char* const FASTPATH_UPDATETYPE_STRINGS[] =
{
"Orders", /* 0x0 */
"Bitmap", /* 0x1 */
"Palette", /* 0x2 */
"Synchronize", /* 0x3 */
"Surface Commands", /* 0x4 */
"System Pointer Hidden", /* 0x5 */
"System Pointer Default", /* 0x6 */
"???", /* 0x7 */
"Pointer Position", /* 0x8 */
"Color Pointer", /* 0x9 */
"Cached Pointer", /* 0xA */
"New Pointer", /* 0xB */
};
#endif
/*
* The fastpath header may be two or three bytes long.
* This function assumes that at least two bytes are available in the stream
@ -170,6 +188,11 @@ static boolean fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uin
rdpContext* context = fastpath->rdp->update->context;
rdpPointerUpdate* pointer = update->pointer;
#ifdef WITH_DEBUG_RDP
DEBUG_RDP("recv Fast-Path %s Update (0x%X), length:%d",
updateCode < ARRAY_SIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, size);
#endif
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:

View File

@ -27,6 +27,8 @@
#include "nego.h"
#include "transport.h"
static const char* const NEGO_STATE_STRINGS[] =
{
"NEGO_STATE_INITIAL",
@ -44,6 +46,8 @@ static const char PROTOCOL_SECURITY_STRINGS[3][4] =
"NLA"
};
boolean nego_security_connect(rdpNego* nego);
/**
* Negotiate protocol security and connect.
* @param nego
@ -61,7 +65,31 @@ boolean nego_connect(rdpNego* nego)
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
nego->state = NEGO_STATE_RDP;
else
{
DEBUG_NEGO("No security protocol is enabled");
nego->state = NEGO_STATE_FAIL;
}
if (!nego->security_layer_negotiation_enabled)
{
DEBUG_NEGO("Security Layer Negotiation is disabled");
nego->enabled_protocols[PROTOCOL_NLA] = 0;
nego->enabled_protocols[PROTOCOL_TLS] = 0;
nego->enabled_protocols[PROTOCOL_RDP] = 0;
if(nego->state == NEGO_STATE_NLA)
nego->enabled_protocols[PROTOCOL_NLA] = 1;
else if (nego->state == NEGO_STATE_TLS)
nego->enabled_protocols[PROTOCOL_TLS] = 1;
else if (nego->state == NEGO_STATE_RDP)
nego->enabled_protocols[PROTOCOL_RDP] = 1;
}
if(!nego_send_preconnection_pdu(nego))
{
DEBUG_NEGO("Failed to send preconnection information");
nego->state = NEGO_STATE_FINAL;
return false;
}
}
do
@ -93,9 +121,35 @@ boolean nego_connect(rdpNego* nego)
nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
}
/* finally connect security layer (if not already done) */
if(!nego_security_connect(nego))
{
DEBUG_NEGO("Failed to connect with %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
return false;
}
return true;
}
/* connect to selected security layer */
boolean nego_security_connect(rdpNego* nego)
{
if(!nego->tcp_connected)
{
nego->security_connected = false;
}
else if (!nego->security_connected)
{
if (nego->enabled_protocols[PROTOCOL_NLA] > 0)
nego->security_connected = transport_connect_nla(nego->transport);
else if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
nego->security_connected = transport_connect_tls(nego->transport);
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
nego->security_connected = transport_connect_rdp(nego->transport);
}
return nego->security_connected;
}
/**
* Connect TCP layer.
* @param nego
@ -104,21 +158,25 @@ boolean nego_connect(rdpNego* nego)
boolean nego_tcp_connect(rdpNego* nego)
{
if (nego->tcp_connected == 0)
{
if (transport_connect(nego->transport, nego->hostname, nego->port) == false)
{
nego->tcp_connected = 0;
return false;
}
else
{
nego->tcp_connected = 1;
return true;
}
}
if (!nego->tcp_connected)
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
return nego->tcp_connected;
}
return true;
/**
* Connect TCP layer. For direct approach, connect security layer as well.
* @param nego
* @return
*/
boolean nego_transport_connect(rdpNego* nego)
{
nego_tcp_connect(nego);
if (nego->tcp_connected && !nego->security_layer_negotiation_enabled)
return nego_security_connect(nego);
return nego->tcp_connected;
}
/**
@ -127,15 +185,65 @@ boolean nego_tcp_connect(rdpNego* nego)
* @return
*/
int nego_tcp_disconnect(rdpNego* nego)
int nego_transport_disconnect(rdpNego* nego)
{
if (nego->tcp_connected)
transport_disconnect(nego->transport);
nego->tcp_connected = 0;
nego->security_connected = 0;
return 1;
}
/**
* Send preconnection information if enabled.
* @param nego
* @return
*/
boolean nego_send_preconnection_pdu(rdpNego* nego)
{
STREAM* s;
uint32 cbSize;
UNICONV* uniconv;
uint16 cchPCB_times2 = 0;
char* wszPCB = NULL;
if(!nego->send_preconnection_pdu)
return true;
DEBUG_NEGO("Sending preconnection PDU");
if(!nego_tcp_connect(nego))
return false;
/* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */
cbSize = PRECONNECTION_PDU_V2_MIN_SIZE;
if(nego->preconnection_blob) {
uniconv = freerdp_uniconv_new();
wszPCB = freerdp_uniconv_out(uniconv, nego->preconnection_blob, &cchPCB_times2);
freerdp_uniconv_free(uniconv);
cchPCB_times2 += 2; /* zero-termination */
cbSize += cchPCB_times2;
}
s = transport_send_stream_init(nego->transport, cbSize);
stream_write_uint32(s, cbSize); /* cbSize */
stream_write_uint32(s, 0); /* Flags */
stream_write_uint32(s, PRECONNECTION_PDU_V2); /* Version */
stream_write_uint32(s, nego->preconnection_id); /* Id */
stream_write_uint16(s, cchPCB_times2 / 2); /* cchPCB */
if(wszPCB)
{
stream_write(s, wszPCB, cchPCB_times2); /* wszPCB */
xfree(wszPCB);
}
if (transport_write(nego->transport, s) < 0)
return false;
return true;
}
/**
* Attempt negotiating NLA + TLS security.
* @param nego
@ -147,7 +255,7 @@ void nego_attempt_nla(rdpNego* nego)
DEBUG_NEGO("Attempting NLA security");
if (!nego_tcp_connect(nego))
if (!nego_transport_connect(nego))
{
nego->state = NEGO_STATE_FAIL;
return;
@ -168,7 +276,7 @@ void nego_attempt_nla(rdpNego* nego)
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
if (nego->state != NEGO_STATE_FINAL)
{
nego_tcp_disconnect(nego);
nego_transport_disconnect(nego);
if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
nego->state = NEGO_STATE_TLS;
@ -190,7 +298,7 @@ void nego_attempt_tls(rdpNego* nego)
DEBUG_NEGO("Attempting TLS security");
if (!nego_tcp_connect(nego))
if (!nego_transport_connect(nego))
{
nego->state = NEGO_STATE_FAIL;
return;
@ -210,7 +318,7 @@ void nego_attempt_tls(rdpNego* nego)
if (nego->state != NEGO_STATE_FINAL)
{
nego_tcp_disconnect(nego);
nego_transport_disconnect(nego);
if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
nego->state = NEGO_STATE_RDP;
@ -230,7 +338,7 @@ void nego_attempt_rdp(rdpNego* nego)
DEBUG_NEGO("Attempting RDP security");
if (!nego_tcp_connect(nego))
if (!nego_transport_connect(nego))
{
nego->state = NEGO_STATE_FAIL;
return;
@ -261,7 +369,7 @@ boolean nego_recv_response(rdpNego* nego)
if (transport_read(nego->transport, s) < 0)
return false;
return nego_recv(nego->transport, s, nego->transport->recv_extra);
return nego_recv(nego->transport, s, nego);
}
/**
@ -704,6 +812,18 @@ void nego_set_target(rdpNego* nego, char* hostname, int port)
nego->port = port;
}
/**
* Enable security layer negotiation.
* @param nego pointer to the negotiation structure
* @param enable_rdp whether to enable security layer negotiation (true for enabled, false for disabled)
*/
void nego_set_negotiation_enabled(rdpNego* nego, boolean security_layer_negotiation_enabled)
{
DEBUG_NEGO("Enabling security layer negotiation: %s", security_layer_negotiation_enabled ? "true" : "false");
nego->security_layer_negotiation_enabled = security_layer_negotiation_enabled;
}
/**
* Enable RDP security protocol.
* @param nego pointer to the negotiation structure
@ -761,3 +881,36 @@ void nego_set_cookie(rdpNego* nego, char* cookie)
{
nego->cookie = cookie;
}
/**
* Enable / disable preconnection PDU.
* @param nego
* @param send_pcpdu
*/
void nego_set_send_preconnection_pdu(rdpNego* nego, boolean send_pcpdu)
{
nego->send_preconnection_pdu = send_pcpdu;
}
/**
* Set preconnection id.
* @param nego
* @param id
*/
void nego_set_preconnection_id(rdpNego* nego, uint32 id)
{
nego->preconnection_id = id;
}
/**
* Set preconnection blob.
* @param nego
* @param blob
*/
void nego_set_preconnection_blob(rdpNego* nego, char* blob)
{
nego->preconnection_blob = blob;
}

View File

@ -68,24 +68,40 @@ enum RDP_NEG_MSG
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
#define PRECONNECTION_PDU_V1_SIZE 16
#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE+2)
#define PRECONNECTION_PDU_V1 1
#define PRECONNECTION_PDU_V2 2
struct rdp_nego
{
int port;
uint32 flags;
char* hostname;
char* cookie;
NEGO_STATE state;
int tcp_connected;
rdpBlob* routing_token;
boolean send_preconnection_pdu;
uint32 preconnection_id;
char* preconnection_blob;
NEGO_STATE state;
boolean tcp_connected;
boolean security_connected;
uint32 selected_protocol;
uint32 requested_protocols;
boolean security_layer_negotiation_enabled;
uint8 enabled_protocols[3];
rdpTransport* transport;
};
typedef struct rdp_nego rdpNego;
boolean nego_connect(rdpNego* nego);
boolean nego_send_preconnection_pdu(rdpNego* nego);
void nego_attempt_nla(rdpNego* nego);
void nego_attempt_tls(rdpNego* nego);
void nego_attempt_rdp(rdpNego* nego);
@ -105,11 +121,15 @@ rdpNego* nego_new(struct rdp_transport * transport);
void nego_free(rdpNego* nego);
void nego_init(rdpNego* nego);
void nego_set_target(rdpNego* nego, char* hostname, int port);
void nego_set_negotiation_enabled(rdpNego* nego, boolean security_layer_negotiation_enabled);
void nego_enable_rdp(rdpNego* nego, boolean enable_rdp);
void nego_enable_nla(rdpNego* nego, boolean enable_nla);
void nego_enable_tls(rdpNego* nego, boolean enable_tls);
void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token);
void nego_set_cookie(rdpNego* nego, char* cookie);
void nego_set_send_preconnection_pdu(rdpNego* nego, boolean send_pcpdu);
void nego_set_preconnection_id(rdpNego* nego, uint32 id);
void nego_set_preconnection_blob(rdpNego* nego, char* blob);
#ifdef WITH_DEBUG_NEGO
#define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__)

View File

@ -135,6 +135,7 @@ rdpSettings* settings_new(void* instance)
settings->nla_security = true;
settings->tls_security = true;
settings->rdp_security = true;
settings->security_layer_negotiation = true;
settings->client_build = 2600;
settings->kbd_type = 4; /* @msdn{cc240510} 'IBM enhanced (101- or 102-key) keyboard' */
settings->kbd_subtype = 0;

View File

@ -122,6 +122,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
" --disable-full-window-drag: disables full window drag\n"
" --disable-menu-animations: disables menu animations\n"
" --disable-theming: disables theming\n"
" --no-nego: disable negotiation of security layer and enforce highest enabled security protocol\n"
" --no-rdp: disable Standard RDP encryption\n"
" --no-tls: disable TLS encryption\n"
" --no-nla: disable network level authentication\n"
@ -132,6 +133,8 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
" --tsg: Terminal Server Gateway (<username> <password> <hostname>)\n"
" --kbd-list: list all keyboard layout ids used by -k\n"
" --no-salted-checksum: disable salted checksums with Standard RDP encryption\n"
" --pcid: preconnection id\n"
" --pcb: preconnection blob\n"
" --version: print version information\n"
"\n", argv[0]);
return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */
@ -579,6 +582,10 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
return FREERDP_ARGS_PARSE_FAILURE;
}
}
else if (strcmp("--no-nego", argv[index]) == 0)
{
settings->security_layer_negotiation = false;
}
else if (strcmp("--tsg", argv[index]) == 0)
{
settings->ts_gateway = true;
@ -698,6 +705,28 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
{
settings->salted_checksum = false;
}
else if (strcmp("--pcid", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing preconnection id value\n");
return -1;
}
settings->send_preconnection_pdu = true;
settings->preconnection_id = atoi(argv[index]);
}
else if (strcmp("--pcb", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing preconnection blob value\n");
return -1;
}
settings->send_preconnection_pdu = true;
settings->preconnection_blob = xstrdup(argv[index]);
}
else if (strcmp("--version", argv[index]) == 0)
{
printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL);

View File

@ -360,6 +360,6 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context)
NTLM_AV_PAIR* AvEOL;
AvEOL = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvEOL);
ZeroMemory((void*) AvEOL, 12);
ZeroMemory((void*) AvEOL, 4);
}
}