20#include <winpr/path.h> 
   21#include <winpr/file.h> 
   22#include <winpr/sysinfo.h> 
   24#include <freerdp/crypto/certificate_store.h> 
   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-----";
 
   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-----";
 
   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-----";
 
  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-----";
 
  119static int prepare(
const char* currentFileV2)
 
  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" };
 
  127  fc = winpr_fopen(currentFileV2, 
"w+");
 
  132  for (
size_t i = 0; i < ARRAYSIZE(hosts); i++)
 
  134    if (fwrite(hosts[i], strlen(hosts[i]), 1, fc) != 1)
 
  147static BOOL setup_config(rdpSettings** settings)
 
  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);
 
  167  path = GetKnownSubPath(KNOWN_PATH_TEMP, sname);
 
  170  if (!winpr_PathFileExists(path))
 
  172    if (!CreateDirectoryA(path, NULL))
 
  174      (void)fprintf(stderr, 
"Could not create %s!\n", path);
 
  185static BOOL equal(
const char* a, 
const char* b)
 
  191  return strcmp(a, b) == 0;
 
  194static BOOL compare(
const rdpCertificateData* data, 
const rdpCertificateData* stored)
 
  196  if (!data || !stored)
 
  198  if (!equal(freerdp_certificate_data_get_subject(data),
 
  199             freerdp_certificate_data_get_subject(stored)))
 
  201  if (!equal(freerdp_certificate_data_get_issuer(data),
 
  202             freerdp_certificate_data_get_issuer(stored)))
 
  204  if (!equal(freerdp_certificate_data_get_fingerprint(data),
 
  205             freerdp_certificate_data_get_fingerprint(stored)))
 
  210static BOOL pem_equal(
const char* a, 
const char* b)
 
  212  return strcmp(a, b) == 0;
 
  215static BOOL compare_ex(
const rdpCertificateData* data, 
const rdpCertificateData* stored)
 
  217  if (!compare(data, stored))
 
  219  if (!pem_equal(freerdp_certificate_data_get_pem(data),
 
  220                 freerdp_certificate_data_get_pem(stored)))
 
  226static BOOL test_get_data(rdpCertificateStore* store, 
const rdpCertificateData* data)
 
  229  rdpCertificateData* stored = freerdp_certificate_store_load_data(
 
  230      store, freerdp_certificate_data_get_host(data), freerdp_certificate_data_get_port(data));
 
  234  res = compare(data, stored);
 
  235  freerdp_certificate_data_free(stored);
 
  239static BOOL test_get_data_ex(rdpCertificateStore* store, 
const rdpCertificateData* data)
 
  242  rdpCertificateData* stored = freerdp_certificate_store_load_data(
 
  243      store, freerdp_certificate_data_get_host(data), freerdp_certificate_data_get_port(data));
 
  247  res = compare_ex(data, stored);
 
  248  freerdp_certificate_data_free(stored);
 
  252static BOOL test_certs_dir(
void)
 
  255  rdpSettings* settings = NULL;
 
  256  rdpCertificateStore* store = NULL;
 
  257  rdpCertificateData* data1 = NULL;
 
  258  rdpCertificateData* data2 = NULL;
 
  259  rdpCertificateData* data3 = NULL;
 
  260  rdpCertificateData* data4 = NULL;
 
  262  printf(
"%s\n", __func__);
 
  263  if (!setup_config(&settings))
 
  266  printf(
"freerdp_certificate_store_new()\n");
 
  267  store = freerdp_certificate_store_new(settings);
 
  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)
 
  281    printf(
"freerdp_certificate_store_load_data on empty store\n");
 
  282    if (test_get_data(store, data1))
 
  284    if (test_get_data_ex(store, data1))
 
  286    if (test_get_data(store, data2))
 
  288    if (test_get_data_ex(store, data2))
 
  290    if (test_get_data(store, data3))
 
  292    if (test_get_data_ex(store, data3))
 
  296    printf(
"freerdp_certificate_store_save_data\n");
 
  297    if (!freerdp_certificate_store_save_data(store, data1))
 
  299    if (!freerdp_certificate_store_save_data(store, data2))
 
  303    printf(
"freerdp_certificate_store_load_data on filled store, non existing value\n");
 
  304    if (test_get_data(store, data3))
 
  306    if (test_get_data_ex(store, data3))
 
  310    printf(
"freerdp_certificate_store_save_data\n");
 
  311    if (!freerdp_certificate_store_save_data(store, data3))
 
  315    printf(
"freerdp_certificate_store_load_data on filled store, existing value\n");
 
  316    if (!test_get_data(store, data1))
 
  318    if (!test_get_data_ex(store, data1))
 
  320    if (!test_get_data(store, data2))
 
  322    if (!test_get_data_ex(store, data2))
 
  324    if (!test_get_data(store, data3))
 
  326    if (!test_get_data_ex(store, data3))
 
  330    printf(
"freerdp_certificate_store_save_data modify data\n");
 
  331    if (!freerdp_certificate_store_save_data(store, data4))
 
  335    printf(
"freerdp_certificate_store_load_data check modified data can be loaded\n");
 
  336    if (!test_get_data(store, data4))
 
  338    if (!test_get_data_ex(store, data4))
 
  342    printf(
"freerdp_certificate_store_load_data check original data no longer there\n");
 
  343    if (test_get_data(store, data2))
 
  345    if (test_get_data_ex(store, data2))
 
  349    printf(
"freerdp_certificate_store_remove_data\n");
 
  350    if (!freerdp_certificate_store_remove_data(store, data3))
 
  353    printf(
"freerdp_certificate_store_remove_data missing value\n");
 
  354    if (!freerdp_certificate_store_remove_data(store, data3))
 
  357    printf(
"freerdp_certificate_store_load_data on filled store, existing value\n");
 
  358    if (!test_get_data(store, data1))
 
  360    if (!test_get_data_ex(store, data1))
 
  362    if (!test_get_data(store, data4))
 
  364    if (!test_get_data_ex(store, data4))
 
  367    printf(
"freerdp_certificate_store_load_data on filled store, removed value\n");
 
  368    if (test_get_data(store, data3))
 
  370    if (test_get_data_ex(store, data3))
 
  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);
 
  386int TestKnownHosts(
int argc, 
char* argv[])
 
  391  if (!test_certs_dir())
 
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.