Merge pull request #11634 from akallabeth/tls-config

JSON configuration helpers
This commit is contained in:
akallabeth
2025-05-26 20:01:08 +02:00
committed by GitHub
8 changed files with 91 additions and 151 deletions

View File

@@ -41,10 +41,7 @@ namespace fs = std::experimental::filesystem;
SdlPref::WINPR_JSONPtr SdlPref::get()
{
auto config = get_pref_file();
std::ifstream ifs(config);
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
return { WINPR_JSON_ParseWithLength(content.c_str(), content.size()), WINPR_JSON_Delete };
return { WINPR_JSON_ParseFromFile(config.c_str()), WINPR_JSON_Delete };
}
WINPR_JSON* SdlPref::get_item(const std::string& key)

View File

@@ -21,6 +21,8 @@
#pragma once
#include <winpr/wtypes.h>
#include <winpr/json.h>
#include <freerdp/api.h>
/** @brief Return the absolute path of a configuration file (the path of the configuration
@@ -38,3 +40,15 @@
*/
WINPR_ATTR_MALLOC(free, 1)
FREERDP_API char* freerdp_GetConfigFilePath(BOOL system, const char* filename);
/** @brief return a parsed JSON for a given config file name.
*
* @param system a boolean indicating the configuration base, \b TRUE for system configuration,
* \b FALSE for user configuration
* @param filename an optional configuration file name to append.
*
* @return A parsed \b WINPR_JSON object or \b NULL in case of any failure.
* @since version 3.16.0
*/
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
FREERDP_API WINPR_JSON* freerdp_GetJSONConfigFile(BOOL system, const char* filename);

View File

@@ -1498,42 +1498,6 @@ static int tls_config_parse_bool(WINPR_JSON* json, const char* opt)
return 0;
}
static char* tls_config_read(const char* configfile)
{
char* data = NULL;
FILE* fp = winpr_fopen(configfile, "r");
if (!fp)
return NULL;
const int rc = fseek(fp, 0, SEEK_END);
if (rc != 0)
goto fail;
const INT64 size = _ftelli64(fp);
if (size <= 0)
goto fail;
const int rc2 = fseek(fp, 0, SEEK_SET);
if (rc2 != 0)
goto fail;
data = calloc((size_t)size + 1, sizeof(char));
if (!data)
goto fail;
const size_t read = fread(data, 1, (size_t)size, fp);
if (read != (size_t)size)
{
free(data);
data = NULL;
goto fail;
}
fail:
fclose(fp);
return data;
}
static int tls_config_check_allowed_hashed(const char* configfile, const rdpCertificate* cert,
WINPR_JSON* json)
{
@@ -1604,26 +1568,12 @@ static int tls_config_check_certificate(const rdpCertificate* cert, BOOL* pAllow
WINPR_ASSERT(pAllowUserconfig);
int rc = 0;
char* configfile = freerdp_GetConfigFilePath(TRUE, "certificates.json");
WINPR_JSON* json = NULL;
const char configfile[] = "certificates.json";
WINPR_JSON* json = freerdp_GetJSONConfigFile(TRUE, configfile);
if (!configfile)
{
WLog_DBG(TAG, "No configuration file for certificate handling, asking user");
goto fail;
}
char* configdata = tls_config_read(configfile);
if (!configdata)
{
WLog_DBG(TAG, "Configuration file for certificate handling, asking user");
goto fail;
}
json = WINPR_JSON_Parse(configdata);
if (!json)
{
WLog_DBG(TAG, "No valid configuration file '%s' for certificate handling, asking user",
configfile);
WLog_DBG(TAG, "No or no valid configuration file for certificate handling, asking user");
goto fail;
}
@@ -1659,7 +1609,6 @@ fail:
*pAllowUserconfig = (rc == 0);
WINPR_JSON_Delete(json);
free(configfile);
return rc;
}

View File

@@ -924,7 +924,7 @@ static BOOL load_layout_file(void)
if (!fp)
goto end;
(void)fprintf(fp, "%s", str);
fclose(fp);
(void)fclose(fp);
}
end:
free(str);
@@ -1006,54 +1006,9 @@ static void clear_layout_tables(void)
static WINPR_JSON* load_layouts_from_file(const char* filename)
{
INT64 jstrlen = 0;
char* jstr = NULL;
WINPR_JSON* json = NULL;
FILE* fp = winpr_fopen(filename, "r");
if (!fp)
{
WLog_WARN(TAG, "resource file '%s' does not exist or is not readable", filename);
return NULL;
}
if (_fseeki64(fp, 0, SEEK_END) < 0)
{
WLog_WARN(TAG, "resource file '%s' seek failed", filename);
goto end;
}
jstrlen = _ftelli64(fp);
if (jstrlen < 0)
{
WLog_WARN(TAG, "resource file '%s' invalid length %" PRId64, filename, jstrlen);
goto end;
}
if (_fseeki64(fp, 0, SEEK_SET) < 0)
{
WLog_WARN(TAG, "resource file '%s' seek failed", filename);
goto end;
}
jstr = calloc((size_t)jstrlen + 1, sizeof(char));
if (!jstr)
{
WLog_WARN(TAG, "resource file '%s' failed to allocate buffer of size %" PRId64, filename,
jstrlen);
goto end;
}
if (fread(jstr, (size_t)jstrlen, sizeof(char), fp) != 1)
{
WLog_WARN(TAG, "resource file '%s' failed to read buffer of size %" PRId64, filename,
jstrlen);
goto end;
}
json = WINPR_JSON_ParseWithLength(jstr, (size_t)jstrlen);
WINPR_JSON* json = WINPR_JSON_ParseFromFile(filename);
if (!json)
WLog_WARN(TAG, "resource file '%s' is not a valid JSON file", filename);
end:
fclose(fp);
free(jstr);
return json;
}

View File

@@ -59,3 +59,14 @@ char* freerdp_GetConfigFilePath(BOOL system, const char* filename)
free(base);
return path;
}
WINPR_JSON* freerdp_GetJSONConfigFile(BOOL system, const char* filename)
{
char* path = freerdp_GetConfigFilePath(system, filename);
if (!path)
return NULL;
WINPR_JSON* json = WINPR_JSON_ParseFromFile(path);
free(path);
return json;
}

View File

@@ -77,6 +77,26 @@ extern "C"
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
WINPR_API WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length);
/**
* @brief Parse a JSON string read from a file \b filename
*
* @param filename the name of the file to read from
* @return A @ref WINPR_JSON object holding the parsed string or \b NULL if failed
* @since version 3.16.0
*/
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
WINPR_API WINPR_JSON* WINPR_JSON_ParseFromFile(const char* filename);
/**
* @brief Parse a JSON string read from a \b FILE
*
* @param fp a \b FILE pointer to read from.
* @return A @ref WINPR_JSON object holding the parsed string or \b NULL if failed
* @since version 3.16.0
*/
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
WINPR_API WINPR_JSON* WINPR_JSON_ParseFromFileFP(FILE* fp);
/**
* @brief Get the number of arrayitems from an array
*

View File

@@ -149,54 +149,9 @@ static BOOL tz_parse_json_entry(WINPR_JSON* json, size_t pos, TimeZoneNameMapEnt
static WINPR_JSON* load_timezones_from_file(const char* filename)
{
INT64 jstrlen = 0;
char* jstr = NULL;
WINPR_JSON* json = NULL;
FILE* fp = winpr_fopen(filename, "r");
if (!fp)
{
WLog_WARN(TAG, "Timezone resource file '%s' does not exist or is not readable", filename);
return NULL;
}
if (_fseeki64(fp, 0, SEEK_END) < 0)
{
WLog_WARN(TAG, "Timezone resource file '%s' seek failed", filename);
goto end;
}
jstrlen = _ftelli64(fp);
if (jstrlen < 0)
{
WLog_WARN(TAG, "Timezone resource file '%s' invalid length %" PRId64, filename, jstrlen);
goto end;
}
if (_fseeki64(fp, 0, SEEK_SET) < 0)
{
WLog_WARN(TAG, "Timezone resource file '%s' seek failed", filename);
goto end;
}
jstr = calloc(WINPR_ASSERTING_INT_CAST(size_t, jstrlen + 1), sizeof(char));
if (!jstr)
{
WLog_WARN(TAG, "Timezone resource file '%s' failed to allocate buffer of size %" PRId64,
filename, jstrlen);
goto end;
}
if (fread(jstr, WINPR_ASSERTING_INT_CAST(size_t, jstrlen), sizeof(char), fp) != 1)
{
WLog_WARN(TAG, "Timezone resource file '%s' failed to read buffer of size %" PRId64,
filename, jstrlen);
goto end;
}
json = WINPR_JSON_ParseWithLength(jstr, WINPR_ASSERTING_INT_CAST(size_t, jstrlen));
WINPR_JSON* json = WINPR_JSON_ParseFromFile(filename);
if (!json)
WLog_WARN(TAG, "Timezone resource file '%s' is not a valid JSON file", filename);
end:
fclose(fp);
free(jstr);
return json;
}
#endif

View File

@@ -20,6 +20,7 @@
#include <math.h>
#include <errno.h>
#include <winpr/file.h>
#include <winpr/json.h>
#include <winpr/assert.h>
@@ -679,3 +680,41 @@ char* WINPR_JSON_PrintUnformatted(WINPR_JSON* item)
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_ParseFromFile(const char* filename)
{
FILE* fp = winpr_fopen(filename, "r");
if (!fp)
return NULL;
WINPR_JSON* json = WINPR_JSON_ParseFromFileFP(fp);
(void)fclose(fp);
return json;
}
WINPR_JSON* WINPR_JSON_ParseFromFileFP(FILE* fp)
{
if (!fp)
return NULL;
if (fseek(fp, 0, SEEK_END) != 0)
return NULL;
const INT64 size = _ftelli64(fp);
if (size < 0)
return NULL;
if (fseek(fp, 0, SEEK_SET) != 0)
return NULL;
const size_t usize = WINPR_ASSERTING_INT_CAST(size_t, size);
char* str = calloc(usize + 1, sizeof(char));
if (!str)
return NULL;
WINPR_JSON* json = NULL;
const size_t s = fread(str, sizeof(char), usize, fp);
if (s == usize)
json = WINPR_JSON_ParseWithLength(str, usize);
free(str);
return json;
}