FreeRDP
Loading...
Searching...
No Matches
TestKnownHosts.c
1
20#include <winpr/path.h>
21#include <winpr/file.h>
22#include <winpr/sysinfo.h>
23
24#include <freerdp/crypto/certificate_store.h>
25
26/* Some certificates copied from /usr/share/ca-certificates */
27static const char pem1[] = "-----BEGIN CERTIFICATE-----\n"
28 "MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH\n"
29 "MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n"
30 "QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\n"
31 "MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\n"
32 "cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB\n"
33 "AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM\n"
34 "f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX\n"
35 "mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7\n"
36 "zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P\n"
37 "fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc\n"
38 "vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4\n"
39 "Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp\n"
40 "zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO\n"
41 "Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW\n"
42 "k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+\n"
43 "DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF\n"
44 "lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n"
45 "HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW\n"
46 "Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1\n"
47 "d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z\n"
48 "XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR\n"
49 "gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3\n"
50 "d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv\n"
51 "J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg\n"
52 "DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM\n"
53 "+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy\n"
54 "F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9\n"
55 "SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws\n"
56 "E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl\n"
57 "-----END CERTIFICATE-----";
58
59static const char pem2[] = "-----BEGIN CERTIFICATE-----\n"
60 "MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH\n"
61 "MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n"
62 "QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\n"
63 "MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\n"
64 "cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB\n"
65 "AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv\n"
66 "CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg\n"
67 "GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu\n"
68 "XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd\n"
69 "re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu\n"
70 "PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1\n"
71 "mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K\n"
72 "8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj\n"
73 "x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR\n"
74 "nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0\n"
75 "kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok\n"
76 "twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n"
77 "HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp\n"
78 "8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT\n"
79 "vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT\n"
80 "z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA\n"
81 "pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb\n"
82 "pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB\n"
83 "R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R\n"
84 "RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk\n"
85 "0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC\n"
86 "5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF\n"
87 "izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn\n"
88 "yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC\n"
89 "-----END CERTIFICATE-----";
90
91static const char pem3[] = "-----BEGIN CERTIFICATE-----\n"
92 "MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw\n"
93 "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n"
94 "MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\n"
95 "MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n"
96 "Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA\n"
97 "IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout\n"
98 "736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A\n"
99 "DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n"
100 "DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk\n"
101 "fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA\n"
102 "njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd\n"
103 "-----END CERTIFICATE-----";
104
105static const char pem4[] = "-----BEGIN CERTIFICATE-----\n"
106 "MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw\n"
107 "CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n"
108 "MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\n"
109 "MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n"
110 "Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA\n"
111 "IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu\n"
112 "hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l\n"
113 "xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n"
114 "DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0\n"
115 "CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx\n"
116 "sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==\n"
117 "-----END CERTIFICATE-----";
118
119static int prepare(const char* currentFileV2)
120{
121 int rc = -1;
122 const char* hosts[] = { "#somecomment\r\n"
123 "someurl 3389 ff:11:22:dd c3ViamVjdA== aXNzdWVy\r\n"
124 " \t#anothercomment\r\n"
125 "otherurl\t3389\taa:bb:cc:dd\tsubject2\tissuer2\r" };
126 FILE* fc = NULL;
127 fc = winpr_fopen(currentFileV2, "w+");
128
129 if (!fc)
130 goto finish;
131
132 for (size_t i = 0; i < ARRAYSIZE(hosts); i++)
133 {
134 if (fwrite(hosts[i], strlen(hosts[i]), 1, fc) != 1)
135 goto finish;
136 }
137
138 rc = 0;
139finish:
140
141 if (fc)
142 (void)fclose(fc);
143
144 return rc;
145}
146
147static BOOL setup_config(rdpSettings** settings)
148{
149 BOOL rc = FALSE;
150 char* path = NULL;
151 char sname[8192];
152 SYSTEMTIME systemTime;
153
154 if (!settings)
155 goto fail;
156 *settings = freerdp_settings_new(0);
157 if (!*settings)
158 goto fail;
159
160 GetSystemTime(&systemTime);
161 (void)sprintf_s(sname, sizeof(sname),
162 "TestKnownHostsCurrent-%04" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16
163 "%02" PRIu16 "%02" PRIu16 "%04" PRIu16,
164 systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
165 systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
166
167 path = GetKnownSubPath(KNOWN_PATH_TEMP, sname);
168 if (!path)
169 goto fail;
170 if (!winpr_PathFileExists(path))
171 {
172 if (!CreateDirectoryA(path, NULL))
173 {
174 (void)fprintf(stderr, "Could not create %s!\n", path);
175 goto fail;
176 }
177 }
178
179 rc = freerdp_settings_set_string(*settings, FreeRDP_ConfigPath, path);
180fail:
181 free(path);
182 return rc;
183}
184
185static BOOL equal(const char* a, const char* b)
186{
187 if (!a && !b)
188 return TRUE;
189 if (!a || !b)
190 return FALSE;
191 return strcmp(a, b) == 0;
192}
193
194static BOOL compare(const rdpCertificateData* data, const rdpCertificateData* stored)
195{
196 if (!data || !stored)
197 return FALSE;
198 if (!equal(freerdp_certificate_data_get_subject(data),
199 freerdp_certificate_data_get_subject(stored)))
200 return FALSE;
201 if (!equal(freerdp_certificate_data_get_issuer(data),
202 freerdp_certificate_data_get_issuer(stored)))
203 return FALSE;
204 if (!equal(freerdp_certificate_data_get_fingerprint(data),
205 freerdp_certificate_data_get_fingerprint(stored)))
206 return FALSE;
207 return TRUE;
208}
209
210static BOOL pem_equal(const char* a, const char* b)
211{
212 return strcmp(a, b) == 0;
213}
214
215static BOOL compare_ex(const rdpCertificateData* data, const rdpCertificateData* stored)
216{
217 if (!compare(data, stored))
218 return FALSE;
219 if (!pem_equal(freerdp_certificate_data_get_pem(data),
220 freerdp_certificate_data_get_pem(stored)))
221 return FALSE;
222
223 return TRUE;
224}
225
226static BOOL test_get_data(rdpCertificateStore* store, const rdpCertificateData* data)
227{
228 BOOL res = 0;
229 rdpCertificateData* stored = freerdp_certificate_store_load_data(
230 store, freerdp_certificate_data_get_host(data), freerdp_certificate_data_get_port(data));
231 if (!stored)
232 return FALSE;
233
234 res = compare(data, stored);
235 freerdp_certificate_data_free(stored);
236 return res;
237}
238
239static BOOL test_get_data_ex(rdpCertificateStore* store, const rdpCertificateData* data)
240{
241 BOOL res = 0;
242 rdpCertificateData* stored = freerdp_certificate_store_load_data(
243 store, freerdp_certificate_data_get_host(data), freerdp_certificate_data_get_port(data));
244 if (!stored)
245 return FALSE;
246
247 res = compare_ex(data, stored);
248 freerdp_certificate_data_free(stored);
249 return res;
250}
251
252static BOOL test_certs_dir(void)
253{
254 BOOL rc = FALSE;
255 rdpSettings* settings = NULL;
256 rdpCertificateStore* store = NULL;
257 rdpCertificateData* data1 = NULL;
258 rdpCertificateData* data2 = NULL;
259 rdpCertificateData* data3 = NULL;
260 rdpCertificateData* data4 = NULL;
261
262 printf("%s\n", __func__);
263 if (!setup_config(&settings))
264 goto fail;
265
266 printf("freerdp_certificate_store_new()\n");
267 store = freerdp_certificate_store_new(settings);
268 if (!store)
269 goto fail;
270
271 {
272 printf("freerdp_certificate_data_new()\n");
273 data1 = freerdp_certificate_data_new_from_pem("somehost", 1234, pem1, strlen(pem1));
274 data2 = freerdp_certificate_data_new_from_pem("otherhost", 4321, pem2, strlen(pem2));
275 data3 = freerdp_certificate_data_new_from_pem("otherhost4", 444, pem3, strlen(pem3));
276 data4 = freerdp_certificate_data_new_from_pem("otherhost", 4321, pem4, strlen(pem4));
277 if (!data1 || !data2 || !data3 || !data4)
278 goto fail;
279
280 /* Find non existing in empty store */
281 printf("freerdp_certificate_store_load_data on empty store\n");
282 if (test_get_data(store, data1))
283 goto fail;
284 if (test_get_data_ex(store, data1))
285 goto fail;
286 if (test_get_data(store, data2))
287 goto fail;
288 if (test_get_data_ex(store, data2))
289 goto fail;
290 if (test_get_data(store, data3))
291 goto fail;
292 if (test_get_data_ex(store, data3))
293 goto fail;
294
295 /* Add certificates */
296 printf("freerdp_certificate_store_save_data\n");
297 if (!freerdp_certificate_store_save_data(store, data1))
298 goto fail;
299 if (!freerdp_certificate_store_save_data(store, data2))
300 goto fail;
301
302 /* Find non existing in non empty store */
303 printf("freerdp_certificate_store_load_data on filled store, non existing value\n");
304 if (test_get_data(store, data3))
305 goto fail;
306 if (test_get_data_ex(store, data3))
307 goto fail;
308
309 /* Add remaining certs */
310 printf("freerdp_certificate_store_save_data\n");
311 if (!freerdp_certificate_store_save_data(store, data3))
312 goto fail;
313
314 /* Check existing can all be found */
315 printf("freerdp_certificate_store_load_data on filled store, existing value\n");
316 if (!test_get_data(store, data1))
317 goto fail;
318 if (!test_get_data_ex(store, data1))
319 goto fail;
320 if (!test_get_data(store, data2))
321 goto fail;
322 if (!test_get_data_ex(store, data2))
323 goto fail;
324 if (!test_get_data(store, data3))
325 goto fail;
326 if (!test_get_data_ex(store, data3))
327 goto fail;
328
329 /* Modify existing entry */
330 printf("freerdp_certificate_store_save_data modify data\n");
331 if (!freerdp_certificate_store_save_data(store, data4))
332 goto fail;
333
334 /* Check new data is in store */
335 printf("freerdp_certificate_store_load_data check modified data can be loaded\n");
336 if (!test_get_data(store, data4))
337 goto fail;
338 if (!test_get_data_ex(store, data4))
339 goto fail;
340
341 /* Check old data is no longer valid */
342 printf("freerdp_certificate_store_load_data check original data no longer there\n");
343 if (test_get_data(store, data2))
344 goto fail;
345 if (test_get_data_ex(store, data2))
346 goto fail;
347
348 /* Delete a cert */
349 printf("freerdp_certificate_store_remove_data\n");
350 if (!freerdp_certificate_store_remove_data(store, data3))
351 goto fail;
352 /* Delete non existing, should succeed */
353 printf("freerdp_certificate_store_remove_data missing value\n");
354 if (!freerdp_certificate_store_remove_data(store, data3))
355 goto fail;
356
357 printf("freerdp_certificate_store_load_data on filled store, existing value\n");
358 if (!test_get_data(store, data1))
359 goto fail;
360 if (!test_get_data_ex(store, data1))
361 goto fail;
362 if (!test_get_data(store, data4))
363 goto fail;
364 if (!test_get_data_ex(store, data4))
365 goto fail;
366
367 printf("freerdp_certificate_store_load_data on filled store, removed value\n");
368 if (test_get_data(store, data3))
369 goto fail;
370 if (test_get_data_ex(store, data3))
371 goto fail;
372 }
373
374 rc = TRUE;
375fail:
376 printf("freerdp_certificate_data_free %d\n", rc);
377 freerdp_certificate_data_free(data1);
378 freerdp_certificate_data_free(data2);
379 freerdp_certificate_data_free(data3);
380 freerdp_certificate_data_free(data4);
381 freerdp_certificate_store_free(store);
382 freerdp_settings_free(settings);
383 return rc;
384}
385
386int TestKnownHosts(int argc, char* argv[])
387{
388 WINPR_UNUSED(argc);
389 WINPR_UNUSED(argv);
390
391 if (!test_certs_dir())
392 return -1;
393 return 0;
394}
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
FREERDP_API rdpSettings * freerdp_settings_new(DWORD flags)
creates a new setting struct
FREERDP_API void freerdp_settings_free(rdpSettings *settings)
Free a settings struct with all data in it.