mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-04 15:23:32 +08:00
Merge remote-tracking branch 'upstream/master' into rail
This commit is contained in:
commit
585b436915
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,8 +14,9 @@ Makefile
|
||||
*.cproject
|
||||
*.settings
|
||||
|
||||
# Doxygen
|
||||
# Documentation
|
||||
docs/api
|
||||
client/X11/xfreerdp.1
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
@ -122,6 +122,8 @@ static void rdpsnd_pulse_stream_success_callback(pa_stream* stream, int success,
|
||||
|
||||
static void rdpsnd_pulse_wait_for_operation(rdpsndPulsePlugin* pulse, pa_operation* operation)
|
||||
{
|
||||
if (operation == NULL)
|
||||
return;
|
||||
while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING)
|
||||
{
|
||||
pa_threaded_mainloop_wait(pulse->mainloop);
|
||||
|
@ -17,6 +17,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include(FindXmlto)
|
||||
include_directories(${X11_INCLUDE_DIRS})
|
||||
|
||||
add_executable(xfreerdp
|
||||
@ -32,26 +33,41 @@ add_executable(xfreerdp
|
||||
xf_window.h
|
||||
xfreerdp.c
|
||||
xfreerdp.h)
|
||||
|
||||
|
||||
if(WITH_MANPAGES)
|
||||
if(XMLTO_FOUND)
|
||||
add_custom_command(OUTPUT xfreerdp.1
|
||||
COMMAND ${XMLTO_EXECUTABLE} man ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml
|
||||
DEPENDS xfreerdp.1.xml)
|
||||
|
||||
add_custom_target(xfreerdp.manpage ALL
|
||||
DEPENDS xfreerdp.1)
|
||||
|
||||
install(FILES xfreerdp.1 DESTINATION share/man/man1)
|
||||
else(XMLTO_FOUND)
|
||||
message(WARNING "WITH_MANPAGES was set, but xmlto was not found. man-pages will not be installed")
|
||||
endif(XMLTO_FOUND)
|
||||
endif(WITH_MANPAGES)
|
||||
|
||||
find_package(Xinerama)
|
||||
if(XINERAMA_FOUND)
|
||||
add_definitions(-DWITH_XINERAMA)
|
||||
add_definitions(-DWITH_XINERAMA -DWITH_XEXT)
|
||||
include_directories(${XINERAMA_INCLUDE_DIRS})
|
||||
target_link_libraries(xfreerdp ${XINERAMA_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(Xext)
|
||||
if(Xext_FOUND)
|
||||
if(XEXT_FOUND)
|
||||
add_definitions(-DWITH_XEXT)
|
||||
include_directories(${Xext_INCLUDE_DIRS})
|
||||
target_link_libraries(xfreerdp ${Xext_LIBRARIES})
|
||||
include_directories(${XEXT_INCLUDE_DIRS})
|
||||
target_link_libraries(xfreerdp ${XEXT_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(Xcursor)
|
||||
if(Xcursor_FOUND)
|
||||
add_definitions(-DWITH_XCURSOR)
|
||||
include_directories(${Xcursor_INCLUDE_DIRS})
|
||||
target_link_libraries(xfreerdp ${Xext_LIBRARIES})
|
||||
target_link_libraries(xfreerdp ${Xcursor_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(xfreerdp freerdp-core)
|
||||
@ -63,3 +79,4 @@ target_link_libraries(xfreerdp freerdp-utils)
|
||||
target_link_libraries(xfreerdp ${X11_LIBRARIES})
|
||||
|
||||
install(TARGETS xfreerdp DESTINATION bin)
|
||||
|
||||
|
@ -343,7 +343,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app)
|
||||
if (xfi->mouse_active && (app != True))
|
||||
XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
xf_rail_send_activate(xfi, event->xany.window, True);
|
||||
//xf_rail_send_activate(xfi, event->xany.window, True);
|
||||
xf_kbd_focus_in(xfi);
|
||||
|
||||
return True;
|
||||
@ -359,7 +359,7 @@ boolean xf_event_FocusOut(xfInfo* xfi, XEvent* event, boolean app)
|
||||
if (event->xfocus.mode == NotifyWhileGrabbed)
|
||||
XUngrabKeyboard(xfi->display, CurrentTime);
|
||||
|
||||
xf_rail_send_activate(xfi, event->xany.window, False);
|
||||
//xf_rail_send_activate(xfi, event->xany.window, False);
|
||||
|
||||
return True;
|
||||
}
|
||||
@ -476,7 +476,7 @@ boolean xf_event_process(freerdp* instance, XEvent* event)
|
||||
app = True;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
if (event->type != MotionNotify)
|
||||
printf("X11 %s Event: wnd=0x%X\n", X11_EVENT_STRINGS[event->type], (uint32)event->xany.window);
|
||||
#endif
|
||||
|
@ -82,6 +82,7 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
|
||||
window->windowId, window->ownerWindowId);
|
||||
|
||||
xfparent = NULL;
|
||||
|
||||
if (window->ownerWindowId != 0)
|
||||
{
|
||||
rdpWindow* p = NULL;
|
||||
@ -89,7 +90,7 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
|
||||
p = window_list_get_by_id(xfi->rail->list, window->ownerWindowId);
|
||||
|
||||
if (p != NULL)
|
||||
xfparent = (xfWindow *)p->extra;
|
||||
xfparent = (xfWindow *) p->extra;
|
||||
}
|
||||
|
||||
xfw = xf_CreateWindow((xfInfo*) rail->extra, xfparent,
|
||||
@ -97,10 +98,10 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
|
||||
window->windowWidth, window->windowHeight,
|
||||
window->windowId);
|
||||
|
||||
XStoreName(xfi->display, xfw->handle, window->title);
|
||||
|
||||
xf_SetWindowStyle(xfi, xfw, window->style, window->extendedStyle);
|
||||
|
||||
XStoreName(xfi->display, xfw->handle, window->title);
|
||||
|
||||
window->extra = (void*) xfw;
|
||||
window->extraId = (void*) xfw->handle;
|
||||
}
|
||||
@ -165,6 +166,17 @@ void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window)
|
||||
xf_SetWindowRects(xfi, xfw, window->windowRects, window->numWindowRects);
|
||||
}
|
||||
|
||||
void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window)
|
||||
{
|
||||
xfInfo* xfi;
|
||||
xfWindow* xfw;
|
||||
|
||||
xfi = (xfInfo*) rail->extra;
|
||||
xfw = (xfWindow*) window->extra;
|
||||
|
||||
xf_SetWindowVisibilityRects(xfi, xfw, window->windowRects, window->numWindowRects);
|
||||
}
|
||||
|
||||
void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
|
||||
{
|
||||
xfWindow* xfw;
|
||||
@ -181,6 +193,7 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
|
||||
rail->SetWindowText = xf_rail_SetWindowText;
|
||||
rail->SetWindowIcon = xf_rail_SetWindowIcon;
|
||||
rail->SetWindowRects = xf_rail_SetWindowRects;
|
||||
rail->SetWindowVisibilityRects = xf_rail_SetWindowVisibilityRects;
|
||||
rail->DestroyWindow = xf_rail_DestroyWindow;
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,6 @@ struct _PropMotifWmHints
|
||||
};
|
||||
typedef struct _PropMotifWmHints PropMotifWmHints;
|
||||
|
||||
void xf_ReferenceWindow(xfInfo* xfi, xfWindow* window);
|
||||
void xf_DereferenceWindow(xfInfo* xfi, xfWindow* window);
|
||||
|
||||
void xf_SendClientMessage(xfInfo* xfi, xfWindow* window, Atom atom, long msg, long d1, long d2, long d3)
|
||||
{
|
||||
XEvent xevent;
|
||||
@ -162,43 +159,38 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show)
|
||||
window->decorations = show;
|
||||
}
|
||||
|
||||
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
Atom window_state[2];
|
||||
|
||||
window_state[0] = xfi->_NET_WM_STATE_SKIP_PAGER;
|
||||
window_state[1] = xfi->_NET_WM_STATE_SKIP_TASKBAR;
|
||||
|
||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_STATE,
|
||||
XA_ATOM, 32, PropModeReplace, (uint8*) &window_state, 2);
|
||||
}
|
||||
|
||||
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style)
|
||||
{
|
||||
Atom window_type;
|
||||
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
|
||||
|
||||
if (((style & WS_POPUP) !=0) ||
|
||||
((style & WS_DLGFRAME) != 0) ||
|
||||
((ex_style & WS_EX_DLGMODALFRAME) != 0)
|
||||
)
|
||||
if ((style & WS_POPUP) || (style & WS_DLGFRAME) || (ex_style & WS_EX_DLGMODALFRAME))
|
||||
{
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG;
|
||||
}
|
||||
else if ((ex_style & WS_EX_TOOLWINDOW) != 0)
|
||||
|
||||
if (ex_style & WS_EX_TOOLWINDOW)
|
||||
{
|
||||
xf_SetWindowUnlisted(xfi, window);
|
||||
window_type = xfi->_NET_WM_WINDOW_TYPE_UTILITY;
|
||||
}
|
||||
|
||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE,
|
||||
xfi->_NET_WM_WINDOW_TYPE, 32, PropModeReplace, (unsigned char*)&window_type, 1);
|
||||
XA_ATOM, 32, PropModeReplace, (uint8*) &window_type, 1);
|
||||
}
|
||||
|
||||
void xf_SetWindowChildState(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
Atom window_state[2];
|
||||
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
window_state[0] = xfi->_NET_WM_STATE_SKIP_PAGER;
|
||||
window_state[1] = xfi->_NET_WM_STATE_SKIP_TASKBAR;
|
||||
|
||||
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_STATE,
|
||||
xfi->_NET_WM_STATE, 32, PropModeReplace, (unsigned char*)&window_state, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height)
|
||||
{
|
||||
xfWindow* window;
|
||||
@ -295,36 +287,18 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
|
||||
XGCValues gcv;
|
||||
int input_mask;
|
||||
XClassHint* class_hints;
|
||||
Window parent_handle;
|
||||
int lx;
|
||||
int ly;
|
||||
|
||||
window->ref_count = 0;
|
||||
window->decorations = False;
|
||||
window->fullscreen = False;
|
||||
window->parent = parent;
|
||||
|
||||
lx = x;
|
||||
ly = y;
|
||||
parent_handle = RootWindowOfScreen(xfi->screen);
|
||||
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
lx = x - window->parent->left;
|
||||
ly = y - window->parent->top;
|
||||
parent_handle = parent->handle;
|
||||
}
|
||||
|
||||
window->handle = XCreateWindow(xfi->display, parent_handle,
|
||||
lx, ly, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
|
||||
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
|
||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||
CWBorderPixel, &xfi->attribs);
|
||||
|
||||
xf_ReferenceWindow(xfi, window);
|
||||
xf_ReferenceWindow(xfi, window->parent);
|
||||
|
||||
xf_SetWindowDecorations(xfi, window, window->decorations);
|
||||
xf_SetWindowChildState(xfi, window);
|
||||
|
||||
class_hints = XAllocClassHint();
|
||||
|
||||
@ -352,10 +326,6 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
|
||||
window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv);
|
||||
window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth);
|
||||
|
||||
printf("xf_CreateWindow: h=0x%X p=0x%X x=%d y=%d w=%d h=%d\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0,
|
||||
x, y, width, height);
|
||||
|
||||
xf_MoveWindow(xfi, window, x, y, width, height);
|
||||
}
|
||||
|
||||
@ -364,37 +334,19 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, xfWindow* parent, int x, int y, int width
|
||||
|
||||
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
|
||||
{
|
||||
int lx, ly;
|
||||
Pixmap surface;
|
||||
|
||||
if ((width * height) < 1)
|
||||
return;
|
||||
|
||||
printf("xf_MoveWindow: BEFORE correctness h=0x%X x=%d y=%d w=%d h=%d\n",
|
||||
(uint32) window->handle, x, y, width, height);
|
||||
|
||||
xf_FixWindowCoordinates(&x, &y, &width, &height);
|
||||
|
||||
if (window->parent != NULL)
|
||||
{
|
||||
lx = x - window->parent->left;
|
||||
ly = y - window->parent->top;
|
||||
}
|
||||
else
|
||||
{
|
||||
lx = x;
|
||||
ly = y;
|
||||
}
|
||||
|
||||
printf("xf_MoveWindow: AFTER correctness h=0x%X x=%d y=%d lx=%d ly=%d w=%d h=%d \n",
|
||||
(uint32) window->handle, x, y, lx, ly, width, height);
|
||||
|
||||
if (window->width == width && window->height == height)
|
||||
XMoveWindow(xfi->display, window->handle, lx, ly);
|
||||
XMoveWindow(xfi->display, window->handle, x, y);
|
||||
else if (window->left == x && window->top == y)
|
||||
XResizeWindow(xfi->display, window->handle, width, height);
|
||||
else
|
||||
XMoveResizeWindow(xfi->display, window->handle, lx, ly, width, height);
|
||||
XMoveResizeWindow(xfi->display, window->handle, x, y, width, height);
|
||||
|
||||
surface = XCreatePixmap(xfi->display, window->handle, width, height, xfi->depth);
|
||||
XCopyArea(xfi->display, surface, window->surface, window->gc, 0, 0, window->width, window->height, 0, 0);
|
||||
@ -490,42 +442,41 @@ void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int n
|
||||
xfree(xrects);
|
||||
}
|
||||
|
||||
void xf_ReferenceWindow(xfInfo* xfi, xfWindow* window)
|
||||
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects)
|
||||
{
|
||||
if (window == NULL) return;
|
||||
window->ref_count++;
|
||||
}
|
||||
int i;
|
||||
XRectangle* xrects;
|
||||
|
||||
void xf_DereferenceWindow(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
if (window == NULL) return;
|
||||
xrects = xmalloc(sizeof(XRectangle) * nrects);
|
||||
|
||||
window->ref_count--;
|
||||
if (window->ref_count == 0)
|
||||
for (i = 0; i < nrects; i++)
|
||||
{
|
||||
printf("xf_DerefrenceWindow: destroying h=0x%X p=0x%X\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0);
|
||||
|
||||
if (window->gc)
|
||||
XFreeGC(xfi->display, window->gc);
|
||||
if (window->surface)
|
||||
XFreePixmap(xfi->display, window->surface);
|
||||
if (window->handle)
|
||||
{
|
||||
XUnmapWindow(xfi->display, window->handle);
|
||||
XDestroyWindow(xfi->display, window->handle);
|
||||
}
|
||||
xfree(window);
|
||||
xrects[i].x = rects[i].left;
|
||||
xrects[i].y = rects[i].top;
|
||||
xrects[i].width = rects[i].right - rects[i].left;
|
||||
xrects[i].height = rects[i].bottom - rects[i].top;
|
||||
}
|
||||
|
||||
#ifdef WITH_XEXT
|
||||
XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
|
||||
#endif
|
||||
|
||||
xfree(xrects);
|
||||
}
|
||||
|
||||
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
|
||||
{
|
||||
xfWindow* parent = window->parent;
|
||||
if (window->gc)
|
||||
XFreeGC(xfi->display, window->gc);
|
||||
|
||||
printf("xf_DestroyWindow: h=0x%X p=0x%X\n", (uint32)window->handle,
|
||||
(window->parent != NULL) ? (uint32)window->parent->handle : 0);
|
||||
if (window->surface)
|
||||
XFreePixmap(xfi->display, window->surface);
|
||||
|
||||
xf_DereferenceWindow(xfi, window);
|
||||
xf_DereferenceWindow(xfi, parent);
|
||||
if (window->handle)
|
||||
{
|
||||
XUnmapWindow(xfi->display, window->handle);
|
||||
XDestroyWindow(xfi->display, window->handle);
|
||||
}
|
||||
|
||||
xfree(window);
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ boolean xf_GetWorkArea(xfInfo* xfi);
|
||||
|
||||
void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen);
|
||||
void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show);
|
||||
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window);
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height);
|
||||
|
||||
@ -60,6 +61,7 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
|
||||
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state);
|
||||
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon);
|
||||
void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
|
||||
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
|
||||
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style);
|
||||
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window);
|
||||
|
||||
|
389
client/X11/xfreerdp.1.xml
Normal file
389
client/X11/xfreerdp.1.xml
Normal file
@ -0,0 +1,389 @@
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>2011-08-27</date>
|
||||
<author>
|
||||
<authorblurb><para>The FreeRDP-Team</para></authorblurb>
|
||||
</author>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
<refentrytitle>xfreerdp</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">freerdp</refmiscinfo>
|
||||
<refmiscinfo class="manual">xfreerdp</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname><application>xfreerdp</application></refname>
|
||||
<refpurpose>X11 frontend to libFreeRDP</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<refsynopsisdivinfo>
|
||||
<date>2011-08-27</date>
|
||||
</refsynopsisdivinfo>
|
||||
<para>
|
||||
<command>xfreerdp</command> [options] server[:port] [[options] server[:port] …]
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<refsect1info>
|
||||
<date>2011-08-27</date>
|
||||
</refsect1info>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
<command>xfreerdp</command> is a frontend to libFreeRDP,
|
||||
which implements a client to the Remote Desktop Protocol (RDP).
|
||||
RDP is used in a number of Microsoft products including Microsoft Windows
|
||||
versions starting from NT Terminal Server. RDP is also implemented by xrdp and VirtualBox.
|
||||
</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-0</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Attach to the admin console of the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-a <replaceable class="parameter">bpp</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the color depth for the connection to <replaceable class="parameter">bpp</replaceable> bits per pixel.
|
||||
Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="WorkingDir">
|
||||
<term>-c <replaceable class="parameter">dir</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the working-dir to <replaceable class="parameter">dir</replaceable>.
|
||||
This parameter is only used when an AlternateShell (<xref linkend="AlternateShell"/>) is requested.
|
||||
<replaceable class="parameter">dir</replaceable> should contain the executable file specified in the AlternateShell.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Removes the windows decorations.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Domain used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-f</term>
|
||||
<listitem>
|
||||
<para>
|
||||
start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-g <replaceable class="parameter">geometry</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the size of the FreeRDP-window (and of the remote desktop, when establishing a new connection).
|
||||
<replaceable class="parameter">geometry</replaceable> can have one of the following forms:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> -
|
||||
in this case the resulting window will be of
|
||||
<replaceable class="parameter">W</replaceable>x<replaceable class="parameter">H</replaceable> pixels.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">P</replaceable>% -
|
||||
in this case the resulting window will be <replaceable class="parameter">P</replaceable>%
|
||||
of your screen.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The special keyword <emphasis>workarea</emphasis> -
|
||||
in this case the resulting window will be of the same size as your workarea.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">id</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the keyboard-layout-id to <replaceable class="parameter">id</replaceable>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-m</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Don't send mouse motion events.
|
||||
<!-- TODO: what is this good for? -->
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">hostname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the reported client hostname to <replaceable class="parameter">hostname</replaceable>.
|
||||
Default is to automatically detect the hostname.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-o</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Play audio on the console instead of redirecting to the client.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-p <replaceable class="parameter">password</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Password used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="AlternateShell">
|
||||
<term>-s <replaceable class="parameter">shell</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Sets the startup-shell to <replaceable class="parameter">shell</replaceable>.
|
||||
This parameter should contain a complete path to the alternate shell.
|
||||
If the alternete shell requires a different working directory use <xref linkend="WorkingDir"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-t <replaceable class="parameter">port</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Connect to <replaceable class="parameter">port</replaceable>, instead of the default 3389.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-u <replaceable class="parameter">username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Username used in authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-x <replaceable class="parameter">flag</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the experiance performance flags.
|
||||
<replaceable class="parameter">flag</replaceable> can be one of:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
m - (modem): Equivalent to 15.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
b - (broadband): Equivalent to 1.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
l - (lan): Equivalent to 0.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">num</replaceable> - A number that represents a
|
||||
bit-mask, were numbers mean the following
|
||||
<footnote><para>Taken from <ulink url="http://msdn.microsoft.com/en-us/library/cc240476%28v=prot.10%29.aspx">
|
||||
MS-RDPBCGR Scetion 2.2.1.11.1.1.1 - Extended Info Packet</ulink></para></footnote>:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>1: Disable desktop wallpaper.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>2: Disable full-window drag (only the window outline is displayed when the window is moved).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>4: Disable menu animations.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>8: Disable user interface themes.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>32: Disable mouse cursor shadows.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>64: Disable cursor blinking.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>128: Enable font smoothing.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>256: Enable Desktop Composition.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable compression.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--app</term>
|
||||
<listitem>
|
||||
<para>
|
||||
initialize a RemoteApp connection. This implies -g workarea.
|
||||
FIXME: How to do RemoteApp
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--ext</term>
|
||||
<listitem>
|
||||
<para>
|
||||
load an extension
|
||||
FIXME: How to do this
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-auth</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-fastpath</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disables fast-path. Use slow-path packets instead, which have larger headers.
|
||||
It might be good for debugging certain issues when you suspect it might be
|
||||
linked to the parsing of one of the two header types.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-osb</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable off screen bitmaps.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--plugin</term>
|
||||
<listitem>
|
||||
<para>
|
||||
load a plugin
|
||||
FIXME: How to do this
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--rfx</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable RemoteFX.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-rdp</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable Standard RDP encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-tls</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable TLS encryption.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--no-nla</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable network level authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--sec <replaceable class="parameter">proto</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
force protocol security. <replaceable class="parameter">proto</replaceable> can be one of rdp, tls or nla.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print version information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<!-- refsect1>
|
||||
<title>USAGE</title>
|
||||
<para>
|
||||
<command>foo</command> -f foo.conf -d2 foodata.foo
|
||||
</para>
|
||||
</refsect1 -->
|
||||
<!-- refsect1>
|
||||
<title>CAVEATS</title>
|
||||
<para>
|
||||
Other programs named <command>foo</command> may exist and actually
|
||||
do something!
|
||||
</para>
|
||||
</refsect1 -->
|
||||
<!-- refsect1>
|
||||
<title>BUGS</title>
|
||||
<para>
|
||||
None. Program does nothing.
|
||||
</para>
|
||||
</refsect1 -->
|
||||
<refsect1>
|
||||
<title>LINKS</title>
|
||||
<para>
|
||||
<ulink url="http://www.freerdp.com/">http://www.freerdp.com/</ulink>
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
@ -718,7 +718,7 @@ int main(int argc, char* argv[])
|
||||
chanman = freerdp_chanman_new();
|
||||
SET_CHANMAN(instance, chanman);
|
||||
|
||||
instance->settings->sw_gdi = False;
|
||||
instance->settings->sw_gdi = True;
|
||||
|
||||
if (freerdp_parse_args(instance->settings, argc, argv,
|
||||
xf_process_plugin_args, chanman, xf_process_ui_args, NULL) < 0)
|
||||
|
@ -9,5 +9,6 @@ option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." OFF)
|
||||
option(WITH_DEBUG_LICENSE "Print license debug messages." OFF)
|
||||
option(WITH_DEBUG_GDI "Print graphics debug messages." OFF)
|
||||
option(WITH_DEBUG_RFX "Print RemoteFX debug messages." OFF)
|
||||
option(WITH_MANPAGES "Generate manpages." ON)
|
||||
option(WITH_PROFILER "Compile profiler." OFF)
|
||||
option(WITH_SSE2 "Use SSE2 optimization." OFF)
|
||||
|
@ -28,22 +28,22 @@
|
||||
# limitations under the License.
|
||||
#=============================================================================
|
||||
|
||||
find_path(Xext_INCLUDE_DIR NAMES Xext.h
|
||||
find_path(XEXT_INCLUDE_DIR NAMES Xext.h
|
||||
PATH_SUFFIXES X11/extensions
|
||||
DOC "The Xext include directory"
|
||||
)
|
||||
|
||||
find_library(Xext_LIBRARY NAMES Xext
|
||||
find_library(XEXT_LIBRARY NAMES Xext
|
||||
DOC "The Xext library"
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xext DEFAULT_MSG Xext_LIBRARY Xext_INCLUDE_DIR)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(XEXT DEFAULT_MSG XEXT_LIBRARY XEXT_INCLUDE_DIR)
|
||||
|
||||
if(Xext_FOUND)
|
||||
set( Xext_LIBRARIES ${Xext_LIBRARY} )
|
||||
set( Xext_INCLUDE_DIRS ${Xext_INCLUDE_DIR} )
|
||||
if(XEXT_FOUND)
|
||||
set( XEXT_LIBRARIES ${XEXT_LIBRARY} )
|
||||
set( XEXT_INCLUDE_DIRS ${XEXT_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
mark_as_advanced(Xext_INCLUDE_DIR Xext_LIBRARY)
|
||||
mark_as_advanced(XEXT_INCLUDE_DIR XEXT_LIBRARY)
|
||||
|
||||
|
35
cmake/FindXmlto.cmake
Normal file
35
cmake/FindXmlto.cmake
Normal file
@ -0,0 +1,35 @@
|
||||
# - Find xmlto
|
||||
# Find the xmlto docbook xslt frontend
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# XMLTO_FOUND - True if xmlto was found
|
||||
# XMLTO_EXECUTABLE - Path to xmlto, if xmlto was found
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nils Andresen <nils@nils-andresen.de>
|
||||
#
|
||||
# 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(XMLTO_FOUND false)
|
||||
|
||||
find_program(XMLTO_EXECUTABLE
|
||||
NAMES xmlto
|
||||
DOC "docbook xslt frontend")
|
||||
|
||||
if(XMLTO_EXECUTABLE)
|
||||
set(XMLTO_FOUND true)
|
||||
message(STATUS "Found XMLTO: ${XMLTO_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(XMLTO_EXECUTABLE)
|
@ -44,6 +44,8 @@ add_executable(test_freerdp
|
||||
test_list.h
|
||||
test_orders.c
|
||||
test_orders.h
|
||||
test_pcap.c
|
||||
test_pcap.h
|
||||
test_license.c
|
||||
test_license.h
|
||||
test_stream.c
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "test_librfx.h"
|
||||
#include "test_freerdp.h"
|
||||
#include "test_rail.h"
|
||||
#include "test_pcap.h"
|
||||
|
||||
void dump_data(unsigned char * p, int len, int width, char* name)
|
||||
{
|
||||
@ -188,6 +189,10 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
add_per_suite();
|
||||
}
|
||||
else if (strcmp("pcap", argv[*pindex]) == 0)
|
||||
{
|
||||
add_pcap_suite();
|
||||
}
|
||||
else if (strcmp("ber", argv[*pindex]) == 0)
|
||||
{
|
||||
add_ber_suite();
|
||||
|
99
cunit/test_pcap.c
Normal file
99
cunit/test_pcap.c
Normal file
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* pcap File Format 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 <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/hexdump.h>
|
||||
#include <freerdp/utils/pcap.h>
|
||||
|
||||
#include "test_pcap.h"
|
||||
|
||||
int init_pcap_suite(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clean_pcap_suite(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_pcap_suite(void)
|
||||
{
|
||||
add_test_suite(pcap);
|
||||
|
||||
add_test_function(pcap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 test_packet_1[16] =
|
||||
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
|
||||
|
||||
uint8 test_packet_2[32] =
|
||||
"\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
|
||||
"\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB";
|
||||
|
||||
uint8 test_packet_3[64] =
|
||||
"\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
|
||||
"\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
|
||||
"\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
|
||||
"\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC";
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* data;
|
||||
uint32 length;
|
||||
} test_packet;
|
||||
|
||||
void test_pcap(void)
|
||||
{
|
||||
rdpPcap* pcap;
|
||||
pcap_record record;
|
||||
test_packet packets[3];
|
||||
|
||||
packets[0].data = test_packet_1;
|
||||
packets[0].length = sizeof(test_packet_1);
|
||||
packets[1].data = test_packet_2;
|
||||
packets[1].length = sizeof(test_packet_2);
|
||||
packets[2].data = test_packet_3;
|
||||
packets[2].length = sizeof(test_packet_3);
|
||||
|
||||
pcap = pcap_open("/tmp/test.pcap", True);
|
||||
pcap_add_record(pcap, test_packet_1, sizeof(test_packet_1));
|
||||
pcap_flush(pcap);
|
||||
pcap_add_record(pcap, test_packet_2, sizeof(test_packet_2));
|
||||
pcap_flush(pcap);
|
||||
pcap_add_record(pcap, test_packet_3, sizeof(test_packet_3));
|
||||
pcap_close(pcap);
|
||||
|
||||
pcap = pcap_open("/tmp/test.pcap", False);
|
||||
|
||||
int i = 0;
|
||||
while (pcap_has_next_record(pcap))
|
||||
{
|
||||
pcap_get_next_record(pcap, &record);
|
||||
CU_ASSERT(record.length == packets[i].length)
|
||||
i++;
|
||||
}
|
||||
|
||||
CU_ASSERT(i == 3);
|
||||
|
||||
pcap_close(pcap);
|
||||
}
|
||||
|
26
cunit/test_pcap.h
Normal file
26
cunit/test_pcap.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* pcap File Format 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_pcap_suite(void);
|
||||
int clean_pcap_suite(void);
|
||||
int add_pcap_suite(void);
|
||||
|
||||
void test_pcap(void);
|
@ -17,5 +17,5 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
file(GLOB HEADERS "freerdp/*.h")
|
||||
file(GLOB HEADERS "freerdp/*")
|
||||
install_files(/include/freerdp FILES ${HEADERS})
|
||||
|
@ -40,6 +40,7 @@ typedef void (*railShowWindow)(rdpRail* rail, rdpWindow* window, uint8 state);
|
||||
typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window);
|
||||
typedef void (*railSetWindowIcon)(rdpRail* rail, rdpWindow* window, rdpIcon* icon);
|
||||
typedef void (*railSetWindowRects)(rdpRail* rail, rdpWindow* window);
|
||||
typedef void (*railSetWindowVisibilityRects)(rdpRail* rail, rdpWindow* window);
|
||||
|
||||
struct rdp_rail
|
||||
{
|
||||
@ -56,6 +57,7 @@ struct rdp_rail
|
||||
railSetWindowText SetWindowText;
|
||||
railSetWindowIcon SetWindowIcon;
|
||||
railSetWindowRects SetWindowRects;
|
||||
railSetWindowVisibilityRects SetWindowVisibilityRects;
|
||||
};
|
||||
|
||||
FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update);
|
||||
|
@ -297,6 +297,11 @@ struct rdp_settings
|
||||
uint8 rfx_codec_id;
|
||||
boolean frame_acknowledge;
|
||||
|
||||
boolean dump_rfx;
|
||||
boolean play_rfx;
|
||||
char* dump_rfx_file;
|
||||
char* play_rfx_file;
|
||||
|
||||
boolean remote_app;
|
||||
uint8 num_icon_caches;
|
||||
uint16 num_icon_cache_entries;
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/pcap.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
/* Common */
|
||||
|
||||
@ -1063,6 +1065,7 @@ typedef void (*pcMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderIn
|
||||
typedef void (*pcNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo);
|
||||
|
||||
typedef void (*pcSurfaceBits)(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command);
|
||||
typedef void (*pcSurfaceCommand)(rdpUpdate* update, STREAM* s);
|
||||
|
||||
struct rdp_update
|
||||
{
|
||||
@ -1072,6 +1075,10 @@ struct rdp_update
|
||||
void* param1;
|
||||
void* param2;
|
||||
|
||||
boolean dump_rfx;
|
||||
boolean play_rfx;
|
||||
rdpPcap* pcap_rfx;
|
||||
|
||||
pcBeginPaint BeginPaint;
|
||||
pcEndPaint EndPaint;
|
||||
pcSetBounds SetBounds;
|
||||
@ -1142,6 +1149,7 @@ struct rdp_update
|
||||
pcNonMonitoredDesktop NonMonitoredDesktop;
|
||||
|
||||
pcSurfaceBits SurfaceBits;
|
||||
pcSurfaceCommand SurfaceCommand;
|
||||
|
||||
BITMAP_UPDATE bitmap_update;
|
||||
PALETTE_UPDATE palette_update;
|
||||
|
42
include/freerdp/utils/certstore.h
Normal file
42
include/freerdp/utils/certstore.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef __CERTSTORE_UTILS_H
|
||||
#define __CERTSTORE_UTILS_H
|
||||
|
||||
typedef struct rdp_certstore rdpCertstore;
|
||||
typedef struct rdp_certdata rdpCertdata;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
struct rdp_certdata
|
||||
{
|
||||
char* thumbprint;
|
||||
char* hostname;
|
||||
};
|
||||
|
||||
struct rdp_certstore
|
||||
{
|
||||
FILE* fp;
|
||||
char* path;
|
||||
char* file;
|
||||
char* home;
|
||||
int match;
|
||||
struct rdp_certdata* certdata;
|
||||
};
|
||||
|
||||
void certstore_create(rdpCertstore* certstore);
|
||||
void certstore_open(rdpCertstore* certstore);
|
||||
void certstore_load(rdpCertstore* certstore);
|
||||
void certstore_close(rdpCertstore* certstore);
|
||||
char* get_local_certloc();
|
||||
rdpCertdata* certdata_new(char* host_name,char* fingerprint);
|
||||
void certdata_free(rdpCertdata* certdata);
|
||||
void certstore_init(rdpCertstore* certstore);
|
||||
rdpCertstore* certstore_new(rdpCertdata* certdata);
|
||||
void certstore_free(rdpCertstore* certstore);
|
||||
int match_certdata(rdpCertstore* certstore);
|
||||
void print_certdata(rdpCertstore* certstore);
|
||||
#endif /* __CERTSTORE_UTILS_H */
|
83
include/freerdp/utils/pcap.h
Normal file
83
include/freerdp/utils/pcap.h
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* pcap File Format Utils
|
||||
*
|
||||
* 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 __UTILS_PCAP_H
|
||||
#define __UTILS_PCAP_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/stopwatch.h>
|
||||
|
||||
struct _pcap_header
|
||||
{
|
||||
uint32 magic_number; /* magic number */
|
||||
uint16 version_major; /* major version number */
|
||||
uint16 version_minor; /* minor version number */
|
||||
sint32 thiszone; /* GMT to local correction */
|
||||
uint32 sigfigs; /* accuracy of timestamps */
|
||||
uint32 snaplen; /* max length of captured packets, in octets */
|
||||
uint32 network; /* data link type */
|
||||
};
|
||||
typedef struct _pcap_header pcap_header;
|
||||
|
||||
struct _pcap_record_header
|
||||
{
|
||||
uint32 ts_sec; /* timestamp seconds */
|
||||
uint32 ts_usec; /* timestamp microseconds */
|
||||
uint32 incl_len; /* number of octets of packet saved in file */
|
||||
uint32 orig_len; /* actual length of packet */
|
||||
};
|
||||
typedef struct _pcap_record_header pcap_record_header;
|
||||
|
||||
typedef struct _pcap_record pcap_record;
|
||||
|
||||
struct _pcap_record
|
||||
{
|
||||
pcap_record_header header;
|
||||
void* data;
|
||||
uint32 length;
|
||||
pcap_record* next;
|
||||
};
|
||||
|
||||
struct rdp_pcap
|
||||
{
|
||||
FILE* fp;
|
||||
char* name;
|
||||
STOPWATCH* sw;
|
||||
boolean write;
|
||||
int file_size;
|
||||
int record_count;
|
||||
pcap_header header;
|
||||
pcap_record* head;
|
||||
pcap_record* tail;
|
||||
pcap_record* record;
|
||||
};
|
||||
typedef struct rdp_pcap rdpPcap;
|
||||
|
||||
FREERDP_API rdpPcap* pcap_open(char* name, boolean write);
|
||||
FREERDP_API void pcap_close(rdpPcap* pcap);
|
||||
|
||||
FREERDP_API void pcap_add_record(rdpPcap* pcap, void* data, uint32 length);
|
||||
FREERDP_API boolean pcap_has_next_record(rdpPcap* pcap);
|
||||
FREERDP_API boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record);
|
||||
FREERDP_API boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record);
|
||||
FREERDP_API boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record);
|
||||
FREERDP_API void pcap_flush(rdpPcap* pcap);
|
||||
|
||||
#endif /* __UTILS_PCAP_H */
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <time.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
struct _STOPWATCH
|
||||
@ -40,6 +41,7 @@ FREERDP_API void stopwatch_start(STOPWATCH* stopwatch);
|
||||
FREERDP_API void stopwatch_stop(STOPWATCH* stopwatch);
|
||||
FREERDP_API void stopwatch_reset(STOPWATCH* stopwatch);
|
||||
|
||||
double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch);
|
||||
FREERDP_API double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch);
|
||||
FREERDP_API void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, uint32* sec, uint32* usec);
|
||||
|
||||
#endif /* __UTILS_STOPWATCH_H */
|
||||
|
@ -1371,6 +1371,10 @@ void rdp_read_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
|
||||
*/
|
||||
void rdp_write_rfx_client_capability_container(STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
uint16 captureFlags;
|
||||
|
||||
captureFlags = settings->dump_rfx ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
|
||||
|
||||
stream_write_uint16(s, 49); /* codecPropertiesLength */
|
||||
|
||||
/* TS_RFX_CLNT_CAPS_CONTAINER */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@ -25,7 +25,6 @@
|
||||
#include "ntlmssp.h"
|
||||
|
||||
#include "credssp.h"
|
||||
|
||||
/**
|
||||
* TSRequest ::= SEQUENCE {
|
||||
* version [0] INTEGER,
|
||||
@ -109,7 +108,7 @@ int credssp_get_public_key(rdpCredssp* credssp)
|
||||
{
|
||||
int ret;
|
||||
CryptoCert cert;
|
||||
|
||||
|
||||
cert = tls_get_certificate(credssp->transport->tls);
|
||||
|
||||
if (cert == NULL)
|
||||
@ -117,7 +116,8 @@ int credssp_get_public_key(rdpCredssp* credssp)
|
||||
printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tls_verify_certificate(cert,credssp->transport->settings->hostname))
|
||||
tls_disconnect(credssp->transport->tls);
|
||||
ret = crypto_cert_get_public_key(cert, &credssp->public_key);
|
||||
crypto_cert_free(cert);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@ -189,3 +189,113 @@ void crypto_nonce(uint8* nonce, int size)
|
||||
{
|
||||
RAND_bytes((void*) nonce, size);
|
||||
}
|
||||
|
||||
char* crypto_cert_fingerprint(X509* xcert)
|
||||
{
|
||||
char* p;
|
||||
int i = 0;
|
||||
char* fp_buffer;
|
||||
unsigned int fp_len;
|
||||
unsigned char fp[EVP_MAX_MD_SIZE];
|
||||
|
||||
X509_digest(xcert, EVP_sha1(), fp, &fp_len);
|
||||
|
||||
fp_buffer = xzalloc(3 * fp_len);
|
||||
p = fp_buffer;
|
||||
|
||||
for (i = 0; i < fp_len - 1; i++)
|
||||
{
|
||||
sprintf(p, "%02x:", fp[i]);
|
||||
p = (char*) &fp_buffer[i * 3];
|
||||
}
|
||||
sprintf(p, "%02x", fp[i]);
|
||||
|
||||
return fp_buffer;
|
||||
}
|
||||
|
||||
boolean x509_verify_cert(CryptoCert cert)
|
||||
{
|
||||
char* cert_loc;
|
||||
X509_STORE_CTX* csc;
|
||||
boolean status = False;
|
||||
X509_STORE* cert_ctx = NULL;
|
||||
X509_LOOKUP* lookup = NULL;
|
||||
X509* xcert = cert->px509;
|
||||
|
||||
cert_ctx = X509_STORE_new();
|
||||
|
||||
if (cert_ctx == NULL)
|
||||
goto end;
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
|
||||
|
||||
if (lookup == NULL)
|
||||
goto end;
|
||||
|
||||
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
|
||||
|
||||
if (lookup == NULL)
|
||||
goto end;
|
||||
|
||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
|
||||
cert_loc = get_local_certloc();
|
||||
|
||||
if(cert_loc != NULL)
|
||||
{
|
||||
X509_LOOKUP_add_dir(lookup, cert_loc, X509_FILETYPE_ASN1);
|
||||
xfree(cert_loc);
|
||||
}
|
||||
|
||||
csc = X509_STORE_CTX_new();
|
||||
|
||||
if (csc == NULL)
|
||||
goto end;
|
||||
|
||||
X509_STORE_set_flags(cert_ctx, 0);
|
||||
|
||||
if(!X509_STORE_CTX_init(csc, cert_ctx, xcert, 0))
|
||||
goto end;
|
||||
|
||||
if (X509_verify_cert(csc) == 1)
|
||||
status = True;
|
||||
|
||||
X509_STORE_CTX_free(csc);
|
||||
X509_STORE_free(cert_ctx);
|
||||
|
||||
end:
|
||||
return status;
|
||||
}
|
||||
|
||||
rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname)
|
||||
{
|
||||
char* fp;
|
||||
rdpCertdata* certdata;
|
||||
|
||||
fp = crypto_cert_fingerprint(xcert);
|
||||
certdata = certdata_new(hostname, fp);
|
||||
xfree(fp);
|
||||
|
||||
return certdata;
|
||||
}
|
||||
|
||||
void crypto_cert_printinfo(X509* xcert)
|
||||
{
|
||||
char* fp;
|
||||
char* issuer;
|
||||
char* subject;
|
||||
|
||||
subject = X509_NAME_oneline(X509_get_subject_name(xcert), NULL, 0);
|
||||
issuer = X509_NAME_oneline(X509_get_issuer_name(xcert), NULL, 0);
|
||||
fp = crypto_cert_fingerprint(xcert);
|
||||
|
||||
printf("Certificate details:\n");
|
||||
printf("\tSubject: %s\n", subject);
|
||||
printf("\tIssuer: %s\n", issuer);
|
||||
printf("\tThumbprint: %s\n", fp);
|
||||
printf("The above X.509 certificate could not be verified, possibly because you do not have "
|
||||
"the CA certificate in your certificate store, or the certificate has expired."
|
||||
"Please look at the documentation on how to create local certificate store for a private CA.\n");
|
||||
|
||||
xfree(fp);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/blob.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/certstore.h>
|
||||
|
||||
struct crypto_sha1_struct
|
||||
{
|
||||
@ -83,8 +84,12 @@ void crypto_rc4_free(CryptoRc4 rc4);
|
||||
|
||||
typedef struct crypto_cert_struct* CryptoCert;
|
||||
CryptoCert crypto_cert_read(uint8* data, uint32 length);
|
||||
char* cypto_cert_fingerprint(X509* xcert);
|
||||
void crypto_cert_printinfo(X509* xcert);
|
||||
void crypto_cert_free(CryptoCert cert);
|
||||
boolean x509_verify_cert(CryptoCert cert);
|
||||
boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert);
|
||||
rdpCertdata* crypto_get_certdata(X509* xcert, char* hostname);
|
||||
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key);
|
||||
|
||||
void crypto_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output);
|
||||
|
@ -73,6 +73,26 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
|
||||
return length;
|
||||
}
|
||||
|
||||
inline void fastpath_read_update_header(STREAM* s, uint8* updateCode, uint8* fragmentation, uint8* compression)
|
||||
{
|
||||
uint8 updateHeader;
|
||||
|
||||
stream_read_uint8(s, updateHeader);
|
||||
*updateCode = updateHeader & 0x0F;
|
||||
*fragmentation = (updateHeader >> 4) & 0x03;
|
||||
*compression = (updateHeader >> 6) & 0x03;
|
||||
}
|
||||
|
||||
inline void fastpath_write_update_header(STREAM* s, uint8 updateCode, uint8 fragmentation, uint8 compression)
|
||||
{
|
||||
uint8 updateHeader = 0;
|
||||
|
||||
updateHeader |= updateCode & 0x0F;
|
||||
updateHeader |= (fragmentation & 0x03) << 4;
|
||||
updateHeader |= (compression & 0x03) << 6;
|
||||
stream_write_uint8(s, updateHeader);
|
||||
}
|
||||
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
/* TODO: fipsInformation */
|
||||
@ -122,7 +142,7 @@ static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s)
|
||||
}
|
||||
}
|
||||
|
||||
static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16 size, STREAM* s)
|
||||
static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32 size, STREAM* s)
|
||||
{
|
||||
switch (updateCode)
|
||||
{
|
||||
@ -175,19 +195,16 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16
|
||||
|
||||
static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 updateHeader;
|
||||
uint16 size;
|
||||
int next_pos;
|
||||
uint32 totalSize;
|
||||
uint8 updateCode;
|
||||
uint8 fragmentation;
|
||||
uint8 compression;
|
||||
uint8 compressionFlags;
|
||||
uint16 size;
|
||||
STREAM* update_stream;
|
||||
int next_pos;
|
||||
|
||||
stream_read_uint8(s, updateHeader);
|
||||
updateCode = updateHeader & 0x0F;
|
||||
fragmentation = (updateHeader >> 4) & 0x03;
|
||||
compression = (updateHeader >> 6) & 0x03;
|
||||
fastpath_read_update_header(s, &updateCode, &fragmentation, &compression);
|
||||
|
||||
if (compression == FASTPATH_OUTPUT_COMPRESSION_USED)
|
||||
stream_read_uint8(s, compressionFlags);
|
||||
@ -207,6 +224,7 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
update_stream = NULL;
|
||||
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
||||
{
|
||||
totalSize = size;
|
||||
update_stream = s;
|
||||
}
|
||||
else
|
||||
@ -220,13 +238,13 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
||||
if (fragmentation == FASTPATH_FRAGMENT_LAST)
|
||||
{
|
||||
update_stream = fastpath->updateData;
|
||||
size = stream_get_length(update_stream);
|
||||
totalSize = stream_get_length(update_stream);
|
||||
stream_set_pos(update_stream, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (update_stream)
|
||||
fastpath_recv_update(fastpath, updateCode, size, update_stream);
|
||||
fastpath_recv_update(fastpath, updateCode, totalSize, update_stream);
|
||||
|
||||
stream_set_pos(s, next_pos);
|
||||
}
|
||||
@ -394,7 +412,7 @@ boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
/**
|
||||
* If numberEvents is not provided in fpInputHeader, it will be provided
|
||||
* as onee additional byte here.
|
||||
* as one additional byte here.
|
||||
*/
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
@ -457,9 +475,10 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
uint16 length;
|
||||
|
||||
length = stream_get_length(s);
|
||||
|
||||
if (length > FASTPATH_MAX_PACKET_SIZE)
|
||||
{
|
||||
printf("Maximum FastPath Update PDU length is %d\n", FASTPATH_MAX_PACKET_SIZE);
|
||||
printf("Maximum FastPath Update PDU length is %d (actual:%d)\n", FASTPATH_MAX_PACKET_SIZE, length);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -475,6 +494,41 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
int fragment;
|
||||
uint16 length;
|
||||
uint16 maxLength;
|
||||
uint32 totalLength;
|
||||
uint8 fragmentation;
|
||||
STREAM* update;
|
||||
|
||||
maxLength = FASTPATH_MAX_PACKET_SIZE - 6;
|
||||
totalLength = stream_get_length(s);
|
||||
stream_set_pos(s, 0);
|
||||
|
||||
for (fragment = 0; totalLength > 0; fragment++)
|
||||
{
|
||||
update = fastpath_update_pdu_init(fastpath);
|
||||
length = MIN(maxLength, totalLength);
|
||||
totalLength -= length;
|
||||
|
||||
if (totalLength == 0)
|
||||
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST;
|
||||
else
|
||||
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT;
|
||||
|
||||
fastpath_write_update_header(update, FASTPATH_UPDATETYPE_SURFCMDS, fragmentation, 0);
|
||||
stream_write_uint16(update, length);
|
||||
stream_write(update, s->p, length);
|
||||
stream_seek(s, length);
|
||||
|
||||
fastpath_send_update_pdu(fastpath, update);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, uint16 frameAction, uint32 frameId)
|
||||
{
|
||||
STREAM* s;
|
||||
@ -520,19 +574,17 @@ boolean fastpath_send_surfcmd_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_C
|
||||
}
|
||||
|
||||
fragment_size = MIN(FASTPATH_MAX_PACKET_SIZE - stream_get_length(s), bitmapDataLength);
|
||||
|
||||
if (fragment_size == bitmapDataLength)
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT);
|
||||
}
|
||||
|
||||
size += fragment_size;
|
||||
|
||||
ep = stream_get_pos(s);
|
||||
stream_set_pos(s, bp);
|
||||
stream_write_uint8(s, FASTPATH_UPDATETYPE_SURFCMDS | (fragmentation << 4));
|
||||
fastpath_write_update_header(s, FASTPATH_UPDATETYPE_SURFCMDS, fragmentation, 0);
|
||||
stream_write_uint16(s, size);
|
||||
stream_set_pos(s, ep);
|
||||
|
||||
|
@ -100,6 +100,7 @@ boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath);
|
||||
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
boolean fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, uint16 frameAction, uint32 frameId);
|
||||
boolean fastpath_send_surfcmd_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "rdp.h"
|
||||
#include "input.h"
|
||||
#include "update.h"
|
||||
#include "surface.h"
|
||||
#include "transport.h"
|
||||
#include "connection.h"
|
||||
|
||||
@ -34,10 +35,51 @@ boolean freerdp_connect(freerdp* instance)
|
||||
rdp = (rdpRdp*) instance->rdp;
|
||||
|
||||
IFCALL(instance->PreConnect, instance);
|
||||
|
||||
status = rdp_client_connect((rdpRdp*) instance->rdp);
|
||||
|
||||
if (status)
|
||||
{
|
||||
if (instance->settings->dump_rfx)
|
||||
{
|
||||
instance->update->dump_rfx = instance->settings->dump_rfx;
|
||||
instance->update->pcap_rfx = pcap_open(instance->settings->dump_rfx_file, True);
|
||||
}
|
||||
|
||||
IFCALL(instance->PostConnect, instance);
|
||||
|
||||
if (instance->settings->play_rfx)
|
||||
{
|
||||
STREAM* s;
|
||||
rdpUpdate* update;
|
||||
pcap_record record;
|
||||
|
||||
s = stream_new(1024);
|
||||
instance->update->play_rfx = instance->settings->play_rfx;
|
||||
instance->update->pcap_rfx = pcap_open(instance->settings->play_rfx_file, False);
|
||||
update = instance->update;
|
||||
|
||||
while (pcap_has_next_record(update->pcap_rfx))
|
||||
{
|
||||
pcap_get_next_record_header(update->pcap_rfx, &record);
|
||||
|
||||
s->data = xrealloc(s->data, record.length);
|
||||
record.data = s->data;
|
||||
s->size = record.length;
|
||||
|
||||
pcap_get_next_record_content(update->pcap_rfx, &record);
|
||||
stream_set_pos(s, 0);
|
||||
|
||||
update->BeginPaint(update);
|
||||
update_recv_surfcmds(update, s->size, s);
|
||||
update->EndPaint(update);
|
||||
}
|
||||
|
||||
xfree(s->data);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <freerdp/utils/pcap.h>
|
||||
|
||||
#include "surface.h"
|
||||
|
||||
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
|
||||
int pos;
|
||||
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
|
||||
|
||||
stream_read_uint16(s, cmd->destLeft);
|
||||
stream_read_uint16(s, cmd->destTop);
|
||||
@ -56,12 +58,16 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
|
||||
return 6;
|
||||
}
|
||||
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s)
|
||||
{
|
||||
uint8* mark;
|
||||
uint16 cmdType;
|
||||
uint32 cmdLength;
|
||||
|
||||
while (size > 2)
|
||||
{
|
||||
stream_get_mark(s, mark);
|
||||
|
||||
stream_read_uint16(s, cmdType);
|
||||
size -= 2;
|
||||
|
||||
@ -69,17 +75,25 @@ boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
|
||||
{
|
||||
case CMDTYPE_SET_SURFACE_BITS:
|
||||
case CMDTYPE_STREAM_SURFACE_BITS:
|
||||
size -= update_recv_surfcmd_surface_bits(update, s);
|
||||
cmdLength = update_recv_surfcmd_surface_bits(update, s);
|
||||
break;
|
||||
|
||||
case CMDTYPE_FRAME_MARKER:
|
||||
size -= update_recv_surfcmd_frame_marker(update, s);
|
||||
cmdLength = update_recv_surfcmd_frame_marker(update, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unknown cmdType 0x%X", cmdType);
|
||||
return False;
|
||||
}
|
||||
|
||||
size -= cmdLength;
|
||||
|
||||
if (update->dump_rfx)
|
||||
{
|
||||
pcap_add_record(update->pcap_rfx, mark, cmdLength + 2);
|
||||
pcap_flush(update->pcap_rfx);
|
||||
}
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ enum SURFCMD_FRAMEACTION
|
||||
SURFACECMD_FRAMEACTION_END = 0x0001
|
||||
};
|
||||
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s);
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s);
|
||||
|
||||
void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
|
||||
void update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId);
|
||||
|
@ -8,7 +8,7 @@
|
||||
* 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
|
||||
* 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,
|
||||
@ -240,7 +240,7 @@ rdpTls* tls_new()
|
||||
tls->connect = tls_connect;
|
||||
tls->accept = tls_accept;
|
||||
tls->disconnect = tls_disconnect;
|
||||
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
}
|
||||
@ -248,6 +248,69 @@ rdpTls* tls_new()
|
||||
return tls;
|
||||
}
|
||||
|
||||
int tls_verify_certificate(CryptoCert cert, char* hostname)
|
||||
{
|
||||
boolean ret;
|
||||
ret = x509_verify_cert(cert);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
rdpCertdata* certdata;
|
||||
certdata = crypto_get_certdata(cert->px509, hostname);
|
||||
rdpCertstore* certstore = certstore_new(certdata);
|
||||
|
||||
if (match_certdata(certstore) == 0)
|
||||
goto end;
|
||||
|
||||
if (certstore->match == 1)
|
||||
{
|
||||
char answer;
|
||||
crypto_cert_printinfo(cert->px509);
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/N) ");
|
||||
answer=fgetc(stdin);
|
||||
|
||||
if(answer=='y' || answer =='Y')
|
||||
{
|
||||
print_certdata(certstore);
|
||||
break;
|
||||
}
|
||||
else if(answer=='n' || answer=='N')
|
||||
{
|
||||
certstore_free(certstore);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (certstore->match == -1)
|
||||
{
|
||||
tls_print_cert_error();
|
||||
certstore_free(certstore);
|
||||
return 1;
|
||||
}
|
||||
|
||||
end:
|
||||
certstore_free(certstore);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tls_print_cert_error()
|
||||
{
|
||||
printf("#####################################\n");
|
||||
printf("##############WARNING################\n");
|
||||
printf("#####################################\n");
|
||||
printf("The thumbprint of certificate received\n");
|
||||
printf("did not match the stored thumbprint.You\n");
|
||||
printf("might be a victim of MAN in the MIDDLE\n");
|
||||
printf("ATTACK.It is also possible that server's\n");
|
||||
printf("certificate have been changed.In that case\n");
|
||||
printf("contact your server administrator\n");
|
||||
}
|
||||
|
||||
void tls_free(rdpTls* tls)
|
||||
{
|
||||
if (tls != NULL)
|
||||
|
@ -49,8 +49,9 @@ 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);
|
||||
int tls_verify_certificate(CryptoCert cert,char* hostname);
|
||||
void tls_print_cert_error();
|
||||
boolean tls_print_error(char* func, SSL* connection, int value);
|
||||
|
||||
rdpTls* tls_new();
|
||||
void tls_free(rdpTls* tls);
|
||||
|
||||
|
@ -322,10 +322,15 @@ static void update_end_paint(rdpUpdate* update)
|
||||
{
|
||||
}
|
||||
|
||||
static void update_send_surface_command(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*) update->rdp;
|
||||
fastpath_send_fragmented_update_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static void update_send_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)update->rdp;
|
||||
|
||||
fastpath_send_surfcmd_surface_bits(rdp->fastpath, surface_bits_command);
|
||||
}
|
||||
|
||||
@ -362,6 +367,7 @@ void update_register_server_callbacks(rdpUpdate* update)
|
||||
update->Synchronize = update_send_synchronize;
|
||||
update->PointerSystem = update_send_pointer_system;
|
||||
update->SurfaceBits = update_send_surface_bits;
|
||||
update->SurfaceCommand = update_send_surface_command;
|
||||
}
|
||||
|
||||
rdpUpdate* update_new(rdpRdp* rdp)
|
||||
|
@ -284,6 +284,10 @@ void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
|
||||
{
|
||||
IFCALL(rail->SetWindowRects, rail, window);
|
||||
}
|
||||
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
|
||||
{
|
||||
IFCALL(rail->SetWindowVisibilityRects, rail, window);
|
||||
}
|
||||
}
|
||||
|
||||
void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
|
||||
@ -356,7 +360,7 @@ void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
|
||||
|
||||
if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
|
||||
{
|
||||
|
||||
IFCALL(rail->SetWindowVisibilityRects, rail, window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,11 @@ set(FREERDP_UTILS_SRCS
|
||||
load_plugin.c
|
||||
memory.c
|
||||
mutex.c
|
||||
pcap.c
|
||||
profiler.c
|
||||
rail.c
|
||||
registry.c
|
||||
certstore.c
|
||||
semaphore.c
|
||||
sleep.c
|
||||
stopwatch.c
|
||||
|
@ -51,7 +51,47 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
|
||||
while (index < argc)
|
||||
{
|
||||
if (strcmp("-a", argv[index]) == 0)
|
||||
if ((strcmp("-h", argv[index]) == 0 ) || (strcmp("--help", argv[index]) == 0 ))
|
||||
{
|
||||
printf("\n"
|
||||
"FreeRDP - A Free Remote Desktop Protocol Client\n"
|
||||
"See http://www.freerdp.com for more information\n"
|
||||
"\n"
|
||||
"Usage: %s [options] server:port\n"
|
||||
" -0: connect to console session\n"
|
||||
" -a: set color depth in bit, default is 16\n"
|
||||
" -c: initial working directory\n"
|
||||
" -D: hide window decorations\n"
|
||||
" -d: domain\n"
|
||||
" -f: fullscreen mode\n"
|
||||
" -g: set geometry, using format WxH or X%% or 'workarea', default is 1024x768\n"
|
||||
" -h: print this help\n"
|
||||
" -k: set keyboard layout ID\n"
|
||||
" -m: don't send mouse motion events\n"
|
||||
" -n: hostname\n"
|
||||
" -o: console audio\n"
|
||||
" -p: password\n"
|
||||
" -s: set startup-shell\n"
|
||||
" -t: alternative port number, default is 3389\n"
|
||||
" -u: username\n"
|
||||
" -x: performance flags (m[odem], b[roadband] or l[an])\n"
|
||||
" -z: enable compression\n"
|
||||
" --app: RemoteApp connection. This implies -g workarea\n"
|
||||
" --ext: load an extension\n"
|
||||
" --no-auth: disable authentication\n"
|
||||
" --no-fastpath: disable fast-path\n"
|
||||
" --no-osb: disable off screen bitmaps, default on\n"
|
||||
" --plugin: load a virtual channel plugin\n"
|
||||
" --rfx: enable RemoteFX\n"
|
||||
" --no-rdp: disable Standard RDP encryption\n"
|
||||
" --no-tls: disable TLS encryption\n"
|
||||
" --no-nla: disable network level authentication\n"
|
||||
" --sec: force protocol security (rdp, tls or nla)\n"
|
||||
" --version: print version information\n"
|
||||
"\n", argv[0]);
|
||||
return -1; //TODO: What is the correct return
|
||||
}
|
||||
else if (strcmp("-a", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
@ -242,6 +282,28 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
settings->performance_flags = PERF_FLAG_NONE;
|
||||
settings->large_pointer = True;
|
||||
}
|
||||
else if (strcmp("--dump-rfx", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing file name\n");
|
||||
return -1;
|
||||
}
|
||||
settings->dump_rfx_file = xstrdup(argv[index]);
|
||||
settings->dump_rfx = True;
|
||||
}
|
||||
else if (strcmp("--play-rfx", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing file name\n");
|
||||
return -1;
|
||||
}
|
||||
settings->play_rfx_file = xstrdup(argv[index]);
|
||||
settings->play_rfx = True;
|
||||
}
|
||||
else if (strcmp("-m", argv[index]) == 0)
|
||||
{
|
||||
settings->mouse_motion = True;
|
||||
|
213
libfreerdp-utils/certstore.c
Normal file
213
libfreerdp-utils/certstore.c
Normal file
@ -0,0 +1,213 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* certstore Utils
|
||||
*
|
||||
* Copyright 2011 Jiten Pathy
|
||||
*
|
||||
* 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/utils/certstore.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static char cert_dir[] = "freerdp";
|
||||
static char cert_loc[] = "cacert";
|
||||
static char certstore_file[] = "known_hosts";
|
||||
|
||||
void certstore_create(rdpCertstore* certstore)
|
||||
{
|
||||
certstore->fp = fopen((char*)certstore->file, "w+");
|
||||
|
||||
if (certstore->fp == NULL)
|
||||
{
|
||||
printf("certstore_create: error opening [%s] for writing\n", certstore->file);
|
||||
return;
|
||||
}
|
||||
fflush(certstore->fp);
|
||||
}
|
||||
|
||||
void certstore_load(rdpCertstore* certstore)
|
||||
{
|
||||
certstore->fp = fopen((char*)certstore->file, "r+");
|
||||
}
|
||||
|
||||
void certstore_open(rdpCertstore* certstore)
|
||||
{
|
||||
struct stat stat_info;
|
||||
|
||||
if (stat((char*)certstore->file, &stat_info) != 0)
|
||||
certstore_create(certstore);
|
||||
else
|
||||
certstore_load(certstore);
|
||||
}
|
||||
|
||||
void certstore_close(rdpCertstore* certstore)
|
||||
{
|
||||
if (certstore->fp != NULL)
|
||||
fclose(certstore->fp);
|
||||
}
|
||||
|
||||
char* get_local_certloc()
|
||||
{
|
||||
char *home_path;
|
||||
char *certloc;
|
||||
struct stat stat_info;
|
||||
home_path=getenv("HOME");
|
||||
certloc=(char*)xmalloc(strlen(home_path)+strlen("/.")+strlen(cert_dir)+strlen("/")+strlen(cert_loc)+1);
|
||||
sprintf(certloc,"%s/.%s/%s",home_path,cert_dir,cert_loc);
|
||||
if(stat((char*)certloc, &stat_info) != 0)
|
||||
mkdir(certloc, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
return certloc;
|
||||
}
|
||||
|
||||
void certstore_init(rdpCertstore* certstore)
|
||||
{
|
||||
int length;
|
||||
char* home_path;
|
||||
struct stat stat_info;
|
||||
|
||||
certstore->match=1;
|
||||
home_path = getenv("HOME");
|
||||
|
||||
if (home_path == NULL)
|
||||
{
|
||||
printf("could not get home path\n");
|
||||
return;
|
||||
}
|
||||
|
||||
certstore->home = (char*) xstrdup(home_path);
|
||||
printf("home path: %s\n", certstore->home);
|
||||
|
||||
certstore->path = (char*) xmalloc(strlen(certstore->home) + strlen("/.") + strlen(cert_dir) + 1);
|
||||
sprintf(certstore->path, "%s/.%s", certstore->home, cert_dir);
|
||||
printf("certstore path: %s\n", certstore->path);
|
||||
|
||||
if (stat(certstore->path, &stat_info) != 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
mkdir(certstore->path, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
#else
|
||||
CreateDirectory(certstore->path, 0);
|
||||
#endif
|
||||
printf("creating directory %s\n", certstore->path);
|
||||
}
|
||||
|
||||
length = strlen(certstore->path);
|
||||
certstore->file = (char*) xmalloc(strlen(certstore->path) + strlen("/") + strlen(certstore_file) + 1);
|
||||
sprintf(certstore->file, "%s/%s", certstore->path, certstore_file);
|
||||
printf("certstore file: %s\n", certstore->file);
|
||||
|
||||
certstore_open(certstore);
|
||||
}
|
||||
|
||||
rdpCertdata* certdata_new(char* host_name,char* fingerprint)
|
||||
{
|
||||
rdpCertdata* certdata=(rdpCertdata*)xzalloc(sizeof(rdpCertdata));
|
||||
if(certdata !=NULL)
|
||||
{
|
||||
certdata->hostname=xzalloc(strlen(host_name)+1);
|
||||
certdata->thumbprint=xzalloc(strlen(fingerprint)+1);
|
||||
sprintf(certdata->hostname,"%s",host_name);
|
||||
sprintf(certdata->thumbprint,"%s",fingerprint);
|
||||
}
|
||||
return certdata;
|
||||
}
|
||||
|
||||
void certdata_free(rdpCertdata* certdata)
|
||||
{
|
||||
if(certdata != NULL)
|
||||
{
|
||||
xfree(certdata->hostname);
|
||||
xfree(certdata->thumbprint);
|
||||
xfree(certdata);
|
||||
}
|
||||
}
|
||||
|
||||
rdpCertstore* certstore_new(rdpCertdata* certdata)
|
||||
{
|
||||
rdpCertstore* certstore = (rdpCertstore*) xzalloc(sizeof(rdpCertstore));
|
||||
|
||||
if (certstore != NULL)
|
||||
{
|
||||
certstore->certdata = certdata;
|
||||
certstore_init(certstore);
|
||||
}
|
||||
|
||||
return certstore;
|
||||
}
|
||||
|
||||
void certstore_free(rdpCertstore* certstore)
|
||||
{
|
||||
if (certstore != NULL)
|
||||
{
|
||||
certstore_close(certstore);
|
||||
xfree(certstore->path);
|
||||
xfree(certstore->file);
|
||||
xfree(certstore->home);
|
||||
certdata_free(certstore->certdata);
|
||||
xfree(certstore);
|
||||
}
|
||||
}
|
||||
|
||||
int match_certdata(rdpCertstore* certstore)
|
||||
{
|
||||
char *host;
|
||||
char *p;
|
||||
char *thumb_print;
|
||||
int length;
|
||||
unsigned char c;
|
||||
FILE* cfp;
|
||||
cfp=certstore->fp;
|
||||
rdpCertdata* cert_data=certstore->certdata;
|
||||
length=strlen(cert_data->thumbprint);
|
||||
host=xzalloc(strlen(cert_data->hostname)+1);
|
||||
for(;;)
|
||||
{
|
||||
if((int)fread(host,sizeof(char),strlen(cert_data->hostname),cfp) < strlen(cert_data->hostname))
|
||||
break;
|
||||
if((!strcmp(host,cert_data->hostname)) && ((c=fgetc(cfp))==' ' || c=='\t') )
|
||||
{
|
||||
ungetc(c,cfp);
|
||||
while((c=fgetc(cfp))==' ' || c=='\t');
|
||||
if(c==EOF)
|
||||
break;
|
||||
ungetc(c,cfp);
|
||||
thumb_print=xzalloc(length+1);
|
||||
p=thumb_print;
|
||||
while((p-thumb_print) < length && (*p=fgetc(cfp))!=EOF && *p!='\n' && *p==*(cert_data->thumbprint+(p-thumb_print)))
|
||||
p++;
|
||||
if(p-thumb_print==length)
|
||||
certstore->match=0;
|
||||
else
|
||||
certstore->match=-1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(c!='\n' && c!=EOF)
|
||||
c=fgetc(cfp);
|
||||
if(c==EOF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
xfree(host);
|
||||
return certstore->match;
|
||||
}
|
||||
void print_certdata(rdpCertstore* certstore)
|
||||
{
|
||||
fseek(certstore->fp,0,SEEK_END);
|
||||
fprintf(certstore->fp,"%s %s\n",certstore->certdata->hostname,certstore->certdata->thumbprint);
|
||||
}
|
193
libfreerdp-utils/pcap.c
Normal file
193
libfreerdp-utils/pcap.c
Normal file
@ -0,0 +1,193 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* pcap File Format Utils
|
||||
*
|
||||
* 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 <time.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/utils/pcap.h>
|
||||
|
||||
#define PCAP_MAGIC 0xA1B2C3D4
|
||||
|
||||
void pcap_read_header(rdpPcap* pcap, pcap_header* header)
|
||||
{
|
||||
fread((void*) header, sizeof(pcap_header), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_write_header(rdpPcap* pcap, pcap_header* header)
|
||||
{
|
||||
fwrite((void*) header, sizeof(pcap_header), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_read_record_header(rdpPcap* pcap, pcap_record_header* record)
|
||||
{
|
||||
fread((void*) record, sizeof(pcap_record_header), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_write_record_header(rdpPcap* pcap, pcap_record_header* record)
|
||||
{
|
||||
fwrite((void*) record, sizeof(pcap_record_header), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_read_record(rdpPcap* pcap, pcap_record* record)
|
||||
{
|
||||
pcap_read_record_header(pcap, &record->header);
|
||||
record->length = record->header.incl_len;
|
||||
record->data = xmalloc(record->length);
|
||||
fread(record->data, record->length, 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_write_record(rdpPcap* pcap, pcap_record* record)
|
||||
{
|
||||
pcap_write_record_header(pcap, &record->header);
|
||||
fwrite(record->data, record->length, 1, pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_add_record(rdpPcap* pcap, void* data, uint32 length)
|
||||
{
|
||||
pcap_record* record;
|
||||
|
||||
if (pcap->tail == NULL)
|
||||
{
|
||||
pcap->tail = (pcap_record*) xzalloc(sizeof(pcap_record));
|
||||
pcap->head = pcap->tail;
|
||||
pcap->record = pcap->head;
|
||||
record = pcap->tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
record = (pcap_record*) xzalloc(sizeof(pcap_record));
|
||||
pcap->tail->next = record;
|
||||
pcap->tail = record;
|
||||
}
|
||||
|
||||
if (pcap->record == NULL)
|
||||
pcap->record = record;
|
||||
|
||||
record->data = data;
|
||||
record->length = length;
|
||||
record->header.incl_len = length;
|
||||
record->header.orig_len = length;
|
||||
|
||||
stopwatch_stop(pcap->sw);
|
||||
stopwatch_get_elapsed_time_in_useconds(pcap->sw, &record->header.ts_sec, &record->header.ts_usec);
|
||||
stopwatch_start(pcap->sw);
|
||||
}
|
||||
|
||||
boolean pcap_has_next_record(rdpPcap* pcap)
|
||||
{
|
||||
if (pcap->file_size - (ftell(pcap->fp)) <= 16)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record)
|
||||
{
|
||||
if (pcap_has_next_record(pcap) != True)
|
||||
return False;
|
||||
|
||||
pcap_read_record_header(pcap, &record->header);
|
||||
record->length = record->header.incl_len;
|
||||
record->data = xmalloc(record->length);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record)
|
||||
{
|
||||
fread(record->data, record->length, 1, pcap->fp);
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record)
|
||||
{
|
||||
if (pcap_has_next_record(pcap) != True)
|
||||
return False;
|
||||
|
||||
pcap_read_record(pcap, record);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
rdpPcap* pcap_open(char* name, boolean write)
|
||||
{
|
||||
rdpPcap* pcap;
|
||||
|
||||
pcap = (rdpPcap*) xzalloc(sizeof(rdpPcap));
|
||||
|
||||
if (pcap != NULL)
|
||||
{
|
||||
pcap->name = name;
|
||||
pcap->write = write;
|
||||
pcap->record_count = 0;
|
||||
|
||||
if (write)
|
||||
{
|
||||
pcap->fp = fopen(name, "w+");
|
||||
pcap->header.magic_number = 0xA1B2C3D4;
|
||||
pcap->header.version_major = 2;
|
||||
pcap->header.version_minor = 4;
|
||||
pcap->header.thiszone = 0;
|
||||
pcap->header.sigfigs = 0;
|
||||
pcap->header.snaplen = 0xFFFFFFFF;
|
||||
pcap->header.network = 0;
|
||||
pcap_write_header(pcap, &pcap->header);
|
||||
}
|
||||
else
|
||||
{
|
||||
pcap->fp = fopen(name, "r");
|
||||
fseek(pcap->fp, 0, SEEK_END);
|
||||
pcap->file_size = (int) ftell(pcap->fp);
|
||||
fseek(pcap->fp, 0, SEEK_SET);
|
||||
pcap_read_header(pcap, &pcap->header);
|
||||
}
|
||||
|
||||
pcap->sw = stopwatch_create();
|
||||
stopwatch_start(pcap->sw);
|
||||
}
|
||||
|
||||
return pcap;
|
||||
}
|
||||
|
||||
void pcap_flush(rdpPcap* pcap)
|
||||
{
|
||||
while (pcap->record != NULL)
|
||||
{
|
||||
pcap_write_record(pcap, pcap->record);
|
||||
pcap->record = pcap->record->next;
|
||||
}
|
||||
|
||||
if (pcap->fp != NULL)
|
||||
fflush(pcap->fp);
|
||||
}
|
||||
|
||||
void pcap_close(rdpPcap* pcap)
|
||||
{
|
||||
pcap_flush(pcap);
|
||||
|
||||
if (pcap->fp != NULL)
|
||||
fclose(pcap->fp);
|
||||
|
||||
stopwatch_stop(pcap->sw);
|
||||
stopwatch_free(pcap->sw);
|
||||
}
|
@ -56,5 +56,15 @@ void stopwatch_reset(STOPWATCH* stopwatch)
|
||||
|
||||
double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch)
|
||||
{
|
||||
return ((double)stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, uint32* sec, uint32* usec)
|
||||
{
|
||||
double uelapsed;
|
||||
|
||||
*sec = ((uint32) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC);
|
||||
*usec = (uelapsed / (CLOCKS_PER_SEC / 1000000));
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
#include <freerdp/listener.h>
|
||||
|
||||
static char* test_pcap_file = NULL;
|
||||
|
||||
/* HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3 */
|
||||
static const unsigned int test_quantization_values[] =
|
||||
{
|
||||
@ -183,6 +185,8 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
|
||||
RFX_RECT rect;
|
||||
STREAM* s;
|
||||
|
||||
if (client->update->dump_rfx)
|
||||
return;
|
||||
if (!client->settings->rfx_codec || !info)
|
||||
return;
|
||||
if (info->icon_width < 1)
|
||||
@ -232,6 +236,33 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
|
||||
info->icon_y = y;
|
||||
}
|
||||
|
||||
void test_peer_dump_rfx(freerdp_peer* client)
|
||||
{
|
||||
STREAM* s;
|
||||
rdpUpdate* update;
|
||||
rdpPcap* pcap_rfx;
|
||||
pcap_record record;
|
||||
|
||||
s = stream_new(512);
|
||||
update = client->update;
|
||||
client->update->pcap_rfx = pcap_open(test_pcap_file, False);
|
||||
pcap_rfx = client->update->pcap_rfx;
|
||||
|
||||
while (pcap_has_next_record(pcap_rfx))
|
||||
{
|
||||
pcap_get_next_record_header(pcap_rfx, &record);
|
||||
|
||||
s->data = xrealloc(s->data, record.length);
|
||||
record.data = s->data;
|
||||
s->size = record.length;
|
||||
|
||||
pcap_get_next_record_content(pcap_rfx, &record);
|
||||
s->p = s->data + s->size;
|
||||
|
||||
update->SurfaceCommand(update, s);
|
||||
}
|
||||
}
|
||||
|
||||
boolean test_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
/**
|
||||
@ -256,9 +287,18 @@ boolean test_peer_post_connect(freerdp_peer* client)
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in mainloop. */
|
||||
test_peer_init(client);
|
||||
test_peer_draw_background(client);
|
||||
test_peer_load_icon(client);
|
||||
|
||||
if (test_pcap_file != NULL)
|
||||
{
|
||||
client->update->dump_rfx = True;
|
||||
test_peer_dump_rfx(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
test_peer_draw_background(client);
|
||||
}
|
||||
|
||||
/* Return False here would stop the execution of the peer mainloop. */
|
||||
return True;
|
||||
}
|
||||
@ -292,13 +332,13 @@ void test_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uin
|
||||
|
||||
static void* test_peer_mainloop(void* arg)
|
||||
{
|
||||
freerdp_peer* client = (freerdp_peer*)arg;
|
||||
int i;
|
||||
int fds;
|
||||
int max_fds;
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
fd_set rfds_set;
|
||||
freerdp_peer* client = (freerdp_peer*) arg;
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
@ -452,8 +492,11 @@ int main(int argc, char* argv[])
|
||||
|
||||
instance->PeerAccepted = test_peer_accepted;
|
||||
|
||||
if (argc > 1)
|
||||
test_pcap_file = argv[1];
|
||||
|
||||
/* Open the server socket and start listening. */
|
||||
if (instance->Open(instance, (argc > 1 ? argv[1] : NULL), 3389))
|
||||
if (instance->Open(instance, NULL, 3389))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
test_server_mainloop(instance);
|
||||
|
BIN
server/test/rfx_test.pcap
Normal file
BIN
server/test/rfx_test.pcap
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user