diff --git a/config.h.in b/config.h.in index 397d5eb04..60e8f57cb 100644 --- a/config.h.in +++ b/config.h.in @@ -177,5 +177,6 @@ /* Proxy */ #cmakedefine WITH_PROXY_MODULES +#cmakedefine WITH_PROXY_EMULATE_SMARTCARD #endif /* FREERDP_CONFIG_H */ diff --git a/include/freerdp/server/proxy/proxy_context.h b/include/freerdp/server/proxy/proxy_context.h index bec1db61f..93a365655 100644 --- a/include/freerdp/server/proxy/proxy_context.h +++ b/include/freerdp/server/proxy/proxy_context.h @@ -29,123 +29,124 @@ #define PROXY_SESSION_ID_LENGTH 32 -typedef struct proxy_data proxyData; -typedef struct proxy_module proxyModule; -typedef struct channel_data_event_info proxyChannelDataEventInfo; - -typedef struct _InterceptContextMapEntry +#ifdef __cplusplus +extern "C" { - void (*free)(struct _InterceptContextMapEntry*); -} InterceptContextMapEntry; +#endif -/* All proxy interception channels derive from this base struct - * and set their cleanup function accordingly. */ -static INLINE void intercept_context_entry_free(void* obj) -{ - InterceptContextMapEntry* entry = obj; - if (!entry) - return; - if (!entry->free) - return; - entry->free(entry); -} + typedef struct proxy_data proxyData; + typedef struct proxy_module proxyModule; + typedef struct channel_data_event_info proxyChannelDataEventInfo; -/** - * Wraps rdpContext and holds the state for the proxy's server. - */ -struct p_server_context -{ - rdpContext context; - - proxyData* pdata; - - HANDLE vcm; - HANDLE dynvcReady; - - wHashTable* interceptContextMap; -}; -typedef struct p_server_context pServerContext; - -/** - * Wraps rdpContext and holds the state for the proxy's client. - */ -typedef struct p_client_context pClientContext; - -struct p_client_context -{ - rdpContext context; - - proxyData* pdata; - - /* - * In a case when freerdp_connect fails, - * Used for NLA fallback feature, to check if the server should close the connection. - * When it is set to TRUE, proxy's client knows it shouldn't signal the server thread to - * closed the connection when pf_client_post_disconnect is called, because it is trying to - * connect reconnect without NLA. It must be set to TRUE before the first try, and to FALSE - * after the connection fully established, to ensure graceful shutdown of the connection - * when it will be closed. - */ - BOOL allow_next_conn_failure; - - BOOL connected; /* Set after client post_connect. */ - - pReceiveChannelData client_receive_channel_data_original; - wQueue* cached_server_channel_data; - BOOL (*sendChannelData)(pClientContext* pc, const proxyChannelDataEventInfo* ev); - - /* X509 specific */ - char* remote_hostname; - wStream* remote_pem; - UINT16 remote_port; - UINT32 remote_flags; - - BOOL input_state_sync_pending; - UINT32 input_state; - - wHashTable* interceptContextMap; - UINT32 computerNameLen; - BOOL computerNameUnicode; - union + typedef struct _InterceptContextMapEntry { - WCHAR* wc; - char* c; - void* v; - } computerName; -}; + void (*free)(struct _InterceptContextMapEntry*); + } InterceptContextMapEntry; -/** - * Holds data common to both sides of a proxy's session. - */ -struct proxy_data -{ - proxyModule* module; - const proxyConfig* config; + /* All proxy interception channels derive from this base struct + * and set their cleanup function accordingly. */ + FREERDP_API void intercept_context_entry_free(void* obj); - pServerContext* ps; - pClientContext* pc; + /** + * Wraps rdpContext and holds the state for the proxy's server. + */ + struct p_server_context + { + rdpContext context; - HANDLE abort_event; - HANDLE client_thread; - HANDLE gfx_server_ready; + proxyData* pdata; - char session_id[PROXY_SESSION_ID_LENGTH + 1]; + HANDLE vcm; + HANDLE dynvcReady; - /* used to external modules to store per-session info */ - wHashTable* modules_info; - psPeerReceiveChannelData server_receive_channel_data_original; -}; + wHashTable* interceptContextMap; + }; + typedef struct p_server_context pServerContext; -BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src); -BOOL pf_context_init_server_context(freerdp_peer* client); -pClientContext* pf_context_create_client_context(rdpSettings* clientSettings); + /** + * Wraps rdpContext and holds the state for the proxy's client. + */ + typedef struct p_client_context pClientContext; -proxyData* proxy_data_new(void); -void proxy_data_set_client_context(proxyData* pdata, pClientContext* context); -void proxy_data_set_server_context(proxyData* pdata, pServerContext* context); -void proxy_data_free(proxyData* pdata); + struct p_client_context + { + rdpContext context; -BOOL proxy_data_shall_disconnect(proxyData* pdata); -void proxy_data_abort_connect(proxyData* pdata); + proxyData* pdata; + + /* + * In a case when freerdp_connect fails, + * Used for NLA fallback feature, to check if the server should close the connection. + * When it is set to TRUE, proxy's client knows it shouldn't signal the server thread to + * closed the connection when pf_client_post_disconnect is called, because it is trying to + * connect reconnect without NLA. It must be set to TRUE before the first try, and to FALSE + * after the connection fully established, to ensure graceful shutdown of the connection + * when it will be closed. + */ + BOOL allow_next_conn_failure; + + BOOL connected; /* Set after client post_connect. */ + + pReceiveChannelData client_receive_channel_data_original; + wQueue* cached_server_channel_data; + BOOL (*sendChannelData)(pClientContext* pc, const proxyChannelDataEventInfo* ev); + + /* X509 specific */ + char* remote_hostname; + wStream* remote_pem; + UINT16 remote_port; + UINT32 remote_flags; + + BOOL input_state_sync_pending; + UINT32 input_state; + + wHashTable* interceptContextMap; + UINT32 computerNameLen; + BOOL computerNameUnicode; + union + { + WCHAR* wc; + char* c; + void* v; + } computerName; + }; + + /** + * Holds data common to both sides of a proxy's session. + */ + struct proxy_data + { + proxyModule* module; + const proxyConfig* config; + + pServerContext* ps; + pClientContext* pc; + + HANDLE abort_event; + HANDLE client_thread; + HANDLE gfx_server_ready; + + char session_id[PROXY_SESSION_ID_LENGTH + 1]; + + /* used to external modules to store per-session info */ + wHashTable* modules_info; + psPeerReceiveChannelData server_receive_channel_data_original; + }; + + FREERDP_API BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src); + FREERDP_API BOOL pf_context_init_server_context(freerdp_peer* client); + FREERDP_API pClientContext* pf_context_create_client_context(rdpSettings* clientSettings); + + FREERDP_API proxyData* proxy_data_new(void); + FREERDP_API void proxy_data_set_client_context(proxyData* pdata, pClientContext* context); + FREERDP_API void proxy_data_set_server_context(proxyData* pdata, pServerContext* context); + FREERDP_API void proxy_data_free(proxyData* pdata); + + FREERDP_API BOOL proxy_data_shall_disconnect(proxyData* pdata); + FREERDP_API void proxy_data_abort_connect(proxyData* pdata); + +#ifdef __cplusplus +} +#endif #endif /* FREERDP_SERVER_PROXY_PFCONTEXT_H */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index cc555b16f..de2d09e72 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1745,13 +1745,14 @@ extern "C" FREERDP_API BOOL freerdp_settings_set_uint64(rdpSettings* settings, size_t id, UINT64 param); FREERDP_API const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id); + FREERDP_API char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id); FREERDP_API BOOL freerdp_settings_set_string_len(rdpSettings* settings, size_t id, const char* param, size_t len); FREERDP_API BOOL freerdp_settings_set_string(rdpSettings* settings, size_t id, const char* param); FREERDP_API const void* freerdp_settings_get_pointer(const rdpSettings* settings, size_t id); - FREERDP_API void* freerdp_settings_get_pointer_writable(const rdpSettings* settings, size_t id); + FREERDP_API void* freerdp_settings_get_pointer_writable(rdpSettings* settings, size_t id); FREERDP_API BOOL freerdp_settings_set_pointer(rdpSettings* settings, size_t id, const void* data); FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index 061131813..828e4787b 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -2527,6 +2527,231 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id) } } +char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id) +{ + WINPR_ASSERT(settings); + + switch (id) + { + case FreeRDP_AcceptedCert: + return settings->AcceptedCert; + + case FreeRDP_ActionScript: + return settings->ActionScript; + + case FreeRDP_AllowedTlsCiphers: + return settings->AllowedTlsCiphers; + + case FreeRDP_AlternateShell: + return settings->AlternateShell; + + case FreeRDP_AssistanceFile: + return settings->AssistanceFile; + + case FreeRDP_AuthenticationServiceClass: + return settings->AuthenticationServiceClass; + + case FreeRDP_CertificateAcceptedFingerprints: + return settings->CertificateAcceptedFingerprints; + + case FreeRDP_CertificateContent: + return settings->CertificateContent; + + case FreeRDP_CertificateFile: + return settings->CertificateFile; + + case FreeRDP_CertificateName: + return settings->CertificateName; + + case FreeRDP_ClientAddress: + return settings->ClientAddress; + + case FreeRDP_ClientDir: + return settings->ClientDir; + + case FreeRDP_ClientHostname: + return settings->ClientHostname; + + case FreeRDP_ClientProductId: + return settings->ClientProductId; + + case FreeRDP_ComputerName: + return settings->ComputerName; + + case FreeRDP_ConfigPath: + return settings->ConfigPath; + + case FreeRDP_ConnectionFile: + return settings->ConnectionFile; + + case FreeRDP_CurrentPath: + return settings->CurrentPath; + + case FreeRDP_Domain: + return settings->Domain; + + case FreeRDP_DrivesToRedirect: + return settings->DrivesToRedirect; + + case FreeRDP_DumpRemoteFxFile: + return settings->DumpRemoteFxFile; + + case FreeRDP_DynamicDSTTimeZoneKeyName: + return settings->DynamicDSTTimeZoneKeyName; + + case FreeRDP_GatewayAcceptedCert: + return settings->GatewayAcceptedCert; + + case FreeRDP_GatewayAccessToken: + return settings->GatewayAccessToken; + + case FreeRDP_GatewayDomain: + return settings->GatewayDomain; + + case FreeRDP_GatewayHostname: + return settings->GatewayHostname; + + case FreeRDP_GatewayPassword: + return settings->GatewayPassword; + + case FreeRDP_GatewayUsername: + return settings->GatewayUsername; + + case FreeRDP_HomePath: + return settings->HomePath; + + case FreeRDP_ImeFileName: + return settings->ImeFileName; + + case FreeRDP_KerberosKdc: + return settings->KerberosKdc; + + case FreeRDP_KerberosRealm: + return settings->KerberosRealm; + + case FreeRDP_KeyboardRemappingList: + return settings->KeyboardRemappingList; + + case FreeRDP_NtlmSamFile: + return settings->NtlmSamFile; + + case FreeRDP_Password: + return settings->Password; + + case FreeRDP_PasswordHash: + return settings->PasswordHash; + + case FreeRDP_PlayRemoteFxFile: + return settings->PlayRemoteFxFile; + + case FreeRDP_PreconnectionBlob: + return settings->PreconnectionBlob; + + case FreeRDP_PrivateKeyContent: + return settings->PrivateKeyContent; + + case FreeRDP_PrivateKeyFile: + return settings->PrivateKeyFile; + + case FreeRDP_ProxyHostname: + return settings->ProxyHostname; + + case FreeRDP_ProxyPassword: + return settings->ProxyPassword; + + case FreeRDP_ProxyUsername: + return settings->ProxyUsername; + + case FreeRDP_RDP2TCPArgs: + return settings->RDP2TCPArgs; + + case FreeRDP_RdpKeyContent: + return settings->RdpKeyContent; + + case FreeRDP_RdpKeyFile: + return settings->RdpKeyFile; + + case FreeRDP_RedirectionAcceptedCert: + return settings->RedirectionAcceptedCert; + + case FreeRDP_RedirectionDomain: + return settings->RedirectionDomain; + + case FreeRDP_RedirectionTargetFQDN: + return settings->RedirectionTargetFQDN; + + case FreeRDP_RedirectionTargetNetBiosName: + return settings->RedirectionTargetNetBiosName; + + case FreeRDP_RedirectionUsername: + return settings->RedirectionUsername; + + case FreeRDP_RemoteApplicationCmdLine: + return settings->RemoteApplicationCmdLine; + + case FreeRDP_RemoteApplicationFile: + return settings->RemoteApplicationFile; + + case FreeRDP_RemoteApplicationGuid: + return settings->RemoteApplicationGuid; + + case FreeRDP_RemoteApplicationIcon: + return settings->RemoteApplicationIcon; + + case FreeRDP_RemoteApplicationName: + return settings->RemoteApplicationName; + + case FreeRDP_RemoteApplicationProgram: + return settings->RemoteApplicationProgram; + + case FreeRDP_RemoteApplicationWorkingDir: + return settings->RemoteApplicationWorkingDir; + + case FreeRDP_RemoteAssistancePassStub: + return settings->RemoteAssistancePassStub; + + case FreeRDP_RemoteAssistancePassword: + return settings->RemoteAssistancePassword; + + case FreeRDP_RemoteAssistanceRCTicket: + return settings->RemoteAssistanceRCTicket; + + case FreeRDP_RemoteAssistanceSessionId: + return settings->RemoteAssistanceSessionId; + + case FreeRDP_ServerHostname: + return settings->ServerHostname; + + case FreeRDP_ShellWorkingDirectory: + return settings->ShellWorkingDirectory; + + case FreeRDP_SmartcardCertificate: + return settings->SmartcardCertificate; + + case FreeRDP_SmartcardPrivateKey: + return settings->SmartcardPrivateKey; + + case FreeRDP_TargetNetAddress: + return settings->TargetNetAddress; + + case FreeRDP_TransportDumpFile: + return settings->TransportDumpFile; + + case FreeRDP_Username: + return settings->Username; + + case FreeRDP_WindowTitle: + return settings->WindowTitle; + + case FreeRDP_WmClass: + return settings->WmClass; + + default: + WLog_ERR(TAG, "[%s] Invalid key index %" PRIuz, __FUNCTION__, id); + return FALSE; + } +} + BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char* val, size_t len, BOOL cleanup) { @@ -2776,7 +3001,7 @@ BOOL freerdp_settings_set_string(rdpSettings* settings, size_t id, const char* v return freerdp_settings_set_string_(settings, id, val, len, TRUE); } -void* freerdp_settings_get_pointer_writable(const rdpSettings* settings, size_t id) +void* freerdp_settings_get_pointer_writable(rdpSettings* settings, size_t id) { WINPR_ASSERT(settings); diff --git a/scripts/update-settings-tests b/scripts/update-settings-tests index 55b9fef6c..4be49f0f3 100755 --- a/scripts/update-settings-tests +++ b/scripts/update-settings-tests @@ -269,21 +269,7 @@ def write_getter_case(f, val): f.write('\t\tcase FreeRDP_' + val + ':\n') f.write('\t\t\treturn settings->' + val + ';\n\n') -def write_getter(f, entry_dict, entry_type, entry_name): - isString = 'string' in entry_name - isPointer = 'pointer' in entry_name - values = get_values(entry_dict, entry_type) - - if isPointer: - f.write('void*') - elif isString: - f.write('const ' + entry_type) - else: - f.write(entry_type) - if isPointer: - f.write(' freerdp_settings_get_pointer_writable(const rdpSettings* settings, size_t id)\n') - else: - f.write(' freerdp_settings_get_' + entry_name.lower() + '(const rdpSettings* settings, size_t id)\n') +def write_getter_body(f, values): f.write('{\n') f.write('\tWINPR_ASSERT(settings);\n\n') f.write('\tswitch (id)\n') @@ -297,6 +283,28 @@ def write_getter(f, entry_dict, entry_type, entry_name): f.write('\t}\n') f.write('}\n\n') +def write_getter(f, entry_dict, entry_type, entry_name): + isString = 'string' in entry_name + isPointer = 'pointer' in entry_name + values = get_values(entry_dict, entry_type) + + if isPointer: + f.write('void*') + elif isString: + f.write('const ' + entry_type) + else: + f.write(entry_type) + + if isPointer: + f.write(' freerdp_settings_get_pointer_writable(rdpSettings* settings, size_t id)\n') + else: + f.write(' freerdp_settings_get_' + entry_name.lower() + '(const rdpSettings* settings, size_t id)\n') + write_getter_body(f, values) + + if isString: + f.write('char* freerdp_settings_get_' + entry_name.lower() + '_writable(rdpSettings* settings, size_t id)\n') + write_getter_body(f, values) + def write_setter_case(f, val, isString, isPointer): f.write('\t\tcase FreeRDP_' + val + ':\n') if isPointer: diff --git a/server/proxy/CMakeLists.txt b/server/proxy/CMakeLists.txt index c7076009d..7edcc7223 100644 --- a/server/proxy/CMakeLists.txt +++ b/server/proxy/CMakeLists.txt @@ -41,6 +41,7 @@ set(${MODULE_PREFIX}_SRCS set(PROXY_APP_SRCS freerdp_proxy.c) +option(WITH_PROXY_EMULATE_SMARTCARD "Compile proxy smartcard emulation" OFF) add_subdirectory("channels") # On windows create dll version information. @@ -116,7 +117,3 @@ if (WITH_PROXY_MODULES) add_subdirectory("modules") endif() -option(WITH_PROXY_EMULATE_SMARTCARD "Compile proxy smartcard emulation" OFF) -if (WITH_PROXY_EMULATE_SMARTCARD) - add_definitions("-DWITH_PROXY_EMULATE_SMARTCARD") -endif() diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index c0f628e71..6cb7c70f9 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -18,6 +18,10 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include diff --git a/server/proxy/pf_context.c b/server/proxy/pf_context.c index 1506381d4..d41cc9301 100644 --- a/server/proxy/pf_context.c +++ b/server/proxy/pf_context.c @@ -121,6 +121,16 @@ static BOOL pf_context_revert_str_settings(rdpSettings* dst, const rdpSettings* return TRUE; } +void intercept_context_entry_free(void* obj) +{ + InterceptContextMapEntry* entry = obj; + if (!entry) + return; + if (!entry->free) + return; + entry->free(entry); +} + BOOL pf_context_copy_settings(rdpSettings* dst, const rdpSettings* src) { BOOL rc = FALSE;