|
Packit Service |
fa4841 |
/**
|
|
Packit Service |
fa4841 |
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Copyright 2015 Thincast Technologies GmbH
|
|
Packit Service |
fa4841 |
* Copyright 2015 Armin Novak <armin.novak@thincast.com>
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit Service |
fa4841 |
* you may not use this file except in compliance with the License.
|
|
Packit Service |
fa4841 |
* You may obtain a copy of the License at
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit Service |
fa4841 |
*
|
|
Packit Service |
fa4841 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit Service |
fa4841 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit Service |
fa4841 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit Service |
fa4841 |
* See the License for the specific language governing permissions and
|
|
Packit Service |
fa4841 |
* limitations under the License.
|
|
Packit Service |
fa4841 |
*/
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#include <winpr/path.h>
|
|
Packit Service |
fa4841 |
#include <winpr/file.h>
|
|
Packit Service |
fa4841 |
#include <winpr/sysinfo.h>
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
#include <freerdp/crypto/certificate.h>
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
static int prepare(const char* currentFileV2, const char* legacyFileV2, const char* legacyFile)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
const char* legacy[] = { "someurl ff:11:22:dd\r\n", "otherurl aa:bb:cc:dd\r",
|
|
Packit Service |
fa4841 |
"legacyurl aa:bb:cc:dd\n" };
|
|
Packit Service |
fa4841 |
const char* hosts[] = { "#somecomment\r\n"
|
|
Packit Service |
fa4841 |
"someurl 3389 ff:11:22:dd subject issuer\r\n"
|
|
Packit Service |
fa4841 |
" \t#anothercomment\r\n"
|
|
Packit Service |
fa4841 |
"otherurl\t3389\taa:bb:cc:dd\tsubject2\tissuer2\r" };
|
|
Packit Service |
fa4841 |
FILE* fl = NULL;
|
|
Packit Service |
fa4841 |
FILE* fc = NULL;
|
|
Packit Service |
fa4841 |
size_t i;
|
|
Packit Service |
fa4841 |
fc = fopen(currentFileV2, "w+");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!fc)
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
fl = fopen(legacyFileV2, "w+");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!fl)
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
for (i = 0; i < ARRAYSIZE(hosts); i++)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
if (fwrite(hosts[i], strlen(hosts[i]), 1, fl) != 1 ||
|
|
Packit Service |
fa4841 |
fwrite(hosts[i], strlen(hosts[i]), 1, fc) != 1)
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
fclose(fc);
|
|
Packit Service |
fa4841 |
fc = NULL;
|
|
Packit Service |
fa4841 |
fclose(fl);
|
|
Packit Service |
fa4841 |
fl = NULL;
|
|
Packit Service |
fa4841 |
fl = fopen(legacyFile, "w+");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!fl)
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
for (i = 0; i < ARRAYSIZE(legacy); i++)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
if (fwrite(legacy[i], strlen(legacy[i]), 1, fl) != 1)
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
fclose(fl);
|
|
Packit Service |
fa4841 |
return 0;
|
|
Packit Service |
fa4841 |
finish:
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (fl)
|
|
Packit Service |
fa4841 |
fclose(fl);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (fc)
|
|
Packit Service |
fa4841 |
fclose(fc);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
return -1;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
int TestKnownHosts(int argc, char* argv[])
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
int rc = -1;
|
|
Packit Service |
fa4841 |
rdpSettings current;
|
|
Packit Service |
fa4841 |
rdpSettings legacy;
|
|
Packit Service |
fa4841 |
rdpCertificateData* data = NULL;
|
|
Packit Service |
fa4841 |
rdpCertificateStore* store = NULL;
|
|
Packit Service |
fa4841 |
char* currentFileV2 = NULL;
|
|
Packit Service |
fa4841 |
char* legacyFileV2 = NULL;
|
|
Packit Service |
fa4841 |
char* legacyFile = NULL;
|
|
Packit Service |
fa4841 |
char* subject = NULL;
|
|
Packit Service |
fa4841 |
char* issuer = NULL;
|
|
Packit Service |
fa4841 |
char* fp = NULL;
|
|
Packit Service |
fa4841 |
char sname[8192];
|
|
Packit Service |
fa4841 |
char dname[8192];
|
|
Packit Service |
fa4841 |
SYSTEMTIME systemTime;
|
|
Packit Service |
fa4841 |
WINPR_UNUSED(argc);
|
|
Packit Service |
fa4841 |
WINPR_UNUSED(argv);
|
|
Packit Service |
fa4841 |
GetSystemTime(&systemTime);
|
|
Packit Service |
fa4841 |
sprintf_s(sname, sizeof(sname),
|
|
Packit Service |
fa4841 |
"TestKnownHostsCurrent-%04" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16
|
|
Packit Service |
fa4841 |
"%02" PRIu16 "%04" PRIu16,
|
|
Packit Service |
fa4841 |
systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
|
|
Packit Service |
fa4841 |
systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
|
|
Packit Service |
fa4841 |
sprintf_s(dname, sizeof(dname),
|
|
Packit Service |
fa4841 |
"TestKnownHostsLegacy-%04" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16
|
|
Packit Service |
fa4841 |
"%02" PRIu16 "%04" PRIu16,
|
|
Packit Service |
fa4841 |
systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
|
|
Packit Service |
fa4841 |
systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
current.ConfigPath = GetKnownSubPath(KNOWN_PATH_TEMP, sname);
|
|
Packit Service |
fa4841 |
legacy.ConfigPath = GetKnownSubPath(KNOWN_PATH_TEMP, dname);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!PathFileExistsA(current.ConfigPath))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
if (!CreateDirectoryA(current.ConfigPath, NULL))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create %s!\n", current.ConfigPath);
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!PathFileExistsA(legacy.ConfigPath))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
if (!CreateDirectoryA(legacy.ConfigPath, NULL))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create %s!\n", legacy.ConfigPath);
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
currentFileV2 = GetCombinedPath(current.ConfigPath, "known_hosts2");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!currentFileV2)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not get file path!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
legacyFileV2 = GetCombinedPath(legacy.ConfigPath, "known_hosts2");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!legacyFileV2)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not get file path!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
legacyFile = GetCombinedPath(legacy.ConfigPath, "known_hosts");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!legacyFile)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not get file path!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
store = certificate_store_new(¤t;;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!store)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate store!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (prepare(currentFileV2, legacyFileV2, legacyFile))
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
/* Test if host is found in current file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("someurl", 3389, "subject", "issuer", "ff:11:22:dd");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 != certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not find data in v2 file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
/* Test if we can read out the old fingerprint. */
|
|
Packit Service |
fa4841 |
if (!certificate_get_stored_data(store, data, &subject, &issuer, &fp))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not read old fingerprint!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
printf("Got %s, %s '%s'\n", subject, issuer, fp);
|
|
Packit Service |
fa4841 |
free(subject);
|
|
Packit Service |
fa4841 |
free(issuer);
|
|
Packit Service |
fa4841 |
free(fp);
|
|
Packit Service |
fa4841 |
subject = NULL;
|
|
Packit Service |
fa4841 |
issuer = NULL;
|
|
Packit Service |
fa4841 |
fp = NULL;
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
/* Test if host not found in current file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("somehost", 1234, "", "", "ff:aa:bb:cc");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 == certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Invalid host found in v2 file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
/* Test if we read out the old fingerprint fails. */
|
|
Packit Service |
fa4841 |
if (certificate_get_stored_data(store, data, &subject, &issuer, &fp))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Read out not existing old fingerprint succeeded?!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
/* Test host add current file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("somehost", 1234, "", "", "ff:aa:bb:cc");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!certificate_data_print(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not add host to file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 != certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not find host written in v2 file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
/* Test host replace current file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("somehost", 1234, "", "", "ff:aa:bb:dd:ee");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!certificate_data_replace(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not replace data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 != certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Invalid host found in v2 file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
/* Test host replace invalid entry in current file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("somehostXXXX", 1234, "", "", "ff:aa:bb:dd:ee");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (certificate_data_replace(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Invalid return for replace invalid entry!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 == certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Invalid host found in v2 file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
certificate_store_free(store);
|
|
Packit Service |
fa4841 |
store = certificate_store_new(&legacy);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!store)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "could not create certificate store!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
/* test if host found in legacy file. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("legacyurl", 1234, "", "", "aa:bb:cc:dd");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 != certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not find host in file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
/* test if host not found. */
|
|
Packit Service |
fa4841 |
data = certificate_data_new("somehost-not-in-file", 1234, "", "", "ff:aa:bb:cc");
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (!data)
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Could not create certificate data!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (0 == certificate_data_match(store, data))
|
|
Packit Service |
fa4841 |
{
|
|
Packit Service |
fa4841 |
fprintf(stderr, "Invalid host found in file!\n");
|
|
Packit Service |
fa4841 |
goto finish;
|
|
Packit Service |
fa4841 |
}
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
rc = 0;
|
|
Packit Service |
fa4841 |
finish:
|
|
Packit Service |
fa4841 |
free(current.ConfigPath);
|
|
Packit Service |
fa4841 |
free(legacy.ConfigPath);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (store)
|
|
Packit Service |
fa4841 |
certificate_store_free(store);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
if (data)
|
|
Packit Service |
fa4841 |
certificate_data_free(data);
|
|
Packit Service |
fa4841 |
|
|
Packit Service |
fa4841 |
DeleteFileA(currentFileV2);
|
|
Packit Service |
fa4841 |
// RemoveDirectoryA(current.ConfigPath);
|
|
Packit Service |
fa4841 |
DeleteFileA(legacyFileV2);
|
|
Packit Service |
fa4841 |
DeleteFileA(legacyFile);
|
|
Packit Service |
fa4841 |
// RemoveDirectoryA(legacy.ConfigPath);
|
|
Packit Service |
fa4841 |
free(currentFileV2);
|
|
Packit Service |
fa4841 |
free(legacyFileV2);
|
|
Packit Service |
fa4841 |
free(legacyFile);
|
|
Packit Service |
fa4841 |
free(subject);
|
|
Packit Service |
fa4841 |
free(issuer);
|
|
Packit Service |
fa4841 |
free(fp);
|
|
Packit Service |
fa4841 |
return rc;
|
|
Packit Service |
fa4841 |
}
|