mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #668 from lysannkessler/spikes/hyperv
Allow connections to Hyper-V VMMS
This commit is contained in:
commit
32390d7807
|
@ -329,13 +329,14 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||||
rdpBrush* brush;
|
rdpBrush* brush;
|
||||||
uint32 foreColor;
|
uint32 foreColor;
|
||||||
uint32 backColor;
|
uint32 backColor;
|
||||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
xfContext* context_ = (xfContext*) context;
|
||||||
|
xfInfo* xfi = context_->xfi;
|
||||||
|
|
||||||
brush = &patblt->brush;
|
brush = &patblt->brush;
|
||||||
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
|
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
|
||||||
|
|
||||||
foreColor = freerdp_color_convert_rgb(patblt->foreColor, 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, xfi->srcBpp, 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)
|
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)
|
void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
|
||||||
{
|
{
|
||||||
uint32 color;
|
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);
|
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
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;
|
int i;
|
||||||
uint32 color;
|
uint32 color;
|
||||||
DELTA_RECT* rectangle;
|
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);
|
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
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)
|
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
|
||||||
{
|
{
|
||||||
uint32 color;
|
uint32 color;
|
||||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
xfContext* context_ = (xfContext*) context;
|
||||||
|
xfInfo* xfi = context_->xfi;
|
||||||
|
|
||||||
xf_set_rop2(xfi, line_to->bRop2);
|
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);
|
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||||
XSetForeground(xfi->display, xfi->gc, color);
|
XSetForeground(xfi->display, xfi->gc, color);
|
||||||
|
@ -550,10 +554,11 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
|
||||||
uint32 color;
|
uint32 color;
|
||||||
XPoint* points;
|
XPoint* points;
|
||||||
int width, height;
|
int width, height;
|
||||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
xfContext* context_ = (xfContext*) context;
|
||||||
|
xfInfo* xfi = context_->xfi;
|
||||||
|
|
||||||
xf_set_rop2(xfi, polyline->bRop2);
|
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);
|
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||||
XSetForeground(xfi->display, xfi->gc, color);
|
XSetForeground(xfi->display, xfi->gc, color);
|
||||||
|
@ -636,13 +641,14 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||||
uint32 foreColor;
|
uint32 foreColor;
|
||||||
uint32 backColor;
|
uint32 backColor;
|
||||||
Pixmap pattern = 0;
|
Pixmap pattern = 0;
|
||||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
xfContext* context_ = (xfContext*) context;
|
||||||
|
xfInfo* xfi = context_->xfi;
|
||||||
|
|
||||||
brush = &mem3blt->brush;
|
brush = &mem3blt->brush;
|
||||||
bitmap = (xfBitmap*) mem3blt->bitmap;
|
bitmap = (xfBitmap*) mem3blt->bitmap;
|
||||||
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
|
xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop));
|
||||||
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, 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, xfi->srcBpp, 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)
|
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;
|
xfInfo* xfi = ((xfContext*) context)->xfi;
|
||||||
|
|
||||||
xf_set_rop2(xfi, polygon_sc->bRop2);
|
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;
|
npoints = polygon_sc->numPoints + 1;
|
||||||
points = xmalloc(sizeof(XPoint) * npoints);
|
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);
|
brush = &(polygon_cb->brush);
|
||||||
xf_set_rop2(xfi, polygon_cb->bRop2);
|
xf_set_rop2(xfi, polygon_cb->bRop2);
|
||||||
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, 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, xfi->srcBpp, 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;
|
npoints = polygon_cb->numPoints + 1;
|
||||||
points = xmalloc(sizeof(XPoint) * npoints);
|
points = xmalloc(sizeof(XPoint) * npoints);
|
||||||
|
|
|
@ -35,7 +35,8 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||||
uint8* data;
|
uint8* data;
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
XImage* image;
|
XImage* image;
|
||||||
xfInfo* xfi = ((xfContext*) context)->xfi;
|
xfContext* context_ = (xfContext*) context;
|
||||||
|
xfInfo* xfi = context_->xfi;
|
||||||
|
|
||||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||||
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
|
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)
|
if (bitmap->data != NULL)
|
||||||
{
|
{
|
||||||
data = freerdp_image_convert(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)
|
if (bitmap->ephemeral != true)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +61,7 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||||
{
|
{
|
||||||
if (data != bitmap->data)
|
if (data != bitmap->data)
|
||||||
xfree(bitmap->data);
|
xfree(bitmap->data);
|
||||||
|
|
||||||
bitmap->data = 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)
|
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)?
|
bgcolor = (xfi->clrconv->invert)?
|
||||||
freerdp_color_convert_var_bgr(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, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
freerdp_color_convert_var_rgb(bgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
|
||||||
|
|
||||||
fgcolor = (xfi->clrconv->invert)?
|
fgcolor = (xfi->clrconv->invert)?
|
||||||
freerdp_color_convert_var_bgr(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, xfi->srcBpp, xfi->bpp, xfi->clrconv);
|
freerdp_color_convert_var_rgb(fgcolor, context_->settings->color_depth, xfi->bpp, xfi->clrconv);
|
||||||
|
|
||||||
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
XSetFunction(xfi->display, xfi->gc, GXcopy);
|
||||||
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
|
||||||
|
|
|
@ -269,7 +269,8 @@ struct rdp_settings
|
||||||
ALIGN64 uint32 encryption_level; /* 28 */
|
ALIGN64 uint32 encryption_level; /* 28 */
|
||||||
ALIGN64 boolean authentication; /* 29 */
|
ALIGN64 boolean authentication; /* 29 */
|
||||||
ALIGN64 uint32 negotiationFlags; /* 30 */
|
ALIGN64 uint32 negotiationFlags; /* 30 */
|
||||||
ALIGN64 uint64 paddingB[48 - 31]; /* 31 */
|
ALIGN64 boolean security_layer_negotiation; /* 31 */
|
||||||
|
ALIGN64 uint64 paddingB[48 - 32]; /* 32 */
|
||||||
|
|
||||||
/* Connection Settings */
|
/* Connection Settings */
|
||||||
ALIGN64 uint32 port; /* 48 */
|
ALIGN64 uint32 port; /* 48 */
|
||||||
|
@ -295,7 +296,10 @@ struct rdp_settings
|
||||||
ALIGN64 boolean local; /* 68 */
|
ALIGN64 boolean local; /* 68 */
|
||||||
ALIGN64 boolean authentication_only; /* 69 */
|
ALIGN64 boolean authentication_only; /* 69 */
|
||||||
ALIGN64 boolean from_stdin; /* 70 */
|
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 */
|
/* User Interface Parameters */
|
||||||
ALIGN64 boolean sw_gdi; /* 80 */
|
ALIGN64 boolean sw_gdi; /* 80 */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
#include <freerdp/errorcodes.h>
|
#include <freerdp/errorcodes.h>
|
||||||
|
|
||||||
|
@ -63,13 +64,16 @@
|
||||||
|
|
||||||
boolean rdp_client_connect(rdpRdp* rdp)
|
boolean rdp_client_connect(rdpRdp* rdp)
|
||||||
{
|
{
|
||||||
boolean status;
|
|
||||||
uint32 selectedProtocol;
|
|
||||||
rdpSettings* settings = rdp->settings;
|
rdpSettings* settings = rdp->settings;
|
||||||
|
|
||||||
nego_init(rdp->nego);
|
nego_init(rdp->nego);
|
||||||
nego_set_target(rdp->nego, settings->hostname, settings->port);
|
nego_set_target(rdp->nego, settings->hostname, settings->port);
|
||||||
nego_set_cookie(rdp->nego, settings->username);
|
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);
|
nego_enable_rdp(rdp->nego, settings->rdp_security);
|
||||||
|
|
||||||
if (!settings->ts_gateway)
|
if (!settings->ts_gateway)
|
||||||
|
@ -78,36 +82,23 @@ boolean rdp_client_connect(rdpRdp* rdp)
|
||||||
nego_enable_tls(rdp->nego, settings->tls_security);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedProtocol = rdp->nego->selected_protocol;
|
if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP))
|
||||||
|
|
||||||
if ((selectedProtocol & PROTOCOL_TLS) || (selectedProtocol == PROTOCOL_RDP))
|
|
||||||
{
|
{
|
||||||
if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0)))
|
if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0)))
|
||||||
settings->autologon = true;
|
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_set_blocking_mode(rdp, false);
|
||||||
rdp->state = CONNECTION_STATE_NEGO;
|
rdp->state = CONNECTION_STATE_NEGO;
|
||||||
rdp->finalize_sc_pdus = 0;
|
rdp->finalize_sc_pdus = 0;
|
||||||
|
|
||||||
if (mcs_send_connect_initial(rdp->mcs) != true)
|
if (!mcs_send_connect_initial(rdp->mcs))
|
||||||
{
|
{
|
||||||
if (!connectErrorCode)
|
if (!connectErrorCode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "tpdu.h"
|
#include "tpdu.h"
|
||||||
#include "nego.h"
|
#include "nego.h"
|
||||||
#include "mcs.h"
|
#include "mcs.h"
|
||||||
#include "transport.h"
|
|
||||||
#include "activation.h"
|
#include "activation.h"
|
||||||
|
|
||||||
#include <freerdp/settings.h>
|
#include <freerdp/settings.h>
|
||||||
|
|
|
@ -42,6 +42,24 @@
|
||||||
|
|
||||||
#define FASTPATH_MAX_PACKET_SIZE 0x3FFF
|
#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.
|
* The fastpath header may be two or three bytes long.
|
||||||
* This function assumes that at least two bytes are available in the stream
|
* 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;
|
rdpContext* context = fastpath->rdp->update->context;
|
||||||
rdpPointerUpdate* pointer = update->pointer;
|
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)
|
switch (updateCode)
|
||||||
{
|
{
|
||||||
case FASTPATH_UPDATETYPE_ORDERS:
|
case FASTPATH_UPDATETYPE_ORDERS:
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "nego.h"
|
#include "nego.h"
|
||||||
|
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
static const char* const NEGO_STATE_STRINGS[] =
|
static const char* const NEGO_STATE_STRINGS[] =
|
||||||
{
|
{
|
||||||
"NEGO_STATE_INITIAL",
|
"NEGO_STATE_INITIAL",
|
||||||
|
@ -44,6 +46,8 @@ static const char PROTOCOL_SECURITY_STRINGS[3][4] =
|
||||||
"NLA"
|
"NLA"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boolean nego_security_connect(rdpNego* nego);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Negotiate protocol security and connect.
|
* Negotiate protocol security and connect.
|
||||||
* @param nego
|
* @param nego
|
||||||
|
@ -61,7 +65,31 @@ boolean nego_connect(rdpNego* nego)
|
||||||
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
|
else if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
DEBUG_NEGO("No security protocol is enabled");
|
||||||
nego->state = NEGO_STATE_FAIL;
|
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
|
do
|
||||||
|
@ -93,9 +121,35 @@ boolean nego_connect(rdpNego* nego)
|
||||||
nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
|
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;
|
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.
|
* Connect TCP layer.
|
||||||
* @param nego
|
* @param nego
|
||||||
|
@ -104,21 +158,25 @@ boolean nego_connect(rdpNego* nego)
|
||||||
|
|
||||||
boolean nego_tcp_connect(rdpNego* nego)
|
boolean nego_tcp_connect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (nego->tcp_connected == 0)
|
if (!nego->tcp_connected)
|
||||||
{
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
||||||
if (transport_connect(nego->transport, nego->hostname, nego->port) == false)
|
return nego->tcp_connected;
|
||||||
{
|
}
|
||||||
nego->tcp_connected = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nego->tcp_connected = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int nego_tcp_disconnect(rdpNego* nego)
|
int nego_transport_disconnect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (nego->tcp_connected)
|
if (nego->tcp_connected)
|
||||||
transport_disconnect(nego->transport);
|
transport_disconnect(nego->transport);
|
||||||
|
|
||||||
nego->tcp_connected = 0;
|
nego->tcp_connected = 0;
|
||||||
|
nego->security_connected = 0;
|
||||||
return 1;
|
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.
|
* Attempt negotiating NLA + TLS security.
|
||||||
* @param nego
|
* @param nego
|
||||||
|
@ -147,7 +255,7 @@ void nego_attempt_nla(rdpNego* nego)
|
||||||
|
|
||||||
DEBUG_NEGO("Attempting NLA security");
|
DEBUG_NEGO("Attempting NLA security");
|
||||||
|
|
||||||
if (!nego_tcp_connect(nego))
|
if (!nego_transport_connect(nego))
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +276,7 @@ void nego_attempt_nla(rdpNego* nego)
|
||||||
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
|
DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]);
|
||||||
if (nego->state != NEGO_STATE_FINAL)
|
if (nego->state != NEGO_STATE_FINAL)
|
||||||
{
|
{
|
||||||
nego_tcp_disconnect(nego);
|
nego_transport_disconnect(nego);
|
||||||
|
|
||||||
if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
|
if (nego->enabled_protocols[PROTOCOL_TLS] > 0)
|
||||||
nego->state = NEGO_STATE_TLS;
|
nego->state = NEGO_STATE_TLS;
|
||||||
|
@ -190,7 +298,7 @@ void nego_attempt_tls(rdpNego* nego)
|
||||||
|
|
||||||
DEBUG_NEGO("Attempting TLS security");
|
DEBUG_NEGO("Attempting TLS security");
|
||||||
|
|
||||||
if (!nego_tcp_connect(nego))
|
if (!nego_transport_connect(nego))
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
return;
|
return;
|
||||||
|
@ -210,7 +318,7 @@ void nego_attempt_tls(rdpNego* nego)
|
||||||
|
|
||||||
if (nego->state != NEGO_STATE_FINAL)
|
if (nego->state != NEGO_STATE_FINAL)
|
||||||
{
|
{
|
||||||
nego_tcp_disconnect(nego);
|
nego_transport_disconnect(nego);
|
||||||
|
|
||||||
if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
|
if (nego->enabled_protocols[PROTOCOL_RDP] > 0)
|
||||||
nego->state = NEGO_STATE_RDP;
|
nego->state = NEGO_STATE_RDP;
|
||||||
|
@ -230,7 +338,7 @@ void nego_attempt_rdp(rdpNego* nego)
|
||||||
|
|
||||||
DEBUG_NEGO("Attempting RDP security");
|
DEBUG_NEGO("Attempting RDP security");
|
||||||
|
|
||||||
if (!nego_tcp_connect(nego))
|
if (!nego_transport_connect(nego))
|
||||||
{
|
{
|
||||||
nego->state = NEGO_STATE_FAIL;
|
nego->state = NEGO_STATE_FAIL;
|
||||||
return;
|
return;
|
||||||
|
@ -261,7 +369,7 @@ boolean nego_recv_response(rdpNego* nego)
|
||||||
if (transport_read(nego->transport, s) < 0)
|
if (transport_read(nego->transport, s) < 0)
|
||||||
return false;
|
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;
|
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.
|
* Enable RDP security protocol.
|
||||||
* @param nego pointer to the negotiation structure
|
* @param nego pointer to the negotiation structure
|
||||||
|
@ -761,3 +881,36 @@ void nego_set_cookie(rdpNego* nego, char* cookie)
|
||||||
{
|
{
|
||||||
nego->cookie = 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;
|
||||||
|
}
|
||||||
|
|
|
@ -68,24 +68,40 @@ enum RDP_NEG_MSG
|
||||||
|
|
||||||
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
|
#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
|
struct rdp_nego
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
char* hostname;
|
char* hostname;
|
||||||
char* cookie;
|
char* cookie;
|
||||||
NEGO_STATE state;
|
|
||||||
int tcp_connected;
|
|
||||||
rdpBlob* routing_token;
|
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 selected_protocol;
|
||||||
uint32 requested_protocols;
|
uint32 requested_protocols;
|
||||||
|
boolean security_layer_negotiation_enabled;
|
||||||
uint8 enabled_protocols[3];
|
uint8 enabled_protocols[3];
|
||||||
|
|
||||||
rdpTransport* transport;
|
rdpTransport* transport;
|
||||||
};
|
};
|
||||||
typedef struct rdp_nego rdpNego;
|
typedef struct rdp_nego rdpNego;
|
||||||
|
|
||||||
boolean nego_connect(rdpNego* nego);
|
boolean nego_connect(rdpNego* nego);
|
||||||
|
|
||||||
|
boolean nego_send_preconnection_pdu(rdpNego* nego);
|
||||||
|
|
||||||
void nego_attempt_nla(rdpNego* nego);
|
void nego_attempt_nla(rdpNego* nego);
|
||||||
void nego_attempt_tls(rdpNego* nego);
|
void nego_attempt_tls(rdpNego* nego);
|
||||||
void nego_attempt_rdp(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_free(rdpNego* nego);
|
||||||
void nego_init(rdpNego* nego);
|
void nego_init(rdpNego* nego);
|
||||||
void nego_set_target(rdpNego* nego, char* hostname, int port);
|
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_rdp(rdpNego* nego, boolean enable_rdp);
|
||||||
void nego_enable_nla(rdpNego* nego, boolean enable_nla);
|
void nego_enable_nla(rdpNego* nego, boolean enable_nla);
|
||||||
void nego_enable_tls(rdpNego* nego, boolean enable_tls);
|
void nego_enable_tls(rdpNego* nego, boolean enable_tls);
|
||||||
void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token);
|
void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token);
|
||||||
void nego_set_cookie(rdpNego* nego, char* cookie);
|
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
|
#ifdef WITH_DEBUG_NEGO
|
||||||
#define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__)
|
#define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__)
|
||||||
|
|
|
@ -97,6 +97,7 @@ rdpSettings* settings_new(void* instance)
|
||||||
settings->nla_security = true;
|
settings->nla_security = true;
|
||||||
settings->tls_security = true;
|
settings->tls_security = true;
|
||||||
settings->rdp_security = true;
|
settings->rdp_security = true;
|
||||||
|
settings->security_layer_negotiation = true;
|
||||||
settings->client_build = 2600;
|
settings->client_build = 2600;
|
||||||
settings->kbd_type = 4; /* @msdn{cc240510} 'IBM enhanced (101- or 102-key) keyboard' */
|
settings->kbd_type = 4; /* @msdn{cc240510} 'IBM enhanced (101- or 102-key) keyboard' */
|
||||||
settings->kbd_subtype = 0;
|
settings->kbd_subtype = 0;
|
||||||
|
|
|
@ -122,6 +122,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||||
" --disable-full-window-drag: disables full window drag\n"
|
" --disable-full-window-drag: disables full window drag\n"
|
||||||
" --disable-menu-animations: disables menu animations\n"
|
" --disable-menu-animations: disables menu animations\n"
|
||||||
" --disable-theming: disables theming\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-rdp: disable Standard RDP encryption\n"
|
||||||
" --no-tls: disable TLS encryption\n"
|
" --no-tls: disable TLS encryption\n"
|
||||||
" --no-nla: disable network level authentication\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"
|
" --tsg: Terminal Server Gateway (<username> <password> <hostname>)\n"
|
||||||
" --kbd-list: list all keyboard layout ids used by -k\n"
|
" --kbd-list: list all keyboard layout ids used by -k\n"
|
||||||
" --no-salted-checksum: disable salted checksums with Standard RDP encryption\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"
|
" --version: print version information\n"
|
||||||
"\n", argv[0]);
|
"\n", argv[0]);
|
||||||
return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */
|
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;
|
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)
|
else if (strcmp("--tsg", argv[index]) == 0)
|
||||||
{
|
{
|
||||||
settings->ts_gateway = true;
|
settings->ts_gateway = true;
|
||||||
|
@ -698,6 +705,28 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||||
{
|
{
|
||||||
settings->salted_checksum = false;
|
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)
|
else if (strcmp("--version", argv[index]) == 0)
|
||||||
{
|
{
|
||||||
printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL);
|
printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL);
|
||||||
|
|
Loading…
Reference in New Issue