diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 806116137..d27f70d00 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -34,7 +34,7 @@ void xf_rail_enable_remoteapp_mode(xfInfo* xfi) { - if (xfi->remote_app == FALSE) + if (!xfi->remote_app) { xfi->remote_app = TRUE; xfi->drawable = DefaultRootWindow(xfi->display); @@ -45,7 +45,7 @@ void xf_rail_enable_remoteapp_mode(xfInfo* xfi) void xf_rail_disable_remoteapp_mode(xfInfo* xfi) { - if (xfi->remote_app == TRUE) + if (xfi->remote_app) { xfi->remote_app = FALSE; xf_create_window(xfi); @@ -101,9 +101,10 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 u void xf_rail_DesktopNonMonitored(rdpRail *rail, rdpWindow* window) { - xfInfo* xfi; - xfi = (xfInfo*) rail->extra; - xf_rail_disable_remoteapp_mode(xfi); + xfInfo* xfi; + + xfi = (xfInfo*) rail->extra; + xf_rail_disable_remoteapp_mode(xfi); } static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window) diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index 61ca01121..9bc24cb4a 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -26,8 +26,10 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 u void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail); void xf_rail_send_client_system_command(xfInfo* xfi, UINT32 windowId, UINT16 command); void xf_rail_send_activate(xfInfo* xfi, Window xwindow, BOOL enabled); -void xf_process_rail_event(xfInfo* xfi, rdpChannels* chanman, wMessage* event); -void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window); -void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window); +void xf_process_rail_event(xfInfo* xfi, rdpChannels* channels, wMessage* event); +void xf_rail_adjust_position(xfInfo* xfi, rdpWindow* window); +void xf_rail_end_local_move(xfInfo* xfi, rdpWindow* window); +void xf_rail_enable_remoteapp_mode(xfInfo* xfi); +void xf_rail_disable_remoteapp_mode(xfInfo* xfi); #endif /* __XF_RAIL_H */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 907f6a0e0..52849d5e2 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -397,31 +397,38 @@ void xf_create_window(xfInfo* xfi) xfi->attribs.bit_gravity = NorthWestGravity; xfi->attribs.win_gravity = NorthWestGravity; - if (xfi->instance->settings->WindowTitle != NULL) + if (!xfi->remote_app) { - win_title = _strdup(xfi->instance->settings->WindowTitle); - } - else if (xfi->instance->settings->ServerPort == 3389) - { - win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname)); - sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->ServerHostname); + if (xfi->instance->settings->WindowTitle != NULL) + { + win_title = _strdup(xfi->instance->settings->WindowTitle); + } + else if (xfi->instance->settings->ServerPort == 3389) + { + win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname)); + sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->ServerHostname); + } + else + { + win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname) + sizeof(":00000")); + sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->ServerHostname, xfi->instance->settings->ServerPort); + } + + xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations); + free(win_title); + + if (xfi->fullscreen) + xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen); + + xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); + + XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1); + xfi->drawable = xfi->window->handle; } else { - win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname) + sizeof(":00000")); - sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->ServerHostname, xfi->instance->settings->ServerPort); + xfi->drawable = DefaultRootWindow(xfi->display); } - - xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations); - free(win_title); - - if (xfi->fullscreen) - xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen); - - xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); - - XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1); - xfi->drawable = xfi->window->handle; } void xf_toggle_fullscreen(xfInfo* xfi) @@ -774,12 +781,14 @@ BOOL xf_post_connect(freerdp* instance) XGCValues gcv; rdpCache* cache; rdpChannels* channels; + rdpSettings* settings; RFX_CONTEXT* rfx_context = NULL; NSC_CONTEXT* nsc_context = NULL; xfi = ((xfContext*) instance->context)->xfi; cache = instance->context->cache; channels = xfi->_context->channels; + settings = instance->settings; if (xf_get_pixmap_info(xfi) != TRUE) return FALSE; @@ -824,8 +833,11 @@ BOOL xf_post_connect(freerdp* instance) } } - xfi->width = instance->settings->DesktopWidth; - xfi->height = instance->settings->DesktopHeight; + xfi->width = settings->DesktopWidth; + xfi->height = settings->DesktopHeight; + + if (settings->RemoteApplicationMode) + xfi->remote_app = TRUE; xf_create_window(xfi); @@ -961,6 +973,17 @@ BOOL xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* return FALSE; } +int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type) +{ + xfInfo* xfi; + + xfi = ((xfContext*) instance->context)->xfi; + + xf_rail_disable_remoteapp_mode(xfi); + + return 1; +} + int xf_receive_channel_data(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size) { return freerdp_channels_data(instance, channelId, data, size, flags, total_size); @@ -1497,6 +1520,7 @@ int main(int argc, char* argv[]) instance->PostConnect = xf_post_connect; instance->Authenticate = xf_authenticate; instance->VerifyCertificate = xf_verify_certificate; + instance->LogonErrorInfo = xf_logon_error_info; instance->ReceiveChannelData = xf_receive_channel_data; instance->context_size = sizeof(xfContext); diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 24654f58d..6b9aa5315 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -56,6 +56,8 @@ typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** passwor typedef BOOL (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint); typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint); +typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); + typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size); typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size); @@ -175,7 +177,10 @@ struct rdp_freerdp Callback for changed certificate validation. Used when a certificate differs from stored fingerprint. If returns TRUE, the new fingerprint will be trusted and old thrown out. */ - UINT32 paddingD[64 - 51]; /* 51 */ + + pLogonErrorInfo LogonErrorInfo; /**< (offset 53) Callback for logon error info, important for logon system messages with RemoteApp */ + + UINT32 paddingD[64 - 54]; /* 54 */ pSendChannelData SendChannelData; /* (offset 64) Callback for sending data to a channel. diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 4b5e3f3e7..b4c5e86d6 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -226,6 +226,19 @@ struct _TARGET_NET_ADDRESS }; typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS; +/* Logon Error Info */ + +#define LOGON_MSG_NO_PERMISSION 0xFFFFFFFA +#define LOGON_MSG_BUMP_OPTIONS 0xFFFFFFFB +#define LOGON_MSG_SESSION_RECONNECT 0xFFFFFFFC +#define LOGON_MSG_SESSION_TERMINATE 0xFFFFFFFD +#define LOGON_MSG_SESSION_CONTINUE 0xFFFFFFFE + +#define LOGON_FAILED_BAD_PASSWORD 0x00000000 +#define LOGON_FAILED_UPDATE_PASSWORD 0x00000001 +#define LOGON_FAILED_OTHER 0x00000002 +#define LOGON_WARNING 0x00000003 + /* SYSTEM_TIME */ typedef struct { diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 1e6993a5e..60caf5bf1 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -54,7 +54,7 @@ BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings) ARC_SC_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ServerAutoReconnectCookie; - if(stream_get_left(s) < 4+4+4+16) + if (stream_get_left(s) < 4+4+4+16) return FALSE; stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ @@ -118,7 +118,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) UINT16 cbClientDir; UINT16 cbAutoReconnectLen; - if(stream_get_left(s) < 4) + if (stream_get_left(s) < 4) return FALSE; stream_read_UINT16(s, clientAddressFamily); /* clientAddressFamily */ stream_read_UINT16(s, cbClientAddress); /* cbClientAddress */ @@ -131,7 +131,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); stream_seek(s, cbClientAddress); - if(stream_get_left(s) < 2) + if (stream_get_left(s) < 2) return FALSE; stream_read_UINT16(s, cbClientDir); /* cbClientDir */ @@ -147,7 +147,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) if (!rdp_read_client_time_zone(s, settings)) return FALSE; - if(stream_get_left(s) < 10) + if (stream_get_left(s) < 10) return FALSE; stream_seek_UINT32(s); /* clientSessionId, should be set to 0 */ stream_read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ @@ -234,7 +234,7 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings) UINT16 cbAlternateShell; UINT16 cbWorkingDir; - if(stream_get_left(s) < 18) // invalid packet + if (stream_get_left(s) < 18) // invalid packet return FALSE; stream_seek_UINT32(s); /* CodePage */ @@ -452,6 +452,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n"); return FALSE; } + if (securityFlags & SEC_ENCRYPT) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) @@ -487,13 +488,15 @@ BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s) UINT32 cbDomain; UINT32 cbUserName; - if(stream_get_left(s) < 4+52+4+512+4) + if (stream_get_left(s) < (4 + 52 + 4 + 512 + 4)) return FALSE; + stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */ stream_seek(s, 52); /* domain (52 bytes) */ stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ stream_seek(s, 512); /* userName (512 bytes) */ stream_seek_UINT32(s); /* sessionId (4 bytes) */ + return TRUE; } @@ -502,8 +505,9 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s) UINT32 cbDomain; UINT32 cbUserName; - if(stream_get_left(s) < 2+4+4+4+4+558) + if (stream_get_left(s) < (2 + 4 + 4 + 4 + 4 + 558)) return FALSE; + stream_seek_UINT16(s); /* version (2 bytes) */ stream_seek_UINT32(s); /* size (4 bytes) */ stream_seek_UINT32(s); /* sessionId (4 bytes) */ @@ -511,30 +515,38 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s) stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */ stream_seek(s, 558); /* pad */ - if(stream_get_left(s) < cbDomain+cbUserName) + if (stream_get_left(s) < cbDomain+cbUserName) return FALSE; + stream_seek(s, cbDomain); /* domain */ stream_seek(s, cbUserName); /* userName */ + return TRUE; } BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) { - if(stream_get_left(s) < 576) + if (stream_get_left(s) < 576) return FALSE; + stream_seek(s, 576); /* pad */ + return TRUE; } BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s) { - UINT32 errorNotificationType; UINT32 errorNotificationData; + UINT32 errorNotificationType; - if(stream_get_left(s) < 4) + if (stream_get_left(s) < 4) return FALSE; - stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ + stream_read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ + stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ + + IFCALL(rdp->instance->LogonErrorInfo, rdp->instance, errorNotificationData, errorNotificationType); + return TRUE; } @@ -544,7 +556,7 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s) UINT32 fieldsPresent; UINT16 Length; - if(stream_get_left(s) < 6) + if (stream_get_left(s) < 6) return FALSE; stream_read_UINT16(s, Length); /* The total size in bytes of this structure */ @@ -554,25 +566,31 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s) if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE) { - if(stream_get_left(s) < 4) + if (stream_get_left(s) < 4) return FALSE; + stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ - if(rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE) + + if (rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE) return FALSE; } if (fieldsPresent & LOGON_EX_LOGONERRORS) { - if(stream_get_left(s) < 4) + if (stream_get_left(s) < 4) return FALSE; + stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */ - if(rdp_recv_logon_error_info(rdp, s) == FALSE) + + if (rdp_recv_logon_error_info(rdp, s) == FALSE) return FALSE; } - if(stream_get_left(s) < 570) + if (stream_get_left(s) < 570) return FALSE; + stream_seek(s, 570); /* pad */ + return TRUE; } @@ -580,7 +598,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) { UINT32 infoType; - if(stream_get_left(s) < 4) + if (stream_get_left(s) < 4) return FALSE; stream_read_UINT32(s, infoType); /* infoType (4 bytes) */