19#include <freerdp/config.h>
23#include <winpr/path.h>
24#include <winpr/cmdline.h>
25#include <winpr/winsock.h>
27#include <winpr/tools/makecert.h>
29#include <freerdp/server/shadow.h>
30#include <freerdp/settings.h>
32#include <freerdp/log.h>
33#define TAG SERVER_TAG("shadow")
36static const char* boolstr(BOOL val)
38 return val ?
"TRUE" :
"FALSE";
41static void dump_security_settings(
const rdpSettings* settings)
43 WINPR_ASSERT(settings);
51 WLog_INFO(TAG,
"security: RDP:%s, TLS:%s, NLA:%s, EXT:%s, AAD:%s, RDSTLS:%s", boolstr(rdp),
52 boolstr(tls), boolstr(nla), boolstr(ext), boolstr(aad), boolstr(rdstls));
55int main(
int argc,
char** argv)
60 {
"log-filters", COMMAND_LINE_VALUE_REQUIRED,
"<tag>:<level>[,<tag>:<level>[,...]]",
61 nullptr,
nullptr, -1,
nullptr,
"Set logger filters, see wLog(7) for details" },
62 {
"log-level", COMMAND_LINE_VALUE_REQUIRED,
"[OFF|FATAL|ERROR|WARN|INFO|DEBUG|TRACE]",
63 nullptr,
nullptr, -1,
nullptr,
"Set the default log level, see wLog(7) for details" },
64 {
"port", COMMAND_LINE_VALUE_REQUIRED,
"<number>",
nullptr,
nullptr, -1,
nullptr,
66 {
"ipc-socket", COMMAND_LINE_VALUE_REQUIRED,
"<ipc-socket>",
nullptr,
nullptr, -1,
nullptr,
67 "Server IPC socket" },
68 {
"bind-address", COMMAND_LINE_VALUE_REQUIRED,
"<bind-address>[,<another address>, ...]",
69 nullptr,
nullptr, -1,
nullptr,
70 "An address to bind to. Use '[<ipv6>]' for IPv6 addresses, e.g. '[::1]' for "
72 {
"server-side-cursor", COMMAND_LINE_VALUE_BOOL,
nullptr,
nullptr,
nullptr, -1,
nullptr,
73 "hide mouse cursor in RDP client." },
74 {
"monitors", COMMAND_LINE_VALUE_OPTIONAL,
"<0,1,2...>",
nullptr,
nullptr, -1,
nullptr,
75 "Select or list monitors" },
76 {
"max-connections", COMMAND_LINE_VALUE_REQUIRED,
"<number>",
nullptr,
nullptr, -1,
nullptr,
77 "maximum connections allowed to server, 0 to deactivate" },
78 {
"mouse-relative", COMMAND_LINE_VALUE_BOOL,
nullptr,
nullptr,
nullptr, -1,
nullptr,
79 "enable support for relative mouse events" },
80 {
"rect", COMMAND_LINE_VALUE_REQUIRED,
"<x,y,w,h>",
nullptr,
nullptr, -1,
nullptr,
81 "Select rectangle within monitor to share" },
82 {
"auth", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
83 "Clients must authenticate" },
84 {
"remote-guard", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
85 "Remote credential guard" },
86 {
"restricted-admin", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
88 {
"vmconnect", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
89 nullptr, -1,
nullptr,
"Hyper-V console server (bind on vsock://1)" },
90 {
"may-view", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
91 "Clients may view without prompt" },
92 {
"may-interact", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
93 "Clients may interact without prompt" },
94 {
"sec", COMMAND_LINE_VALUE_REQUIRED,
"<rdp|tls|nla|ext>",
nullptr,
nullptr, -1,
nullptr,
95 "force specific protocol security" },
96 {
"sec-rdp", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
97 "rdp protocol security" },
98 {
"sec-tls", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
99 "tls protocol security" },
100 {
"sec-nla", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
101 "nla protocol security" },
102 {
"sec-ext", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
103 "nla extended protocol security" },
104 {
"sam-file", COMMAND_LINE_VALUE_REQUIRED,
"<file>",
nullptr,
nullptr, -1,
nullptr,
105 "NTLM SAM file for NLA authentication" },
106 {
"keytab", COMMAND_LINE_VALUE_REQUIRED,
"<file>",
nullptr,
nullptr, -1,
nullptr,
107 "Kerberos keytab file for NLA authentication" },
108 {
"ccache", COMMAND_LINE_VALUE_REQUIRED,
"<file>",
nullptr,
nullptr, -1,
nullptr,
109 "Kerberos host ccache file for NLA authentication" },
110 {
"tls-secrets-file", COMMAND_LINE_VALUE_REQUIRED,
"<file>",
nullptr,
nullptr, -1,
nullptr,
111 "file where tls secrets shall be stored" },
112 {
"nsc", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
114 {
"rfx", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
115 "Allow RFX surface bits" },
116 {
"gfx", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
117 "Allow GFX pipeline" },
118#if defined(WITH_GFX_AV1)
119 {
"gfx-av1", COMMAND_LINE_VALUE_OPTIONAL,
"[:profile:[low|high|0|1]|off]", BoolValueTrue,
120 nullptr, -1,
nullptr,
"Allow GFX pipeline AV1 codec extension" },
122 {
"gfx-progressive", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
123 "Allow GFX progressive codec" },
124 {
"gfx-rfx", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
125 "Allow GFX RFX codec" },
126 {
"gfx-planar", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
127 "Allow GFX planar codec" },
128 {
"gfx-avc420", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
129 "Allow GFX AVC420 codec" },
130 {
"gfx-avc444", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueTrue,
nullptr, -1,
nullptr,
131 "Allow GFX AVC444 codec" },
132 {
"bitmap-compat", COMMAND_LINE_VALUE_BOOL,
nullptr, BoolValueFalse,
nullptr, -1,
nullptr,
133 "Limit BitmapUpdate to 1 rectangle (fixes broken windows 11 24H2 clients)" },
134 {
"version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION,
nullptr,
nullptr,
135 nullptr, -1,
nullptr,
"Print version" },
136 {
"buildconfig", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_BUILDCONFIG,
nullptr,
nullptr,
137 nullptr, -1,
nullptr,
"Print the build configuration" },
138 {
"help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP,
nullptr,
nullptr,
nullptr, -1,
140 {
nullptr, 0,
nullptr,
nullptr,
nullptr, -1,
nullptr,
nullptr }
143 shadow_subsystem_set_entry_builtin(
nullptr);
145 rdpShadowServer* server = shadow_server_new();
150 WLog_ERR(TAG,
"Server new failed");
155 rdpSettings* settings = server->settings;
156 WINPR_ASSERT(settings);
184 if ((status = shadow_server_parse_command_line(server, argc, argv, shadow_args)) < 0)
186 status = shadow_server_command_line_status_print(server, argc, argv, status, shadow_args);
190 if (server->authentication)
191 dump_security_settings(server->settings);
193 WLog_INFO(TAG,
"authentication: disabled");
195 if ((status = shadow_server_init(server)) < 0)
197 WLog_ERR(TAG,
"Server initialization failed.");
201 if ((status = shadow_server_start(server)) < 0)
203 WLog_ERR(TAG,
"Failed to start server.");
209 MSG msg = WINPR_C_ARRAY_INIT;
210 while (GetMessage(&msg, 0, 0, 0))
212 TranslateMessage(&msg);
213 DispatchMessage(&msg);
218 (void)WaitForSingleObject(server->thread, INFINITE);
220 if (!GetExitCodeThread(server->thread, &dwExitCode))
223 status = (int)dwExitCode;
226 shadow_server_uninit(server);
227 shadow_server_free(server);
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.