FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
shadow.c
1
19#include <freerdp/config.h>
20
21#include <winpr/crt.h>
22#include <winpr/ssl.h>
23#include <winpr/path.h>
24#include <winpr/cmdline.h>
25#include <winpr/winsock.h>
26
27#include <winpr/tools/makecert.h>
28
29#include <freerdp/server/shadow.h>
30#include <freerdp/settings.h>
31
32#include <freerdp/log.h>
33#define TAG SERVER_TAG("shadow")
34
35int main(int argc, char** argv)
36{
37 int status = 0;
38 DWORD dwExitCode = 0;
39 COMMAND_LINE_ARGUMENT_A shadow_args[] = {
40 { "log-filters", COMMAND_LINE_VALUE_REQUIRED, "<tag>:<level>[,<tag>:<level>[,...]]", NULL,
41 NULL, -1, NULL, "Set logger filters, see wLog(7) for details" },
42 { "log-level", COMMAND_LINE_VALUE_REQUIRED, "[OFF|FATAL|ERROR|WARN|INFO|DEBUG|TRACE]", NULL,
43 NULL, -1, NULL, "Set the default log level, see wLog(7) for details" },
44 { "port", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Server port" },
45 { "ipc-socket", COMMAND_LINE_VALUE_REQUIRED, "<ipc-socket>", NULL, NULL, -1, NULL,
46 "Server IPC socket" },
47 { "bind-address", COMMAND_LINE_VALUE_REQUIRED, "<bind-address>[,<another address>, ...]",
48 NULL, NULL, -1, NULL,
49 "An address to bind to. Use '[<ipv6>]' for IPv6 addresses, e.g. '[::1]' for "
50 "localhost" },
51 { "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL,
52 "Select or list monitors" },
53 { "max-connections", COMMAND_LINE_VALUE_REQUIRED, "<number>", 0, NULL, -1, NULL,
54 "maximum connections allowed to server, 0 to deactivate" },
55 { "rect", COMMAND_LINE_VALUE_REQUIRED, "<x,y,w,h>", NULL, NULL, -1, NULL,
56 "Select rectangle within monitor to share" },
57 { "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
58 "Clients must authenticate" },
59 { "remote-guard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
60 "Remote credential guard" },
61 { "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
62 "Clients may view without prompt" },
63 { "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
64 "Clients may interact without prompt" },
65 { "sec", COMMAND_LINE_VALUE_REQUIRED, "<rdp|tls|nla|ext>", NULL, NULL, -1, NULL,
66 "force specific protocol security" },
67 { "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
68 "rdp protocol security" },
69 { "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
70 "tls protocol security" },
71 { "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
72 "nla protocol security" },
73 { "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
74 "nla extended protocol security" },
75 { "sam-file", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
76 "NTLM SAM file for NLA authentication" },
77 { "keytab", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
78 "Kerberos keytab file for NLA authentication" },
79 { "ccache", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
80 "Kerberos host ccache file for NLA authentication" },
81 { "tls-secrets-file", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
82 "file where tls secrets shall be stored" },
83 { "nsc", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Allow NSC codec" },
84 { "rfx", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
85 "Allow RFX surface bits" },
86 { "gfx", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
87 "Allow GFX pipeline" },
88 { "gfx-progressive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
89 "Allow GFX progressive codec" },
90 { "gfx-rfx", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
91 "Allow GFX RFX codec" },
92 { "gfx-planar", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
93 "Allow GFX planar codec" },
94 { "gfx-avc420", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
95 "Allow GFX AVC420 codec" },
96 { "gfx-avc444", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
97 "Allow GFX AVC444 codec" },
98 { "bitmap-compat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
99 "Limit BitmapUpdate to 1 rectangle (fixes broken windows 11 24H2 clients)" },
100 { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1,
101 NULL, "Print version" },
102 { "buildconfig", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_BUILDCONFIG, NULL, NULL, NULL,
103 -1, NULL, "Print the build configuration" },
104 { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?",
105 "Print help" },
106 { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
107 };
108
109 shadow_subsystem_set_entry_builtin(NULL);
110
111 rdpShadowServer* server = shadow_server_new();
112
113 if (!server)
114 {
115 status = -1;
116 WLog_ERR(TAG, "Server new failed");
117 goto fail;
118 }
119
120 rdpSettings* settings = server->settings;
121 WINPR_ASSERT(settings);
122
123 if (!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, TRUE) ||
124 !freerdp_settings_set_bool(settings, FreeRDP_TlsSecurity, TRUE) ||
125 !freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, TRUE))
126 goto fail;
127
128 /* By default allow all GFX modes.
129 * This can be changed with command line flags [+|-]gfx-CODEC
130 */
131 if (!freerdp_settings_set_uint32(settings, FreeRDP_ColorDepth, 32) ||
132 !freerdp_settings_set_bool(settings, FreeRDP_NSCodec, TRUE) ||
133 !freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec, TRUE) ||
134 !freerdp_settings_set_bool(settings, FreeRDP_RemoteFxImageCodec, TRUE) ||
135 !freerdp_settings_set_uint32(settings, FreeRDP_RemoteFxRlgrMode, RLGR3) ||
136 !freerdp_settings_set_bool(settings, FreeRDP_GfxH264, TRUE) ||
137 !freerdp_settings_set_bool(settings, FreeRDP_GfxAVC444, TRUE) ||
138 !freerdp_settings_set_bool(settings, FreeRDP_GfxAVC444v2, TRUE) ||
139 !freerdp_settings_set_bool(settings, FreeRDP_GfxProgressive, TRUE) ||
140 !freerdp_settings_set_bool(settings, FreeRDP_GfxProgressiveV2, TRUE))
141 goto fail;
142
143 /* TODO: We do not implement relative mouse callbacks, so deactivate it for now */
144 if (!freerdp_settings_set_bool(settings, FreeRDP_MouseUseRelativeMove, FALSE) ||
145 !freerdp_settings_set_bool(settings, FreeRDP_HasRelativeMouseEvent, FALSE))
146 goto fail;
147
148 if ((status = shadow_server_parse_command_line(server, argc, argv, shadow_args)) < 0)
149 {
150 shadow_server_command_line_status_print(server, argc, argv, status, shadow_args);
151 goto fail;
152 }
153
154 if ((status = shadow_server_init(server)) < 0)
155 {
156 WLog_ERR(TAG, "Server initialization failed.");
157 goto fail;
158 }
159
160 if ((status = shadow_server_start(server)) < 0)
161 {
162 WLog_ERR(TAG, "Failed to start server.");
163 goto fail;
164 }
165
166#ifdef _WIN32
167 {
168 MSG msg = { 0 };
169 while (GetMessage(&msg, 0, 0, 0))
170 {
171 TranslateMessage(&msg);
172 DispatchMessage(&msg);
173 }
174 }
175#endif
176
177 (void)WaitForSingleObject(server->thread, INFINITE);
178
179 if (!GetExitCodeThread(server->thread, &dwExitCode))
180 status = -1;
181 else
182 status = (int)dwExitCode;
183
184fail:
185 shadow_server_uninit(server);
186 shadow_server_free(server);
187 return status;
188}
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.