Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Philippe Auphelle 2012-02-20 16:12:57 +01:00
commit ff33d867b4
131 changed files with 8368 additions and 3384 deletions

View File

@ -24,6 +24,7 @@ set(CMAKE_COLOR_MAKEFILE ON)
# Include cmake modules
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckStructHasMember)
include(FindPkgConfig)
include(TestBigEndian)
@ -96,6 +97,8 @@ check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(stdbool.h HAVE_STDBOOL_H)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
# Libraries that we have a hard dependency on
find_required_package(OpenSSL)
@ -123,8 +126,9 @@ endif()
# Endian
test_big_endian(BIG_ENDIAN)
# Path to put keymaps
set(FREERDP_KEYMAP_PATH "${CMAKE_INSTALL_PREFIX}/freerdp/keymaps")
# Path to put FreeRDP data
set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp")
set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps")
# Path to put plugins
set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp")
@ -150,16 +154,14 @@ endif()
# Sub-directories
add_subdirectory(include)
add_subdirectory(libfreerdp-utils)
if(NOT WIN32)
add_subdirectory(libfreerdp-kbd)
endif()
add_subdirectory(libfreerdp-gdi)
add_subdirectory(libfreerdp-rail)
add_subdirectory(libfreerdp-cache)
add_subdirectory(libfreerdp-codec)
add_subdirectory(libfreerdp-crypto)
add_subdirectory(libfreerdp-auth)
add_subdirectory(libfreerdp-channels)
add_subdirectory(libfreerdp-locale)
add_subdirectory(libfreerdp-core)
if(NOT WIN32)
@ -185,3 +187,4 @@ string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_PROJECT_NAME_lower)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}-${FREERDP_VERSION_FULL}")
include(CPack)

View File

@ -28,7 +28,7 @@ add_library(audin_pulse ${AUDIN_PULSE_SRCS})
set_target_properties(audin_pulse PROPERTIES PREFIX "")
target_link_libraries(audin_pulse freerdp-utils)
target_link_libraries(audin_pulse ${PULSE_LIBRARIES})
target_link_libraries(audin_pulse ${PULSEAUDIO_LIBRARY})
install(TARGETS audin_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -27,6 +27,13 @@ include_directories(${FFMPEG_INCLUDE_DIRS})
add_library(tsmf_ffmpeg ${TSMF_FFMPEG_SRCS})
set_target_properties(tsmf_ffmpeg PROPERTIES PREFIX "")
if(CMAKE_COMPILER_IS_GNUCC)
CHECK_C_COMPILER_FLAG(-Wno-deprecated-declarations Wno-deprecated-declarations)
if(Wno-deprecated-declarations)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
endif()
endif()
target_link_libraries(tsmf_ffmpeg freerdp-utils)
target_link_libraries(tsmf_ffmpeg ${FFMPEG_LIBRARIES})

View File

@ -28,7 +28,7 @@ add_library(tsmf_pulse ${TSMF_PULSE_SRCS})
set_target_properties(tsmf_pulse PROPERTIES PREFIX "")
target_link_libraries(tsmf_pulse freerdp-utils)
target_link_libraries(tsmf_pulse ${PULSE_LIBRARIES})
target_link_libraries(tsmf_pulse ${PULSEAUDIO_LIBRARY})
install(TARGETS tsmf_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -28,6 +28,6 @@ add_library(rdpsnd_pulse ${RDPSND_PULSE_SRCS})
set_target_properties(rdpsnd_pulse PROPERTIES PREFIX "")
target_link_libraries(rdpsnd_pulse freerdp-utils)
target_link_libraries(rdpsnd_pulse ${PULSE_LIBRARIES})
target_link_libraries(rdpsnd_pulse ${PULSEAUDIO_LIBRARY})
install(TARGETS rdpsnd_pulse DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -29,7 +29,7 @@ add_executable(dfreerdp
target_link_libraries(dfreerdp freerdp-core)
target_link_libraries(dfreerdp freerdp-gdi)
target_link_libraries(dfreerdp freerdp-kbd)
target_link_libraries(dfreerdp freerdp-locale)
target_link_libraries(dfreerdp freerdp-channels)
target_link_libraries(dfreerdp freerdp-utils)
target_link_libraries(dfreerdp ${DIRECTFB_LIBRARIES})

View File

@ -17,8 +17,7 @@
* limitations under the License.
*/
#include <freerdp/kbd/kbd.h>
#include <freerdp/kbd/vkcodes.h>
#include <freerdp/locale/keyboard.h>
#include "df_event.h"
@ -203,7 +202,7 @@ void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8
else
return;
scancode = freerdp_kbd_get_scancode_by_virtualkey(vkcode, &extended);
scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vkcode, &extended);
flags = (extended) ? KBD_FLAGS_EXTENDED : 0;
flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;

View File

@ -89,7 +89,7 @@ include_directories(${CMAKE_SOURCE_DIR}/resources)
target_link_libraries(xfreerdp freerdp-core)
target_link_libraries(xfreerdp freerdp-gdi)
target_link_libraries(xfreerdp freerdp-kbd)
target_link_libraries(xfreerdp freerdp-locale)
target_link_libraries(xfreerdp freerdp-rail)
target_link_libraries(xfreerdp freerdp-channels)
target_link_libraries(xfreerdp freerdp-utils)

View File

@ -20,8 +20,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <freerdp/kbd/kbd.h>
#include <freerdp/kbd/vkcodes.h>
#include <freerdp/locale/keyboard.h>
#include "xf_rail.h"
#include "xf_window.h"

View File

@ -73,15 +73,15 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXclear;
break;
case 0x000500A9:
case GDI_DPon:
function = GXnor;
break;
case 0x000A0329:
case GDI_DPna:
function = GXandInverted;
break;
case 0x000F0001:
case GDI_Pn:
function = GXcopyInverted;
break;
@ -101,7 +101,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXandReverse;
break;
case 0x00500325:
case GDI_PDna:
function = GXandReverse;
break;
@ -113,7 +113,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXxor;
break;
case 0x005F00E9:
case GDI_DPan:
function = GXnand;
break;
@ -121,7 +121,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXxor;
break;
case 0x007700E6:
case GDI_DSan:
function = GXnand;
break;
@ -129,11 +129,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXand;
break;
case 0x00990066:
case GDI_DSxn:
function = GXequiv;
break;
case 0x00A000C9:
case GDI_DPa:
function = GXand;
break;
@ -141,11 +141,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXequiv;
break;
case 0x00AA0029:
case GDI_D:
function = GXnoop;
break;
case 0x00AF0229:
case GDI_DPno:
function = GXorInverted;
break;
@ -157,7 +157,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXcopy;
break;
case 0x00DD0228:
case GDI_SDno:
function = GXorReverse;
break;
@ -169,11 +169,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXcopy;
break;
case 0x00F50225:
case GDI_PDno:
function = GXorReverse;
break;
case 0x00FA0089:
case GDI_DPo:
function = GXor;
break;
@ -181,6 +181,10 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
function = GXset;
break;
case GDI_PSDPxax:
function = GXand;
break;
default:
break;
}
@ -205,17 +209,19 @@ Pixmap xf_brush_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, xfi->depth);
if(data != NULL)
if (data != NULL)
{
GC gc; // FIXME, should cache
GC gc;
cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) cdata, width, height, xfi->scanline_pad, 0);
gc = XCreateGC(xfi->display, xfi->drawable, 0, NULL);
XPutImage(xfi->display, bitmap, gc, image, 0, 0, 0, 0, width, height);
XFree(image);
if (cdata != data)
xfree(cdata);
@ -489,6 +495,11 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
}
}
void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
{
printf("DrawNineGrid\n");
}
void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
{
uint32 color;
@ -542,7 +553,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
xfInfo* xfi = ((xfContext*) context)->xfi;
xf_set_rop2(xfi, polyline->bRop2);
color = freerdp_color_convert_rgb(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv);
color = freerdp_color_convert_var(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, color);
@ -620,7 +631,242 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
rdpBrush* brush;
xfBitmap* bitmap;
uint32 foreColor;
uint32 backColor;
Pixmap pattern = 0;
xfInfo* xfi = ((xfContext*) 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, 32, xfi->clrconv);
backColor = freerdp_color_convert_rgb(mem3blt->backColor, xfi->srcBpp, 32, xfi->clrconv);
if (brush->style == GDI_BS_PATTERN)
{
if (brush->bpp > 1)
{
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
XSetTile(xfi->display, xfi->gc, pattern);
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
}
else
{
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
XSetForeground(xfi->display, xfi->gc, backColor);
XSetBackground(xfi->display, xfi->gc, foreColor);
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
XSetStipple(xfi->display, xfi->gc, pattern);
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
}
}
else if (brush->style == GDI_BS_SOLID)
{
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, backColor);
XSetBackground(xfi->display, xfi->gc, foreColor);
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
}
else
{
printf("Mem3Blt unimplemented brush style:%d\n", brush->style);
}
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc,
mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
mem3blt->nLeftRect, mem3blt->nTopRect);
if (xfi->drawing == xfi->primary)
{
if (xfi->remote_app != true)
{
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc,
mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight,
mem3blt->nLeftRect, mem3blt->nTopRect);
}
gdi_InvalidateRegion(xfi->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight);
}
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
if (pattern != 0)
XFreePixmap(xfi->display, pattern);
XSetFunction(xfi->display, xfi->gc, GXcopy);
}
void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
{
int i, npoints;
XPoint* points;
uint32 brush_color;
xfInfo* xfi = ((xfContext*) context)->xfi;
xf_set_rop2(xfi, polygon_sc->bRop2);
brush_color = freerdp_color_convert_var(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv);
npoints = polygon_sc->numPoints + 1;
points = xmalloc(sizeof(XPoint) * npoints);
points[0].x = polygon_sc->xStart;
points[0].y = polygon_sc->yStart;
for (i = 0; i < polygon_sc->numPoints; i++)
{
points[i + 1].x = polygon_sc->points[i].x;
points[i + 1].y = polygon_sc->points[i].y;
}
switch (polygon_sc->fillMode)
{
case 1: /* alternate */
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
break;
case 2: /* winding */
XSetFillRule(xfi->display, xfi->gc, WindingRule);
break;
default:
printf("PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode);
break;
}
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, brush_color);
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
points, npoints, Complex, CoordModePrevious);
if (xfi->drawing == xfi->primary)
{
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
points, npoints, Complex, CoordModePrevious);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
xfree(points);
}
void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
{
int i, npoints;
XPoint* points;
Pixmap pattern;
rdpBrush* brush;
uint32 foreColor;
uint32 backColor;
xfInfo* xfi = ((xfContext*) context)->xfi;
brush = &(polygon_cb->brush);
xf_set_rop2(xfi, polygon_cb->bRop2);
foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, 32, xfi->clrconv);
backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, 32, xfi->clrconv);
npoints = polygon_cb->numPoints + 1;
points = xmalloc(sizeof(XPoint) * npoints);
points[0].x = polygon_cb->xStart;
points[0].y = polygon_cb->yStart;
for (i = 0; i < polygon_cb->numPoints; i++)
{
points[i + 1].x = polygon_cb->points[i].x;
points[i + 1].y = polygon_cb->points[i].y;
}
switch (polygon_cb->fillMode)
{
case 1: /* alternate */
XSetFillRule(xfi->display, xfi->gc, EvenOddRule);
break;
case 2: /* winding */
XSetFillRule(xfi->display, xfi->gc, WindingRule);
break;
default:
printf("PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode);
break;
}
if (brush->style == GDI_BS_PATTERN)
{
if (brush->bpp > 1)
{
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
XSetTile(xfi->display, xfi->gc, pattern);
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
points, npoints, Complex, CoordModePrevious);
if (xfi->drawing == xfi->primary)
{
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
points, npoints, Complex, CoordModePrevious);
}
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
XFreePixmap(xfi->display, pattern);
}
else
{
pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data);
XSetForeground(xfi->display, xfi->gc, backColor);
XSetBackground(xfi->display, xfi->gc, foreColor);
if (polygon_cb->backMode == BACKMODE_TRANSPARENT)
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
else if (polygon_cb->backMode == BACKMODE_OPAQUE)
XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled);
XSetStipple(xfi->display, xfi->gc, pattern);
XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y);
XFillPolygon(xfi->display, xfi->drawing, xfi->gc,
points, npoints, Complex, CoordModePrevious);
if (xfi->drawing == xfi->primary)
{
XFillPolygon(xfi->display, xfi->drawable, xfi->gc,
points, npoints, Complex, CoordModePrevious);
}
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetTSOrigin(xfi->display, xfi->gc, 0, 0);
XFreePixmap(xfi->display, pattern);
}
}
else
{
printf("PolygonCB unimplemented brush style:%d\n", brush->style);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
xfree(points);
}
void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
{
printf("EllipseSC\n");
}
void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
{
printf("EllipseCB\n");
}
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
@ -777,10 +1023,10 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
primary->GlyphIndex = NULL;
primary->FastIndex = NULL;
primary->FastGlyph = NULL;
primary->PolygonSC = NULL;
primary->PolygonCB = NULL;
primary->EllipseSC = NULL;
primary->EllipseCB = NULL;
primary->PolygonSC = xf_gdi_polygon_sc;
primary->PolygonCB = xf_gdi_polygon_cb;
primary->EllipseSC = xf_gdi_ellipse_sc;
primary->EllipseCB = xf_gdi_ellipse_cb;
update->SurfaceBits = xf_gdi_surface_bits;
update->SurfaceFrameMarker = xf_gdi_surface_frame_marker;

View File

@ -30,7 +30,7 @@ void xf_kbd_init(xfInfo* xfi)
{
memset(xfi->pressed_keys, 0, 256 * sizeof(boolean));
xfi->keyboard_layout_id = xfi->instance->settings->kbd_layout;
xfi->keyboard_layout_id = freerdp_kbd_init(xfi->display, xfi->keyboard_layout_id);
xfi->keyboard_layout_id = freerdp_keyboard_init(xfi->keyboard_layout_id);
xfi->instance->settings->kbd_layout = xfi->keyboard_layout_id;
}
@ -64,7 +64,7 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode)
rdpInput* input;
input = xfi->instance->input;
scancode = freerdp_kbd_get_scancode_by_keycode(keycode, &extended);
scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode, &extended);
if (scancode == 0)
{

View File

@ -20,8 +20,7 @@
#ifndef __XF_KEYBOARD_H
#define __XF_KEYBOARD_H
#include <freerdp/kbd/kbd.h>
#include <freerdp/kbd/vkcodes.h>
#include <freerdp/locale/keyboard.h>
#include "xfreerdp.h"

View File

@ -137,14 +137,6 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-m</term>
<listitem>
<para>
Don't send mouse motion events.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-n <replaceable class="parameter">hostname</replaceable></term>
<listitem>
@ -298,6 +290,14 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>--no-motion</term>
<listitem>
<para>
Don't send mouse motion events.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>--gdi</term>
<listitem>

View File

@ -481,6 +481,7 @@ boolean xf_pre_connect(freerdp* instance)
settings->os_major_type = OSMAJORTYPE_UNIX;
settings->os_minor_type = OSMINORTYPE_NATIVE_XSERVER;
settings->order_support[NEG_DSTBLT_INDEX] = true;
settings->order_support[NEG_PATBLT_INDEX] = true;
settings->order_support[NEG_SCRBLT_INDEX] = true;
@ -494,15 +495,19 @@ boolean xf_pre_connect(freerdp* instance)
settings->order_support[NEG_LINETO_INDEX] = true;
settings->order_support[NEG_POLYLINE_INDEX] = true;
settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache;
settings->order_support[NEG_MEM3BLT_INDEX] = false;
settings->order_support[NEG_MEM3BLT_INDEX] = (settings->sw_gdi) ? true : false;
settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache;
settings->order_support[NEG_MEM3BLT_V2_INDEX] = false;
settings->order_support[NEG_SAVEBITMAP_INDEX] = false;
settings->order_support[NEG_GLYPH_INDEX_INDEX] = true;
settings->order_support[NEG_FAST_INDEX_INDEX] = true;
settings->order_support[NEG_FAST_GLYPH_INDEX] = true;
settings->order_support[NEG_POLYGON_SC_INDEX] = false;
settings->order_support[NEG_POLYGON_CB_INDEX] = false;
settings->order_support[NEG_POLYGON_SC_INDEX] = (settings->sw_gdi) ? false : true;
settings->order_support[NEG_POLYGON_CB_INDEX] = (settings->sw_gdi) ? false : true;
settings->order_support[NEG_ELLIPSE_SC_INDEX] = false;
settings->order_support[NEG_ELLIPSE_CB_INDEX] = false;
@ -772,21 +777,21 @@ int xf_process_client_args(rdpSettings* settings, const char* opt, const char* v
if (strcmp("--kbd-list", opt) == 0)
{
int i;
rdpKeyboardLayout* layouts;
RDP_KEYBOARD_LAYOUT* layouts;
layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
printf("\nKeyboard Layouts\n");
for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);
free(layouts);
layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
printf("\nKeyboard Layout Variants\n");
for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);
free(layouts);
layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
printf("\nKeyboard Input Method Editors (IMEs)\n");
for (i = 0; layouts[i].code; i++)
printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);

View File

@ -7,6 +7,10 @@
#define FREERDP_VERSION_MINOR ${FREERDP_VERSION_MINOR}
#define FREERDP_VERSION_REVISION ${FREERDP_VERSION_REVISION}
#define FREERDP_DATA_PATH "${FREERDP_DATA_PATH}"
#define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}"
#define FREERDP_KEYMAP_PATH "${FREERDP_KEYMAP_PATH}"
/* Include files */
#cmakedefine HAVE_SYS_PARAM_H
#cmakedefine HAVE_SYS_SOCKET_H
@ -18,6 +22,8 @@
#cmakedefine HAVE_STDBOOL_H
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_TM_GMTOFF
/* Endian */
#cmakedefine BIG_ENDIAN

View File

@ -38,14 +38,16 @@ add_executable(test_freerdp
test_color.h
test_bitmap.c
test_bitmap.h
test_libgdi.c
test_libgdi.h
test_gdi.c
test_gdi.h
test_list.c
test_list.h
test_orders.c
test_orders.h
test_pcap.c
test_pcap.h
test_ntlmssp.c
test_ntlmssp.h
test_license.c
test_license.h
test_stream.c
@ -58,8 +60,8 @@ add_executable(test_freerdp
test_cliprdr.h
test_drdynvc.c
test_drdynvc.h
test_librfx.c
test_librfx.h
test_rfx.c
test_rfx.h
test_freerdp.c
test_freerdp.h
test_rail.c
@ -73,5 +75,7 @@ target_link_libraries(test_freerdp freerdp-gdi)
target_link_libraries(test_freerdp freerdp-utils)
target_link_libraries(test_freerdp freerdp-channels)
target_link_libraries(test_freerdp freerdp-codec)
target_link_libraries(test_freerdp freerdp-crypto)
target_link_libraries(test_freerdp freerdp-auth)
add_test(CUnitTests ${EXECUTABLE_OUTPUT_PATH}/test_freerdp)

View File

@ -22,7 +22,7 @@
#include <freerdp/utils/stream.h>
#include "test_ber.h"
#include "libfreerdp-core/ber.h"
#include <freerdp/crypto/ber.h>
int init_ber_suite(void)
{

View File

@ -27,23 +27,23 @@
#include "test_channels.h"
int init_chanman_suite(void)
int init_channels_suite(void)
{
freerdp_channels_global_init();
return 0;
}
int clean_chanman_suite(void)
int clean_channels_suite(void)
{
freerdp_channels_global_uninit();
return 0;
}
int add_chanman_suite(void)
int add_channels_suite(void)
{
add_test_suite(chanman);
add_test_suite(channels);
add_test_function(chanman);
add_test_function(channels);
return 0;
}
@ -54,7 +54,7 @@ static int test_rdp_channel_data(freerdp* instance, int chan_id, uint8* data, in
return 0;
}
void test_chanman(void)
void test_channels(void)
{
rdpChannels* chan_man;
rdpSettings settings = { 0 };

View File

@ -19,8 +19,8 @@
#include "test_freerdp.h"
int init_chanman_suite(void);
int clean_chanman_suite(void);
int add_chanman_suite(void);
int init_channels_suite(void);
int clean_channels_suite(void);
int add_channels_suite(void);
void test_chanman(void);
void test_channels(void);

View File

@ -25,16 +25,17 @@
#include "test_mcs.h"
#include "test_color.h"
#include "test_bitmap.h"
#include "test_libgdi.h"
#include "test_gdi.h"
#include "test_list.h"
#include "test_stream.h"
#include "test_utils.h"
#include "test_orders.h"
#include "test_ntlmssp.h"
#include "test_license.h"
#include "test_channels.h"
#include "test_cliprdr.h"
#include "test_drdynvc.h"
#include "test_librfx.h"
#include "test_rfx.h"
#include "test_freerdp.h"
#include "test_rail.h"
#include "test_pcap.h"
@ -107,109 +108,80 @@ void assert_stream(STREAM* s, uint8* data, int length, const char* func, int lin
}
}
typedef boolean (*pInitTestSuite)(void);
struct _test_suite
{
char name[32];
pInitTestSuite Init;
};
typedef struct _test_suite test_suite;
static test_suite suites[] =
{
{ "ber", add_ber_suite },
{ "bitmap", add_bitmap_suite },
{ "channels", add_channels_suite },
{ "cliprdr", add_cliprdr_suite },
{ "color", add_color_suite },
{ "drdynvc", add_drdynvc_suite },
{ "gcc", add_gcc_suite },
{ "gdi", add_gdi_suite },
{ "license", add_license_suite },
{ "list", add_list_suite },
{ "mcs", add_mcs_suite },
{ "mppc", add_mppc_suite },
{ "ntlmssp", add_ntlmssp_suite },
{ "orders", add_orders_suite },
{ "pcap", add_pcap_suite },
{ "per", add_per_suite },
{ "rail", add_rail_suite },
{ "rfx", add_rfx_suite },
{ "stream", add_stream_suite },
{ "utils", add_utils_suite },
{ "", NULL }
};
int main(int argc, char* argv[])
{
int k;
int index = 1;
int *pindex = &index;
int ret = 0;
int status = 0;
if (CU_initialize_registry() != CUE_SUCCESS)
return CU_get_error();
if (argc < *pindex + 1)
{
add_per_suite();
add_ber_suite();
add_gcc_suite();
add_mcs_suite();
add_color_suite();
add_bitmap_suite();
add_libgdi_suite();
add_list_suite();
add_orders_suite();
add_license_suite();
add_stream_suite();
add_mppc_suite();
k = 0;
printf("\ntest suites:\n\n");
while (suites[k].Init != NULL)
{
printf("\t%s\n", suites[k].name);
k++;
}
printf("\nusage: ./test_freerdp <suite-1> <suite-2> ... <suite-n>\n");
return 0;
}
else
{
while (*pindex < argc)
{
if (strcmp("rail", argv[*pindex]) == 0)
k = 0;
while (suites[k].Init != NULL)
{
add_rail_suite();
}
if (strcmp("color", argv[*pindex]) == 0)
{
add_color_suite();
}
if (strcmp("bitmap", argv[*pindex]) == 0)
{
add_bitmap_suite();
}
else if (strcmp("libgdi", argv[*pindex]) == 0)
{
add_libgdi_suite();
}
else if (strcmp("list", argv[*pindex]) == 0)
{
add_list_suite();
}
else if (strcmp("orders", argv[*pindex]) == 0)
{
add_orders_suite();
}
else if (strcmp("license", argv[*pindex]) == 0)
{
add_license_suite();
}
else if (strcmp("stream", argv[*pindex]) == 0)
{
add_stream_suite();
}
else if (strcmp("utils", argv[*pindex]) == 0)
{
add_utils_suite();
}
else if (strcmp("chanman", argv[*pindex]) == 0)
{
add_chanman_suite();
}
else if (strcmp("cliprdr", argv[*pindex]) == 0)
{
add_cliprdr_suite();
}
else if (strcmp("drdynvc", argv[*pindex]) == 0)
{
add_drdynvc_suite();
}
else if (strcmp("librfx", argv[*pindex]) == 0)
{
add_librfx_suite();
}
else if (strcmp("per", argv[*pindex]) == 0)
{
add_per_suite();
}
else if (strcmp("pcap", argv[*pindex]) == 0)
{
add_pcap_suite();
}
else if (strcmp("ber", argv[*pindex]) == 0)
{
add_ber_suite();
}
else if (strcmp("gcc", argv[*pindex]) == 0)
{
add_gcc_suite();
}
else if (strcmp("mcs", argv[*pindex]) == 0)
{
add_mcs_suite();
}
else if (strcmp("mppc", argv[*pindex]) == 0)
{
add_mppc_suite();
if (strcmp(suites[k].name, argv[*pindex]) == 0)
{
suites[k].Init();
break;
}
k++;
}
*pindex = *pindex + 1;
@ -218,9 +190,10 @@ int main(int argc, char* argv[])
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
ret = CU_get_number_of_failure_records();
status = CU_get_number_of_failure_records();
CU_cleanup_registry();
return ret;
return status;
}

View File

@ -36,21 +36,21 @@
#include <freerdp/gdi/clipping.h>
#include <freerdp/gdi/32bpp.h>
#include "test_libgdi.h"
#include "test_gdi.h"
int init_libgdi_suite(void)
int init_gdi_suite(void)
{
return 0;
}
int clean_libgdi_suite(void)
int clean_gdi_suite(void)
{
return 0;
}
int add_libgdi_suite(void)
int add_gdi_suite(void)
{
add_test_suite(libgdi);
add_test_suite(gdi);
add_test_function(gdi_GetDC);
add_test_function(gdi_CreateCompatibleDC);

View File

@ -19,9 +19,9 @@
#include "test_freerdp.h"
int init_libgdi_suite(void);
int clean_libgdi_suite(void);
int add_libgdi_suite(void);
int init_gdi_suite(void);
int clean_gdi_suite(void);
int add_gdi_suite(void);
void test_gdi_GetDC(void);
void test_gdi_CreateCompatibleDC(void);

703
cunit/test_ntlmssp.c Normal file
View File

@ -0,0 +1,703 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* NT LAN Manager Security Support Provider (NTLMSSP) Unit Tests
*
* Copyright 2011 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <freerdp/freerdp.h>
#include <freerdp/auth/ntlmssp.h>
#include "test_ntlmssp.h"
int init_ntlmssp_suite(void)
{
return 0;
}
int clean_ntlmssp_suite(void)
{
return 0;
}
int add_ntlmssp_suite(void)
{
add_test_suite(ntlmssp);
add_test_function(ntlmssp_compute_lm_hash);
add_test_function(ntlmssp_compute_ntlm_hash);
add_test_function(ntlmssp_compute_ntlm_v2_hash);
add_test_function(ntlmssp_compute_lm_response);
add_test_function(ntlmssp_compute_lm_v2_response);
add_test_function(ntlmssp_compute_ntlm_v2_response);
add_test_function(ntlmssp_generate_client_signing_key);
add_test_function(ntlmssp_generate_server_signing_key);
add_test_function(ntlmssp_generate_client_sealing_key);
add_test_function(ntlmssp_generate_server_sealing_key);
add_test_function(ntlmssp_encrypt_random_session_key);
add_test_function(ntlmssp_compute_message_integrity_check);
add_test_function(ntlmssp_encrypt_message);
add_test_function(ntlmssp_decrypt_message);
return 0;
}
void test_ntlmssp_compute_lm_hash(void)
{
int i;
int lm_hash_good;
char lm_hash[16];
char password[] = "Password";
char expected_lm_hash[16] = "\xe5\x2c\xac\x67\x41\x9a\x9a\x22\x4a\x3b\x10\x8f\x3f\xa6\xcb\x6d";
ntlmssp_compute_lm_hash(password, lm_hash);
lm_hash_good = 1;
for (i = 0; i < 16; i++) {
if (lm_hash[i] != expected_lm_hash[i])
lm_hash_good = 0;
}
CU_ASSERT(lm_hash_good == 1);
}
void test_ntlmssp_compute_ntlm_hash(void)
{
int i;
NTLMSSP* ntlmssp;
int ntlm_hash_good;
char ntlm_hash[16];
char password[] = "Password";
char expected_ntlm_hash[16] = "\xa4\xf4\x9c\x40\x65\x10\xbd\xca\xb6\x82\x4e\xe7\xc3\x0f\xd8\x52";
ntlmssp = ntlmssp_client_new();
ntlmssp_set_password(ntlmssp, password);
ntlmssp_compute_ntlm_hash(&ntlmssp->password, ntlm_hash);
ntlm_hash_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlm_hash[i] != expected_ntlm_hash[i])
ntlm_hash_good = 0;
}
CU_ASSERT(ntlm_hash_good == 1);
}
void test_ntlmssp_compute_ntlm_v2_hash(void)
{
int i;
NTLMSSP* ntlmssp;
int ntlm_v2_hash_good;
char ntlm_v2_hash[16];
char username[] = "User";
char password[] = "Password";
char domain[] = "Domain";
char expected_ntlm_v2_hash[16] = "\x0c\x86\x8a\x40\x3b\xfd\x7a\x93\xa3\x00\x1e\xf2\x2e\xf0\x2e\x3f";
ntlmssp = ntlmssp_client_new();
ntlmssp_set_password(ntlmssp, password);
ntlmssp_set_username(ntlmssp, username);
ntlmssp_set_domain(ntlmssp, domain);
ntlmssp_compute_ntlm_v2_hash(ntlmssp, ntlm_v2_hash);
ntlm_v2_hash_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlm_v2_hash[i] != expected_ntlm_v2_hash[i])
ntlm_v2_hash_good = 0;
}
CU_ASSERT(ntlm_v2_hash_good == 1);
}
void test_ntlmssp_compute_lm_response(void)
{
int i;
int lm_response_good;
char lm_response[24];
char password[] = "SecREt01";
char challenge[] = "\x01\x23\x45\x67\x89\xAB\xCD\xEF";
char expected_lm_response[24] = "\xC3\x37\xCD\x5C\xBD\x44\xFC\x97\x82\xA6\x67\xAF\x6D\x42\x7C\x6D\xE6\x7C\x20\xC2\xD3\xE7\x7C\x56";
ntlmssp_compute_lm_response(password, challenge, lm_response);
lm_response_good = 1;
for (i = 0; i < 24; i++)
{
if (lm_response[i] != expected_lm_response[i])
lm_response_good = 0;
}
CU_ASSERT(lm_response_good == 1);
}
void test_ntlmssp_compute_lm_v2_response(void)
{
int i;
char *p;
NTLMSSP* ntlmssp;
int lm_v2_response_good;
char password[] = "password";
char username[] = "username";
char domain[] = "win7";
char server_challenge[8] = "\x26\x6e\xcd\x75\xaa\x41\xe7\x6f";
char lm_client_challenge[8] = "\x47\xa2\xe5\xcf\x27\xf7\x3c\x43";
char expected_lm_v2_response[24] = "\xa0\x98\x01\x10\x19\xbb\x5d\x00\xf6\xbe\x00\x33\x90\x20\x34\xb3\x47\xa2\xe5\xcf\x27\xf7\x3c\x43";
ntlmssp = ntlmssp_client_new();
ntlmssp_set_password(ntlmssp, password);
ntlmssp_set_username(ntlmssp, username);
ntlmssp_set_domain(ntlmssp, domain);
memcpy(ntlmssp->server_challenge, server_challenge, 8);
memcpy(ntlmssp->client_challenge, lm_client_challenge, 8);
ntlmssp_compute_lm_v2_response(ntlmssp);
p = (char*) ntlmssp->lm_challenge_response.data;
lm_v2_response_good = 1;
for (i = 0; i < 24; i++)
{
if (p[i] != expected_lm_v2_response[i])
lm_v2_response_good = 0;
}
CU_ASSERT(lm_v2_response_good == 1);
}
void test_ntlmssp_compute_ntlm_v2_response(void)
{
int i;
char* p;
NTLMSSP* ntlmssp;
int session_base_key_good;
int lm_challenge_response_good;
int nt_challenge_response_good;
char password[] = "password";
char username[] = "username";
char domain[] = "win7";
char timestamp[8] = "\xc3\x83\xa2\x1c\x6c\xb0\xcb\x01";
char client_challenge[8] = "\x47\xa2\xe5\xcf\x27\xf7\x3c\x43";
char server_challenge[8] = "\x26\x6e\xcd\x75\xaa\x41\xe7\x6f";
char target_info_data[68] =
"\x02\x00\x08\x00\x57\x00\x49\x00\x4e\x00\x37\x00"
"\x01\x00\x08\x00\x57\x00\x49\x00\x4e\x00\x37\x00"
"\x04\x00\x08\x00\x77\x00\x69\x00\x6e\x00\x37\x00"
"\x03\x00\x08\x00\x77\x00\x69\x00\x6e\x00\x37\x00"
"\x07\x00\x08\x00\xa9\x8d\x9b\x1a\x6c\xb0\xcb\x01"
"\x00\x00\x00\x00\x00\x00\x00\x00";
char expected_nt_challenge_response[112] =
"\x01\x4a\xd0\x8c\x24\xb4\x90\x74\x39\x68\xe8\xbd\x0d\x2b\x70\x10"
"\x01\x01\x00\x00\x00\x00\x00\x00\xc3\x83\xa2\x1c\x6c\xb0\xcb\x01"
"\x47\xa2\xe5\xcf\x27\xf7\x3c\x43\x00\x00\x00\x00\x02\x00\x08\x00"
"\x57\x00\x49\x00\x4e\x00\x37\x00\x01\x00\x08\x00\x57\x00\x49\x00"
"\x4e\x00\x37\x00\x04\x00\x08\x00\x77\x00\x69\x00\x6e\x00\x37\x00"
"\x03\x00\x08\x00\x77\x00\x69\x00\x6e\x00\x37\x00\x07\x00\x08\x00"
"\xa9\x8d\x9b\x1a\x6c\xb0\xcb\x01\x00\x00\x00\x00\x00\x00\x00\x00";
char expected_lm_challenge_response[24] =
"\xa0\x98\x01\x10\x19\xbb\x5d\x00\xf6\xbe\x00\x33\x90\x20\x34\xb3"
"\x47\xa2\xe5\xcf\x27\xf7\x3c\x43";
char expected_session_base_key[16] =
"\x6e\xf1\x6b\x79\x88\xf2\x3d\x7e\x54\x2a\x1a\x38\x4e\xa0\x6b\x52";
ntlmssp = ntlmssp_client_new();
ntlmssp_set_password(ntlmssp, password);
ntlmssp_set_username(ntlmssp, username);
ntlmssp_set_domain(ntlmssp, domain);
ntlmssp->av_pairs->Timestamp.value = xzalloc(8);
ntlmssp->av_pairs->Timestamp.length = 8;
memcpy(ntlmssp->timestamp, timestamp, 8);
memcpy(ntlmssp->server_challenge, server_challenge, 8);
memcpy(ntlmssp->client_challenge, client_challenge, 8);
ntlmssp->target_info.data = target_info_data;
ntlmssp->target_info.length = sizeof(target_info_data);
ntlmssp_compute_lm_v2_response(ntlmssp);
ntlmssp_compute_ntlm_v2_response(ntlmssp);
session_base_key_good = 1;
p = (char*) ntlmssp->session_base_key;
for (i = 0; i < 16; i++)
{
if (p[i] != expected_session_base_key[i])
session_base_key_good = 0;
}
CU_ASSERT(session_base_key_good == 1);
lm_challenge_response_good = 1;
p = (char*) ntlmssp->lm_challenge_response.data;
for (i = 0; i < 24; i++)
{
if (p[i] != expected_lm_challenge_response[i])
lm_challenge_response_good = 0;
}
CU_ASSERT(lm_challenge_response_good == 1);
nt_challenge_response_good = 1;
p = (char*) ntlmssp->nt_challenge_response.data;
for (i = 0; i < 84; i++)
{
if (p[i] != expected_nt_challenge_response[i])
nt_challenge_response_good = 0;
}
CU_ASSERT(nt_challenge_response_good == 1);
}
void test_ntlmssp_generate_client_signing_key(void)
{
int i;
NTLMSSP* ntlmssp;
int client_signing_key_good;
uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1";
uint8 expected_client_signing_key[16] = "\xbf\x5e\x42\x76\x55\x68\x38\x97\x45\xd3\xb4\x9f\x5e\x2f\xbc\x89";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key));
ntlmssp_generate_client_signing_key(ntlmssp);
client_signing_key_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->client_signing_key[i] != expected_client_signing_key[i])
client_signing_key_good = 0;
}
CU_ASSERT(client_signing_key_good == 1);
}
void test_ntlmssp_generate_server_signing_key(void)
{
int i;
NTLMSSP* ntlmssp;
int server_signing_key_good;
uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1";
uint8 expected_server_signing_key[16] = "\x9b\x3b\x64\x89\xda\x84\x52\x17\xd5\xc2\x6e\x90\x16\x3b\x42\x11";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key));
ntlmssp_generate_server_signing_key(ntlmssp);
server_signing_key_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->server_signing_key[i] != expected_server_signing_key[i])
server_signing_key_good = 0;
}
CU_ASSERT(server_signing_key_good == 1);
}
void test_ntlmssp_generate_client_sealing_key(void)
{
int i;
NTLMSSP* ntlmssp;
int client_sealing_key_good;
uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1";
uint8 expected_client_sealing_key[16] = "\xca\x41\xcd\x08\x48\x07\x22\x6e\x0d\x84\xc3\x88\xa5\x07\xa9\x73";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key));
ntlmssp_generate_client_sealing_key(ntlmssp);
client_sealing_key_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->client_sealing_key[i] != expected_client_sealing_key[i])
client_sealing_key_good = 0;
}
CU_ASSERT(client_sealing_key_good == 1);
}
void test_ntlmssp_generate_server_sealing_key(void)
{
int i;
NTLMSSP* ntlmssp;
int server_sealing_key_good;
uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1";
uint8 expected_server_sealing_key[16] = "\x14\xb7\x1d\x06\x2c\x68\x2e\xad\x4b\x0e\x95\x23\x70\x91\x98\x90";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key));
ntlmssp_generate_server_sealing_key(ntlmssp);
server_sealing_key_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->server_sealing_key[i] != expected_server_sealing_key[i])
server_sealing_key_good = 0;
}
CU_ASSERT(server_sealing_key_good == 1);
}
void test_ntlmssp_encrypt_random_session_key(void)
{
int i;
NTLMSSP* ntlmssp;
int encrypted_random_session_key_good;
uint8 key_exchange_key[16] = "\x6e\xf1\x6b\x79\x88\xf2\x3d\x7e\x54\x2a\x1a\x38\x4e\xa0\x6b\x52";
uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1";
uint8 expected_encrypted_random_session_key[16] = "\xb1\xd2\x45\x42\x0f\x37\x9a\x0e\xe0\xce\x77\x40\x10\x8a\xda\xba";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->key_exchange_key, key_exchange_key, 16);
memcpy(ntlmssp->exported_session_key, exported_session_key, 16);
memcpy(ntlmssp->random_session_key, exported_session_key, 16);
ntlmssp_encrypt_random_session_key(ntlmssp);
encrypted_random_session_key_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->encrypted_random_session_key[i] != expected_encrypted_random_session_key[i])
encrypted_random_session_key_good = 0;
}
CU_ASSERT(encrypted_random_session_key_good == 1);
}
void test_ntlmssp_compute_message_integrity_check(void)
{
int i;
NTLMSSP* ntlmssp;
int message_integrity_check_good;
uint8 exported_session_key[16] = "\xfd\x35\x59\x39\x23\x81\x29\xcd\xb8\x1c\x11\x04\xd7\x54\x4f\xd4";
uint8 expected_message_integrity_check[16] = "\x81\x37\x56\xcf\x19\x76\x71\xf2\xc0\x3f\x95\x87\xe3\x30\xe6\x9b";
uint8 negotiate_message_data[40] =
"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\xb7\x82\x08\xe2"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x06\x01\xb0\x1d\x00\x00\x00\x0f";
uint8 challenge_message_data[278] =
"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x16\x00\x16\x00"
"\x38\x00\x00\x00\x35\x82\x89\xe2\xed\x75\x9b\x8d\x1c\x2e\x3e\xc8"
"\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x00\xc8\x00\x4e\x00\x00\x00"
"\x06\x01\xb0\x1d\x00\x00\x00\x0f\x41\x00\x57\x00\x41\x00\x4b\x00"
"\x45\x00\x43\x00\x4f\x00\x44\x00\x49\x00\x4e\x00\x47\x00\x02\x00"
"\x16\x00\x41\x00\x57\x00\x41\x00\x4b\x00\x45\x00\x43\x00\x4f\x00"
"\x44\x00\x49\x00\x4e\x00\x47\x00\x01\x00\x10\x00\x57\x00\x49\x00"
"\x4e\x00\x32\x00\x4b\x00\x38\x00\x52\x00\x32\x00\x04\x00\x24\x00"
"\x61\x00\x77\x00\x61\x00\x6b\x00\x65\x00\x63\x00\x6f\x00\x64\x00"
"\x69\x00\x6e\x00\x67\x00\x2e\x00\x61\x00\x74\x00\x68\x00\x2e\x00"
"\x63\x00\x78\x00\x03\x00\x36\x00\x57\x00\x49\x00\x4e\x00\x32\x00"
"\x4b\x00\x38\x00\x52\x00\x32\x00\x2e\x00\x61\x00\x77\x00\x61\x00"
"\x6b\x00\x65\x00\x63\x00\x6f\x00\x64\x00\x69\x00\x6e\x00\x67\x00"
"\x2e\x00\x61\x00\x74\x00\x68\x00\x2e\x00\x63\x00\x78\x00\x05\x00"
"\x24\x00\x61\x00\x77\x00\x61\x00\x6b\x00\x65\x00\x63\x00\x6f\x00"
"\x64\x00\x69\x00\x6e\x00\x67\x00\x2e\x00\x61\x00\x74\x00\x68\x00"
"\x2e\x00\x63\x00\x78\x00\x07\x00\x08\x00\xd1\x12\x78\x10\xde\xd2"
"\xcb\x01\x00\x00\x00\x00";
uint8 authenticate_message_data[504] =
"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
"\x98\x00\x00\x00\x38\x01\x38\x01\xb0\x00\x00\x00\x16\x00\x16\x00"
"\x58\x00\x00\x00\x1a\x00\x1a\x00\x6e\x00\x00\x00\x10\x00\x10\x00"
"\x88\x00\x00\x00\x10\x00\x10\x00\xe8\x01\x00\x00\x35\x82\x88\xe2"
"\x06\x01\xb0\x1d\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x57\x00\x41\x00\x4b\x00"
"\x45\x00\x43\x00\x4f\x00\x44\x00\x49\x00\x4e\x00\x47\x00\x41\x00"
"\x64\x00\x6d\x00\x69\x00\x6e\x00\x69\x00\x73\x00\x74\x00\x72\x00"
"\x61\x00\x74\x00\x6f\x00\x72\x00\x57\x00\x49\x00\x4e\x00\x44\x00"
"\x4f\x00\x57\x00\x53\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\xff\xd9\x76\x1a\x97\xa6\xe8\x47\x4c\x99\xd0\xe4\x68\xd1\x02\x36"
"\x01\x01\x00\x00\x00\x00\x00\x00\xd1\x12\x78\x10\xde\xd2\xcb\x01"
"\x53\xca\xac\xf2\x3f\xcb\xcf\x09\x00\x00\x00\x00\x02\x00\x16\x00"
"\x41\x00\x57\x00\x41\x00\x4b\x00\x45\x00\x43\x00\x4f\x00\x44\x00"
"\x49\x00\x4e\x00\x47\x00\x01\x00\x10\x00\x57\x00\x49\x00\x4e\x00"
"\x32\x00\x4b\x00\x38\x00\x52\x00\x32\x00\x04\x00\x24\x00\x61\x00"
"\x77\x00\x61\x00\x6b\x00\x65\x00\x63\x00\x6f\x00\x64\x00\x69\x00"
"\x6e\x00\x67\x00\x2e\x00\x61\x00\x74\x00\x68\x00\x2e\x00\x63\x00"
"\x78\x00\x03\x00\x36\x00\x57\x00\x49\x00\x4e\x00\x32\x00\x4b\x00"
"\x38\x00\x52\x00\x32\x00\x2e\x00\x61\x00\x77\x00\x61\x00\x6b\x00"
"\x65\x00\x63\x00\x6f\x00\x64\x00\x69\x00\x6e\x00\x67\x00\x2e\x00"
"\x61\x00\x74\x00\x68\x00\x2e\x00\x63\x00\x78\x00\x05\x00\x24\x00"
"\x61\x00\x77\x00\x61\x00\x6b\x00\x65\x00\x63\x00\x6f\x00\x64\x00"
"\x69\x00\x6e\x00\x67\x00\x2e\x00\x61\x00\x74\x00\x68\x00\x2e\x00"
"\x63\x00\x78\x00\x07\x00\x08\x00\xd1\x12\x78\x10\xde\xd2\xcb\x01"
"\x06\x00\x04\x00\x02\x00\x00\x00\x08\x00\x30\x00\x30\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x20\x00\x00\x61\x53\xad\x3f"
"\x58\xf3\x5d\x83\xa2\x00\xbe\x43\x11\x77\xc9\xcf\x96\x31\xe1\xc3"
"\x3f\x76\x2f\x38\x81\xb4\x45\xf9\xb4\xbb\x32\xcf\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x82\xff\x1e\xb6\xf8\x4a\x1c"
"\x08\x78\x69\x9f\xa8\x84\x32\xaa";
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->exported_session_key, exported_session_key, 16);
ntlmssp->negotiate_message.data = (void*) negotiate_message_data;
ntlmssp->negotiate_message.length = sizeof(negotiate_message_data);
ntlmssp->challenge_message.data = (void*) challenge_message_data;
ntlmssp->challenge_message.length = sizeof(challenge_message_data);
ntlmssp->authenticate_message.data = (void*) authenticate_message_data;
ntlmssp->authenticate_message.length = sizeof(authenticate_message_data);
ntlmssp_compute_message_integrity_check(ntlmssp);
message_integrity_check_good = 1;
for (i = 0; i < 16; i++)
{
if (ntlmssp->message_integrity_check[i] != expected_message_integrity_check[i])
message_integrity_check_good = 0;
}
CU_ASSERT(message_integrity_check_good == 1);
}
void test_ntlmssp_encrypt_message(void)
{
int i;
uint8* p;
NTLMSSP* ntlmssp;
rdpBlob public_key;
rdpBlob ts_credentials;
rdpBlob encrypted_public_key;
rdpBlob encrypted_ts_credentials;
uint8 public_key_signature[16];
uint8 ts_credentials_signature[16];
int encrypted_public_key_good;
int public_key_signature_good;
int encrypted_ts_credentials_good;
int ts_credentials_signature_good;
uint8 client_signing_key[16] = "\xbf\x5e\x42\x76\x55\x68\x38\x97\x45\xd3\xb4\x9f\x5e\x2f\xbc\x89";
uint8 client_sealing_key[16] = "\xca\x41\xcd\x08\x48\x07\x22\x6e\x0d\x84\xc3\x88\xa5\x07\xa9\x73";
uint8 public_key_data[270] =
"\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xc2\x1c\x54\xaf\x07\xf1\x16"
"\x97\xc3\x0f\x6b\xa6\x33\x2e\xdd\x1e\xe4\xb2\x9c\xe4\x12\x7f\xda"
"\x58\x21\xc0\x68\xe6\xd3\xf5\x20\x1c\xba\x06\x64\x7d\x7f\x44\xb5"
"\xbf\xe3\xd5\xc7\xa4\x86\x8b\xbc\x6f\xca\x25\x78\xdf\xeb\xcf\x5a"
"\x96\xf6\xc7\x00\xbe\x7d\x6d\x06\x1f\x1d\x7f\x30\xaf\xc4\x59\x4f"
"\x91\x6d\x97\xe8\x55\x8b\x39\x01\x68\x50\x59\xbb\xe4\x65\x71\x32"
"\x76\x9e\x1b\xcf\x58\xfc\x52\xd9\x43\x01\x8e\x33\xc1\x74\x14\xbc"
"\x1f\x5c\x1d\xdb\x0e\xbd\xbb\x37\x50\x13\x78\x57\x93\x34\x3b\x73"
"\xc9\x5c\x44\x1f\x16\xe6\x2e\x00\x57\xa3\xe6\x5c\x6a\x2c\x90\xdc"
"\xa3\x6d\x7f\x92\xdf\x2f\xe5\x97\xae\x3b\x07\x23\x03\x91\x71\xd4"
"\xf2\x50\x3a\x3a\xb9\xde\x1f\xb1\xd5\xa1\x38\x7c\xf7\x07\x49\x83"
"\x68\xaa\xdf\xad\xfd\x1a\xe9\xb5\x0a\x1e\x8b\xf3\x88\xae\x3f\x32"
"\xd0\x3b\xd8\xc7\x50\x11\xf7\xad\x3b\x11\xe6\x92\xbb\x2a\x73\x8b"
"\xed\xfd\x45\x29\x50\xbf\x0d\x1e\x47\xfd\x61\x1d\x18\x27\x58\xa2"
"\xb2\x1f\xb5\x2d\x84\x18\x2f\x88\x8e\x7f\x70\xed\x4e\xbf\x14\x5d"
"\x1b\xbc\x0b\x47\x66\x16\x3a\x7b\x6d\x8e\xcf\x55\xe8\x8c\x8a\xfe"
"\x24\xce\x19\x99\xc3\x5a\xe5\xc2\xf3\x02\x03\x01\x00\x01";
uint8 expected_encrypted_public_key[270] =
"\x27\x29\x73\xa9\xfa\x46\x17\x3c\x74\x14\x45\x2a\xd1\xe2\x92\xa1"
"\xc6\x0a\x30\xd4\xcc\xe0\x92\xf6\xb3\x20\xb3\xa0\xf1\x38\xb1\xf4"
"\xe5\x96\xdf\xa1\x65\x5b\xd6\x0c\x2a\x86\x99\xcc\x72\x80\xbd\xe9"
"\x19\x1f\x42\x53\xf6\x84\xa3\xda\x0e\xec\x10\x29\x15\x52\x5c\x77"
"\x40\xc8\x3d\x44\x01\x34\xb6\x0a\x75\x33\xc0\x25\x71\xd3\x25\x38"
"\x3b\xfc\x3b\xa8\xcf\xba\x2b\xf6\x99\x0e\x5f\x4e\xa9\x16\x2b\x52"
"\x9f\xbb\x76\xf8\x03\xfc\x11\x5e\x36\x83\xd8\x4c\x9a\xdc\x9d\x35"
"\xe2\xc8\x63\xa9\x3d\x07\x97\x52\x64\x54\x72\x9e\x9a\x8c\x56\x79"
"\x4a\x78\x91\x0a\x4c\x52\x84\x5a\x4a\xb8\x28\x0b\x2f\xe6\x89\x7d"
"\x07\x3b\x7b\x6e\x22\xcc\x4c\xff\xf4\x10\x96\xf2\x27\x29\xa0\x76"
"\x0d\x4c\x7e\x7a\x42\xe4\x1e\x6a\x95\x7d\x4c\xaf\xdb\x86\x49\x5c"
"\xbf\xc2\x65\xb6\xf2\xed\xae\x8d\x57\xed\xf0\xd4\xcb\x7a\xbb\x23"
"\xde\xe3\x43\xea\xb1\x02\xe3\xb4\x96\xe9\xe7\x48\x69\xb0\xaa\xec"
"\x89\x38\x8b\xc2\xbd\xdd\xf7\xdf\xa1\x37\xe7\x34\x72\x7f\x91\x10"
"\x14\x73\xfe\x32\xdc\xfe\x68\x2b\xc0\x08\xdf\x05\xf7\xbd\x46\x33"
"\xfb\xc9\xfc\x89\xaa\x5d\x25\x49\xc8\x6e\x86\xee\xc2\xce\xc4\x8e"
"\x85\x9f\xe8\x30\xb3\x86\x11\xd5\xb8\x34\x4a\xe0\x03\xe5";
uint8 expected_public_key_signature[16] =
"\x01\x00\x00\x00\x91\x5e\xb0\x6e\x72\x82\x53\xae\x00\x00\x00\x00";
uint8 ts_credentials_data[65] =
"\x30\x3f\xa0\x03\x02\x01\x01\xa1\x38\x04\x36\x30\x34\xa0\x0a\x04"
"\x08\x77\x00\x69\x00\x6e\x00\x37\x00\xa1\x12\x04\x10\x75\x00\x73"
"\x00\x65\x00\x72\x00\x6e\x00\x61\x00\x6d\x00\x65\x00\xa2\x12\x04"
"\x10\x70\x00\x61\x00\x73\x00\x73\x00\x77\x00\x6f\x00\x72\x00\x64"
"\x00";
uint8 expected_encrypted_ts_credentials[65] =
"\xa8\x85\x7d\x11\xef\x92\xa0\xd6\xff\xee\xa1\xae\x6d\xc5\x2e\x4e"
"\x65\x50\x28\x93\x75\x30\xe1\xc3\x37\xeb\xac\x1f\xdd\xf3\xe0\x92"
"\xf6\x21\xbc\x8f\xa8\xd4\xe0\x5a\xa6\xff\xda\x09\x50\x24\x0d\x8f"
"\x8f\xf4\x92\xfe\x49\x2a\x13\x52\xa6\x52\x75\x50\x8d\x3e\xe9\x6b"
"\x57";
uint8 expected_ts_credentials_signature[16] =
"\x01\x00\x00\x00\xb3\x2c\x3b\xa1\x36\xf6\x55\x71\x01\x00\x00\x00";
public_key.data = public_key_data;
public_key.length = sizeof(public_key_data);
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->client_signing_key, client_signing_key, 16);
memcpy(ntlmssp->client_sealing_key, client_sealing_key, 16);
ntlmssp_init_rc4_seal_states(ntlmssp);
ntlmssp_encrypt_message(ntlmssp, &public_key, &encrypted_public_key, public_key_signature);
p = (uint8*) encrypted_public_key.data;
encrypted_public_key_good = 1;
for (i = 0; i < encrypted_public_key.length; i++)
{
if (p[i] != expected_encrypted_public_key[i])
encrypted_public_key_good = 0;
}
CU_ASSERT(encrypted_public_key_good == 1);
public_key_signature_good = 1;
for (i = 0; i < 16; i++)
{
if (public_key_signature[i] != expected_public_key_signature[i])
public_key_signature_good = 0;
}
CU_ASSERT(public_key_signature_good == 1);
ts_credentials.data = ts_credentials_data;
ts_credentials.length = sizeof(ts_credentials_data);
ntlmssp_encrypt_message(ntlmssp, &ts_credentials, &encrypted_ts_credentials, ts_credentials_signature);
p = (uint8*) encrypted_ts_credentials.data;
encrypted_ts_credentials_good = 1;
for (i = 0; i < encrypted_ts_credentials.length; i++)
{
if (p[i] != expected_encrypted_ts_credentials[i])
encrypted_ts_credentials_good = 0;
}
CU_ASSERT(encrypted_ts_credentials_good == 1);
ts_credentials_signature_good = 1;
for (i = 0; i < 16; i++)
{
if (ts_credentials_signature[i] != expected_ts_credentials_signature[i])
ts_credentials_signature_good = 0;
}
CU_ASSERT(ts_credentials_signature_good == 1);
}
void test_ntlmssp_decrypt_message(void)
{
int i;
uint8* p;
NTLMSSP* ntlmssp;
rdpBlob public_key;
rdpBlob encrypted_public_key;
int public_key_good;
uint8 server_signing_key[16] = "\x9b\x3b\x64\x89\xda\x84\x52\x17\xd5\xc2\x6e\x90\x16\x3b\x42\x11";
uint8 server_sealing_key[16] = "\x14\xb7\x1d\x06\x2c\x68\x2e\xad\x4b\x0e\x95\x23\x70\x91\x98\x90";
uint8 encrypted_public_key_data[270] =
"\xc7\x51\xf4\x71\xd3\x9f\xb6\x50\xbe\xa8\xf6\x20\x77\xa1\xfc\xdd"
"\x8e\x02\xf0\xa4\x6b\xba\x3f\x9d\x65\x9d\xab\x4a\x95\xc9\xb4\x38"
"\x03\x87\x04\xb1\xfe\x42\xec\xfa\xfc\xaa\x85\xf1\x31\x2d\x26\xcf"
"\x63\xfd\x62\x36\xcf\x56\xc3\xfb\xf6\x36\x9b\xe5\xb2\xe7\xce\xcb"
"\xe1\x82\xb2\x89\xff\xdd\x87\x5e\xd3\xd8\xff\x2e\x16\x35\xad\xdb"
"\xda\xc9\xc5\x81\xad\x48\xf1\x8b\x76\x3d\x74\x34\xdf\x80\x6b\xf3"
"\x68\x6d\xf6\xec\x5f\xbe\xea\xb7\x6c\xea\xe4\xeb\xe9\x17\xf9\x4e"
"\x0d\x79\xd5\x82\xdd\xb7\xdc\xcd\xfc\xbb\xf1\x0b\x9b\xe9\x18\xe7"
"\xb3\xb3\x8b\x40\x82\xa0\x9d\x58\x73\xda\x54\xa2\x2b\xd2\xb6\x41"
"\x60\x8a\x64\xf2\xa2\x59\x64\xcf\x27\x1a\xe6\xb5\x1a\x0e\x0e\xe1"
"\x14\xef\x26\x68\xeb\xc8\x49\xe2\x66\xbb\x11\x71\x49\xad\x7e\xae"
"\xde\xa8\x78\xfd\x64\x51\xd8\x18\x01\x11\xc0\x8d\x3b\xec\x40\x2b"
"\x1f\xc5\xa4\x45\x1e\x07\xae\x5a\xd8\x1c\xab\xdf\x89\x96\xdc\xdc"
"\x29\xd8\x30\xdb\xbf\x48\x2a\x42\x27\xc2\x50\xac\xf9\x02\xd1\x20"
"\x12\xdd\x50\x22\x09\x44\xac\xe0\x22\x1f\x66\x64\xec\xfa\x2b\xb8"
"\xcd\x43\x3a\xce\x40\x74\xe1\x34\x81\xe3\x94\x47\x6f\x49\x01\xf8"
"\xb5\xfc\xd0\x75\x80\xc6\x35\xac\xc0\xfd\x1b\xb5\xa2\xd3";
uint8 expected_public_key[270] =
"\x31\x82\x01\x0a\x02\x82\x01\x01\x00\xc2\x1c\x54\xaf\x07\xf1\x16"
"\x97\xc3\x0f\x6b\xa6\x33\x2e\xdd\x1e\xe4\xb2\x9c\xe4\x12\x7f\xda"
"\x58\x21\xc0\x68\xe6\xd3\xf5\x20\x1c\xba\x06\x64\x7d\x7f\x44\xb5"
"\xbf\xe3\xd5\xc7\xa4\x86\x8b\xbc\x6f\xca\x25\x78\xdf\xeb\xcf\x5a"
"\x96\xf6\xc7\x00\xbe\x7d\x6d\x06\x1f\x1d\x7f\x30\xaf\xc4\x59\x4f"
"\x91\x6d\x97\xe8\x55\x8b\x39\x01\x68\x50\x59\xbb\xe4\x65\x71\x32"
"\x76\x9e\x1b\xcf\x58\xfc\x52\xd9\x43\x01\x8e\x33\xc1\x74\x14\xbc"
"\x1f\x5c\x1d\xdb\x0e\xbd\xbb\x37\x50\x13\x78\x57\x93\x34\x3b\x73"
"\xc9\x5c\x44\x1f\x16\xe6\x2e\x00\x57\xa3\xe6\x5c\x6a\x2c\x90\xdc"
"\xa3\x6d\x7f\x92\xdf\x2f\xe5\x97\xae\x3b\x07\x23\x03\x91\x71\xd4"
"\xf2\x50\x3a\x3a\xb9\xde\x1f\xb1\xd5\xa1\x38\x7c\xf7\x07\x49\x83"
"\x68\xaa\xdf\xad\xfd\x1a\xe9\xb5\x0a\x1e\x8b\xf3\x88\xae\x3f\x32"
"\xd0\x3b\xd8\xc7\x50\x11\xf7\xad\x3b\x11\xe6\x92\xbb\x2a\x73\x8b"
"\xed\xfd\x45\x29\x50\xbf\x0d\x1e\x47\xfd\x61\x1d\x18\x27\x58\xa2"
"\xb2\x1f\xb5\x2d\x84\x18\x2f\x88\x8e\x7f\x70\xed\x4e\xbf\x14\x5d"
"\x1b\xbc\x0b\x47\x66\x16\x3a\x7b\x6d\x8e\xcf\x55\xe8\x8c\x8a\xfe"
"\x24\xce\x19\x99\xc3\x5a\xe5\xc2\xf3\x02\x03\x01\x00\x01";
uint8 public_key_signature[16] =
"\x01\x00\x00\x00\xc9\x88\xfc\xf1\x11\x68\x2c\x72\x00\x00\x00\x00";
encrypted_public_key.data = encrypted_public_key_data;
encrypted_public_key.length = sizeof(encrypted_public_key_data);
ntlmssp = ntlmssp_client_new();
memcpy(ntlmssp->server_signing_key, server_signing_key, 16);
memcpy(ntlmssp->server_sealing_key, server_sealing_key, 16);
ntlmssp_init_rc4_seal_states(ntlmssp);
ntlmssp_decrypt_message(ntlmssp, &encrypted_public_key, &public_key, public_key_signature);
p = (uint8*) public_key.data;
public_key_good = 1;
for (i = 0; i < public_key.length; i++)
{
if (p[i] != expected_public_key[i])
public_key_good = 0;
}
CU_ASSERT(public_key_good == 1);
}

39
cunit/test_ntlmssp.h Normal file
View File

@ -0,0 +1,39 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* NT LAN Manager Security Support Provider (NTLMSSP) Unit Tests
*
* Copyright 2011 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.
*/
#include "test_freerdp.h"
int init_ntlmssp_suite(void);
int clean_ntlmssp_suite(void);
int add_ntlmssp_suite(void);
void test_ntlmssp_compute_lm_hash(void);
void test_ntlmssp_compute_ntlm_hash(void);
void test_ntlmssp_compute_ntlm_v2_hash(void);
void test_ntlmssp_compute_lm_response(void);
void test_ntlmssp_compute_lm_v2_response(void);
void test_ntlmssp_compute_ntlm_v2_response(void);
void test_ntlmssp_generate_client_signing_key(void);
void test_ntlmssp_generate_server_signing_key(void);
void test_ntlmssp_generate_client_sealing_key(void);
void test_ntlmssp_generate_server_sealing_key(void);
void test_ntlmssp_encrypt_random_session_key(void);
void test_ntlmssp_compute_message_integrity_check(void);
void test_ntlmssp_encrypt_message(void);
void test_ntlmssp_decrypt_message(void);

View File

@ -517,7 +517,7 @@ void test_read_polygon_cb_order(void)
CU_ASSERT(polygon_cb.brush.x == 4);
CU_ASSERT(polygon_cb.brush.y == 3);
CU_ASSERT(polygon_cb.brush.style == 0x81);
CU_ASSERT(polygon_cb.nDeltaEntries == 3);
CU_ASSERT(polygon_cb.numPoints == 3);
CU_ASSERT(polygon_cb.cbData == 5);
CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1));

View File

@ -22,7 +22,7 @@
#include <freerdp/utils/stream.h>
#include "test_per.h"
#include "libfreerdp-core/per.h"
#include <freerdp/crypto/per.h>
int init_per_suite(void)
{

View File

@ -39,7 +39,7 @@
#include "rfx_decode.h"
#include "rfx_encode.h"
#include "test_librfx.h"
#include "test_rfx.h"
static const uint8 y_data[] =
{
@ -159,19 +159,19 @@ static const uint8 rgb_scanline_data[] =
static uint8* rgb_data;
int init_librfx_suite(void)
int init_rfx_suite(void)
{
return 0;
}
int clean_librfx_suite(void)
int clean_rfx_suite(void)
{
return 0;
}
int add_librfx_suite(void)
int add_rfx_suite(void)
{
add_test_suite(librfx);
add_test_suite(rfx);
add_test_function(bitstream);
add_test_function(bitstream_enc);

View File

@ -19,9 +19,9 @@
#include "test_freerdp.h"
int init_librfx_suite(void);
int clean_librfx_suite(void);
int add_librfx_suite(void);
int init_rfx_suite(void);
int clean_rfx_suite(void);
int add_rfx_suite(void);
void test_bitstream(void);
void test_bitstream_enc(void);

View File

@ -8,6 +8,6 @@ Description: A free remote desktop protocol client
URL: http://www.freerdp.com/
Version: @FREERDP_VERSION_FULL@
Requires:
Libs: -L${libdir} -lfreerdp-core -lfreerdp-codec -lfreerdp-gdi -lfreerdp-kbd -lfreerdp-rail -lfreerdp-channels -lfreerdp-utils
Libs: -L${libdir} -lfreerdp-core -lfreerdp-codec -lfreerdp-gdi -lfreerdp-locale -lfreerdp-crypto -lfreeerdp-auth -lfreerdp-rail -lfreerdp-channels -lfreerdp-utils
Cflags: -I${includedir}

View File

@ -22,11 +22,11 @@
typedef struct rdp_credssp rdpCredssp;
#include "tls.h"
#include "ber.h"
#include "crypto.h"
#include "transport.h"
#include <freerdp/settings.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/crypto/ber.h>
#include <freerdp/crypto/crypto.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/blob.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
@ -36,16 +36,17 @@ typedef struct rdp_credssp rdpCredssp;
struct rdp_credssp
{
rdpTls* tls;
freerdp* instance;
boolean server;
rdpBlob negoToken;
rdpBlob pubKeyAuth;
rdpBlob authInfo;
int send_seq_num;
rdpBlob public_key;
rdpBlob ts_credentials;
rdpSettings* settings;
CryptoRc4 rc4_seal_state;
struct _NTLMSSP *ntlmssp;
struct rdp_transport* transport;
rdpSettings* settings;
};
int credssp_authenticate(rdpCredssp* credssp);
@ -61,7 +62,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp);
void credssp_current_time(uint8* timestamp);
void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext);
rdpCredssp* credssp_new(rdpTransport* transport);
rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings);
void credssp_free(rdpCredssp* credssp);
#endif /* __CREDSSP_H */

View File

@ -20,7 +20,7 @@
#ifndef __NTLMSSP_H
#define __NTLMSSP_H
#include "credssp.h"
#include <freerdp/crypto/crypto.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/blob.h>
@ -78,6 +78,7 @@ typedef enum _NTLMSSP_STATE NTLMSSP_STATE;
struct _NTLMSSP
{
NTLMSSP_STATE state;
boolean server;
rdpBlob password;
rdpBlob username;
rdpBlob domain;
@ -118,8 +119,10 @@ void ntlmssp_set_username(NTLMSSP* ntlmssp, char* username);
void ntlmssp_set_domain(NTLMSSP* ntlmssp, char* domain);
void ntlmssp_set_password(NTLMSSP* ntlmssp, char* password);
void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation);
void ntlmssp_set_target_name(NTLMSSP* ntlmssp, char* target_name);
void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp);
void ntlmssp_generate_server_challenge(NTLMSSP* ntlmssp);
void ntlmssp_generate_key_exchange_key(NTLMSSP* ntlmssp);
void ntlmssp_generate_random_session_key(NTLMSSP* ntlmssp);
void ntlmssp_generate_exported_session_key(NTLMSSP* ntlmssp);
@ -153,7 +156,8 @@ int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* m
int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s);
int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s);
NTLMSSP* ntlmssp_new();
NTLMSSP* ntlmssp_client_new();
NTLMSSP* ntlmssp_server_new();
void ntlmssp_init(NTLMSSP* ntlmssp);
void ntlmssp_free(NTLMSSP* ntlmssp);

View File

@ -41,7 +41,9 @@ struct rdp_brush_cache
{
pPatBlt PatBlt; /* 0 */
pCacheBrush CacheBrush; /* 1 */
uint32 paddingA[16 - 2]; /* 2 */
pPolygonSC PolygonSC; /* 2 */
pPolygonCB PolygonCB; /* 3 */
uint32 paddingA[16 - 4]; /* 4 */
uint32 maxEntries; /* 16 */
uint32 maxMonoEntries; /* 17 */

View File

@ -29,6 +29,7 @@
#include <freerdp/cache/brush.h>
#include <freerdp/cache/pointer.h>
#include <freerdp/cache/bitmap.h>
#include <freerdp/cache/nine_grid.h>
#include <freerdp/cache/offscreen.h>
#include <freerdp/cache/palette.h>
@ -40,6 +41,7 @@ struct rdp_cache
rdpBitmapCache* bitmap; /* 3 */
rdpOffscreenCache* offscreen; /* 4 */
rdpPaletteCache* palette; /* 5 */
rdpNineGridCache* nine_grid; /* 6 */
/* internal */

63
include/freerdp/cache/nine_grid.h vendored Normal file
View File

@ -0,0 +1,63 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* NineGrid Cache
*
* 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 __NINE_GRID_CACHE_H
#define __NINE_GRID_CACHE_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
#include <freerdp/update.h>
#include <freerdp/utils/stream.h>
typedef struct _NINE_GRID_ENTRY NINE_GRID_ENTRY;
typedef struct rdp_nine_grid_cache rdpNineGridCache;
#include <freerdp/cache/cache.h>
struct _NINE_GRID_ENTRY
{
void* entry;
};
struct rdp_nine_grid_cache
{
pDrawNineGrid DrawNineGrid; /* 0 */
pMultiDrawNineGrid MultiDrawNineGrid; /* 1 */
uint32 paddingA[16 - 2]; /* 2 */
uint32 maxEntries; /* 16 */
uint32 maxSize; /* 17 */
NINE_GRID_ENTRY* entries; /* 18 */
uint32 paddingB[32 - 19]; /* 19 */
/* internal */
rdpSettings* settings;
};
FREERDP_API void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index);
FREERDP_API void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry);
FREERDP_API void nine_grid_cache_register_callbacks(rdpUpdate* update);
FREERDP_API rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings);
FREERDP_API void nine_grid_cache_free(rdpNineGridCache* nine_grid);
#endif /* __NINE_GRID_CACHE_H */

View File

@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __BER_H
#define __BER_H
#ifndef __CRYPTO_BER_H
#define __CRYPTO_BER_H
#include <freerdp/types.h>
#include <freerdp/utils/stream.h>
@ -80,4 +80,4 @@ int ber_write_integer(STREAM* s, uint32 value);
boolean ber_read_integer_length(STREAM* s, int* length);
int ber_skip_integer(uint32 value);
#endif /* __BER_H */
#endif /* __CRYPTO_BER_H */

View File

@ -0,0 +1,56 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Certificate Handling
*
* Copyright 2011 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 __CRYPTO_CERTIFICATE_H
#define __CRYPTO_CERTIFICATE_H
typedef struct rdp_certificate_data rdpCertificateData;
typedef struct rdp_certificate_store rdpCertificateStore;
#include <freerdp/crypto/ber.h>
#include <freerdp/crypto/crypto.h>
#include <freerdp/settings.h>
#include <freerdp/utils/blob.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/hexdump.h>
struct rdp_certificate_data
{
char* hostname;
char* fingerprint;
};
struct rdp_certificate_store
{
FILE* fp;
char* path;
char* file;
rdpSettings* settings;
rdpCertificateData* certificate_data;
};
rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint);
void certificate_data_free(rdpCertificateData* certificate_data);
rdpCertificateStore* certificate_store_new(rdpSettings* settings);
void certificate_store_free(rdpCertificateStore* certificate_store);
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
#endif /* __CRYPTO_CERTIFICATE_H */

View File

@ -20,10 +20,6 @@
#ifndef __CRYPTO_H
#define __CRYPTO_H
#ifdef _WIN32
#include "tcp.h"
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rc4.h>
@ -110,7 +106,7 @@ void crypto_hmac_free(CryptoHmac hmac);
typedef struct crypto_cert_struct* CryptoCert;
#include "certificate.h"
#include <freerdp/crypto/certificate.h>
CryptoCert crypto_cert_read(uint8* data, uint32 length);
char* crypto_cert_fingerprint(X509* xcert);

View File

@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __PER_H
#define __PER_H
#ifndef __CRYPTO_PER_H
#define __CRYTPO_PER_H
#include <freerdp/utils/stream.h>
@ -45,4 +45,4 @@ void per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min);
boolean per_read_numeric_string(STREAM* s, int min);
void per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min);
#endif /* __PER_H */
#endif /* __CRYTPO_PER_H */

View File

@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __TLS_H
#define __TLS_H
#ifndef __CRYPTO_TLS_H
#define __CRYPTO_TLS_H
#include "crypto.h"
#include "certificate.h"
@ -36,6 +36,7 @@ struct rdp_tls
SSL* ssl;
int sockfd;
SSL_CTX* ctx;
rdpBlob public_key;
rdpSettings* settings;
rdpCertificateStore* certificate_store;
};
@ -47,7 +48,6 @@ boolean tls_disconnect(rdpTls* tls);
int tls_read(rdpTls* tls, uint8* data, int length);
int tls_write(rdpTls* tls, uint8* data, int length);
CryptoCert tls_get_certificate(rdpTls* tls);
boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
void tls_print_certificate_error(char* hostname, char* fingerprint);
void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);
@ -57,4 +57,4 @@ boolean tls_print_error(char* func, SSL* connection, int value);
rdpTls* tls_new(rdpSettings* settings);
void tls_free(rdpTls* tls);
#endif /* __TLS_H */
#endif /* __CRYPTO_TLS_H */

View File

@ -35,6 +35,7 @@ typedef struct rdp_freerdp_peer freerdp_peer;
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/extension.h>
#include <freerdp/utils/stream.h>
#include <freerdp/input.h>
#include <freerdp/update.h>
@ -109,7 +110,6 @@ FREERDP_API boolean freerdp_disconnect(freerdp* instance);
FREERDP_API boolean freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount);
FREERDP_API boolean freerdp_check_fds(freerdp* instance);
FREERDP_API void freerdp_send_keep_alive(freerdp* instance);
FREERDP_API uint32 freerdp_error_info(freerdp* instance);
FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);

View File

@ -63,10 +63,26 @@
#define GDI_BLACKNESS 0x00000042 /* D = 0 */
#define GDI_WHITENESS 0x00FF0062 /* D = 1 */
#define GDI_DSPDxax 0x00E20746 /* D = (S & P) | (~S & D) */
#define GDI_PSDPxax 0x00B8074A /* D = (S & D) | (~S & P) */
#define GDI_SPna 0x000C0324 /* D = S & ~P */
#define GDI_DSna 0x00220326 /* D = D & ~S */
#define GDI_DPa 0x00A000C9 /* D = D & P */
#define GDI_PDxn 0x00A50065 /* D = D ^ ~P */
#define GDI_DPon 0x000500A9
#define GDI_DPna 0x000A0329
#define GDI_Pn 0x000F0001
#define GDI_PDna 0x00500325
#define GDI_DPan 0x005F00E9
#define GDI_DSan 0x007700E6
#define GDI_DSxn 0x00990066
#define GDI_DPa 0x00A000C9
#define GDI_D 0x00AA0029
#define GDI_DPno 0x00AF0229
#define GDI_SDno 0x00DD0228
#define GDI_PDno 0x00F50225
#define GDI_DPo 0x00FA0089
/* Brush Styles */
#define GDI_BS_SOLID 0x00
#define GDI_BS_NULL 0x01

View File

@ -22,6 +22,7 @@
typedef struct rdp_input rdpInput;
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
/* keyboard Flags */
@ -72,4 +73,10 @@ struct rdp_input
uint32 paddingB[32 - 21]; /* 21 */
};
FREERDP_API void freerdp_input_send_synchronize_event(rdpInput* input, uint32 flags);
FREERDP_API void freerdp_input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code);
FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code);
FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
#endif /* __INPUT_API_H */

View File

@ -1,42 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* XKB-based keyboard mapping
*
* Copyright 2009 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 __FREERDP_KBD_H
#define __FREERDP_KBD_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#define RDP_KEYBOARD_LAYOUT_TYPE_STANDARD 1
#define RDP_KEYBOARD_LAYOUT_TYPE_VARIANT 2
#define RDP_KEYBOARD_LAYOUT_TYPE_IME 4
typedef struct rdp_keyboard_layout
{
uint32 code;
char name[50];
} rdpKeyboardLayout;
FREERDP_API rdpKeyboardLayout* freerdp_kbd_get_layouts(int types);
FREERDP_API uint32 freerdp_kbd_init(void *dpy, uint32 keyboard_layout_id);
FREERDP_API uint8 freerdp_kbd_get_scancode_by_keycode(uint8 keycode, boolean* extended);
FREERDP_API uint8 freerdp_kbd_get_keycode_by_scancode(uint8 scancode, boolean extended);
FREERDP_API uint8 freerdp_kbd_get_scancode_by_virtualkey(int vkcode, boolean* extended);
#endif /* __FREERDP_KBD_H */

View File

@ -1,184 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* XKB-based Keyboard Mapping to Microsoft Keyboard System
*
* Copyright 2009 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.
*/
/* Keyboard layout IDs used in the RDP protocol */
#ifndef __LAYOUT_IDS_H
#define __LAYOUT_IDS_H
#include <freerdp/api.h>
#include <freerdp/kbd/kbd.h>
/* Keyboard layout IDs */
#define KBD_ARABIC_101 0x00000401
#define KBD_BULGARIAN 0x00000402
#define KBD_CHINESE_TRADITIONAL_US 0x00000404
#define KBD_CZECH 0x00000405
#define KBD_DANISH 0x00000406
#define KBD_GERMAN 0x00000407
#define KBD_GREEK 0x00000408
#define KBD_US 0x00000409
#define KBD_SPANISH 0x0000040A
#define KBD_FINNISH 0x0000040B
#define KBD_FRENCH 0x0000040C
#define KBD_HEBREW 0x0000040D
#define KBD_HUNGARIAN 0x0000040E
#define KBD_ICELANDIC 0x0000040F
#define KBD_ITALIAN 0x00000410
#define KBD_JAPANESE 0x00000411
#define KBD_KOREAN 0x00000412
#define KBD_DUTCH 0x00000413
#define KBD_NORWEGIAN 0x00000414
#define KBD_POLISH_PROGRAMMERS 0x00000415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT 0x00000416
#define KBD_ROMANIAN 0x00000418
#define KBD_RUSSIAN 0x00000419
#define KBD_CROATIAN 0x0000041A
#define KBD_SLOVAK 0x0000041B
#define KBD_ALBANIAN 0x0000041C
#define KBD_SWEDISH 0x0000041D
#define KBD_THAI_KEDMANEE 0x0000041E
#define KBD_TURKISH_Q 0x0000041F
#define KBD_URDU 0x00000420
#define KBD_UKRAINIAN 0x00000422
#define KBD_BELARUSIAN 0x00000423
#define KBD_SLOVENIAN 0x00000424
#define KBD_ESTONIAN 0x00000425
#define KBD_LATVIAN 0x00000426
#define KBD_LITHUANIAN_IBM 0x00000427
#define KBD_FARSI 0x00000429
#define KBD_VIETNAMESE 0x0000042A
#define KBD_ARMENIAN_EASTERN 0x0000042B
#define KBD_AZERI_LATIN 0x0000042C
#define KBD_FYRO_MACEDONIAN 0x0000042F
#define KBD_GEORGIAN 0x00000437
#define KBD_FAEROESE 0x00000438
#define KBD_DEVANAGARI_INSCRIPT 0x00000439
#define KBD_MALTESE_47_KEY 0x0000043A
#define KBD_NORWEGIAN_WITH_SAMI 0x0000043B
#define KBD_KAZAKH 0x0000043F
#define KBD_KYRGYZ_CYRILLIC 0x00000440
#define KBD_TATAR 0x00000444
#define KBD_BENGALI 0x00000445
#define KBD_PUNJABI 0x00000446
#define KBD_GUJARATI 0x00000447
#define KBD_TAMIL 0x00000449
#define KBD_TELUGU 0x0000044A
#define KBD_KANNADA 0x0000044B
#define KBD_MALAYALAM 0x0000044C
#define KBD_MARATHI 0x0000044E
#define KBD_MONGOLIAN_CYRILLIC 0x00000450
#define KBD_UNITED_KINGDOM_EXTENDED 0x00000452
#define KBD_SYRIAC 0x0000045A
#define KBD_NEPALI 0x00000461
#define KBD_PASHTO 0x00000463
#define KBD_DIVEHI_PHONETIC 0x00000465
#define KBD_LUXEMBOURGISH 0x0000046E
#define KBD_MAORI 0x00000481
#define KBD_CHINESE_SIMPLIFIED_US 0x00000804
#define KBD_SWISS_GERMAN 0x00000807
#define KBD_UNITED_KINGDOM 0x00000809
#define KBD_LATIN_AMERICAN 0x0000080A
#define KBD_BELGIAN_FRENCH 0x0000080C
#define KBD_BELGIAN_PERIOD 0x00000813
#define KBD_PORTUGUESE 0x00000816
#define KBD_SERBIAN_LATIN 0x0000081A
#define KBD_AZERI_CYRILLIC 0x0000082C
#define KBD_SWEDISH_WITH_SAMI 0x0000083B
#define KBD_UZBEK_CYRILLIC 0x00000843
#define KBD_INUKTITUT_LATIN 0x0000085D
#define KBD_CANADIAN_FRENCH_LEGACY 0x00000C0C
#define KBD_SERBIAN_CYRILLIC 0x00000C1A
#define KBD_CANADIAN_FRENCH 0x00001009
#define KBD_SWISS_FRENCH 0x0000100C
#define KBD_BOSNIAN 0x0000141A
#define KBD_IRISH 0x00001809
#define KBD_BOSNIAN_CYRILLIC 0x0000201A
/* Keyboard layout variant IDs */
#define KBD_ARABIC_102 0x00010401
#define KBD_BULGARIAN_LATIN 0x00010402
#define KBD_CZECH_QWERTY 0x00010405
#define KBD_GERMAN_IBM 0x00010407
#define KBD_GREEK_220 0x00010408
#define KBD_UNITED_STATES_DVORAK 0x00010409
#define KBD_SPANISH_VARIATION 0x0001040A
#define KBD_HUNGARIAN_101_KEY 0x0001040E
#define KBD_ITALIAN_142 0x00010410
#define KBD_POLISH_214 0x00010415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT2 0x00010416
#define KBD_RUSSIAN_TYPEWRITER 0x00010419
#define KBD_SLOVAK_QWERTY 0x0001041B
#define KBD_THAI_PATTACHOTE 0x0001041E
#define KBD_TURKISH_F 0x0001041F
#define KBD_LATVIAN_QWERTY 0x00010426
#define KBD_LITHUANIAN 0x00010427
#define KBD_ARMENIAN_WESTERN 0x0001042B
#define KBD_HINDI_TRADITIONAL 0x00010439
#define KBD_MALTESE_48_KEY 0x0001043A
#define KBD_SAMI_EXTENDED_NORWAY 0x0001043B
#define KBD_BENGALI_INSCRIPT 0x00010445
#define KBD_SYRIAC_PHONETIC 0x0001045A
#define KBD_DIVEHI_TYPEWRITER 0x00010465
#define KBD_BELGIAN_COMMA 0x0001080C
#define KBD_FINNISH_WITH_SAMI 0x0001083B
#define KBD_CANADIAN_MULTILINGUAL_STANDARD 0x00011009
#define KBD_GAELIC 0x00011809
#define KBD_ARABIC_102_AZERTY 0x00020401
#define KBD_CZECH_PROGRAMMERS 0x00020405
#define KBD_GREEK_319 0x00020408
#define KBD_UNITED_STATES_INTERNATIONAL 0x00020409
#define KBD_THAI_KEDMANEE_NON_SHIFTLOCK 0x0002041E
#define KBD_SAMI_EXTENDED_FINLAND_SWEDEN 0x0002083B
#define KBD_GREEK_220_LATIN 0x00030408
#define KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND 0x00030409
#define KBD_THAI_PATTACHOTE_NON_SHIFTLOCK 0x0003041E
#define KBD_GREEK_319_LATIN 0x00040408
#define KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND 0x00040409
#define KBD_GREEK_LATIN 0x00050408
#define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409
#define KBD_GREEK_POLYTONIC 0x00060408
#define KBD_GERMAN_NEO 0xB0000407
/* Global Input Method Editor (IME) IDs */
#define KBD_CHINESE_TRADITIONAL_PHONETIC 0xE0010404
#define KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 0xE0010411
#define KBD_KOREAN_INPUT_SYSTEM_IME_2000 0xE0010412
#define KBD_CHINESE_SIMPLIFIED_QUANPIN 0xE0010804
#define KBD_CHINESE_TRADITIONAL_CHANGJIE 0xE0020404
#define KBD_CHINESE_SIMPLIFIED_SHUANGPIN 0xE0020804
#define KBD_CHINESE_TRADITIONAL_QUICK 0xE0030404
#define KBD_CHINESE_SIMPLIFIED_ZHENGMA 0xE0030804
#define KBD_CHINESE_TRADITIONAL_BIG5_CODE 0xE0040404
#define KBD_CHINESE_TRADITIONAL_ARRAY 0xE0050404
#define KBD_CHINESE_SIMPLIFIED_NEIMA 0xE0050804
#define KBD_CHINESE_TRADITIONAL_DAYI 0xE0060404
#define KBD_CHINESE_TRADITIONAL_UNICODE 0xE0070404
#define KBD_CHINESE_TRADITIONAL_NEW_PHONETIC 0xE0080404
#define KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE 0xE0090404
#define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804
#define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404
FREERDP_API rdpKeyboardLayout* get_keyboard_layouts(int types);
FREERDP_API const char* get_layout_name(uint32 keyboardLayoutID);
#endif

View File

@ -1,328 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* XKB-based Keyboard Mapping to Microsoft Keyboard System
*
* Copyright 2009 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.
*/
/* Detection of plausible keyboard layout id based on current locale (LANG) setting. */
/*
* Refer to "Windows XP/Server 2003 - List of Locale IDs, Input Locale, and Language Collection":
* http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx
*/
#ifndef __LOCALES_H
#define __LOCALES_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#define AFRIKAANS 0x0436
#define ALBANIAN 0x041c
#define ALSATIAN 0x0484
#define AMHARIC 0x045E
#define ARABIC_SAUDI_ARABIA 0x0401
#define ARABIC_IRAQ 0x0801
#define ARABIC_EGYPT 0x0c01
#define ARABIC_LIBYA 0x1001
#define ARABIC_ALGERIA 0x1401
#define ARABIC_MOROCCO 0x1801
#define ARABIC_TUNISIA 0x1c01
#define ARABIC_OMAN 0x2001
#define ARABIC_YEMEN 0x2401
#define ARABIC_SYRIA 0x2801
#define ARABIC_JORDAN 0x2c01
#define ARABIC_LEBANON 0x3001
#define ARABIC_KUWAIT 0x3401
#define ARABIC_UAE 0x3801
#define ARABIC_BAHRAIN 0x3c01
#define ARABIC_QATAR 0x4001
#define ARMENIAN 0x042b
#define ASSAMESE 0x044D
#define AZERI_LATIN 0x042c
#define AZERI_CYRILLIC 0x082c
#define BASHKIR 0x046D
#define BASQUE 0x042d
#define BELARUSIAN 0x0423
#define BENGALI_INDIA 0x0445
#define BOSNIAN_LATIN 0x141A
#define BRETON 0x047E
#define BULGARIAN 0x0402
#define CATALAN 0x0403
#define CHINESE_TAIWAN 0x0404
#define CHINESE_PRC 0x0804
#define CHINESE_HONG_KONG 0x0c04
#define CHINESE_SINGAPORE 0x1004
#define CHINESE_MACAU 0x1404
#define CROATIAN 0x041a
#define CROATIAN_BOSNIA_HERZEGOVINA 0x101A
#define CZECH 0x0405
#define DANISH 0x0406
#define DARI 0x048C
#define DIVEHI 0x0465
#define DUTCH_STANDARD 0x0413
#define DUTCH_BELGIAN 0x0813
#define ENGLISH_UNITED_STATES 0x0409
#define ENGLISH_UNITED_KINGDOM 0x0809
#define ENGLISH_AUSTRALIAN 0x0c09
#define ENGLISH_CANADIAN 0x1009
#define ENGLISH_NEW_ZEALAND 0x1409
#define ENGLISH_INDIA 0x4009
#define ENGLISH_IRELAND 0x1809
#define ENGLISH_MALAYSIA 0x4409
#define ENGLISH_SOUTH_AFRICA 0x1c09
#define ENGLISH_JAMAICA 0x2009
#define ENGLISH_CARIBBEAN 0x2409
#define ENGLISH_BELIZE 0x2809
#define ENGLISH_TRINIDAD 0x2c09
#define ENGLISH_ZIMBABWE 0x3009
#define ENGLISH_PHILIPPINES 0x3409
#define ENGLISH_SINGAPORE 0x4809
#define ESTONIAN 0x0425
#define FAEROESE 0x0438
#define FARSI 0x0429
#define FILIPINO 0x0464
#define FINNISH 0x040b
#define FRENCH_STANDARD 0x040c
#define FRENCH_BELGIAN 0x080c
#define FRENCH_CANADIAN 0x0c0c
#define FRENCH_SWISS 0x100c
#define FRENCH_LUXEMBOURG 0x140c
#define FRENCH_MONACO 0x180c
#define FRISIAN 0x0462
#define GEORGIAN 0x0437
#define GALICIAN 0x0456
#define GERMAN_STANDARD 0x0407
#define GERMAN_SWISS 0x0807
#define GERMAN_AUSTRIAN 0x0c07
#define GERMAN_LUXEMBOURG 0x1007
#define GERMAN_LIECHTENSTEIN 0x1407
#define GREEK 0x0408
#define GREENLANDIC 0x046F
#define GUJARATI 0x0447
#define HEBREW 0x040d
#define HINDI 0x0439
#define HUNGARIAN 0x040e
#define ICELANDIC 0x040f
#define IGBO 0x0470
#define INDONESIAN 0x0421
#define IRISH 0x083C
#define ITALIAN_STANDARD 0x0410
#define ITALIAN_SWISS 0x0810
#define JAPANESE 0x0411
#define KANNADA 0x044b
#define KAZAKH 0x043f
#define KHMER 0x0453
#define KICHE 0x0486
#define KINYARWANDA 0x0487
#define KONKANI 0x0457
#define KOREAN 0x0412
#define KYRGYZ 0x0440
#define LAO 0x0454
#define LATVIAN 0x0426
#define LITHUANIAN 0x0427
#define LOWER_SORBIAN 0x082E
#define LUXEMBOURGISH 0x046E
#define MACEDONIAN 0x042f
#define MALAY_MALAYSIA 0x043e
#define MALAY_BRUNEI_DARUSSALAM 0x083e
#define MALAYALAM 0x044c
#define MALTESE 0x043a
#define MAPUDUNGUN 0x047A
#define MAORI 0x0481
#define MARATHI 0x044e
#define MOHAWK 0x047C
#define MONGOLIAN 0x0450
#define NEPALI 0x0461
#define NORWEGIAN_BOKMAL 0x0414
#define NORWEGIAN_NYNORSK 0x0814
#define OCCITAN 0x0482
#define ORIYA 0x0448
#define PASHTO 0x0463
#define POLISH 0x0415
#define PORTUGUESE_BRAZILIAN 0x0416
#define PORTUGUESE_STANDARD 0x0816
#define PUNJABI 0x0446
#define QUECHUA_BOLIVIA 0x046b
#define QUECHUA_ECUADOR 0x086b
#define QUECHUA_PERU 0x0c6b
#define ROMANIAN 0x0418
#define ROMANSH 0x0417
#define RUSSIAN 0x0419
#define SAMI_INARI 0x243b
#define SAMI_LULE_NORWAY 0x103b
#define SAMI_LULE_SWEDEN 0x143b
#define SAMI_NORTHERN_FINLAND 0x0c3b
#define SAMI_NORTHERN_NORWAY 0x043b
#define SAMI_NORTHERN_SWEDEN 0x083b
#define SAMI_SKOLT 0x203b
#define SAMI_SOUTHERN_NORWAY 0x183b
#define SAMI_SOUTHERN_SWEDEN 0x1c3b
#define SANSKRIT 0x044f
#define SERBIAN_LATIN 0x081a
#define SERBIAN_LATIN_BOSNIA_HERZEGOVINA 0x181a
#define SERBIAN_CYRILLIC 0x0c1a
#define SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA 0x1c1a
#define SESOTHO_SA_LEBOA 0x046C
#define SINHALA 0x045B
#define SLOVAK 0x041b
#define SLOVENIAN 0x0424
#define SPANISH_TRADITIONAL_SORT 0x040a
#define SPANISH_MEXICAN 0x080a
#define SPANISH_MODERN_SORT 0x0c0a
#define SPANISH_GUATEMALA 0x100a
#define SPANISH_COSTA_RICA 0x140a
#define SPANISH_PANAMA 0x180a
#define SPANISH_DOMINICAN_REPUBLIC 0x1c0a
#define SPANISH_VENEZUELA 0x200a
#define SPANISH_COLOMBIA 0x240a
#define SPANISH_PERU 0x280a
#define SPANISH_ARGENTINA 0x2c0a
#define SPANISH_ECUADOR 0x300a
#define SPANISH_CHILE 0x340a
#define SPANISH_UNITED_STATES 0x540A
#define SPANISH_URUGUAY 0x380a
#define SPANISH_PARAGUAY 0x3c0a
#define SPANISH_BOLIVIA 0x400a
#define SPANISH_EL_SALVADOR 0x440a
#define SPANISH_HONDURAS 0x480a
#define SPANISH_NICARAGUA 0x4c0a
#define SPANISH_PUERTO_RICO 0x500a
#define SWAHILI 0x0441
#define SWEDISH 0x041d
#define SWEDISH_FINLAND 0x081d
#define SYRIAC 0x045a
#define TAMIL 0x0449
#define TATAR 0x0444
#define TELUGU 0x044a
#define THAI 0x041e
#define TIBETAN_BHUTAN 0x0851
#define TIBETAN_PRC 0x0451
#define TSWANA 0x0432
#define UKRAINIAN 0x0422
#define TURKISH 0x041f
#define TURKMEN 0x0442
#define UIGHUR 0x0480
#define UPPER_SORBIAN 0x042E
#define URDU 0x0420
#define URDU_INDIA 0x0820
#define UZBEK_LATIN 0x0443
#define UZBEK_CYRILLIC 0x0843
#define VIETNAMESE 0x042a
#define WELSH 0x0452
#define WOLOF 0x0488
#define XHOSA 0x0434
#define YAKUT 0x0485
#define YI 0x0478
#define YORUBA 0x046A
#define ZULU 0x0435
/*
Time zones, taken from Windows Server 2008
(GMT -12:00) International Date Line West
(GMT -11:00) Midway Island, Samoa
(GMT -10:00) Hawaii
(GMT -09:00) Alaska
(GMT -08:00) Pacific Time (US & Canada)
(GMT -08:00) Tijuana, Baja California
(GMT -07:00) Arizona
(GMT -07:00) Chihuahua, La Paz, Mazatlan
(GMT -07:00) Mountain Time (US & Canada)
(GMT -06:00) Central America
(GMT -06:00) Central Time (US & Canada)
(GMT -06:00) Guadalajara, Mexico City, Monterrey
(GMT -06:00) Saskatchewan
(GMT -05:00) Bogota, Lima, Quito, Rio Branco
(GMT -05:00) Eastern Time (US & Canada)
(GMT -05:00) Indiana (East)
(GMT -04:30) Caracas
(GMT -04:00) Atlantic Time (Canada)
(GMT -04:00) La Paz
(GMT -04:00) Manaus
(GMT -04:00) Santiago
(GMT -03:30) Newfoundland
(GMT -03:00) Brasilia
(GMT -03:00) Buenos Aires
(GMT -03:00) Georgetown
(GMT -03:00) Greenland
(GMT -03:00) Montevideo
(GMT -02:00) Mid-Atlantic
(GMT -01:00) Azores
(GMT -01:00) Cape Verde Is.
(GMT +00:00) Casablanca
(GMT +00:00) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London
(GMT +00:00) Monrovia, Reykjavik
(GMT +01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
(GMT +01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
(GMT +01:00) Brussels, Copenhagen, Madrid, Paris
(GMT +01:00) Sarajevo, Skopje, Warsaw, Zagreb
(GMT +01:00) West Central Africa
(GMT +02:00) Amman
(GMT +02:00) Athens, Bucharest, Istanbul
(GMT +02:00) Beirut
(GMT +02:00) Cairo
(GMT +02:00) Harare, Pretoria
(GMT +02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
(GMT +02:00) Jerusalem
(GMT +02:00) Minsk
(GMT +02:00) Windhoek
(GMT +03:00) Baghdad
(GMT +03:00) Kuwait, Riyadh
(GMT +03:00) Moscow, St. Petersburg, Volgograd
(GMT +03:00) Nairobi
(GMT +03:00) Tbilisi
(GMT +03:30) Tehran
(GMT +04:00) Abu Dhabi, Muscat
(GMT +04:00) Baku
(GMT +04:00) Port Louis
(GMT +04:00) Yerevan
(GMT +04:30) Kabul
(GMT +05:00) Ekaterinburg
(GMT +05:00) Islamabad, Karachi
(GMT +05:00) Tashkent
(GMT +05:30) Chennai, Kolkata, Mumbai, New Delhi
(GMT +05:30) Sri Jayawardenepura
(GMT +05:45) Kathmandu
(GMT +06:00) Almaty, Novosibirsk
(GMT +06:00) Astana, Dhaka
(GMT +06:30) Yangon (Rangoon)
(GMT +07:00) Bangkok, Hanoi, Jakarta
(GMT +07:00) Krasnoyarsk
(GMT +08:00) Beijing, Chongqing, Hong Kong, Urumqi
(GMT +08:00) Irkutsk, Ulaan Bataar
(GMT +08:00) Kuala Lumpur, Singapore
(GMT +08:00) Perth
(GMT +08:00) Taipei
(GMT +09:00) Osaka, Sapporo, Tokyo
(GMT +09:00) Seoul
(GMT +09:00) Yakutsk
(GMT +09:30) Adelaide
(GMT +09:30) Darwin
(GMT +10:00) Brisbane
(GMT +10:00) Canberra, Melbourne, Sydney
(GMT +10:00) Guam, Port Moresby
(GMT +10:00) Hobart, Vladivostok
(GMT +11:00) Magadan, Solomon Is., New Caledonia
(GMT +12:00) Auckland, Wellington
(GMT +12:00) Fiji, Kamchatka, Marshall Is.
(GMT +13:00) Nuku'alofa
*/
FREERDP_API uint32 detect_keyboard_layout_from_locale();
#endif /* __LOCALES_H */

View File

@ -1,587 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Microsoft Virtual Key Code Definitions and Conversion Tables
*
* Copyright 2009 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.
*/
/* Microsoft Windows Virtual Key Codes: http://msdn.microsoft.com/en-us/library/ms645540.aspx */
#ifndef __VKCODES_H
#define __VKCODES_H
#include <stddef.h>
#include <freerdp/api.h>
#include <freerdp/kbd/layouts.h>
/* Mouse buttons */
#define VK_LBUTTON 0x01 /* Left mouse button */
#define VK_RBUTTON 0x02 /* Right mouse button */
#define VK_CANCEL 0x03 /* Control-break processing */
#define VK_MBUTTON 0x04 /* Middle mouse button (three-button mouse) */
#define VK_XBUTTON1 0x05 /* Windows 2000/XP: X1 mouse button */
#define VK_XBUTTON2 0x06 /* Windows 2000/XP: X2 mouse button */
/* 0x07 is undefined */
#define VK_BACK 0x08 /* BACKSPACE key */
#define VK_TAB 0x09 /* TAB key */
/* 0x0A to 0x0B are reserved */
#define VK_CLEAR 0x0C /* CLEAR key */
#define VK_RETURN 0x0D /* ENTER key */
/* 0x0E to 0x0F are undefined */
#define VK_SHIFT 0x10 /* SHIFT key */
#define VK_CONTROL 0x11 /* CTRL key */
#define VK_MENU 0x12 /* ALT key */
#define VK_PAUSE 0x13 /* PAUSE key */
#define VK_CAPITAL 0x14 /* CAPS LOCK key */
#define VK_KANA 0x15 /* Input Method Editor (IME) Kana mode */
#define VK_HANGUEL 0x15 /* IME Hanguel mode (maintained for compatibility; use #define VK_HANGUL) */
#define VK_HANGUL 0x15 /* IME Hangul mode */
/* 0x16 is undefined */
#define VK_JUNJA 0x17 /* IME Junja mode */
#define VK_FINAL 0x18 /* IME final mode */
#define VK_HANJA 0x19 /* IME Hanja mode */
#define VK_KANJI 0x19 /* IME Kanji mode */
/* 0x1A is undefined */
#define VK_ESCAPE 0x1B /* ESC key */
#define VK_CONVERT 0x1C /* IME convert */
#define VK_NONCONVERT 0x1D /* IME nonconvert */
#define VK_ACCEPT 0x1E /* IME accept */
#define VK_MODECHANGE 0x1F /* IME mode change request */
#define VK_SPACE 0x20 /* SPACEBAR */
#define VK_PRIOR 0x21 /* PAGE UP key */
#define VK_NEXT 0x22 /* PAGE DOWN key */
#define VK_END 0x23 /* END key */
#define VK_HOME 0x24 /* HOME key */
#define VK_LEFT 0x25 /* LEFT ARROW key */
#define VK_UP 0x26 /* UP ARROW key */
#define VK_RIGHT 0x27 /* RIGHT ARROW key */
#define VK_DOWN 0x28 /* DOWN ARROW key */
#define VK_SELECT 0x29 /* SELECT key */
#define VK_PRINT 0x2A /* PRINT key */
#define VK_EXECUTE 0x2B /* EXECUTE key */
#define VK_SNAPSHOT 0x2C /* PRINT SCREEN key */
#define VK_INSERT 0x2D /* INS key */
#define VK_DELETE 0x2E /* DEL key */
#define VK_HELP 0x2F /* HELP key */
/* Digits, the last 4 bits of the code represent the corresponding digit */
#define VK_KEY_0 0x30 /* '0' key */
#define VK_KEY_1 0x31 /* '1' key */
#define VK_KEY_2 0x32 /* '2' key */
#define VK_KEY_3 0x33 /* '3' key */
#define VK_KEY_4 0x34 /* '4' key */
#define VK_KEY_5 0x35 /* '5' key */
#define VK_KEY_6 0x36 /* '6' key */
#define VK_KEY_7 0x37 /* '7' key */
#define VK_KEY_8 0x38 /* '8' key */
#define VK_KEY_9 0x39 /* '9' key */
/* 0x3A to 0x40 are undefined */
/* The alphabet, the code corresponds to the capitalized letter in the ASCII code */
#define VK_KEY_A 0x41 /* 'A' key */
#define VK_KEY_B 0x42 /* 'B' key */
#define VK_KEY_C 0x43 /* 'C' key */
#define VK_KEY_D 0x44 /* 'D' key */
#define VK_KEY_E 0x45 /* 'E' key */
#define VK_KEY_F 0x46 /* 'F' key */
#define VK_KEY_G 0x47 /* 'G' key */
#define VK_KEY_H 0x48 /* 'H' key */
#define VK_KEY_I 0x49 /* 'I' key */
#define VK_KEY_J 0x4A /* 'J' key */
#define VK_KEY_K 0x4B /* 'K' key */
#define VK_KEY_L 0x4C /* 'L' key */
#define VK_KEY_M 0x4D /* 'M' key */
#define VK_KEY_N 0x4E /* 'N' key */
#define VK_KEY_O 0x4F /* 'O' key */
#define VK_KEY_P 0x50 /* 'P' key */
#define VK_KEY_Q 0x51 /* 'Q' key */
#define VK_KEY_R 0x52 /* 'R' key */
#define VK_KEY_S 0x53 /* 'S' key */
#define VK_KEY_T 0x54 /* 'T' key */
#define VK_KEY_U 0x55 /* 'U' key */
#define VK_KEY_V 0x56 /* 'V' key */
#define VK_KEY_W 0x57 /* 'W' key */
#define VK_KEY_X 0x58 /* 'X' key */
#define VK_KEY_Y 0x59 /* 'Y' key */
#define VK_KEY_Z 0x5A /* 'Z' key */
#define VK_LWIN 0x5B /* Left Windows key (Microsoft Natural keyboard) */
#define VK_RWIN 0x5C /* Right Windows key (Natural keyboard) */
#define VK_APPS 0x5D /* Applications key (Natural keyboard) */
/* 0x5E is reserved */
#define VK_SLEEP 0x5F /* Computer Sleep key */
/* Numeric keypad digits, the last four bits of the code represent the corresponding digit */
#define VK_NUMPAD0 0x60 /* Numeric keypad '0' key */
#define VK_NUMPAD1 0x61 /* Numeric keypad '1' key */
#define VK_NUMPAD2 0x62 /* Numeric keypad '2' key */
#define VK_NUMPAD3 0x63 /* Numeric keypad '3' key */
#define VK_NUMPAD4 0x64 /* Numeric keypad '4' key */
#define VK_NUMPAD5 0x65 /* Numeric keypad '5' key */
#define VK_NUMPAD6 0x66 /* Numeric keypad '6' key */
#define VK_NUMPAD7 0x67 /* Numeric keypad '7' key */
#define VK_NUMPAD8 0x68 /* Numeric keypad '8' key */
#define VK_NUMPAD9 0x69 /* Numeric keypad '9' key */
/* Numeric keypad operators and special keys */
#define VK_MULTIPLY 0x6A /* Multiply key */
#define VK_ADD 0x6B /* Add key */
#define VK_SEPARATOR 0x6C /* Separator key */
#define VK_SUBTRACT 0x6D /* Subtract key */
#define VK_DECIMAL 0x6E /* Decimal key */
#define VK_DIVIDE 0x6F /* Divide key */
/* Function keys, from F1 to F24 */
#define VK_F1 0x70 /* F1 key */
#define VK_F2 0x71 /* F2 key */
#define VK_F3 0x72 /* F3 key */
#define VK_F4 0x73 /* F4 key */
#define VK_F5 0x74 /* F5 key */
#define VK_F6 0x75 /* F6 key */
#define VK_F7 0x76 /* F7 key */
#define VK_F8 0x77 /* F8 key */
#define VK_F9 0x78 /* F9 key */
#define VK_F10 0x79 /* F10 key */
#define VK_F11 0x7A /* F11 key */
#define VK_F12 0x7B /* F12 key */
#define VK_F13 0x7C /* F13 key */
#define VK_F14 0x7D /* F14 key */
#define VK_F15 0x7E /* F15 key */
#define VK_F16 0x7F /* F16 key */
#define VK_F17 0x80 /* F17 key */
#define VK_F18 0x81 /* F18 key */
#define VK_F19 0x82 /* F19 key */
#define VK_F20 0x83 /* F20 key */
#define VK_F21 0x84 /* F21 key */
#define VK_F22 0x85 /* F22 key */
#define VK_F23 0x86 /* F23 key */
#define VK_F24 0x87 /* F24 key */
/* 0x88 to 0x8F are unassigned */
#define VK_NUMLOCK 0x90 /* NUM LOCK key */
#define VK_SCROLL 0x91 /* SCROLL LOCK key */
/* 0x92 to 0x96 are OEM specific */
/* 0x97 to 0x9F are unassigned */
/* Modifier keys */
#define VK_LSHIFT 0xA0 /* Left SHIFT key */
#define VK_RSHIFT 0xA1 /* Right SHIFT key */
#define VK_LCONTROL 0xA2 /* Left CONTROL key */
#define VK_RCONTROL 0xA3 /* Right CONTROL key */
#define VK_LMENU 0xA4 /* Left MENU key */
#define VK_RMENU 0xA5 /* Right MENU key */
/* Browser related keys */
#define VK_BROWSER_BACK 0xA6 /* Windows 2000/XP: Browser Back key */
#define VK_BROWSER_FORWARD 0xA7 /* Windows 2000/XP: Browser Forward key */
#define VK_BROWSER_REFRESH 0xA8 /* Windows 2000/XP: Browser Refresh key */
#define VK_BROWSER_STOP 0xA9 /* Windows 2000/XP: Browser Stop key */
#define VK_BROWSER_SEARCH 0xAA /* Windows 2000/XP: Browser Search key */
#define VK_BROWSER_FAVORITES 0xAB /* Windows 2000/XP: Browser Favorites key */
#define VK_BROWSER_HOME 0xAC /* Windows 2000/XP: Browser Start and Home key */
/* Volume related keys */
#define VK_VOLUME_MUTE 0xAD /* Windows 2000/XP: Volume Mute key */
#define VK_VOLUME_DOWN 0xAE /* Windows 2000/XP: Volume Down key */
#define VK_VOLUME_UP 0xAF /* Windows 2000/XP: Volume Up key */
/* Media player related keys */
#define VK_MEDIA_NEXT_TRACK 0xB0 /* Windows 2000/XP: Next Track key */
#define VK_MEDIA_PREV_TRACK 0xB1 /* Windows 2000/XP: Previous Track key */
#define VK_MEDIA_STOP 0xB2 /* Windows 2000/XP: Stop Media key */
#define VK_MEDIA_PLAY_PAUSE 0xB3 /* Windows 2000/XP: Play/Pause Media key */
/* Application launcher keys */
#define VK_LAUNCH_MAIL 0xB4 /* Windows 2000/XP: Start Mail key */
#define VK_LAUNCH_MEDIA_SELECT 0xB5 /* Windows 2000/XP: Select Media key */
#define VK_LAUNCH_APP1 0xB6 /* Windows 2000/XP: Start Application 1 key */
#define VK_LAUNCH_APP2 0xB7 /* Windows 2000/XP: Start Application 2 key */
/* 0xB8 and 0xB9 are reserved */
/* OEM keys */
#define VK_OEM_1 0xBA /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ';:' key */
#define VK_OEM_PLUS 0xBB /* Windows 2000/XP: For any country/region, the '+' key */
#define VK_OEM_COMMA 0xBC /* Windows 2000/XP: For any country/region, the ',' key */
#define VK_OEM_MINUS 0xBD /* Windows 2000/XP: For any country/region, the '-' key */
#define VK_OEM_PERIOD 0xBE /* Windows 2000/XP: For any country/region, the '.' key */
#define VK_OEM_2 0xBF /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '/?' key */
#define VK_OEM_3 0xC0 /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '`~' key */
/* 0xC1 to 0xD7 are reserved */
#define VK_ABNT_C1 0xC1 /* Brazilian (ABNT) Keyboard */
#define VK_ABNT_C2 0xC2 /* Brazilian (ABNT) Keyboard */
/* 0xD8 to 0xDA are unassigned */
#define VK_OEM_4 0xDB /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '[{' key */
#define VK_OEM_5 0xDC /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '\|' key */
#define VK_OEM_6 0xDD /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ']}' key */
#define VK_OEM_7 0xDE /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key */
#define VK_OEM_8 0xDF /* Used for miscellaneous characters; it can vary by keyboard. */
/* 0xE0 is reserved */
/* 0xE1 is OEM specific */
#define VK_OEM_102 0xE2 /* Windows 2000/XP: Either the angle bracket key or */
/* the backslash key on the RT 102-key keyboard */
/* 0xE3 and 0xE4 are OEM specific */
#define VK_PROCESSKEY 0xE5 /* Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key */
/* 0xE6 is OEM specific */
#define VK_PACKET 0xE7 /* Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. */
/* The #define VK_PACKET key is the low word of a 32-bit Virtual Key value used */
/* for non-keyboard input methods. For more information, */
/* see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP */
/* 0xE8 is unassigned */
/* 0xE9 to 0xF5 are OEM specific */
#define VK_ATTN 0xF6 /* Attn key */
#define VK_CRSEL 0xF7 /* CrSel key */
#define VK_EXSEL 0xF8 /* ExSel key */
#define VK_EREOF 0xF9 /* Erase EOF key */
#define VK_PLAY 0xFA /* Play key */
#define VK_ZOOM 0xFB /* Zoom key */
#define VK_NONAME 0xFC /* Reserved */
#define VK_PA1 0xFD /* PA1 key */
#define VK_OEM_CLEAR 0xFE /* Clear key */
/* Use the virtual key code as an index in this array in order to get its associated scan code */
typedef struct _virtualKey
{
/* Windows "scan code", aka keycode in RDP */
unsigned char scancode;
/* Windows "extended" flag, boolean */
unsigned char extended;
/* Windows virtual key name */
char *name;
/* XKB keyname */
char *x_keyname;
} virtualKey;
static const virtualKey virtualKeyboard[256 + 2] =
{
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_LBUTTON" , NULL },
{ 0x00, 0, "VK_RBUTTON" , NULL },
{ 0x00, 0, "VK_CANCEL" , NULL },
{ 0x00, 0, "VK_MBUTTON" , NULL },
{ 0x00, 0, "VK_XBUTTON1" , NULL },
{ 0x00, 0, "VK_XBUTTON2" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x0E, 0, "VK_BACK" , "BKSP" },
{ 0x0F, 0, "VK_TAB" , "TAB" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_CLEAR" , NULL },
{ 0x1C, 0, "VK_RETURN" , "RTRN" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x2A, 0, "VK_SHIFT" , "LFSH" },
{ 0x00, 0, "VK_CONTROL" , NULL },
{ 0x38, 0, "VK_MENU" , "LALT" },
{ 0x46, 1, "VK_PAUSE" , "PAUS" },
{ 0x3A, 0, "VK_CAPITAL" , "CAPS" },
{ 0x72, 0, "VK_KANA / VK_HANGUL" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_JUNJA" , NULL },
{ 0x00, 0, "VK_FINAL" , NULL },
{ 0x71, 0, "VK_HANJA / VK_KANJI" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x01, 0, "VK_ESCAPE" , "ESC" },
{ 0x00, 0, "VK_CONVERT" , NULL },
{ 0x00, 0, "VK_NONCONVERT" , NULL },
{ 0x00, 0, "VK_ACCEPT" , NULL },
{ 0x00, 0, "VK_MODECHANGE" , NULL },
{ 0x39, 0, "VK_SPACE" , "SPCE" },
{ 0x49, 1, "VK_PRIOR" , "PGUP" },
{ 0x51, 1, "VK_NEXT" , "PGDN" },
{ 0x4F, 1, "VK_END" , "END" },
{ 0x47, 1, "VK_HOME" , "HOME" },
{ 0x4B, 1, "VK_LEFT" , "LEFT" },
{ 0x48, 1, "VK_UP" , "UP" },
{ 0x4D, 1, "VK_RIGHT" , "RGHT" },
{ 0x50, 1, "VK_DOWN" , "DOWN" },
{ 0x00, 0, "VK_SELECT" , NULL },
{ 0x37, 1, "VK_PRINT" , "PRSC" },
{ 0x37, 1, "VK_EXECUTE" , NULL },
{ 0x37, 1, "VK_SNAPSHOT" , NULL },
{ 0x52, 1, "VK_INSERT" , "INS" },
{ 0x53, 1, "VK_DELETE" , "DELE" },
{ 0x63, 0, "VK_HELP" , NULL },
{ 0x0B, 0, "VK_KEY_0" , "AE10" },
{ 0x02, 0, "VK_KEY_1" , "AE01" },
{ 0x03, 0, "VK_KEY_2" , "AE02" },
{ 0x04, 0, "VK_KEY_3" , "AE03" },
{ 0x05, 0, "VK_KEY_4" , "AE04" },
{ 0x06, 0, "VK_KEY_5" , "AE05" },
{ 0x07, 0, "VK_KEY_6" , "AE06" },
{ 0x08, 0, "VK_KEY_7" , "AE07" },
{ 0x09, 0, "VK_KEY_8" , "AE08" },
{ 0x0A, 0, "VK_KEY_9" , "AE09" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x1E, 0, "VK_KEY_A" , "AC01" },
{ 0x30, 0, "VK_KEY_B" , "AB05" },
{ 0x2E, 0, "VK_KEY_C" , "AB03" },
{ 0x20, 0, "VK_KEY_D" , "AC03" },
{ 0x12, 0, "VK_KEY_E" , "AD03" },
{ 0x21, 0, "VK_KEY_F" , "AC04" },
{ 0x22, 0, "VK_KEY_G" , "AC05" },
{ 0x23, 0, "VK_KEY_H" , "AC06" },
{ 0x17, 0, "VK_KEY_I" , "AD08" },
{ 0x24, 0, "VK_KEY_J" , "AC07" },
{ 0x25, 0, "VK_KEY_K" , "AC08" },
{ 0x26, 0, "VK_KEY_L" , "AC09" },
{ 0x32, 0, "VK_KEY_M" , "AB07" },
{ 0x31, 0, "VK_KEY_N" , "AB06" },
{ 0x18, 0, "VK_KEY_O" , "AD09" },
{ 0x19, 0, "VK_KEY_P" , "AD10" },
{ 0x10, 0, "VK_KEY_Q" , "AD01" },
{ 0x13, 0, "VK_KEY_R" , "AD04" },
{ 0x1F, 0, "VK_KEY_S" , "AC02" },
{ 0x14, 0, "VK_KEY_T" , "AD05" },
{ 0x16, 0, "VK_KEY_U" , "AD07" },
{ 0x2F, 0, "VK_KEY_V" , "AB04" },
{ 0x11, 0, "VK_KEY_W" , "AD02" },
{ 0x2D, 0, "VK_KEY_X" , "AB02" },
{ 0x15, 0, "VK_KEY_Y" , "AD06" },
{ 0x2C, 0, "VK_KEY_Z" , "AB01" },
{ 0x5B, 1, "VK_LWIN" , "LWIN" },
{ 0x5C, 1, "VK_RWIN" , "RWIN" },
{ 0x5D, 1, "VK_APPS" , "COMP" },
{ 0x00, 0, "" , NULL },
{ 0x5F, 0, "VK_SLEEP" , NULL },
{ 0x52, 0, "VK_NUMPAD0" , "KP0" },
{ 0x4F, 0, "VK_NUMPAD1" , "KP1" },
{ 0x50, 0, "VK_NUMPAD2" , "KP2" },
{ 0x51, 0, "VK_NUMPAD3" , "KP3" },
{ 0x4B, 0, "VK_NUMPAD4" , "KP4" },
{ 0x4C, 0, "VK_NUMPAD5" , "KP5" },
{ 0x4D, 0, "VK_NUMPAD6" , "KP6" },
{ 0x47, 0, "VK_NUMPAD7" , "KP7" },
{ 0x48, 0, "VK_NUMPAD8" , "KP8" },
{ 0x49, 0, "VK_NUMPAD9" , "KP9" },
{ 0x37, 0, "VK_MULTIPLY" , "KPMU" },
{ 0x4E, 0, "VK_ADD" , "KPAD" },
{ 0x00, 0, "VK_SEPARATOR" , NULL },
{ 0x4A, 0, "VK_SUBTRACT" , "KPSU" },
{ 0x53, 0, "VK_DECIMAL" , "KPDL" },
{ 0x35, 0, "VK_DIVIDE" , "KPDV" },
{ 0x3B, 0, "VK_F1" , "FK01" },
{ 0x3C, 0, "VK_F2" , "FK02" },
{ 0x3D, 0, "VK_F3" , "FK03" },
{ 0x3E, 0, "VK_F4" , "FK04" },
{ 0x3F, 0, "VK_F5" , "FK05" },
{ 0x40, 0, "VK_F6" , "FK06" },
{ 0x41, 0, "VK_F7" , "FK07" },
{ 0x42, 0, "VK_F8" , "FK08" },
{ 0x43, 0, "VK_F9" , "FK09" },
{ 0x44, 0, "VK_F10" , "FK10" },
{ 0x57, 0, "VK_F11" , "FK11" },
{ 0x58, 0, "VK_F12" , "FK12" },
{ 0x64, 0, "VK_F13" , NULL },
{ 0x65, 0, "VK_F14" , NULL },
{ 0x66, 0, "VK_F15" , NULL },
{ 0x67, 0, "VK_F16" , NULL },
{ 0x68, 0, "VK_F17" , NULL },
{ 0x69, 0, "VK_F18" , NULL },
{ 0x6A, 0, "VK_F19" , NULL },
{ 0x6B, 0, "VK_F20" , NULL },
{ 0x6C, 0, "VK_F21" , NULL },
{ 0x6D, 0, "VK_F22" , NULL },
{ 0x6E, 0, "VK_F23" , NULL },
{ 0x6F, 0, "VK_F24" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x45, 0, "VK_NUMLOCK" , "NMLK" },
{ 0x46, 0, "VK_SCROLL" , "SCLK" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x2A, 0, "VK_LSHIFT" , NULL },
{ 0x36, 0, "VK_RSHIFT" , "RTSH" },
{ 0x1D, 0, "VK_LCONTROL" , "LCTL" },
{ 0x1D, 1, "VK_RCONTROL" , "RCTL" },
{ 0x38, 0, "VK_LMENU" , NULL },
{ 0x38, 1, "VK_RMENU" , "RALT" },
{ 0x00, 0, "VK_BROWSER_BACK" , NULL },
{ 0x00, 0, "VK_BROWSER_FORWARD" , NULL },
{ 0x00, 0, "VK_BROWSER_REFRESH" , NULL },
{ 0x00, 0, "VK_BROWSER_STOP" , NULL },
{ 0x00, 0, "VK_BROWSER_SEARCH" , NULL },
{ 0x00, 0, "VK_BROWSER_FAVORITES", NULL },
{ 0x00, 0, "VK_BROWSER_HOME" , NULL },
{ 0x00, 0, "VK_VOLUME_MUTE" , NULL },
{ 0x00, 0, "VK_VOLUME_DOWN" , NULL },
{ 0x00, 0, "VK_VOLUME_UP" , NULL },
{ 0x00, 0, "VK_MEDIA_NEXT_TRACK" , NULL },
{ 0x00, 0, "VK_MEDIA_PREV_TRACK" , NULL },
{ 0x00, 0, "VK_MEDIA_STOP" , NULL },
{ 0x00, 0, "VK_MEDIA_PLAY_PAUSE" , NULL },
{ 0x00, 0, "VK_LAUNCH_MAIL" , NULL },
{ 0x00, 0, "VK_MEDIA_SELECT" , NULL },
{ 0x00, 0, "VK_LAUNCH_APP1" , NULL },
{ 0x00, 0, "VK_LAUNCH_APP2" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x27, 0, "VK_OEM_1" , "AC10" },
{ 0x0D, 0, "VK_OEM_PLUS" , "AE12" },
{ 0x33, 0, "VK_OEM_COMMA" , "AB08" },
{ 0x0C, 0, "VK_OEM_MINUS" , "AE11" },
{ 0x34, 0, "VK_OEM_PERIOD" , "AB09" },
{ 0x35, 0, "VK_OEM_2" , "AB10" },
{ 0x29, 0, "VK_OEM_3" , "TLDE" },
{ 0x73, 0, "VK_ABNT_C1" , "AB11" },
{ 0x7E, 0, "VK_ABNT_C2" , "I129" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x1A, 0, "VK_OEM_4" , "AD11" },
{ 0x2B, 0, "VK_OEM_5" , "BKSL" },
{ 0x1B, 0, "VK_OEM_6" , "AD12" },
{ 0x28, 0, "VK_OEM_7" , "AC11" },
{ 0x1D, 0, "VK_OEM_8" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x56, 0, "VK_OEM_102" , "LSGT" },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_PROCESSKEY" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_PACKET" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_ATTN" , NULL },
{ 0x00, 0, "VK_CRSEL" , NULL },
{ 0x00, 0, "VK_EXSEL" , NULL },
{ 0x00, 0, "VK_EREOF" , NULL },
{ 0x00, 0, "VK_PLAY" , NULL },
{ 0x62, 0, "VK_ZOOM" , NULL },
{ 0x00, 0, "VK_NONAME" , NULL },
{ 0x00, 0, "VK_PA1" , NULL },
{ 0x00, 0, "VK_OEM_CLEAR" , NULL },
{ 0x00, 0, "" , NULL },
/* end of 256 VK entries */
{ 0x54, 0, "" , "LVL3" },
{ 0x1C, 1, "" , "KPEN" },
};
#endif /* __VKCODES_H */

View File

@ -0,0 +1,490 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Keyboard Mapping
*
* Copyright 2009-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 __FREERDP_LOCALE_KEYBOARD_H
#define __FREERDP_LOCALE_KEYBOARD_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#define RDP_KEYBOARD_LAYOUT_TYPE_STANDARD 1
#define RDP_KEYBOARD_LAYOUT_TYPE_VARIANT 2
#define RDP_KEYBOARD_LAYOUT_TYPE_IME 4
struct _RDP_KEYBOARD_LAYOUT
{
uint32 code; /* Keyboard layout code */
char* name; /* Keyboard layout name */
};
typedef struct _RDP_KEYBOARD_LAYOUT RDP_KEYBOARD_LAYOUT;
struct _RDP_SCANCODE
{
uint32 code; /* Windows "scan code" */
boolean extended; /* extended key flag */
};
typedef struct _RDP_SCANCODE RDP_SCANCODE;
struct _VIRTUAL_KEY_CODE
{
uint32 code; /* Windows Virtual Key Code */
const char* name; /* Virtual Key Code Name */
};
typedef struct _VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE;
/* Mouse buttons */
#define VK_LBUTTON 0x01 /* Left mouse button */
#define VK_RBUTTON 0x02 /* Right mouse button */
#define VK_CANCEL 0x03 /* Control-break processing */
#define VK_MBUTTON 0x04 /* Middle mouse button (three-button mouse) */
#define VK_XBUTTON1 0x05 /* Windows 2000/XP: X1 mouse button */
#define VK_XBUTTON2 0x06 /* Windows 2000/XP: X2 mouse button */
/* 0x07 is undefined */
#define VK_BACK 0x08 /* BACKSPACE key */
#define VK_TAB 0x09 /* TAB key */
/* 0x0A to 0x0B are reserved */
#define VK_CLEAR 0x0C /* CLEAR key */
#define VK_RETURN 0x0D /* ENTER key */
/* 0x0E to 0x0F are undefined */
#define VK_SHIFT 0x10 /* SHIFT key */
#define VK_CONTROL 0x11 /* CTRL key */
#define VK_MENU 0x12 /* ALT key */
#define VK_PAUSE 0x13 /* PAUSE key */
#define VK_CAPITAL 0x14 /* CAPS LOCK key */
#define VK_KANA 0x15 /* Input Method Editor (IME) Kana mode */
#define VK_HANGUEL 0x15 /* IME Hanguel mode (maintained for compatibility; use #define VK_HANGUL) */
#define VK_HANGUL 0x15 /* IME Hangul mode */
/* 0x16 is undefined */
#define VK_JUNJA 0x17 /* IME Junja mode */
#define VK_FINAL 0x18 /* IME final mode */
#define VK_HANJA 0x19 /* IME Hanja mode */
#define VK_KANJI 0x19 /* IME Kanji mode */
/* 0x1A is undefined */
#define VK_ESCAPE 0x1B /* ESC key */
#define VK_CONVERT 0x1C /* IME convert */
#define VK_NONCONVERT 0x1D /* IME nonconvert */
#define VK_ACCEPT 0x1E /* IME accept */
#define VK_MODECHANGE 0x1F /* IME mode change request */
#define VK_SPACE 0x20 /* SPACEBAR */
#define VK_PRIOR 0x21 /* PAGE UP key */
#define VK_NEXT 0x22 /* PAGE DOWN key */
#define VK_END 0x23 /* END key */
#define VK_HOME 0x24 /* HOME key */
#define VK_LEFT 0x25 /* LEFT ARROW key */
#define VK_UP 0x26 /* UP ARROW key */
#define VK_RIGHT 0x27 /* RIGHT ARROW key */
#define VK_DOWN 0x28 /* DOWN ARROW key */
#define VK_SELECT 0x29 /* SELECT key */
#define VK_PRINT 0x2A /* PRINT key */
#define VK_EXECUTE 0x2B /* EXECUTE key */
#define VK_SNAPSHOT 0x2C /* PRINT SCREEN key */
#define VK_INSERT 0x2D /* INS key */
#define VK_DELETE 0x2E /* DEL key */
#define VK_HELP 0x2F /* HELP key */
/* Digits, the last 4 bits of the code represent the corresponding digit */
#define VK_KEY_0 0x30 /* '0' key */
#define VK_KEY_1 0x31 /* '1' key */
#define VK_KEY_2 0x32 /* '2' key */
#define VK_KEY_3 0x33 /* '3' key */
#define VK_KEY_4 0x34 /* '4' key */
#define VK_KEY_5 0x35 /* '5' key */
#define VK_KEY_6 0x36 /* '6' key */
#define VK_KEY_7 0x37 /* '7' key */
#define VK_KEY_8 0x38 /* '8' key */
#define VK_KEY_9 0x39 /* '9' key */
/* 0x3A to 0x40 are undefined */
/* The alphabet, the code corresponds to the capitalized letter in the ASCII code */
#define VK_KEY_A 0x41 /* 'A' key */
#define VK_KEY_B 0x42 /* 'B' key */
#define VK_KEY_C 0x43 /* 'C' key */
#define VK_KEY_D 0x44 /* 'D' key */
#define VK_KEY_E 0x45 /* 'E' key */
#define VK_KEY_F 0x46 /* 'F' key */
#define VK_KEY_G 0x47 /* 'G' key */
#define VK_KEY_H 0x48 /* 'H' key */
#define VK_KEY_I 0x49 /* 'I' key */
#define VK_KEY_J 0x4A /* 'J' key */
#define VK_KEY_K 0x4B /* 'K' key */
#define VK_KEY_L 0x4C /* 'L' key */
#define VK_KEY_M 0x4D /* 'M' key */
#define VK_KEY_N 0x4E /* 'N' key */
#define VK_KEY_O 0x4F /* 'O' key */
#define VK_KEY_P 0x50 /* 'P' key */
#define VK_KEY_Q 0x51 /* 'Q' key */
#define VK_KEY_R 0x52 /* 'R' key */
#define VK_KEY_S 0x53 /* 'S' key */
#define VK_KEY_T 0x54 /* 'T' key */
#define VK_KEY_U 0x55 /* 'U' key */
#define VK_KEY_V 0x56 /* 'V' key */
#define VK_KEY_W 0x57 /* 'W' key */
#define VK_KEY_X 0x58 /* 'X' key */
#define VK_KEY_Y 0x59 /* 'Y' key */
#define VK_KEY_Z 0x5A /* 'Z' key */
#define VK_LWIN 0x5B /* Left Windows key (Microsoft Natural keyboard) */
#define VK_RWIN 0x5C /* Right Windows key (Natural keyboard) */
#define VK_APPS 0x5D /* Applications key (Natural keyboard) */
/* 0x5E is reserved */
#define VK_SLEEP 0x5F /* Computer Sleep key */
/* Numeric keypad digits, the last four bits of the code represent the corresponding digit */
#define VK_NUMPAD0 0x60 /* Numeric keypad '0' key */
#define VK_NUMPAD1 0x61 /* Numeric keypad '1' key */
#define VK_NUMPAD2 0x62 /* Numeric keypad '2' key */
#define VK_NUMPAD3 0x63 /* Numeric keypad '3' key */
#define VK_NUMPAD4 0x64 /* Numeric keypad '4' key */
#define VK_NUMPAD5 0x65 /* Numeric keypad '5' key */
#define VK_NUMPAD6 0x66 /* Numeric keypad '6' key */
#define VK_NUMPAD7 0x67 /* Numeric keypad '7' key */
#define VK_NUMPAD8 0x68 /* Numeric keypad '8' key */
#define VK_NUMPAD9 0x69 /* Numeric keypad '9' key */
/* Numeric keypad operators and special keys */
#define VK_MULTIPLY 0x6A /* Multiply key */
#define VK_ADD 0x6B /* Add key */
#define VK_SEPARATOR 0x6C /* Separator key */
#define VK_SUBTRACT 0x6D /* Subtract key */
#define VK_DECIMAL 0x6E /* Decimal key */
#define VK_DIVIDE 0x6F /* Divide key */
/* Function keys, from F1 to F24 */
#define VK_F1 0x70 /* F1 key */
#define VK_F2 0x71 /* F2 key */
#define VK_F3 0x72 /* F3 key */
#define VK_F4 0x73 /* F4 key */
#define VK_F5 0x74 /* F5 key */
#define VK_F6 0x75 /* F6 key */
#define VK_F7 0x76 /* F7 key */
#define VK_F8 0x77 /* F8 key */
#define VK_F9 0x78 /* F9 key */
#define VK_F10 0x79 /* F10 key */
#define VK_F11 0x7A /* F11 key */
#define VK_F12 0x7B /* F12 key */
#define VK_F13 0x7C /* F13 key */
#define VK_F14 0x7D /* F14 key */
#define VK_F15 0x7E /* F15 key */
#define VK_F16 0x7F /* F16 key */
#define VK_F17 0x80 /* F17 key */
#define VK_F18 0x81 /* F18 key */
#define VK_F19 0x82 /* F19 key */
#define VK_F20 0x83 /* F20 key */
#define VK_F21 0x84 /* F21 key */
#define VK_F22 0x85 /* F22 key */
#define VK_F23 0x86 /* F23 key */
#define VK_F24 0x87 /* F24 key */
/* 0x88 to 0x8F are unassigned */
#define VK_NUMLOCK 0x90 /* NUM LOCK key */
#define VK_SCROLL 0x91 /* SCROLL LOCK key */
/* 0x92 to 0x96 are OEM specific */
/* 0x97 to 0x9F are unassigned */
/* Modifier keys */
#define VK_LSHIFT 0xA0 /* Left SHIFT key */
#define VK_RSHIFT 0xA1 /* Right SHIFT key */
#define VK_LCONTROL 0xA2 /* Left CONTROL key */
#define VK_RCONTROL 0xA3 /* Right CONTROL key */
#define VK_LMENU 0xA4 /* Left MENU key */
#define VK_RMENU 0xA5 /* Right MENU key */
/* Browser related keys */
#define VK_BROWSER_BACK 0xA6 /* Windows 2000/XP: Browser Back key */
#define VK_BROWSER_FORWARD 0xA7 /* Windows 2000/XP: Browser Forward key */
#define VK_BROWSER_REFRESH 0xA8 /* Windows 2000/XP: Browser Refresh key */
#define VK_BROWSER_STOP 0xA9 /* Windows 2000/XP: Browser Stop key */
#define VK_BROWSER_SEARCH 0xAA /* Windows 2000/XP: Browser Search key */
#define VK_BROWSER_FAVORITES 0xAB /* Windows 2000/XP: Browser Favorites key */
#define VK_BROWSER_HOME 0xAC /* Windows 2000/XP: Browser Start and Home key */
/* Volume related keys */
#define VK_VOLUME_MUTE 0xAD /* Windows 2000/XP: Volume Mute key */
#define VK_VOLUME_DOWN 0xAE /* Windows 2000/XP: Volume Down key */
#define VK_VOLUME_UP 0xAF /* Windows 2000/XP: Volume Up key */
/* Media player related keys */
#define VK_MEDIA_NEXT_TRACK 0xB0 /* Windows 2000/XP: Next Track key */
#define VK_MEDIA_PREV_TRACK 0xB1 /* Windows 2000/XP: Previous Track key */
#define VK_MEDIA_STOP 0xB2 /* Windows 2000/XP: Stop Media key */
#define VK_MEDIA_PLAY_PAUSE 0xB3 /* Windows 2000/XP: Play/Pause Media key */
/* Application launcher keys */
#define VK_LAUNCH_MAIL 0xB4 /* Windows 2000/XP: Start Mail key */
#define VK_MEDIA_SELECT 0xB5 /* Windows 2000/XP: Select Media key */
#define VK_LAUNCH_APP1 0xB6 /* Windows 2000/XP: Start Application 1 key */
#define VK_LAUNCH_APP2 0xB7 /* Windows 2000/XP: Start Application 2 key */
/* 0xB8 and 0xB9 are reserved */
/* OEM keys */
#define VK_OEM_1 0xBA /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ';:' key */
#define VK_OEM_PLUS 0xBB /* Windows 2000/XP: For any country/region, the '+' key */
#define VK_OEM_COMMA 0xBC /* Windows 2000/XP: For any country/region, the ',' key */
#define VK_OEM_MINUS 0xBD /* Windows 2000/XP: For any country/region, the '-' key */
#define VK_OEM_PERIOD 0xBE /* Windows 2000/XP: For any country/region, the '.' key */
#define VK_OEM_2 0xBF /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '/?' key */
#define VK_OEM_3 0xC0 /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '`~' key */
/* 0xC1 to 0xD7 are reserved */
#define VK_ABNT_C1 0xC1 /* Brazilian (ABNT) Keyboard */
#define VK_ABNT_C2 0xC2 /* Brazilian (ABNT) Keyboard */
/* 0xD8 to 0xDA are unassigned */
#define VK_OEM_4 0xDB /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '[{' key */
#define VK_OEM_5 0xDC /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '\|' key */
#define VK_OEM_6 0xDD /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ']}' key */
#define VK_OEM_7 0xDE /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key */
#define VK_OEM_8 0xDF /* Used for miscellaneous characters; it can vary by keyboard. */
/* 0xE0 is reserved */
/* 0xE1 is OEM specific */
#define VK_OEM_102 0xE2 /* Windows 2000/XP: Either the angle bracket key or */
/* the backslash key on the RT 102-key keyboard */
/* 0xE3 and 0xE4 are OEM specific */
#define VK_PROCESSKEY 0xE5 /* Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key */
/* 0xE6 is OEM specific */
#define VK_PACKET 0xE7 /* Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. */
/* The #define VK_PACKET key is the low word of a 32-bit Virtual Key value used */
/* for non-keyboard input methods. For more information, */
/* see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP */
/* 0xE8 is unassigned */
/* 0xE9 to 0xF5 are OEM specific */
#define VK_ATTN 0xF6 /* Attn key */
#define VK_CRSEL 0xF7 /* CrSel key */
#define VK_EXSEL 0xF8 /* ExSel key */
#define VK_EREOF 0xF9 /* Erase EOF key */
#define VK_PLAY 0xFA /* Play key */
#define VK_ZOOM 0xFB /* Zoom key */
#define VK_NONAME 0xFC /* Reserved */
#define VK_PA1 0xFD /* PA1 key */
#define VK_OEM_CLEAR 0xFE /* Clear key */
/* Keyboard layout IDs */
#define KBD_ARABIC_101 0x00000401
#define KBD_BULGARIAN 0x00000402
#define KBD_CHINESE_TRADITIONAL_US 0x00000404
#define KBD_CZECH 0x00000405
#define KBD_DANISH 0x00000406
#define KBD_GERMAN 0x00000407
#define KBD_GREEK 0x00000408
#define KBD_US 0x00000409
#define KBD_SPANISH 0x0000040A
#define KBD_FINNISH 0x0000040B
#define KBD_FRENCH 0x0000040C
#define KBD_HEBREW 0x0000040D
#define KBD_HUNGARIAN 0x0000040E
#define KBD_ICELANDIC 0x0000040F
#define KBD_ITALIAN 0x00000410
#define KBD_JAPANESE 0x00000411
#define KBD_KOREAN 0x00000412
#define KBD_DUTCH 0x00000413
#define KBD_NORWEGIAN 0x00000414
#define KBD_POLISH_PROGRAMMERS 0x00000415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT 0x00000416
#define KBD_ROMANIAN 0x00000418
#define KBD_RUSSIAN 0x00000419
#define KBD_CROATIAN 0x0000041A
#define KBD_SLOVAK 0x0000041B
#define KBD_ALBANIAN 0x0000041C
#define KBD_SWEDISH 0x0000041D
#define KBD_THAI_KEDMANEE 0x0000041E
#define KBD_TURKISH_Q 0x0000041F
#define KBD_URDU 0x00000420
#define KBD_UKRAINIAN 0x00000422
#define KBD_BELARUSIAN 0x00000423
#define KBD_SLOVENIAN 0x00000424
#define KBD_ESTONIAN 0x00000425
#define KBD_LATVIAN 0x00000426
#define KBD_LITHUANIAN_IBM 0x00000427
#define KBD_FARSI 0x00000429
#define KBD_VIETNAMESE 0x0000042A
#define KBD_ARMENIAN_EASTERN 0x0000042B
#define KBD_AZERI_LATIN 0x0000042C
#define KBD_FYRO_MACEDONIAN 0x0000042F
#define KBD_GEORGIAN 0x00000437
#define KBD_FAEROESE 0x00000438
#define KBD_DEVANAGARI_INSCRIPT 0x00000439
#define KBD_MALTESE_47_KEY 0x0000043A
#define KBD_NORWEGIAN_WITH_SAMI 0x0000043B
#define KBD_KAZAKH 0x0000043F
#define KBD_KYRGYZ_CYRILLIC 0x00000440
#define KBD_TATAR 0x00000444
#define KBD_BENGALI 0x00000445
#define KBD_PUNJABI 0x00000446
#define KBD_GUJARATI 0x00000447
#define KBD_TAMIL 0x00000449
#define KBD_TELUGU 0x0000044A
#define KBD_KANNADA 0x0000044B
#define KBD_MALAYALAM 0x0000044C
#define KBD_MARATHI 0x0000044E
#define KBD_MONGOLIAN_CYRILLIC 0x00000450
#define KBD_UNITED_KINGDOM_EXTENDED 0x00000452
#define KBD_SYRIAC 0x0000045A
#define KBD_NEPALI 0x00000461
#define KBD_PASHTO 0x00000463
#define KBD_DIVEHI_PHONETIC 0x00000465
#define KBD_LUXEMBOURGISH 0x0000046E
#define KBD_MAORI 0x00000481
#define KBD_CHINESE_SIMPLIFIED_US 0x00000804
#define KBD_SWISS_GERMAN 0x00000807
#define KBD_UNITED_KINGDOM 0x00000809
#define KBD_LATIN_AMERICAN 0x0000080A
#define KBD_BELGIAN_FRENCH 0x0000080C
#define KBD_BELGIAN_PERIOD 0x00000813
#define KBD_PORTUGUESE 0x00000816
#define KBD_SERBIAN_LATIN 0x0000081A
#define KBD_AZERI_CYRILLIC 0x0000082C
#define KBD_SWEDISH_WITH_SAMI 0x0000083B
#define KBD_UZBEK_CYRILLIC 0x00000843
#define KBD_INUKTITUT_LATIN 0x0000085D
#define KBD_CANADIAN_FRENCH_LEGACY 0x00000C0C
#define KBD_SERBIAN_CYRILLIC 0x00000C1A
#define KBD_CANADIAN_FRENCH 0x00001009
#define KBD_SWISS_FRENCH 0x0000100C
#define KBD_BOSNIAN 0x0000141A
#define KBD_IRISH 0x00001809
#define KBD_BOSNIAN_CYRILLIC 0x0000201A
/* Keyboard layout variant IDs */
#define KBD_ARABIC_102 0x00010401
#define KBD_BULGARIAN_LATIN 0x00010402
#define KBD_CZECH_QWERTY 0x00010405
#define KBD_GERMAN_IBM 0x00010407
#define KBD_GREEK_220 0x00010408
#define KBD_UNITED_STATES_DVORAK 0x00010409
#define KBD_SPANISH_VARIATION 0x0001040A
#define KBD_HUNGARIAN_101_KEY 0x0001040E
#define KBD_ITALIAN_142 0x00010410
#define KBD_POLISH_214 0x00010415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT2 0x00010416
#define KBD_RUSSIAN_TYPEWRITER 0x00010419
#define KBD_SLOVAK_QWERTY 0x0001041B
#define KBD_THAI_PATTACHOTE 0x0001041E
#define KBD_TURKISH_F 0x0001041F
#define KBD_LATVIAN_QWERTY 0x00010426
#define KBD_LITHUANIAN 0x00010427
#define KBD_ARMENIAN_WESTERN 0x0001042B
#define KBD_HINDI_TRADITIONAL 0x00010439
#define KBD_MALTESE_48_KEY 0x0001043A
#define KBD_SAMI_EXTENDED_NORWAY 0x0001043B
#define KBD_BENGALI_INSCRIPT 0x00010445
#define KBD_SYRIAC_PHONETIC 0x0001045A
#define KBD_DIVEHI_TYPEWRITER 0x00010465
#define KBD_BELGIAN_COMMA 0x0001080C
#define KBD_FINNISH_WITH_SAMI 0x0001083B
#define KBD_CANADIAN_MULTILINGUAL_STANDARD 0x00011009
#define KBD_GAELIC 0x00011809
#define KBD_ARABIC_102_AZERTY 0x00020401
#define KBD_CZECH_PROGRAMMERS 0x00020405
#define KBD_GREEK_319 0x00020408
#define KBD_UNITED_STATES_INTERNATIONAL 0x00020409
#define KBD_THAI_KEDMANEE_NON_SHIFTLOCK 0x0002041E
#define KBD_SAMI_EXTENDED_FINLAND_SWEDEN 0x0002083B
#define KBD_GREEK_220_LATIN 0x00030408
#define KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND 0x00030409
#define KBD_THAI_PATTACHOTE_NON_SHIFTLOCK 0x0003041E
#define KBD_GREEK_319_LATIN 0x00040408
#define KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND 0x00040409
#define KBD_GREEK_LATIN 0x00050408
#define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409
#define KBD_GREEK_POLYTONIC 0x00060408
#define KBD_GERMAN_NEO 0xB0000407
/* Global Input Method Editor (IME) IDs */
#define KBD_CHINESE_TRADITIONAL_PHONETIC 0xE0010404
#define KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 0xE0010411
#define KBD_KOREAN_INPUT_SYSTEM_IME_2000 0xE0010412
#define KBD_CHINESE_SIMPLIFIED_QUANPIN 0xE0010804
#define KBD_CHINESE_TRADITIONAL_CHANGJIE 0xE0020404
#define KBD_CHINESE_SIMPLIFIED_SHUANGPIN 0xE0020804
#define KBD_CHINESE_TRADITIONAL_QUICK 0xE0030404
#define KBD_CHINESE_SIMPLIFIED_ZHENGMA 0xE0030804
#define KBD_CHINESE_TRADITIONAL_BIG5_CODE 0xE0040404
#define KBD_CHINESE_TRADITIONAL_ARRAY 0xE0050404
#define KBD_CHINESE_SIMPLIFIED_NEIMA 0xE0050804
#define KBD_CHINESE_TRADITIONAL_DAYI 0xE0060404
#define KBD_CHINESE_TRADITIONAL_UNICODE 0xE0070404
#define KBD_CHINESE_TRADITIONAL_NEW_PHONETIC 0xE0080404
#define KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE 0xE0090404
#define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804
#define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404
FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboardLayoutId);
FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types);
FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutId);
FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_x11_keycode(uint32 keycode, boolean* extended);
FREERDP_API uint32 freerdp_keyboard_get_x11_keycode_from_rdp_scancode(uint32 scancode, boolean extended);
FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(uint32 vkcode, boolean* extended);
FREERDP_API char* freerdp_keyboard_get_virtual_key_code_name(uint32 vkcode);
#endif /* __FREERDP_LOCALE_KEYBOARD_H */

View File

@ -0,0 +1,237 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Microsoft Locales
*
* Copyright 2009-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.
*/
/* Detection of plausible keyboard layout id based on current locale (LANG) setting. */
/*
* Refer to "Windows XP/Server 2003 - List of Locale IDs, Input Locale, and Language Collection":
* http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx
*/
#ifndef __FREERDP_LOCALE_H
#define __FREERDP_LOCALE_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#define AFRIKAANS 0x0436
#define ALBANIAN 0x041C
#define ALSATIAN 0x0484
#define AMHARIC 0x045E
#define ARABIC_SAUDI_ARABIA 0x0401
#define ARABIC_IRAQ 0x0801
#define ARABIC_EGYPT 0x0C01
#define ARABIC_LIBYA 0x1001
#define ARABIC_ALGERIA 0x1401
#define ARABIC_MOROCCO 0x1801
#define ARABIC_TUNISIA 0x1C01
#define ARABIC_OMAN 0x2001
#define ARABIC_YEMEN 0x2401
#define ARABIC_SYRIA 0x2801
#define ARABIC_JORDAN 0x2C01
#define ARABIC_LEBANON 0x3001
#define ARABIC_KUWAIT 0x3401
#define ARABIC_UAE 0x3801
#define ARABIC_BAHRAIN 0x3C01
#define ARABIC_QATAR 0x4001
#define ARMENIAN 0x042B
#define ASSAMESE 0x044D
#define AZERI_LATIN 0x042C
#define AZERI_CYRILLIC 0x082C
#define BASHKIR 0x046D
#define BASQUE 0x042D
#define BELARUSIAN 0x0423
#define BENGALI_INDIA 0x0445
#define BOSNIAN_LATIN 0x141A
#define BRETON 0x047E
#define BULGARIAN 0x0402
#define CATALAN 0x0403
#define CHINESE_TAIWAN 0x0404
#define CHINESE_PRC 0x0804
#define CHINESE_HONG_KONG 0x0C04
#define CHINESE_SINGAPORE 0x1004
#define CHINESE_MACAU 0x1404
#define CROATIAN 0x041A
#define CROATIAN_BOSNIA_HERZEGOVINA 0x101A
#define CZECH 0x0405
#define DANISH 0x0406
#define DARI 0x048C
#define DIVEHI 0x0465
#define DUTCH_STANDARD 0x0413
#define DUTCH_BELGIAN 0x0813
#define ENGLISH_UNITED_STATES 0x0409
#define ENGLISH_UNITED_KINGDOM 0x0809
#define ENGLISH_AUSTRALIAN 0x0C09
#define ENGLISH_CANADIAN 0x1009
#define ENGLISH_NEW_ZEALAND 0x1409
#define ENGLISH_INDIA 0x4009
#define ENGLISH_IRELAND 0x1809
#define ENGLISH_MALAYSIA 0x4409
#define ENGLISH_SOUTH_AFRICA 0x1C09
#define ENGLISH_JAMAICA 0x2009
#define ENGLISH_CARIBBEAN 0x2409
#define ENGLISH_BELIZE 0x2809
#define ENGLISH_TRINIDAD 0x2C09
#define ENGLISH_ZIMBABWE 0x3009
#define ENGLISH_PHILIPPINES 0x3409
#define ENGLISH_SINGAPORE 0x4809
#define ESTONIAN 0x0425
#define FAEROESE 0x0438
#define FARSI 0x0429
#define FILIPINO 0x0464
#define FINNISH 0x040B
#define FRENCH_STANDARD 0x040C
#define FRENCH_BELGIAN 0x080C
#define FRENCH_CANADIAN 0x0C0C
#define FRENCH_SWISS 0x100C
#define FRENCH_LUXEMBOURG 0x140C
#define FRENCH_MONACO 0x180C
#define FRISIAN 0x0462
#define GEORGIAN 0x0437
#define GALICIAN 0x0456
#define GERMAN_STANDARD 0x0407
#define GERMAN_SWISS 0x0807
#define GERMAN_AUSTRIAN 0x0C07
#define GERMAN_LUXEMBOURG 0x1007
#define GERMAN_LIECHTENSTEIN 0x1407
#define GREEK 0x0408
#define GREENLANDIC 0x046F
#define GUJARATI 0x0447
#define HEBREW 0x040D
#define HINDI 0x0439
#define HUNGARIAN 0x040E
#define ICELANDIC 0x040F
#define IGBO 0x0470
#define INDONESIAN 0x0421
#define IRISH 0x083C
#define ITALIAN_STANDARD 0x0410
#define ITALIAN_SWISS 0x0810
#define JAPANESE 0x0411
#define KANNADA 0x044B
#define KAZAKH 0x043F
#define KHMER 0x0453
#define KICHE 0x0486
#define KINYARWANDA 0x0487
#define KONKANI 0x0457
#define KOREAN 0x0412
#define KYRGYZ 0x0440
#define LAO 0x0454
#define LATVIAN 0x0426
#define LITHUANIAN 0x0427
#define LOWER_SORBIAN 0x082E
#define LUXEMBOURGISH 0x046E
#define MACEDONIAN 0x042F
#define MALAY_MALAYSIA 0x043E
#define MALAY_BRUNEI_DARUSSALAM 0x083E
#define MALAYALAM 0x044C
#define MALTESE 0x043A
#define MAPUDUNGUN 0x047A
#define MAORI 0x0481
#define MARATHI 0x044E
#define MOHAWK 0x047C
#define MONGOLIAN 0x0450
#define NEPALI 0x0461
#define NORWEGIAN_BOKMAL 0x0414
#define NORWEGIAN_NYNORSK 0x0814
#define OCCITAN 0x0482
#define ORIYA 0x0448
#define PASHTO 0x0463
#define POLISH 0x0415
#define PORTUGUESE_BRAZILIAN 0x0416
#define PORTUGUESE_STANDARD 0x0816
#define PUNJABI 0x0446
#define QUECHUA_BOLIVIA 0x046B
#define QUECHUA_ECUADOR 0x086B
#define QUECHUA_PERU 0x0C6B
#define ROMANIAN 0x0418
#define ROMANSH 0x0417
#define RUSSIAN 0x0419
#define SAMI_INARI 0x243B
#define SAMI_LULE_NORWAY 0x103B
#define SAMI_LULE_SWEDEN 0x143B
#define SAMI_NORTHERN_FINLAND 0x0C3B
#define SAMI_NORTHERN_NORWAY 0x043B
#define SAMI_NORTHERN_SWEDEN 0x083B
#define SAMI_SKOLT 0x203B
#define SAMI_SOUTHERN_NORWAY 0x183B
#define SAMI_SOUTHERN_SWEDEN 0x1C3B
#define SANSKRIT 0x044F
#define SERBIAN_LATIN 0x081A
#define SERBIAN_LATIN_BOSNIA_HERZEGOVINA 0x181A
#define SERBIAN_CYRILLIC 0x0C1A
#define SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA 0x1C1A
#define SESOTHO_SA_LEBOA 0x046C
#define SINHALA 0x045B
#define SLOVAK 0x041B
#define SLOVENIAN 0x0424
#define SPANISH_TRADITIONAL_SORT 0x040A
#define SPANISH_MEXICAN 0x080A
#define SPANISH_MODERN_SORT 0x0C0A
#define SPANISH_GUATEMALA 0x100A
#define SPANISH_COSTA_RICA 0x140A
#define SPANISH_PANAMA 0x180A
#define SPANISH_DOMINICAN_REPUBLIC 0x1C0A
#define SPANISH_VENEZUELA 0x200A
#define SPANISH_COLOMBIA 0x240A
#define SPANISH_PERU 0x280A
#define SPANISH_ARGENTINA 0x2C0A
#define SPANISH_ECUADOR 0x300A
#define SPANISH_CHILE 0x340A
#define SPANISH_UNITED_STATES 0x540A
#define SPANISH_URUGUAY 0x380A
#define SPANISH_PARAGUAY 0x3C0A
#define SPANISH_BOLIVIA 0x400A
#define SPANISH_EL_SALVADOR 0x440A
#define SPANISH_HONDURAS 0x480A
#define SPANISH_NICARAGUA 0x4C0A
#define SPANISH_PUERTO_RICO 0x500A
#define SWAHILI 0x0441
#define SWEDISH 0x041D
#define SWEDISH_FINLAND 0x081D
#define SYRIAC 0x045A
#define TAMIL 0x0449
#define TATAR 0x0444
#define TELUGU 0x044A
#define THAI 0x041E
#define TIBETAN_BHUTAN 0x0851
#define TIBETAN_PRC 0x0451
#define TSWANA 0x0432
#define UKRAINIAN 0x0422
#define TURKISH 0x041F
#define TURKMEN 0x0442
#define UIGHUR 0x0480
#define UPPER_SORBIAN 0x042E
#define URDU 0x0420
#define URDU_INDIA 0x0820
#define UZBEK_LATIN 0x0443
#define UZBEK_CYRILLIC 0x0843
#define VIETNAMESE 0x042A
#define WELSH 0x0452
#define WOLOF 0x0488
#define XHOSA 0x0434
#define YAKUT 0x0485
#define YI 0x0478
#define YORUBA 0x046A
#define ZULU 0x0435
FREERDP_API uint32 freerdp_get_system_locale_id();
FREERDP_API uint32 freerdp_detect_keyboard_layout_from_system_locale();
FREERDP_API const char* freerdp_get_system_locale_name_from_id(uint32 localeId);
#endif /* __FREERDP_LOCALE_H */

View File

@ -1,8 +1,8 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* XKB-based Keyboard Mapping to Microsoft Keyboard System
* FreeRDP: A Remote Desktop Protocol Implementation
* Time Zone Redirection
*
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* 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.
@ -17,15 +17,13 @@
* limitations under the License.
*/
/* Hardcoded mapping from xkb layout names and variants to RDP layout ids */
#ifndef __LOCALE_TIMEZONE_H
#define __LOCALE_TIMEZONE_H
#ifndef __LAYOUTS_X_H
#define __LAYOUTS_X_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant);
FREERDP_API void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone);
#if defined(sun)
unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length);
#endif
#endif
#endif /* __LOCALE_TIMEZONE_H */

View File

@ -22,6 +22,9 @@
#include <freerdp/types.h>
#define BACKMODE_TRANSPARENT 0x0001
#define BACKMODE_OPAQUE 0x0002
struct rdp_bounds
{
sint32 left;
@ -365,9 +368,9 @@ struct _POLYGON_SC_ORDER
uint32 bRop2;
uint32 fillMode;
uint32 brushColor;
uint32 nDeltaEntries;
uint32 numPoints;
uint32 cbData;
uint8* codeDeltaList;
DELTA_POINT* points;
};
typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER;
@ -376,13 +379,14 @@ struct _POLYGON_CB_ORDER
sint32 xStart;
sint32 yStart;
uint32 bRop2;
uint32 backMode;
uint32 fillMode;
uint32 backColor;
uint32 foreColor;
rdpBrush brush;
uint32 nDeltaEntries;
uint32 numPoints;
uint32 cbData;
uint8* codeDeltaList;
DELTA_POINT* points;
};
typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER;

View File

@ -144,9 +144,6 @@ typedef struct
/* Certificates */
typedef struct rdp_certificate rdpCertificate;
typedef struct rdp_key rdpKey;
struct rdp_CertBlob
{
uint32 length;
@ -173,6 +170,15 @@ struct rdp_certificate
rdpCertInfo cert_info;
rdpX509CertChain* x509_cert_chain;
};
typedef struct rdp_certificate rdpCertificate;
struct rdp_key
{
rdpBlob modulus;
rdpBlob private_exponent;
uint8 exponent[4];
};
typedef struct rdp_key rdpKey;
/* Channels */
@ -302,7 +308,7 @@ struct rdp_settings
boolean nla_security; /* 146 */
boolean rdp_security; /* 147 */
uint32 ntlm_version; /* 148 */
boolean secure_checksum; /* 149 */
boolean salted_checksum; /* 149 */
uint32 paddingF[160 - 150]; /* 150 */
/* Session */

View File

@ -1,3 +1,23 @@
install(FILES aliases amiga ataritt empty evdev fujitsu hp ibm macintosh macosx sony sun xfree86 xfree98 xkb.pl DESTINATION share/freerdp/keymaps)
install(DIRECTORY digital_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*")
install(DIRECTORY sgi_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*")
# FreeRDP: A Remote Desktop Protocol Client
# keymaps cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 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.
install(FILES aliases amiga ataritt empty evdev fujitsu hp ibm macintosh macosx sony sun xfree86 xfree98 DESTINATION ${FREERDP_KEYMAP_PATH})
install(DIRECTORY digital_vndr DESTINATION ${FREERDP_KEYMAP_PATH} FILES_MATCHING PATTERN "*")
install(DIRECTORY sgi_vndr DESTINATION ${FREERDP_KEYMAP_PATH} FILES_MATCHING PATTERN "*")

View File

@ -0,0 +1,32 @@
# FreeRDP: A Remote Desktop Protocol Client
# libfreerdp-auth cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 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(FREERDP_AUTH_SRCS
credssp.c
ntlmssp.c)
add_library(freerdp-auth ${FREERDP_AUTH_SRCS})
set_target_properties(freerdp-auth PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
target_link_libraries(freerdp-auth freerdp-utils)
target_link_libraries(freerdp-auth freerdp-crypto)
install(TARGETS freerdp-auth DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -22,9 +22,12 @@
#endif
#include <time.h>
#include "ntlmssp.h"
#include <freerdp/crypto/tls.h>
#include <freerdp/auth/ntlmssp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/auth/credssp.h>
#include "credssp.h"
/**
* TSRequest ::= SEQUENCE {
* version [0] INTEGER,
@ -68,20 +71,20 @@
*/
/**
* Initialize NTLMSSP authentication module.
* Initialize NTLMSSP authentication module (client).
* @param credssp
*/
int credssp_ntlmssp_init(rdpCredssp* credssp)
int credssp_ntlmssp_client_init(rdpCredssp* credssp)
{
freerdp* instance;
NTLMSSP* ntlmssp = credssp->ntlmssp;
rdpSettings* settings = credssp->transport->settings;
rdpSettings* settings = credssp->settings;
instance = (freerdp*) settings->instance;
if ((settings->password == NULL) || (settings->username == NULL))
{
if(instance->Authenticate)
if (instance->Authenticate)
{
boolean proceed = instance->Authenticate(instance,
&settings->username, &settings->password, &settings->domain);
@ -119,48 +122,32 @@ int credssp_ntlmssp_init(rdpCredssp* credssp)
}
/**
* Get TLS public key.
* Initialize NTLMSSP authentication module (server).
* @param credssp
*/
int credssp_get_public_key(rdpCredssp* credssp)
int credssp_ntlmssp_server_init(rdpCredssp* credssp)
{
int status;
CryptoCert cert;
cert = tls_get_certificate(credssp->transport->tls);
NTLMSSP* ntlmssp = credssp->ntlmssp;
if (cert == NULL)
{
printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n");
return 0;
}
ntlmssp_generate_server_challenge(ntlmssp);
if (!tls_verify_certificate(credssp->transport->tls, cert, credssp->transport->settings->hostname))
tls_disconnect(credssp->transport->tls);
status = crypto_cert_get_public_key(cert, &credssp->public_key);
crypto_cert_free(cert);
return status;
return 1;
}
/**
* Authenticate with server using CredSSP.
* Authenticate with server using CredSSP (client).
* @param credssp
* @return 1 if authentication is successful
*/
int credssp_authenticate(rdpCredssp* credssp)
int credssp_client_authenticate(rdpCredssp* credssp)
{
NTLMSSP* ntlmssp = credssp->ntlmssp;
STREAM* s = stream_new(0);
uint8* negoTokenBuffer = (uint8*) xmalloc(2048);
if (credssp_ntlmssp_init(credssp) == 0)
return 0;
if (credssp_get_public_key(credssp) == 0)
if (credssp_ntlmssp_client_init(credssp) == 0)
return 0;
/* NTLMSSP NEGOTIATE MESSAGE */
@ -214,6 +201,61 @@ int credssp_authenticate(rdpCredssp* credssp)
return 1;
}
/**
* Authenticate with client using CredSSP (server).
* @param credssp
* @return 1 if authentication is successful
*/
int credssp_server_authenticate(rdpCredssp* credssp)
{
STREAM* s = stream_new(0);
NTLMSSP* ntlmssp = credssp->ntlmssp;
uint8* negoTokenBuffer = (uint8*) xmalloc(2048);
if (credssp_ntlmssp_server_init(credssp) == 0)
return 0;
/* NTLMSSP NEGOTIATE MESSAGE */
if (credssp_recv(credssp, &credssp->negoToken, NULL, NULL) < 0)
return -1;
stream_attach(s, credssp->negoToken.data, credssp->negoToken.length);
ntlmssp_recv(ntlmssp, s);
freerdp_blob_free(&credssp->negoToken);
/* NTLMSSP CHALLENGE MESSAGE */
stream_attach(s, negoTokenBuffer, 2048);
ntlmssp_send(ntlmssp, s);
credssp->negoToken.data = stream_get_head(s);
credssp->negoToken.length = stream_get_length(s);
credssp_send(credssp, &credssp->negoToken, NULL, NULL);
/* NTLMSSP AUTHENTICATE MESSAGE */
if (credssp_recv(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth) < 0)
return -1;
stream_attach(s, credssp->negoToken.data, credssp->negoToken.length);
ntlmssp_recv(ntlmssp, s);
return 1;
}
/**
* Authenticate using CredSSP.
* @param credssp
* @return 1 if authentication is successful
*/
int credssp_authenticate(rdpCredssp* credssp)
{
if (credssp->server)
return credssp_server_authenticate(credssp);
else
return credssp_client_authenticate(credssp);
}
/**
* Encrypt TLS public key using CredSSP.
* @param credssp
@ -223,16 +265,18 @@ int credssp_authenticate(rdpCredssp* credssp)
void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d)
{
uint8* p;
rdpTls* tls;
uint8 signature[16];
rdpBlob encrypted_public_key;
NTLMSSP *ntlmssp = credssp->ntlmssp;
tls = credssp->tls;
freerdp_blob_alloc(d, credssp->public_key.length + 16);
ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature);
freerdp_blob_alloc(d, tls->public_key.length + 16);
ntlmssp_encrypt_message(ntlmssp, &tls->public_key, &encrypted_public_key, signature);
#ifdef WITH_DEBUG_NLA
printf("Public Key (length = %d)\n", credssp->public_key.length);
freerdp_hexdump(credssp->public_key.data, credssp->public_key.length);
printf("Public Key (length = %d)\n", tls->public_key.length);
freerdp_hexdump(tls->public_key.data, tls->public_key.length);
printf("\n");
printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length);
@ -264,6 +308,7 @@ int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d)
uint8* signature;
rdpBlob public_key;
rdpBlob encrypted_public_key;
rdpTls* tls = credssp->tls;
signature = d->data;
encrypted_public_key.data = (void*) (signature + 16);
@ -271,7 +316,7 @@ int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d)
ntlmssp_decrypt_message(credssp->ntlmssp, &encrypted_public_key, &public_key, signature);
p1 = (uint8*) credssp->public_key.data;
p1 = (uint8*) tls->public_key.data;
p2 = (uint8*) public_key.data;
p2[0]--;
@ -530,7 +575,7 @@ void credssp_send(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rd
ber_write_octet_string(s, pubKeyAuth->data, length);
}
transport_write(credssp->transport, s);
tls_write(credssp->tls, s->data, stream_get_length(s));
stream_free(s);
}
@ -550,8 +595,8 @@ int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdp
int status;
uint32 version;
s = transport_recv_stream_init(credssp->transport, 2048);
status = transport_read(credssp->transport, s);
s = stream_new(2048);
status = tls_read(credssp->tls, s->data, stream_get_left(s));
if (status < 0)
return -1;
@ -635,21 +680,28 @@ void credssp_current_time(uint8* timestamp)
* @return new CredSSP state machine.
*/
rdpCredssp* credssp_new(rdpTransport* transport)
rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings)
{
rdpCredssp* self;
rdpCredssp* credssp;
self = (rdpCredssp*) xzalloc(sizeof(rdpCredssp));
credssp = (rdpCredssp*) xzalloc(sizeof(rdpCredssp));
if (self != NULL)
if (credssp != NULL)
{
self->transport = transport;
self->send_seq_num = 0;
self->ntlmssp = ntlmssp_new();
self->settings = transport->settings;
credssp->instance = instance;
credssp->settings = settings;
credssp->server = settings->server_mode;
credssp->tls = tls;
credssp->send_seq_num = 0;
if (credssp->server)
credssp->ntlmssp = ntlmssp_server_new();
else
credssp->ntlmssp = ntlmssp_client_new();
}
return self;
return credssp;
}
/**
@ -661,7 +713,6 @@ void credssp_free(rdpCredssp* credssp)
{
if (credssp != NULL)
{
freerdp_blob_free(&credssp->public_key);
freerdp_blob_free(&credssp->ts_credentials);
ntlmssp_free(credssp->ntlmssp);

View File

@ -25,7 +25,9 @@
#include <openssl/engine.h>
#include <freerdp/utils/memory.h>
#include "ntlmssp.h"
#include <freerdp/auth/credssp.h>
#include <freerdp/auth/ntlmssp.h>
#define NTLMSSP_NEGOTIATE_56 0x80000000 /* W (0) */
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 /* V (1) */
@ -67,6 +69,10 @@
#define WINDOWS_MINOR_VERSION_2 0x02
#define NTLMSSP_REVISION_W2K3 0x0F
#define MESSAGE_TYPE_NEGOTIATE 1
#define MESSAGE_TYPE_CHALLENGE 2
#define MESSAGE_TYPE_AUTHENTICATE 3
static const char ntlm_signature[] = "NTLMSSP";
static const char lm_magic[] = "KGS!@#$%";
@ -190,6 +196,22 @@ void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation)
}
}
/**
* Set NTLMSSP target name.
* @param ntlmssp
* @param target_name target name
*/
void ntlmssp_set_target_name(NTLMSSP* ntlmssp, char* target_name)
{
freerdp_blob_free(&ntlmssp->target_name);
if (target_name != NULL)
{
ntlmssp->target_name.data = freerdp_uniconv_out(ntlmssp->uniconv, target_name, (size_t*) &(ntlmssp->target_name.length));
}
}
/**
* Generate client challenge (8-byte nonce).
* @param ntlmssp
@ -197,10 +219,20 @@ void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation)
void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp)
{
/* ClientChallenge in computation of LMv2 and NTLMv2 responses */
/* ClientChallenge is used in computation of LMv2 and NTLMv2 responses */
crypto_nonce(ntlmssp->client_challenge, 8);
}
/**
* Generate server challenge (8-byte nonce).
* @param ntlmssp
*/
void ntlmssp_generate_server_challenge(NTLMSSP* ntlmssp)
{
crypto_nonce(ntlmssp->server_challenge, 8);
}
/**
* Generate KeyExchangeKey (the 128-bit SessionBaseKey).\n
* @msdn{cc236710}
@ -1278,7 +1310,7 @@ void ntlmssp_send_negotiate_message(NTLMSSP* ntlmssp, STREAM* s)
uint32 negotiateFlags = 0;
stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
stream_write_uint32(s, 1); /* MessageType */
stream_write_uint32(s, MESSAGE_TYPE_NEGOTIATE); /* MessageType */
if (ntlmssp->ntlm_v2)
{
@ -1356,6 +1388,124 @@ void ntlmssp_send_negotiate_message(NTLMSSP* ntlmssp, STREAM* s)
ntlmssp->state = NTLMSSP_STATE_CHALLENGE;
}
/**
* Receive NTLMSSP NEGOTIATE_MESSAGE.\n
* NEGOTIATE_MESSAGE @msdn{cc236641}
* @param ntlmssp
* @param s
*/
void ntlmssp_recv_negotiate_message(NTLMSSP* ntlmssp, STREAM* s)
{
uint32 negotiateFlags;
uint16 domainNameLen;
uint16 domainNameMaxLen;
uint32 domainNameBufferOffset;
uint16 workstationLen;
uint16 workstationMaxLen;
uint32 workstationBufferOffset;
ntlmssp_input_negotiate_flags(s, &negotiateFlags); /* NegotiateFlags (4 bytes) */
ntlmssp->negotiate_flags = negotiateFlags;
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
/* DomainNameFields (8 bytes) */
stream_read_uint16(s, domainNameLen); /* DomainNameLen */
stream_read_uint16(s, domainNameMaxLen); /* DomainNameMaxLen */
stream_read_uint32(s, domainNameBufferOffset); /* DomainNameBufferOffset */
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
/* WorkstationFields (8 bytes) */
stream_read_uint16(s, workstationLen); /* WorkstationLen */
stream_read_uint16(s, workstationMaxLen); /* WorkstationMaxLen */
stream_read_uint32(s, workstationBufferOffset); /* WorkstationBufferOffset */
if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
{
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
stream_seek(s, 8); /* Version (8 bytes) */
}
ntlmssp->state = NTLMSSP_STATE_CHALLENGE;
}
/**
* Send NTLMSSP CHALLENGE_MESSAGE.\n
* CHALLENGE_MESSAGE @msdn{cc236642}
* @param ntlmssp
* @param s
*/
void ntlmssp_send_challenge_message(NTLMSSP* ntlmssp, STREAM* s)
{
uint16 targetNameLen;
uint8* targetNameBuffer;
uint32 targetNameBufferOffset;
uint16 targetInfoLen;
uint8* targetInfoBuffer;
uint32 targetInfoBufferOffset;
stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
stream_write_uint32(s, MESSAGE_TYPE_CHALLENGE); /* MessageType */
targetNameLen = ntlmssp->target_name.length;
targetNameBuffer = ntlmssp->target_name.data;
targetInfoLen = ntlmssp->target_info.length;
targetInfoBuffer = ntlmssp->target_info.data;
targetNameBufferOffset = 56;
targetInfoBufferOffset = targetNameBufferOffset + targetNameLen;
/* TargetNameFields (8 bytes) */
stream_write_uint16(s, targetNameLen); /* TargetNameLen (2 bytes) */
stream_write_uint16(s, targetNameLen); /* TargetNameMaxLen (2 bytes) */
stream_write_uint32(s, targetNameBufferOffset); /* TargetNameBufferOffset (4 bytes) */
ntlmssp_output_negotiate_flags(s, ntlmssp->negotiate_flags); /* NegotiateFlags (4 bytes) */
stream_write(s, ntlmssp->server_challenge, 8); /* ServerChallenge (8 bytes) */
stream_write_zero(s, 8); /* Reserved (8 bytes), should be ignored */
/* TargetInfoFields (8 bytes) */
stream_write_uint16(s, targetInfoLen); /* TargetInfoLen (2 bytes) */
stream_write_uint16(s, targetInfoLen); /* TargetInfoMaxLen (2 bytes) */
stream_write_uint32(s, targetInfoBufferOffset); /* TargetInfoBufferOffset (4 bytes) */
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
if (ntlmssp->negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
{
ntlmssp_output_version(s); /* Version (8 bytes), can be ignored */
}
/* Payload (variable) */
if (targetNameLen > 0)
{
stream_write(s, targetNameBuffer, targetNameLen);
#ifdef WITH_DEBUG_NLA
printf("TargetName (length = %d, offset = %d)\n", targetNameLen, targetNameBufferOffset);
freerdp_hexdump(targetNameBuffer, targetNameLen);
printf("\n");
#endif
}
if (targetInfoLen > 0)
{
stream_write(s, targetInfoBuffer, targetInfoLen);
#ifdef WITH_DEBUG_NLA
printf("TargetInfo (length = %d, offset = %d)\n", targetInfoLen, targetInfoBufferOffset);
freerdp_hexdump(targetInfoBuffer, targetInfoLen);
printf("\n");
#endif
}
ntlmssp->state = NTLMSSP_STATE_AUTHENTICATE;
}
/**
* Receive NTLMSSP CHALLENGE_MESSAGE.\n
* CHALLENGE_MESSAGE @msdn{cc236642}
@ -1620,7 +1770,7 @@ void ntlmssp_send_authenticate_message(NTLMSSP* ntlmssp, STREAM* s)
EncryptedRandomSessionKeyBufferOffset = NtChallengeResponseBufferOffset + NtChallengeResponseLen;
stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
stream_write_uint32(s, 3); /* MessageType */
stream_write_uint32(s, MESSAGE_TYPE_AUTHENTICATE); /* MessageType */
/* LmChallengeResponseFields (8 bytes) */
stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseLen */
@ -1780,13 +1930,87 @@ void ntlmssp_send_authenticate_message(NTLMSSP* ntlmssp, STREAM* s)
}
/**
* Send NTLMSSP message.
* Receive NTLMSSP AUTHENTICATE_MESSAGE.\n
* AUTHENTICATE_MESSAGE @msdn{cc236643}
* @param ntlmssp
* @param s
*/
void ntlmssp_recv_authenticate_message(NTLMSSP* ntlmssp, STREAM* s)
{
uint32 negotiateFlags;
uint16 DomainNameLen;
uint16 DomainNameMaxLen;
uint32 DomainNameBufferOffset;
uint16 UserNameLen;
uint16 UserNameMaxLen;
uint32 UserNameBufferOffset;
uint16 WorkstationLen;
uint16 WorkstationMaxLen;
uint32 WorkstationBufferOffset;
uint16 LmChallengeResponseLen;
uint16 LmChallengeResponseMaxLen;
uint32 LmChallengeResponseBufferOffset;
uint16 NtChallengeResponseLen;
uint16 NtChallengeResponseMaxLen;
uint32 NtChallengeResponseBufferOffset;
uint16 EncryptedRandomSessionKeyLen;
uint16 EncryptedRandomSessionKeyMaxLen;
uint32 EncryptedRandomSessionKeyBufferOffset;
/* LmChallengeResponseFields (8 bytes) */
stream_read_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseLen */
stream_read_uint16(s, LmChallengeResponseMaxLen); /* LmChallengeResponseMaxLen */
stream_read_uint32(s, LmChallengeResponseBufferOffset); /* LmChallengeResponseBufferOffset */
/* NtChallengeResponseFields (8 bytes) */
stream_read_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseLen */
stream_read_uint16(s, NtChallengeResponseMaxLen); /* NtChallengeResponseMaxLen */
stream_read_uint32(s, NtChallengeResponseBufferOffset); /* NtChallengeResponseBufferOffset */
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
/* DomainNameFields (8 bytes) */
stream_read_uint16(s, DomainNameLen); /* DomainNameLen */
stream_read_uint16(s, DomainNameMaxLen); /* DomainNameMaxLen */
stream_read_uint32(s, DomainNameBufferOffset); /* DomainNameBufferOffset */
/* UserNameFields (8 bytes) */
stream_read_uint16(s, UserNameLen); /* UserNameLen */
stream_read_uint16(s, UserNameMaxLen); /* UserNameMaxLen */
stream_read_uint32(s, UserNameBufferOffset); /* UserNameBufferOffset */
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
/* WorkstationFields (8 bytes) */
stream_read_uint16(s, WorkstationLen); /* WorkstationLen */
stream_read_uint16(s, WorkstationMaxLen); /* WorkstationMaxLen */
stream_read_uint32(s, WorkstationBufferOffset); /* WorkstationBufferOffset */
/* EncryptedRandomSessionKeyFields (8 bytes) */
stream_read_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyLen */
stream_read_uint16(s, EncryptedRandomSessionKeyMaxLen); /* EncryptedRandomSessionKeyMaxLen */
stream_read_uint32(s, EncryptedRandomSessionKeyBufferOffset); /* EncryptedRandomSessionKeyBufferOffset */
ntlmssp_input_negotiate_flags(s, &negotiateFlags); /* NegotiateFlags (4 bytes) */
if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
{
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
stream_seek(s, 8); /* Version (8 bytes) */
}
ntlmssp->state = NTLMSSP_STATE_FINAL;
}
/**
* Send NTLMSSP message (client).
* @param ntlmssp
* @param s
* @return
*/
int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
int ntlmssp_client_send(NTLMSSP* ntlmssp, STREAM* s)
{
if (ntlmssp->state == NTLMSSP_STATE_INITIAL)
ntlmssp->state = NTLMSSP_STATE_NEGOTIATE;
@ -1799,6 +2023,92 @@ int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
return (ntlmssp->state == NTLMSSP_STATE_FINAL) ? 0 : 1;
}
/**
* Send NTLMSSP message (server).
* @param ntlmssp
* @param s
* @return
*/
int ntlmssp_server_send(NTLMSSP* ntlmssp, STREAM* s)
{
if (ntlmssp->state == NTLMSSP_STATE_CHALLENGE)
ntlmssp_send_challenge_message(ntlmssp, s);
return (ntlmssp->state == NTLMSSP_STATE_FINAL) ? 0 : 1;
}
/**
* Send NTLMSSP message.
* @param ntlmssp
* @param s
* @return
*/
int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
{
if (ntlmssp->server)
return ntlmssp_server_send(ntlmssp, s);
else
return ntlmssp_client_send(ntlmssp, s);
}
/**
* Receive NTLMSSP message (client).
* @param ntlmssp
* @param s
* @return
*/
int ntlmssp_client_recv(NTLMSSP* ntlmssp, STREAM* s)
{
char signature[8]; /* Signature, "NTLMSSP" */
uint32 messageType; /* MessageType */
stream_read(s, signature, 8);
stream_read_uint32(s, messageType);
if (memcmp(signature, ntlm_signature, 8) != 0)
{
printf("Unexpected NTLM signature: %s, expected:%s\n", signature, ntlm_signature);
return -1;
}
if (messageType == MESSAGE_TYPE_CHALLENGE && ntlmssp->state == NTLMSSP_STATE_CHALLENGE)
ntlmssp_recv_challenge_message(ntlmssp, s);
return 1;
}
/**
* Receive NTLMSSP message (server).
* @param ntlmssp
* @param s
* @return
*/
int ntlmssp_server_recv(NTLMSSP* ntlmssp, STREAM* s)
{
char signature[8]; /* Signature, "NTLMSSP" */
uint32 messageType; /* MessageType */
stream_read(s, signature, 8);
stream_read_uint32(s, messageType);
if (memcmp(signature, ntlm_signature, 8) != 0)
{
printf("Unexpected NTLM signature: %s, expected:%s\n", signature, ntlm_signature);
return -1;
}
if (messageType == MESSAGE_TYPE_NEGOTIATE && ntlmssp->state == NTLMSSP_STATE_INITIAL)
ntlmssp_recv_negotiate_message(ntlmssp, s);
else if (messageType == MESSAGE_TYPE_AUTHENTICATE && ntlmssp->state == NTLMSSP_STATE_AUTHENTICATE)
ntlmssp_recv_authenticate_message(ntlmssp, s);
return 1;
}
/**
* Receive NTLMSSP message.
* @param ntlmssp
@ -1808,16 +2118,10 @@ int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s)
{
char signature[8]; /* Signature, "NTLMSSP" */
uint32 messageType; /* MessageType */
stream_read(s, signature, 8);
stream_read_uint32(s, messageType);
if (messageType == 2 && ntlmssp->state == NTLMSSP_STATE_CHALLENGE)
ntlmssp_recv_challenge_message(ntlmssp, s);
return 1;
if (ntlmssp->server)
return ntlmssp_server_recv(ntlmssp, s);
else
return ntlmssp_client_recv(ntlmssp, s);
}
/**
@ -1840,6 +2144,30 @@ NTLMSSP* ntlmssp_new()
return ntlmssp;
}
/**
* Create new NTLMSSP client state machine instance.
* @return
*/
NTLMSSP* ntlmssp_client_new()
{
NTLMSSP* ntlmssp = ntlmssp_new();
ntlmssp->server = false;
return ntlmssp;
}
/**
* Create new NTLMSSP client state machine instance.
* @return
*/
NTLMSSP* ntlmssp_server_new()
{
NTLMSSP* ntlmssp = ntlmssp_new();
ntlmssp->server = true;
return ntlmssp;
}
/**
* Initialize NTLMSSP state machine.
* @param ntlmssp

View File

@ -21,6 +21,7 @@ set(FREERDP_CACHE_SRCS
brush.c
pointer.c
bitmap.c
nine_grid.c
offscreen.c
palette.c
glyph.c

View File

@ -39,16 +39,27 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
uint8 style;
rdpBitmap* bitmap;
rdpCache* cache = context->cache;
rdpBrush* brush = &mem3blt->brush;
if (mem3blt->cacheId == 0xFF)
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
else
bitmap = bitmap_cache_get(cache->bitmap, (uint8) mem3blt->cacheId, mem3blt->cacheIndex);
style = brush->style;
if (brush->style & CACHED_BRUSH)
{
brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
brush->style = 0x03;
}
mem3blt->bitmap = bitmap;
IFCALL(cache->bitmap->Mem3Blt, context, mem3blt);
brush->style = style;
}
void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap)

View File

@ -42,6 +42,30 @@ void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
brush->style = style;
}
void update_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
{
rdpCache* cache = context->cache;
IFCALL(cache->brush->PolygonSC, context, polygon_sc);
}
void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
{
uint8 style;
rdpBrush* brush = &polygon_cb->brush;
rdpCache* cache = context->cache;
style = brush->style;
if (brush->style & CACHED_BRUSH)
{
brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
brush->style = 0x03;
}
IFCALL(cache->brush->PolygonCB, context, polygon_cb);
brush->style = style;
}
void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
{
rdpCache* cache = context->cache;
@ -127,8 +151,12 @@ void brush_cache_register_callbacks(rdpUpdate* update)
rdpCache* cache = update->context->cache;
cache->brush->PatBlt = update->primary->PatBlt;
cache->brush->PolygonSC = update->primary->PolygonSC;
cache->brush->PolygonCB = update->primary->PolygonCB;
update->primary->PatBlt = update_gdi_patblt;
update->primary->PolygonSC = update_gdi_polygon_sc;
update->primary->PolygonCB = update_gdi_polygon_cb;
update->secondary->CacheBrush = update_gdi_cache_brush;
}

View File

@ -37,6 +37,7 @@ rdpCache* cache_new(rdpSettings* settings)
cache->bitmap = bitmap_cache_new(settings);
cache->offscreen = offscreen_cache_new(settings);
cache->palette = palette_cache_new(settings);
cache->nine_grid = nine_grid_cache_new(settings);
}
return cache;
@ -52,6 +53,7 @@ void cache_free(rdpCache* cache)
bitmap_cache_free(cache->bitmap);
offscreen_cache_free(cache->offscreen);
palette_cache_free(cache->palette);
nine_grid_cache_free(cache->nine_grid);
xfree(cache);
}
}

View File

@ -0,0 +1,130 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* NineGrid Cache
*
* 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.
*/
#include <freerdp/update.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/cache/nine_grid.h>
void update_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid)
{
rdpCache* cache = context->cache;
IFCALL(cache->nine_grid->DrawNineGrid, context, draw_nine_grid);
}
void update_gdi_multi_draw_nine_grid(rdpContext* context, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
{
rdpCache* cache = context->cache;
IFCALL(cache->nine_grid->MultiDrawNineGrid, context, multi_draw_nine_grid);
}
void nine_grid_cache_register_callbacks(rdpUpdate* update)
{
rdpCache* cache = update->context->cache;
cache->nine_grid->DrawNineGrid = update->primary->DrawNineGrid;
cache->nine_grid->MultiDrawNineGrid = update->primary->MultiDrawNineGrid;
update->primary->DrawNineGrid = update_gdi_draw_nine_grid;
update->primary->MultiDrawNineGrid = update_gdi_multi_draw_nine_grid;
}
void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index)
{
void* entry;
if (index > nine_grid->maxEntries)
{
printf("invalid NineGrid index: 0x%04X\n", index);
return NULL;
}
entry = nine_grid->entries[index].entry;
if (entry == NULL)
{
printf("invalid NineGrid at index: 0x%04X\n", index);
return NULL;
}
return entry;
}
void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry)
{
void* prevEntry;
if (index > nine_grid->maxEntries)
{
printf("invalid NineGrid index: 0x%04X\n", index);
return;
}
prevEntry = nine_grid->entries[index].entry;
if (prevEntry != NULL)
xfree(prevEntry);
nine_grid->entries[index].entry = entry;
}
rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings)
{
rdpNineGridCache* nine_grid;
nine_grid = (rdpNineGridCache*) xzalloc(sizeof(rdpNineGridCache));
if (nine_grid != NULL)
{
nine_grid->settings = settings;
nine_grid->maxSize = 2560;
nine_grid->maxEntries = 256;
nine_grid->settings->draw_nine_grid_cache_size = nine_grid->maxSize;
nine_grid->settings->draw_nine_grid_cache_entries = nine_grid->maxEntries;
nine_grid->entries = (NINE_GRID_ENTRY*) xzalloc(sizeof(NINE_GRID_ENTRY) * nine_grid->maxEntries);
}
return nine_grid;
}
void nine_grid_cache_free(rdpNineGridCache* nine_grid)
{
int i;
if (nine_grid != NULL)
{
if (nine_grid->entries != NULL)
{
for (i = 0; i < (int) nine_grid->maxEntries; i++)
{
if (nine_grid->entries[i].entry != NULL)
xfree(nine_grid->entries[i].entry);
}
xfree(nine_grid->entries);
}
xfree(nine_grid);
}
}

View File

@ -1,5 +1,5 @@
# FreeRDP: A Remote Desktop Protocol Client
# libfreerdp-chanman cmake build script
# libfreerdp-channels cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>

View File

@ -26,8 +26,6 @@ set(LIBFREERDP_CORE_SRCS
activation.h
extension.c
extension.h
ber.c
ber.h
gcc.c
gcc.h
mcs.c
@ -38,12 +36,6 @@ set(LIBFREERDP_CORE_SRCS
info.h
input.c
input.h
crypto.c
crypto.h
credssp.c
credssp.h
ntlmssp.c
ntlmssp.h
license.c
license.h
errinfo.c
@ -63,14 +55,12 @@ set(LIBFREERDP_CORE_SRCS
connection.h
redirection.c
redirection.h
timezone.c
timezone.h
rdp.c
rdp.h
per.c
per.h
tcp.c
tcp.h
tls.c
tls.h
tpdu.c
tpdu.h
tpkt.c
@ -91,7 +81,7 @@ set(LIBFREERDP_CORE_SRCS
listener.h
peer.c
peer.h
mppc.c
mppc.c
)
add_library(freerdp-core ${LIBFREERDP_CORE_SRCS})
@ -104,8 +94,11 @@ else()
target_link_libraries(freerdp-core ${ZLIB_LIBRARIES})
endif()
target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES})
target_link_libraries(freerdp-core freerdp-utils)
target_link_libraries(freerdp-core freerdp-codec)
target_link_libraries(freerdp-core freerdp-crypto)
target_link_libraries(freerdp-core freerdp-auth)
target_link_libraries(freerdp-core freerdp-locale)
install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -162,6 +162,9 @@ void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings)
if (settings->fastpath_output)
extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
if (settings->salted_checksum)
extraFlags |= ENC_SALTED_CHECKSUM;
if (settings->server_mode)
{
/* not yet supported server-side */
@ -1107,7 +1110,7 @@ void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* setti
header = rdp_capability_set_start(s);
drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT;
drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
stream_write_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */
stream_write_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */
@ -1870,14 +1873,13 @@ void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
numberCapabilities = 14;
numberCapabilities = 13;
rdp_write_general_capability_set(s, settings);
rdp_write_bitmap_capability_set(s, settings);
rdp_write_order_capability_set(s, settings);
rdp_write_pointer_capability_set(s, settings);
rdp_write_input_capability_set(s, settings);
rdp_write_virtual_channel_capability_set(s, settings);
rdp_write_bitmap_cache_host_support_capability_set(s, settings);
rdp_write_share_capability_set(s, settings);
rdp_write_font_capability_set(s, settings);
rdp_write_multifragment_update_capability_set(s, settings);
@ -1886,6 +1888,12 @@ void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
rdp_write_surface_commands_capability_set(s, settings);
rdp_write_bitmap_codecs_capability_set(s, settings);
if (settings->persistent_bitmap_cache)
{
numberCapabilities++;
rdp_write_bitmap_cache_host_support_capability_set(s, settings);
}
stream_get_mark(s, em);
stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
@ -2018,6 +2026,12 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
rdp_write_offscreen_bitmap_cache_capability_set(s, settings);
}
if (settings->draw_nine_grid)
{
numberCapabilities++;
rdp_write_draw_nine_grid_cache_capability_set(s, settings);
}
if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER])
{
if (settings->large_pointer)

View File

@ -557,170 +557,6 @@ void key_free(rdpKey* key)
}
}
void certificate_store_init(rdpCertificateStore* certificate_store)
{
char* config_path;
rdpSettings* settings;
settings = certificate_store->settings;
config_path = freerdp_get_config_path(settings);
certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir);
if (freerdp_check_file_exists(certificate_store->path) == false)
{
freerdp_mkdir(certificate_store->path);
printf("creating directory %s\n", certificate_store->path);
}
certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file);
if (freerdp_check_file_exists(certificate_store->file) == false)
{
certificate_store->fp = fopen((char*) certificate_store->file, "w+");
if (certificate_store->fp == NULL)
{
printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
return;
}
fflush(certificate_store->fp);
}
else
{
certificate_store->fp = fopen((char*) certificate_store->file, "r+");
}
}
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
{
FILE* fp;
int length;
char* data;
char* pline;
int match = 1;
long int size;
fp = certificate_store->fp;
if (!fp)
return match;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (size < 1)
return match;
data = (char*) xmalloc(size + 2);
if (fread(data, size, 1, fp) != 1)
{
xfree(data);
return match;
}
data[size] = '\n';
data[size + 1] = '\0';
pline = strtok(data, "\n");
while (pline != NULL)
{
length = strlen(pline);
if (length > 0)
{
length = strcspn(pline, " \t");
pline[length] = '\0';
if (strcmp(pline, certificate_data->hostname) == 0)
{
pline = &pline[length + 1];
if (strcmp(pline, certificate_data->fingerprint) == 0)
match = 0;
else
match = -1;
break;
}
}
pline = strtok(NULL, "\n");
}
xfree(data);
return match;
}
void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
{
FILE* fp;
/* reopen in append mode */
fp = fopen(certificate_store->file, "a");
if (!fp)
return;
fprintf(certificate_store->fp,"%s %s\n", certificate_data->hostname, certificate_data->fingerprint);
fclose(fp);
}
rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint)
{
rdpCertificateData* certdata;
certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData));
if (certdata != NULL)
{
certdata->hostname = xstrdup(hostname);
certdata->fingerprint = xstrdup(fingerprint);
}
return certdata;
}
void certificate_data_free(rdpCertificateData* certificate_data)
{
if (certificate_data != NULL)
{
xfree(certificate_data->hostname);
xfree(certificate_data->fingerprint);
xfree(certificate_data);
}
}
rdpCertificateStore* certificate_store_new(rdpSettings* settings)
{
rdpCertificateStore* certificate_store;
certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore));
if (certificate_store != NULL)
{
certificate_store->settings = settings;
certificate_store_init(certificate_store);
}
return certificate_store;
}
void certificate_store_free(rdpCertificateStore* certstore)
{
if (certstore != NULL)
{
if (certstore->fp != NULL)
fclose(certstore->fp);
xfree(certstore->path);
xfree(certstore->file);
xfree(certstore);
}
}
/**
* Instantiate new certificate module.\n
* @param rdp RDP module

View File

@ -20,12 +20,10 @@
#ifndef __CERTIFICATE_H
#define __CERTIFICATE_H
typedef struct rdp_certificate_data rdpCertificateData;
typedef struct rdp_certificate_store rdpCertificateStore;
#include "rdp.h"
#include "ber.h"
#include "crypto.h"
#include <freerdp/crypto/ber.h>
#include <freerdp/crypto/crypto.h>
#include <freerdp/settings.h>
#include <freerdp/utils/blob.h>
@ -45,35 +43,6 @@ typedef struct rdp_certificate_store rdpCertificateStore;
#define BB_RSA_KEY_BLOB 6
#define BB_RSA_SIGNATURE_BLOB 8
struct rdp_key
{
rdpBlob modulus;
rdpBlob private_exponent;
uint8 exponent[4];
};
struct rdp_certificate_data
{
char* hostname;
char* fingerprint;
};
struct rdp_certificate_store
{
FILE* fp;
char* path;
char* file;
rdpSettings* settings;
rdpCertificateData* certificate_data;
};
rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint);
void certificate_data_free(rdpCertificateData* certificate_data);
rdpCertificateStore* certificate_store_new(rdpSettings* settings);
void certificate_store_free(rdpCertificateStore* certificate_store);
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data);
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info);
rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count);

View File

@ -17,7 +17,6 @@
* limitations under the License.
*/
#include "per.h"
#include "info.h"
#include "input.h"
@ -227,7 +226,7 @@ static boolean rdp_client_establish_keys(rdpRdp* rdp)
}
rdp->do_crypt = true;
if (rdp->settings->secure_checksum)
if (rdp->settings->salted_checksum)
rdp->do_secure_checksum = true;
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
@ -294,7 +293,7 @@ static boolean rdp_server_establish_keys(rdpRdp* rdp, STREAM* s)
}
rdp->do_crypt = true;
if (rdp->settings->secure_checksum)
if (rdp->settings->salted_checksum)
rdp->do_secure_checksum = true;
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
@ -502,7 +501,7 @@ boolean rdp_client_connect_finalize(rdpRdp* rdp)
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
{
boolean ret;
boolean status;
transport_set_blocking_mode(rdp->transport, true);
@ -547,15 +546,15 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
if (!nego_send_negotiation_response(rdp->nego))
return false;
ret = false;
status = false;
if (rdp->nego->selected_protocol & PROTOCOL_NLA)
ret = transport_accept_nla(rdp->transport);
status = transport_accept_nla(rdp->transport);
else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
ret = transport_accept_tls(rdp->transport);
status = transport_accept_tls(rdp->transport);
else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
ret = transport_accept_rdp(rdp->transport);
status = transport_accept_rdp(rdp->transport);
if (!ret)
if (!status)
return false;
transport_set_blocking_mode(rdp->transport, false);

View File

@ -21,10 +21,10 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/api.h>
#include <freerdp/crypto/per.h>
#include <freerdp/utils/stream.h>
#include "orders.h"
#include "per.h"
#include "update.h"
#include "surface.h"
@ -120,7 +120,7 @@ uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s)
return length - stream_get_length(s);
}
static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s)
static boolean fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s)
{
rdpUpdate* update = fastpath->rdp->update;
uint16 numberOrders;
@ -129,9 +129,12 @@ static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s)
while (numberOrders > 0)
{
update_recv_order(update, s);
if (!update_recv_order(update, s))
return false;
numberOrders--;
}
return true;
}
static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s)
@ -161,7 +164,7 @@ static void fastpath_recv_update_synchronize(rdpFastPath* fastpath, STREAM* s)
stream_seek_uint16(s); /* size (2 bytes), must be set to zero */
}
static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32 size, STREAM* s)
static boolean fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32 size, STREAM* s)
{
rdpUpdate* update = fastpath->rdp->update;
rdpContext* context = fastpath->rdp->update->context;
@ -170,7 +173,8 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:
fastpath_recv_orders(fastpath, s);
if (!fastpath_recv_orders(fastpath, s))
return false;
break;
case FASTPATH_UPDATETYPE_BITMAP:
@ -221,9 +225,11 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32
DEBUG_WARN("unknown updateCode 0x%X", updateCode);
break;
}
return true;
}
static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
static boolean fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
{
uint16 size;
int next_pos;
@ -291,12 +297,17 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
}
if (update_stream)
fastpath_recv_update(fastpath, updateCode, totalSize, update_stream);
{
if (!fastpath_recv_update(fastpath, updateCode, totalSize, update_stream))
return false;
}
stream_set_pos(s, next_pos);
if (comp_stream != s)
xfree(comp_stream);
return true;
}
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
@ -307,7 +318,11 @@ boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
while (stream_get_left(s) >= 3)
{
fastpath_recv_update_data(fastpath, s);
if (!fastpath_recv_update_data(fastpath, s))
{
/* XXX: Do we need to call EndPaint? */
return false;
}
}
IFCALL(update->EndPaint, update->context);

View File

@ -127,11 +127,6 @@ boolean freerdp_check_fds(freerdp* instance)
return true;
}
void freerdp_send_keep_alive(freerdp* instance)
{
input_send_synchronize_event(instance->context->rdp->input, 0);
}
static int freerdp_send_channel_data(freerdp* instance, int channel_id, uint8* data, int size)
{
return rdp_send_channel_data(instance->context->rdp, channel_id, data, size);
@ -192,11 +187,16 @@ void freerdp_context_new(freerdp* instance)
void freerdp_context_free(freerdp* instance)
{
if (instance->context == NULL)
return;
IFCALL(instance->ContextFree, instance, instance->context);
rdp_free(instance->context->rdp);
graphics_free(instance->context->graphics);
xfree(instance->context);
instance->context = NULL;
}
uint32 freerdp_error_info(freerdp* instance)
@ -219,11 +219,10 @@ freerdp* freerdp_new()
return instance;
}
void freerdp_free(freerdp* freerdp)
void freerdp_free(freerdp* instance)
{
if (freerdp)
if (instance)
{
freerdp_context_free(freerdp);
xfree(freerdp);
xfree(instance);
}
}

View File

@ -468,6 +468,7 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 block
uint16 supportedColorDepths = 0;
uint16 earlyCapabilityFlags = 0;
uint32 serverSelectedProtocol = 0;
int color_depth;
char* str;
/* Length of all required fields, until imeFileName */
@ -483,7 +484,7 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 block
stream_seek_uint16(s); /* SASSequence (Secure Access Sequence) */
stream_read_uint32(s, settings->kbd_layout); /* keyboardLayout */
stream_read_uint32(s, settings->client_build); /* clientBuild */
/* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 32);
stream_seek(s, 32);
@ -565,25 +566,25 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 block
} while (0);
if (highColorDepth > 0)
settings->color_depth = highColorDepth;
color_depth = highColorDepth;
else if (postBeta2ColorDepth > 0)
{
switch (postBeta2ColorDepth)
{
case RNS_UD_COLOR_4BPP:
settings->color_depth = 4;
color_depth = 4;
break;
case RNS_UD_COLOR_8BPP:
settings->color_depth = 8;
color_depth = 8;
break;
case RNS_UD_COLOR_16BPP_555:
settings->color_depth = 15;
color_depth = 15;
break;
case RNS_UD_COLOR_16BPP_565:
settings->color_depth = 16;
color_depth = 16;
break;
case RNS_UD_COLOR_24BPP:
settings->color_depth = 24;
color_depth = 24;
break;
default:
return false;
@ -594,16 +595,23 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 block
switch (colorDepth)
{
case RNS_UD_COLOR_4BPP:
settings->color_depth = 4;
color_depth = 4;
break;
case RNS_UD_COLOR_8BPP:
settings->color_depth = 8;
color_depth = 8;
break;
default:
return false;
}
}
/*
* If we are in server mode, accepth client's color depth only if
* it is smaller than ours. This is what Windows server does.
*/
if (color_depth < settings->color_depth || !settings->server_mode)
settings->color_depth = color_depth;
return true;
}

View File

@ -20,8 +20,8 @@
#ifndef __GCC_H
#define __GCC_H
#include "per.h"
#include "mcs.h"
#include <freerdp/crypto/per.h>
#include <freerdp/freerdp.h>
#include <freerdp/settings.h>

View File

@ -17,6 +17,8 @@
* limitations under the License.
*/
#include "timezone.h"
#include "info.h"
#define INFO_TYPE_LOGON 0x00000000
@ -34,182 +36,6 @@ static const char* const INFO_TYPE_LOGON_STRINGS[] =
};
*/
/**
* Read SYSTEM_TIME structure (TS_SYSTEMTIME).\n
* @msdn{cc240478}
* @param s stream
* @param system_time system time structure
*/
void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time)
{
stream_read_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
stream_read_uint16(s, system_time->wMonth); /* wMonth */
stream_read_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
stream_read_uint16(s, system_time->wDay); /* wDay */
stream_read_uint16(s, system_time->wHour); /* wHour */
stream_read_uint16(s, system_time->wMinute); /* wMinute */
stream_read_uint16(s, system_time->wSecond); /* wSecond */
stream_read_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
}
/**
* Write SYSTEM_TIME structure (TS_SYSTEMTIME).\n
* @msdn{cc240478}
* @param s stream
* @param system_time system time structure
*/
void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time)
{
stream_write_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
stream_write_uint16(s, system_time->wMonth); /* wMonth */
stream_write_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
stream_write_uint16(s, system_time->wDay); /* wDay */
stream_write_uint16(s, system_time->wHour); /* wHour */
stream_write_uint16(s, system_time->wMinute); /* wMinute */
stream_write_uint16(s, system_time->wSecond); /* wSecond */
stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
}
/**
* Get client time zone information.\n
* @param s stream
* @param settings settings
*/
void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings)
{
time_t t;
struct tm* local_time;
TIME_ZONE_INFO* clientTimeZone;
time(&t);
local_time = localtime(&t);
clientTimeZone = settings->client_time_zone;
#if defined(sun)
if(local_time->tm_isdst > 0)
clientTimeZone->bias = (uint32) (altzone / 3600);
else
clientTimeZone->bias = (uint32) (timezone / 3600);
#elif defined(HAVE_TM_GMTOFF)
if(local_time->tm_gmtoff >= 0)
clientTimeZone->bias = (uint32) (local_time->tm_gmtoff / 60);
else
clientTimeZone->bias = (uint32) ((-1 * local_time->tm_gmtoff) / 60 + 720);
#else
clientTimeZone->bias = 0;
#endif
if(local_time->tm_isdst > 0)
{
clientTimeZone->standardBias = clientTimeZone->bias - 60;
clientTimeZone->daylightBias = clientTimeZone->bias;
}
else
{
clientTimeZone->standardBias = clientTimeZone->bias;
clientTimeZone->daylightBias = clientTimeZone->bias + 60;
}
strftime(clientTimeZone->standardName, 32, "%Z, Standard Time", local_time);
clientTimeZone->standardName[31] = 0;
strftime(clientTimeZone->daylightName, 32, "%Z, Summer Time", local_time);
clientTimeZone->daylightName[31] = 0;
}
/**
* Read client time zone information (TS_TIME_ZONE_INFORMATION).\n
* @msdn{cc240477}
* @param s stream
* @param settings settings
*/
boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings)
{
char* str;
TIME_ZONE_INFO* clientTimeZone;
if (stream_get_left(s) < 172)
return false;
clientTimeZone = settings->client_time_zone;
stream_read_uint32(s, clientTimeZone->bias); /* Bias */
/* standardName (64 bytes) */
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
stream_seek(s, 64);
strncpy(clientTimeZone->standardName, str, sizeof(clientTimeZone->standardName));
xfree(str);
rdp_read_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
stream_read_uint32(s, clientTimeZone->standardBias); /* StandardBias */
/* daylightName (64 bytes) */
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
stream_seek(s, 64);
strncpy(clientTimeZone->daylightName, str, sizeof(clientTimeZone->daylightName));
xfree(str);
rdp_read_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
stream_read_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
return true;
}
/**
* Write client time zone information (TS_TIME_ZONE_INFORMATION).\n
* @msdn{cc240477}
* @param s stream
* @param settings settings
*/
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings)
{
size_t length;
uint8* standardName;
uint8* daylightName;
size_t standardNameLength;
size_t daylightNameLength;
TIME_ZONE_INFO* clientTimeZone;
rdp_get_client_time_zone(s, settings);
clientTimeZone = settings->client_time_zone;
standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length);
standardNameLength = length;
daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length);
daylightNameLength = length;
if (standardNameLength > 62)
standardNameLength = 62;
if (daylightNameLength > 62)
daylightNameLength = 62;
stream_write_uint32(s, clientTimeZone->bias); /* Bias */
/* standardName (64 bytes) */
stream_write(s, standardName, standardNameLength);
stream_write_zero(s, 64 - standardNameLength);
rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */
/* daylightName (64 bytes) */
stream_write(s, daylightName, daylightNameLength);
stream_write_zero(s, 64 - daylightNameLength);
rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
xfree(standardName);
xfree(daylightName);
}
/**
* Read Server Auto Reconnect Cookie (ARC_SC_PRIVATE_PACKET).\n
* @msdn{cc240540}

View File

@ -17,6 +17,8 @@
* limitations under the License.
*/
#include <freerdp/input.h>
#include "input.h"
void rdp_write_client_input_pdu_header(STREAM* s, uint16 number)
@ -380,6 +382,31 @@ void input_register_client_callbacks(rdpInput* input)
}
}
void freerdp_input_send_synchronize_event(rdpInput* input, uint32 flags)
{
IFCALL(input->SynchronizeEvent, input, flags);
}
void freerdp_input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{
IFCALL(input->KeyboardEvent, input, flags, code);
}
void freerdp_input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{
IFCALL(input->UnicodeKeyboardEvent, input, flags, code);
}
void freerdp_input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{
IFCALL(input->MouseEvent, input, flags, x, y);
}
void freerdp_input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{
IFCALL(input->ExtendedMouseEvent, input, flags, x, y);
}
rdpInput* input_new(rdpRdp* rdp)
{
rdpInput* input;

View File

@ -18,6 +18,7 @@
*/
#include "redirection.h"
#include "certificate.h"
#include "license.h"

View File

@ -23,8 +23,8 @@
typedef struct rdp_license rdpLicense;
#include "rdp.h"
#include "crypto.h"
#include "certificate.h"
#include <freerdp/crypto/crypto.h>
#include <freerdp/crypto/certificate.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/debug.h>

View File

@ -20,8 +20,8 @@
#ifndef __MCS_H
#define __MCS_H
#include "ber.h"
#include "transport.h"
#include <freerdp/crypto/ber.h>
#include <freerdp/types.h>
#include <freerdp/utils/stream.h>

View File

@ -256,8 +256,10 @@ void nego_attempt_rdp(rdpNego* nego)
boolean nego_recv_response(rdpNego* nego)
{
STREAM* s = transport_recv_stream_init(nego->transport, 1024);
if (transport_read(nego->transport, s) < 0)
return false;
return nego_recv(nego->transport, s, nego->transport->recv_extra);
}
@ -319,6 +321,7 @@ boolean nego_read_request(rdpNego* nego, STREAM* s)
tpkt_read_header(s);
li = tpdu_read_connection_request(s);
if (li != stream_get_left(s) + 6)
{
printf("Incorrect TPDU length indicator.\n");
@ -403,7 +406,7 @@ boolean nego_send_negotiation_request(rdpNego* nego)
{
int cookie_length = strlen(nego->cookie);
stream_write(s, "Cookie: mstshash=", 17);
stream_write(s, (uint8*)nego->cookie, cookie_length);
stream_write(s, (uint8*) nego->cookie, cookie_length);
stream_write_uint8(s, 0x0D); /* CR */
stream_write_uint8(s, 0x0A); /* LF */
length += cookie_length + 19;

View File

@ -55,8 +55,6 @@ static const char* const PRIMARY_DRAWING_ORDER_STRINGS[] =
"GlyphIndex"
};
#define PRIMARY_DRAWING_ORDER_COUNT (sizeof(PRIMARY_DRAWING_ORDER_STRINGS) / sizeof(PRIMARY_DRAWING_ORDER_STRINGS[0]))
static const char* const SECONDARY_DRAWING_ORDER_STRINGS[] =
{
"Cache Bitmap",
@ -123,6 +121,8 @@ static const uint8 PRIMARY_DRAWING_ORDER_FIELD_BYTES[] =
GLYPH_INDEX_ORDER_FIELD_BYTES
};
#define PRIMARY_DRAWING_ORDER_COUNT (sizeof(PRIMARY_DRAWING_ORDER_FIELD_BYTES) / sizeof(PRIMARY_DRAWING_ORDER_FIELD_BYTES[0]))
static const uint8 CBR2_BPP[] =
{
0, 0, 0, 8, 16, 24, 32
@ -1086,12 +1086,18 @@ void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_O
update_read_color(s, &polygon_sc->brushColor);
if (orderInfo->fieldFlags & ORDER_FIELD_06)
stream_read_uint8(s, polygon_sc->nDeltaEntries);
stream_read_uint8(s, polygon_sc->numPoints);
if (orderInfo->fieldFlags & ORDER_FIELD_07)
{
stream_read_uint8(s, polygon_sc->cbData);
stream_seek(s, polygon_sc->cbData);
if (polygon_sc->points == NULL)
polygon_sc->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_sc->numPoints);
else
polygon_sc->points = (DELTA_POINT*) xrealloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints);
update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart);
}
}
@ -1118,13 +1124,22 @@ void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_O
update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6);
if (orderInfo->fieldFlags & ORDER_FIELD_12)
stream_read_uint8(s, polygon_cb->nDeltaEntries);
stream_read_uint8(s, polygon_cb->numPoints);
if (orderInfo->fieldFlags & ORDER_FIELD_13)
{
stream_read_uint8(s, polygon_cb->cbData);
stream_seek(s, polygon_cb->cbData);
if (polygon_cb->points == NULL)
polygon_cb->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_cb->numPoints);
else
polygon_cb->points = (DELTA_POINT*) xrealloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints);
update_read_delta_points(s, polygon_cb->points, polygon_cb->numPoints, polygon_cb->xStart, polygon_cb->yStart);
}
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
}
void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc)
@ -1683,7 +1698,7 @@ void update_read_bounds(STREAM* s, rdpBounds* bounds)
update_read_coord(s, &bounds->bottom, true);
}
void update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags)
boolean update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags)
{
ORDER_INFO* orderInfo;
rdpContext* context = update->context;
@ -1694,6 +1709,12 @@ void update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags)
if (flags & ORDER_TYPE_CHANGE)
stream_read_uint8(s, orderInfo->orderType); /* orderType (1 byte) */
if (orderInfo->orderType >= PRIMARY_DRAWING_ORDER_COUNT)
{
printf("Invalid Primary Drawing Order (0x%02X)\n", orderInfo->orderType);
return false;
}
update_read_field_flags(s, &(orderInfo->fieldFlags), flags,
PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]);
@ -1708,10 +1729,7 @@ void update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags)
orderInfo->deltaCoordinates = (flags & ORDER_DELTA_COORDINATES) ? true : false;
#ifdef WITH_DEBUG_ORDERS
if (orderInfo->orderType < PRIMARY_DRAWING_ORDER_COUNT)
printf("%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType);
else
printf("Unknown Primary Drawing Order (0x%02X)\n", orderInfo->orderType);
printf("%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType);
#endif
switch (orderInfo->orderType)
@ -1834,6 +1852,8 @@ void update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags)
{
IFCALL(update->SetBounds, context, NULL);
}
return true;
}
void update_recv_secondary_order(rdpUpdate* update, STREAM* s, uint8 flags)
@ -2004,7 +2024,7 @@ void update_recv_altsec_order(rdpUpdate* update, STREAM* s, uint8 flags)
}
}
void update_recv_order(rdpUpdate* update, STREAM* s)
boolean update_recv_order(rdpUpdate* update, STREAM* s)
{
uint8 controlFlags;
@ -2015,6 +2035,10 @@ void update_recv_order(rdpUpdate* update, STREAM* s)
else if (controlFlags & ORDER_SECONDARY)
update_recv_secondary_order(update, s, controlFlags);
else
update_recv_primary_order(update, s, controlFlags);
}
{
if (!update_recv_primary_order(update, s, controlFlags))
return false;
}
return true;
}

View File

@ -184,7 +184,7 @@
#define CG_GLYPH_UNICODE_PRESENT 0x0010
void update_recv_order(rdpUpdate* update, STREAM* s);
boolean update_recv_order(rdpUpdate* update, STREAM* s);
void update_read_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt);
void update_read_patblt_order(STREAM* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt);

View File

@ -17,6 +17,8 @@
* limitations under the License.
*/
#include "certificate.h"
#include "peer.h"
static boolean freerdp_peer_initialize(freerdp_peer* client)

View File

@ -20,9 +20,10 @@
#include "rdp.h"
#include "info.h"
#include "per.h"
#include "redirection.h"
#include <freerdp/crypto/per.h>
static const char* const DATA_PDU_TYPE_STRINGS[] =
{
"", "", /* 0x00 - 0x01 */
@ -471,7 +472,7 @@ void rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, STREAM* s)
rdp_print_errinfo(rdp->errorInfo);
}
void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
boolean rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
{
uint8 type;
uint16 length;
@ -489,7 +490,8 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
switch (type)
{
case DATA_PDU_TYPE_UPDATE:
update_recv(rdp->update, s);
if (!update_recv(rdp->update, s))
return false;
break;
case DATA_PDU_TYPE_CONTROL:
@ -571,6 +573,8 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
default:
break;
}
return true;
}
boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
@ -583,8 +587,7 @@ boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
if (type == PDU_TYPE_DATA)
{
rdp_recv_data_pdu(rdp, s);
return true;
return rdp_recv_data_pdu(rdp, s);
}
else if (type == PDU_TYPE_SERVER_REDIRECTION)
{
@ -719,7 +722,8 @@ static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
switch (pduType)
{
case PDU_TYPE_DATA:
rdp_recv_data_pdu(rdp, s);
if (!rdp_recv_data_pdu(rdp, s))
return false;
break;
case PDU_TYPE_DEACTIVATE_ALL:
@ -902,6 +906,11 @@ void rdp_free(rdpRdp* rdp)
{
if (rdp != NULL)
{
crypto_rc4_free(rdp->rc4_decrypt_key);
crypto_rc4_free(rdp->rc4_encrypt_key);
crypto_des3_free(rdp->fips_encrypt);
crypto_des3_free(rdp->fips_decrypt);
crypto_hmac_free(rdp->fips_hmac);
extension_free(rdp->extension);
settings_free(rdp->settings);
transport_free(rdp->transport);

View File

@ -179,7 +179,7 @@ boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id);
STREAM* rdp_data_pdu_init(rdpRdp* rdp);
boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id);
void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
boolean rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id);
void rdp_recv(rdpRdp* rdp);

View File

@ -358,6 +358,9 @@ boolean security_establish_keys(uint8* client_random, rdpRdp* rdp)
printf("FIPS Compliant encryption level.\n");
/* disable fastpath input; it doesnt handle FIPS encryption yet */
rdp->settings->fastpath_input = false;
sha1 = crypto_sha1_init();
crypto_sha1_update(sha1, client_random + 16, 16);
crypto_sha1_update(sha1, server_random + 16, 16);

View File

@ -21,7 +21,7 @@
#define __SECURITY_H
#include "rdp.h"
#include "crypto.h"
#include <freerdp/crypto/crypto.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>

View File

@ -18,6 +18,7 @@
*/
#include "config.h"
#include "certificate.h"
#include "capabilities.h"
#include <freerdp/utils/memory.h>
@ -57,7 +58,7 @@ rdpSettings* settings_new(void* instance)
settings->kbd_fn_keys = 0;
settings->kbd_layout = 0;
settings->encryption = false;
settings->secure_checksum = false;
settings->salted_checksum = false;
settings->port = 3389;
settings->desktop_resize = true;

149
libfreerdp-core/timezone.c Normal file
View File

@ -0,0 +1,149 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Time Zone Redirection
*
* 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.
*/
#include "timezone.h"
/**
* Read SYSTEM_TIME structure (TS_SYSTEMTIME).\n
* @msdn{cc240478}
* @param s stream
* @param system_time system time structure
*/
void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time)
{
stream_read_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
stream_read_uint16(s, system_time->wMonth); /* wMonth */
stream_read_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
stream_read_uint16(s, system_time->wDay); /* wDay */
stream_read_uint16(s, system_time->wHour); /* wHour */
stream_read_uint16(s, system_time->wMinute); /* wMinute */
stream_read_uint16(s, system_time->wSecond); /* wSecond */
stream_read_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
}
/**
* Write SYSTEM_TIME structure (TS_SYSTEMTIME).\n
* @msdn{cc240478}
* @param s stream
* @param system_time system time structure
*/
void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time)
{
stream_write_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
stream_write_uint16(s, system_time->wMonth); /* wMonth */
stream_write_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
stream_write_uint16(s, system_time->wDay); /* wDay */
stream_write_uint16(s, system_time->wHour); /* wHour */
stream_write_uint16(s, system_time->wMinute); /* wMinute */
stream_write_uint16(s, system_time->wSecond); /* wSecond */
stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
}
/**
* Read client time zone information (TS_TIME_ZONE_INFORMATION).\n
* @msdn{cc240477}
* @param s stream
* @param settings settings
*/
boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings)
{
char* str;
TIME_ZONE_INFO* clientTimeZone;
if (stream_get_left(s) < 172)
return false;
clientTimeZone = settings->client_time_zone;
stream_read_uint32(s, clientTimeZone->bias); /* Bias */
/* standardName (64 bytes) */
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
stream_seek(s, 64);
strncpy(clientTimeZone->standardName, str, sizeof(clientTimeZone->standardName));
xfree(str);
rdp_read_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
stream_read_uint32(s, clientTimeZone->standardBias); /* StandardBias */
/* daylightName (64 bytes) */
str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
stream_seek(s, 64);
strncpy(clientTimeZone->daylightName, str, sizeof(clientTimeZone->daylightName));
xfree(str);
rdp_read_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
stream_read_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
return true;
}
/**
* Write client time zone information (TS_TIME_ZONE_INFORMATION).\n
* @msdn{cc240477}
* @param s stream
* @param settings settings
*/
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings)
{
size_t length;
uint8* standardName;
uint8* daylightName;
size_t standardNameLength;
size_t daylightNameLength;
TIME_ZONE_INFO* clientTimeZone;
clientTimeZone = settings->client_time_zone;
freerdp_time_zone_detect(clientTimeZone);
standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length);
standardNameLength = length;
daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length);
daylightNameLength = length;
if (standardNameLength > 62)
standardNameLength = 62;
if (daylightNameLength > 62)
daylightNameLength = 62;
stream_write_uint32(s, clientTimeZone->bias); /* Bias */
/* standardName (64 bytes) */
stream_write(s, standardName, standardNameLength);
stream_write_zero(s, 64 - standardNameLength);
rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */
/* daylightName (64 bytes) */
stream_write(s, daylightName, daylightNameLength);
stream_write_zero(s, 64 - daylightNameLength);
rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
xfree(standardName);
xfree(daylightName);
}

View File

@ -0,0 +1,35 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Time Zone Redirection
*
* 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 __TIMEZONE_H
#define __TIMEZONE_H
#include "rdp.h"
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/locale/timezone.h>
void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time);
void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time);
void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings);
boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings);
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings);
#endif /* __TIMEZONE_H */

View File

@ -37,9 +37,10 @@
#include "tpkt.h"
#include "fastpath.h"
#include "credssp.h"
#include "transport.h"
#include <freerdp/auth/credssp.h>
#define BUFFER_SIZE 16384
STREAM* transport_recv_stream_init(rdpTransport* transport, int size)
@ -72,6 +73,7 @@ boolean transport_disconnect(rdpTransport* transport)
{
if (transport->layer == TRANSPORT_LAYER_TLS)
tls_disconnect(transport->tls);
return tcp_disconnect(transport->tcp);
}
@ -98,6 +100,9 @@ boolean transport_connect_tls(rdpTransport* transport)
boolean transport_connect_nla(rdpTransport* transport)
{
freerdp* instance;
rdpSettings* settings;
if (transport->tls == NULL)
transport->tls = tls_new(transport->settings);
@ -112,8 +117,11 @@ boolean transport_connect_nla(rdpTransport* transport)
if (transport->settings->authentication != true)
return true;
settings = transport->settings;
instance = (freerdp*) settings->instance;
if (transport->credssp == NULL)
transport->credssp = credssp_new(transport);
transport->credssp = credssp_new(instance, transport->tls, settings);
if (credssp_authenticate(transport->credssp) < 0)
{
@ -152,6 +160,9 @@ boolean transport_accept_tls(rdpTransport* transport)
boolean transport_accept_nla(rdpTransport* transport)
{
freerdp* instance;
rdpSettings* settings;
if (transport->tls == NULL)
transport->tls = tls_new(transport->settings);
@ -166,7 +177,20 @@ boolean transport_accept_nla(rdpTransport* transport)
if (transport->settings->authentication != true)
return true;
/* Blocking here until NLA is complete */
settings = transport->settings;
instance = (freerdp*) settings->instance;
if (transport->credssp == NULL)
transport->credssp = credssp_new(instance, transport->tls, settings);
if (credssp_authenticate(transport->credssp) < 0)
{
printf("client authentication failure\n");
credssp_free(transport->credssp);
return false;
}
credssp_free(transport->credssp);
return true;
}

View File

@ -30,8 +30,8 @@ typedef enum
typedef struct rdp_transport rdpTransport;
#include "tcp.h"
#include "tls.h"
#include "credssp.h"
#include <freerdp/crypto/tls.h>
#include <freerdp/auth/credssp.h>
#include <time.h>
#include <freerdp/types.h>

View File

@ -32,7 +32,7 @@ static const char* const UPDATE_TYPE_STRINGS[] =
};
*/
void update_recv_orders(rdpUpdate* update, STREAM* s)
boolean update_recv_orders(rdpUpdate* update, STREAM* s)
{
uint16 numberOrders;
@ -42,9 +42,12 @@ void update_recv_orders(rdpUpdate* update, STREAM* s)
while (numberOrders > 0)
{
update_recv_order(update, s);
if (!update_recv_order(update, s))
return false;
numberOrders--;
}
return true;
}
void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
@ -243,7 +246,7 @@ void update_recv_pointer(rdpUpdate* update, STREAM* s)
}
}
void update_recv(rdpUpdate* update, STREAM* s)
boolean update_recv(rdpUpdate* update, STREAM* s)
{
uint16 updateType;
rdpContext* context = update->context;
@ -257,7 +260,11 @@ void update_recv(rdpUpdate* update, STREAM* s)
switch (updateType)
{
case UPDATE_TYPE_ORDERS:
update_recv_orders(update, s);
if (!update_recv_orders(update, s))
{
/* XXX: Do we have to call EndPaint? */
return false;
}
break;
case UPDATE_TYPE_BITMAP:
@ -287,10 +294,13 @@ void update_recv(rdpUpdate* update, STREAM* s)
rdp_read_share_control_header(s, &length, &pduType, &source);
if (pduType != PDU_TYPE_DATA)
return;
return false;
rdp_recv_data_pdu(update->context->rdp, s);
if (!rdp_recv_data_pdu(update->context->rdp, s))
return false;
}
return true;
}
void update_reset_state(rdpUpdate* update)

View File

@ -44,7 +44,7 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update);
void update_recv_play_sound(rdpUpdate* update, STREAM* s);
void update_recv_pointer(rdpUpdate* update, STREAM* s);
void update_recv(rdpUpdate* update, STREAM* s);
boolean update_recv(rdpUpdate* update, STREAM* s);
void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position);
void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system);

View File

@ -0,0 +1,35 @@
# FreeRDP: A Remote Desktop Protocol Client
# libfreerdp-crypto cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 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(FREERDP_CRYPTO_SRCS
ber.c
per.c
certificate.c
crypto.c
tls.c)
add_library(freerdp-crypto ${FREERDP_CRYPTO_SRCS})
set_target_properties(freerdp-crypto PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
target_link_libraries(freerdp-crypto freerdp-utils)
target_link_libraries(freerdp-crypto ${OPENSSL_LIBRARIES})
install(TARGETS freerdp-crypto DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -17,7 +17,7 @@
* limitations under the License.
*/
#include "ber.h"
#include <freerdp/crypto/ber.h>
void ber_read_length(STREAM* s, int* length)
{

View File

@ -0,0 +1,197 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Certificate Handling
*
* Copyright 2011 Jiten Pathy
* Copyright 2011 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.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <freerdp/utils/file.h>
static const char certificate_store_dir[] = "certs";
static const char certificate_known_hosts_file[] = "known_hosts";
#include <freerdp/crypto/certificate.h>
void certificate_store_init(rdpCertificateStore* certificate_store)
{
char* config_path;
rdpSettings* settings;
settings = certificate_store->settings;
config_path = freerdp_get_config_path(settings);
certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir);
if (freerdp_check_file_exists(certificate_store->path) == false)
{
freerdp_mkdir(certificate_store->path);
printf("creating directory %s\n", certificate_store->path);
}
certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file);
if (freerdp_check_file_exists(certificate_store->file) == false)
{
certificate_store->fp = fopen((char*) certificate_store->file, "w+");
if (certificate_store->fp == NULL)
{
printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file);
return;
}
fflush(certificate_store->fp);
}
else
{
certificate_store->fp = fopen((char*) certificate_store->file, "r+");
}
}
int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
{
FILE* fp;
int length;
char* data;
char* pline;
int match = 1;
long int size;
fp = certificate_store->fp;
if (!fp)
return match;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (size < 1)
return match;
data = (char*) xmalloc(size + 2);
if (fread(data, size, 1, fp) != 1)
{
xfree(data);
return match;
}
data[size] = '\n';
data[size + 1] = '\0';
pline = strtok(data, "\n");
while (pline != NULL)
{
length = strlen(pline);
if (length > 0)
{
length = strcspn(pline, " \t");
pline[length] = '\0';
if (strcmp(pline, certificate_data->hostname) == 0)
{
pline = &pline[length + 1];
if (strcmp(pline, certificate_data->fingerprint) == 0)
match = 0;
else
match = -1;
break;
}
}
pline = strtok(NULL, "\n");
}
xfree(data);
return match;
}
void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data)
{
FILE* fp;
/* reopen in append mode */
fp = fopen(certificate_store->file, "a");
if (!fp)
return;
fprintf(fp, "%s %s\n", certificate_data->hostname, certificate_data->fingerprint);
fclose(fp);
}
rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint)
{
rdpCertificateData* certdata;
certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData));
if (certdata != NULL)
{
certdata->hostname = xstrdup(hostname);
certdata->fingerprint = xstrdup(fingerprint);
}
return certdata;
}
void certificate_data_free(rdpCertificateData* certificate_data)
{
if (certificate_data != NULL)
{
xfree(certificate_data->hostname);
xfree(certificate_data->fingerprint);
xfree(certificate_data);
}
}
rdpCertificateStore* certificate_store_new(rdpSettings* settings)
{
rdpCertificateStore* certificate_store;
certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore));
if (certificate_store != NULL)
{
certificate_store->settings = settings;
certificate_store_init(certificate_store);
}
return certificate_store;
}
void certificate_store_free(rdpCertificateStore* certstore)
{
if (certstore != NULL)
{
if (certstore->fp != NULL)
fclose(certstore->fp);
xfree(certstore->path);
xfree(certstore->file);
xfree(certstore);
}
}

View File

@ -17,7 +17,7 @@
* limitations under the License.
*/
#include "crypto.h"
#include <freerdp/crypto/crypto.h>
CryptoSha1 crypto_sha1_init(void)
{
@ -107,6 +107,8 @@ void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, const uint8* in_data, u
void crypto_des3_free(CryptoDes3 des3)
{
if (des3 == NULL)
return;
EVP_CIPHER_CTX_cleanup(&des3->des3_ctx);
xfree(des3);
}
@ -135,6 +137,8 @@ void crypto_hmac_final(CryptoHmac hmac, uint8* out_data, uint32 length)
void crypto_hmac_free(CryptoHmac hmac)
{
if (hmac == NULL)
return;
HMAC_CTX_cleanup(&hmac->hmac_ctx);
xfree(hmac);
}
@ -149,6 +153,8 @@ CryptoCert crypto_cert_read(uint8* data, uint32 length)
void crypto_cert_free(CryptoCert cert)
{
if (cert == NULL)
return;
X509_free(cert->px509);
xfree(cert);
}
@ -437,7 +443,7 @@ char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths)
{
length = ASN1_STRING_to_UTF8(&string, subject_alt_name->d.dNSName);
strings[*count] = (char*) string;
*lengths[*count] = length;
(*lengths)[*count] = length;
(*count)++;
}
}

View File

@ -17,7 +17,7 @@
* limitations under the License.
*/
#include "per.h"
#include <freerdp/crypto/per.h>
/**
* Read PER length.

View File

@ -20,10 +20,39 @@
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include "tls.h"
#include <freerdp/crypto/tls.h>
static CryptoCert tls_get_certificate(rdpTls* tls)
{
CryptoCert cert;
X509* server_cert;
server_cert = SSL_get_peer_certificate(tls->ssl);
if (!server_cert)
{
printf("ssl_verify: failed to get the server SSL certificate\n");
cert = NULL;
}
else
{
cert = xmalloc(sizeof(*cert));
cert->px509 = server_cert;
}
return cert;
}
static void tls_free_certificate(CryptoCert cert)
{
X509_free(cert->px509);
xfree(cert);
}
boolean tls_connect(rdpTls* tls)
{
CryptoCert cert;
int connection_status;
tls->ctx = SSL_CTX_new(TLSv1_client_method());
@ -48,12 +77,15 @@ boolean tls_connect(rdpTls* tls)
if (tls->ssl == NULL)
{
SSL_CTX_free(tls->ctx);
printf("SSL_new failed\n");
return false;
}
if (SSL_set_fd(tls->ssl, tls->sockfd) < 1)
{
SSL_free(tls->ssl);
SSL_CTX_free(tls->ctx);
printf("SSL_set_fd failed\n");
return false;
}
@ -63,9 +95,32 @@ boolean tls_connect(rdpTls* tls)
if (connection_status <= 0)
{
if (tls_print_error("SSL_connect", tls->ssl, connection_status))
{
SSL_free(tls->ssl);
SSL_CTX_free(tls->ctx);
return false;
}
}
cert = tls_get_certificate(tls);
if (cert == NULL)
{
printf("tls_connect: tls_get_certificate failed to return the server certificate.\n");
return false;
}
if (!crypto_cert_get_public_key(cert, &tls->public_key))
{
printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n");
return false;
}
if (!tls_verify_certificate(tls, cert, tls->settings->hostname))
tls_disconnect(tls);
tls_free_certificate(cert);
return true;
}
@ -206,27 +261,6 @@ boolean tls_print_error(char* func, SSL* connection, int value)
}
}
CryptoCert tls_get_certificate(rdpTls* tls)
{
CryptoCert cert;
X509* server_cert;
server_cert = SSL_get_peer_certificate(tls->ssl);
if (!server_cert)
{
printf("ssl_verify: failed to get the server SSL certificate\n");
cert = NULL;
}
else
{
cert = xmalloc(sizeof(*cert));
cert->px509 = server_cert;
}
return cert;
}
boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
{
int match;
@ -427,6 +461,8 @@ void tls_free(rdpTls* tls)
if (tls->ctx)
SSL_CTX_free(tls->ctx);
freerdp_blob_free(&tls->public_key);
certificate_store_free(tls->certificate_store);
xfree(tls);

View File

@ -407,6 +407,60 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi
return 0;
}
static int BitBlt_PSDPxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
uint16* srcp;
uint16* dstp;
uint16* patp;
uint16 color16;
/* D = (S & D) | (~S & P) */
if (hdcDest->brush->style == GDI_BS_SOLID)
{
color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color);
patp = (uint16*) &color16;
for (y = 0; y < nHeight; y++)
{
srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
else
{
for (y = 0; y < nHeight; y++)
{
srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
return 0;
}
static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
@ -434,6 +488,31 @@ static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
return 0;
}
static int BitBlt_DPa_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
uint16* dstp;
uint16* patp;
for (y = 0; y < nHeight; y++)
{
dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = *dstp & *patp;
dstp++;
}
}
}
return 0;
}
static int BitBlt_PDxn_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
@ -696,6 +775,10 @@ int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh
return BitBlt_DSPDxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_PSDPxax:
return BitBlt_PSDPxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_NOTSRCCOPY:
return BitBlt_NOTSRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
@ -778,6 +861,10 @@ int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, i
return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_DPa:
return BitBlt_DPa_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_PDxn:
return BitBlt_PDxn_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;

View File

@ -385,48 +385,115 @@ static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW
static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
uint8* srcp;
uint8* dstp;
uint8* patp;
uint32* srcp;
uint32* dstp;
uint32* patp;
uint8* srcp8;
uint32 src32;
uint32 color32;
HGDI_BITMAP hSrcBmp;
/* D = (S & P) | (~S & D) */
/* DSPDxax, used to draw glyphs */
color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor);
patp = (uint32*) &color32;
hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject;
srcp = hSrcBmp->data;
if (hdcSrc->bytesPerPixel != 1)
if (hdcSrc->bytesPerPixel == 1)
{
printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel);
return 0;
}
for (y = 0; y < nHeight; y++)
{
srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
/* DSPDxax, used to draw glyphs */
if (dstp != 0)
srcp = (uint32*) & src32;
for (y = 0; y < nHeight; y++)
{
for (x = 0; x < nWidth; x++)
srcp8 = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
patp = (uint8*) &color32;
for (x = 0; x < nWidth; x++)
{
*srcp = ((*srcp8) | (*srcp8 << 8) | (*srcp8 << 16) | (*srcp8 << 24));
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
dstp++;
patp++;
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
dstp++;
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
dstp++;
patp++;
srcp8++;
}
}
}
}
else
{
for (y = 0; y < nHeight; y++)
{
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
dstp += 2;
srcp++;
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
*dstp = (*srcp & *patp) | (~(*srcp) & *dstp);
srcp++;
dstp++;
}
}
}
}
return 0;
}
static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
uint32* srcp;
uint32* dstp;
uint32* patp;
uint32 color32;
/* D = (S & D) | (~S & P) */
if (hdcDest->brush->style == GDI_BS_SOLID)
{
color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color);
patp = (uint32*) &color32;
for (y = 0; y < nHeight; y++)
{
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
else
{
for (y = 0; y < nHeight; y++)
{
srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
@ -487,6 +554,31 @@ static int BitBlt_DSna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth
return 0;
}
static int BitBlt_DPa_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
uint32* dstp;
uint32* patp;
for (y = 0; y < nHeight; y++)
{
dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = *dstp & *patp;
dstp++;
}
}
}
return 0;
}
static int BitBlt_PDxn_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
@ -725,6 +817,10 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh
return BitBlt_DSPDxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_PSDPxax:
return BitBlt_PSDPxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_NOTSRCCOPY:
return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
@ -807,6 +903,10 @@ int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, i
return BitBlt_WHITENESS_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_DPa:
return BitBlt_DPa_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_PDxn:
return BitBlt_PDxn_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;

View File

@ -33,6 +33,12 @@
#include <freerdp/gdi/8bpp.h>
uint8 gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color)
{
/* TODO: Implement 8bpp gdi_get_color_8bpp() */
return 0;
}
int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr)
{
/* TODO: Implement 8bpp FillRect() */
@ -310,6 +316,60 @@ static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid
return 0;
}
static int BitBlt_PSDPxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
uint8* srcp;
uint8* dstp;
uint8* patp;
uint8 color8;
/* D = (S & D) | (~S & P) */
if (hdcDest->brush->style == GDI_BS_SOLID)
{
color8 = gdi_get_color_8bpp(hdcDest, hdcDest->brush->color);
patp = (uint8*) &color8;
for (y = 0; y < nHeight; y++)
{
srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
else
{
for (y = 0; y < nHeight; y++)
{
srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y);
dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = (uint8*) gdi_get_brush_pointer(hdcDest, x, y);
*dstp = (*srcp & *dstp) | (~(*srcp) & *patp);
srcp++;
dstp++;
}
}
}
}
return 0;
}
static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc)
{
int x, y;
@ -339,6 +399,31 @@ static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth,
return 0;
}
static int BitBlt_DPa_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
uint8* dstp;
uint8* patp;
for (y = 0; y < nHeight; y++)
{
dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y);
if (dstp != 0)
{
for (x = 0; x < nWidth; x++)
{
patp = gdi_get_brush_pointer(hdcDest, x, y);
*dstp = *dstp & *patp;
dstp++;
}
}
}
return 0;
}
static int BitBlt_PDxn_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight)
{
int x, y;
@ -606,6 +691,10 @@ int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight
return BitBlt_DSPDxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_PSDPxax:
return BitBlt_PSDPxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
case GDI_NOTSRCCOPY:
return BitBlt_NOTSRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc);
break;
@ -688,6 +777,10 @@ int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, in
return BitBlt_WHITENESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_DPa:
return BitBlt_DPa_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;
case GDI_PDxn:
return BitBlt_PDxn_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight);
break;

View File

@ -628,7 +628,55 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
rdpBrush* brush;
uint32 foreColor;
uint32 backColor;
gdiBitmap* bitmap;
HGDI_BRUSH originalBrush;
rdpGdi* gdi = context->gdi;
brush = &mem3blt->brush;
bitmap = (gdiBitmap*) mem3blt->bitmap;
foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv);
backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv);
if (brush->style == GDI_BS_SOLID)
{
originalBrush = gdi->drawing->hdc->brush;
gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor);
gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop));
gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
gdi->drawing->hdc->brush = originalBrush;
}
else
{
printf("Mem3Blt unimplemented brush style:%d\n", brush->style);
}
}
void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
{
printf("PolygonSC\n");
}
void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
{
printf("PolygonCB\n");
}
void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
{
printf("EllipseSC\n");
}
void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
{
printf("EllipseCB\n");
}
int tilenum = 0;
@ -776,10 +824,10 @@ void gdi_register_update_callbacks(rdpUpdate* update)
primary->GlyphIndex = NULL;
primary->FastIndex = NULL;
primary->FastGlyph = NULL;
primary->PolygonSC = NULL;
primary->PolygonCB = NULL;
primary->EllipseSC = NULL;
primary->EllipseCB = NULL;
primary->PolygonSC = gdi_polygon_sc;
primary->PolygonCB = gdi_polygon_cb;
primary->EllipseSC = gdi_ellipse_sc;
primary->EllipseCB = gdi_ellipse_cb;
update->SurfaceBits = gdi_surface_bits;
}

Some files were not shown because too many files have changed in this diff Show More