[core,client] replace cJSON with WinPR wrapper

use the new WinPR JSON wrapper API
This commit is contained in:
akallabeth 2024-05-14 17:41:06 +02:00
parent 1b735a5c17
commit aaded541d9
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
9 changed files with 116 additions and 207 deletions

View File

@ -561,9 +561,6 @@ endif()
find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DESCRIPTION}) find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DESCRIPTION})
find_package(cJSON)
option(WITH_AAD "Compile with support for Azure AD authentication" ${cJSON_FOUND})
if (WITH_DSP_FFMPEG OR WITH_VIDEO_FFMPEG OR WITH_FFMPEG) if (WITH_DSP_FFMPEG OR WITH_VIDEO_FFMPEG OR WITH_FFMPEG)
set(FFMPEG_FEATURE_TYPE "REQUIRED" ) set(FFMPEG_FEATURE_TYPE "REQUIRED" )
endif() endif()
@ -730,6 +727,8 @@ else()
include_directories(${WinPR_INCLUDE_DIR}) include_directories(${WinPR_INCLUDE_DIR})
endif() endif()
option(WITH_AAD "Compile with support for Azure AD authentication" ${WITH_WINPR_JSON})
# Include directories # Include directories
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)

View File

@ -62,14 +62,8 @@ endif()
find_package(SDL2 REQUIRED COMPONENTS) find_package(SDL2 REQUIRED COMPONENTS)
include_directories(${SDL2_INCLUDE_DIR}) include_directories(${SDL2_INCLUDE_DIR})
include_directories(${SDL2_INCLUDE_DIRS}) include_directories(${SDL2_INCLUDE_DIRS})
find_package(cJSON)
set(LIBS "") set(LIBS "")
if (cJSON_FOUND)
include_directories(${CJSON_INCLUDE_DIRS})
list(APPEND LIBS ${CJSON_LIBRARIES})
add_compile_definitions(CJSON_FOUND)
endif()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)

View File

@ -40,6 +40,7 @@
#include <freerdp/channels/channels.h> #include <freerdp/channels/channels.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/config.h>
#include <winpr/assert.h> #include <winpr/assert.h>
#include <winpr/synch.h> #include <winpr/synch.h>
#include <freerdp/log.h> #include <freerdp/log.h>
@ -1553,7 +1554,7 @@ static void SDLCALL winpr_LogOutputFunction(void* userdata, int category, SDL_Lo
static void print_config_file_help() static void print_config_file_help()
{ {
#if defined(CJSON_FOUND) #if defined(WITH_WINPR_JSON)
std::cout << "CONFIGURATION FILE" << std::endl; std::cout << "CONFIGURATION FILE" << std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout << " The SDL client supports some user defined configuration options." << std::endl; std::cout << " The SDL client supports some user defined configuration options." << std::endl;

View File

@ -36,10 +36,9 @@ namespace fs = std::experimental::filesystem;
#include <SDL.h> #include <SDL.h>
#include <winpr/path.h> #include <winpr/path.h>
#include <winpr/config.h>
#include <freerdp/version.h> #include <freerdp/version.h>
#if defined(CJSON_FOUND) #include <winpr/json.h>
#include <cjson/cJSON.h>
#endif
const char* sdl_event_type_str(Uint32 type) const char* sdl_event_type_str(Uint32 type)
{ {
@ -355,33 +354,33 @@ std::string sdl_window_event_str(Uint8 ev)
} }
} }
#if defined(CJSON_FOUND) #if defined(WINPR_JSON_FOUND)
using cJSONPtr = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>; using WINPR_JSONPtr = std::unique_ptr<WINPR_JSON, decltype(&WINPR_JSON_Delete)>;
static cJSONPtr get() static WINPR_JSONPtr get()
{ {
auto config = sdl_get_pref_file(); auto config = sdl_get_pref_file();
std::ifstream ifs(config); std::ifstream ifs(config);
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
return { cJSON_ParseWithLength(content.c_str(), content.size()), cJSON_Delete }; return { WINPR_JSON_ParseWithLength(content.c_str(), content.size()), WINPR_JSON_Delete };
} }
static cJSON* get_item(const std::string& key) static WINPR_JSON* get_item(const std::string& key)
{ {
static cJSONPtr config{ nullptr, cJSON_Delete }; static WINPR_JSONPtr config{ nullptr, WINPR_JSON_Delete };
if (!config) if (!config)
config = get(); config = get();
if (!config) if (!config)
return nullptr; return nullptr;
return cJSON_GetObjectItem(config.get(), key.c_str()); return WINPR_JSON_GetObjectItem(config.get(), key.c_str());
} }
static std::string item_to_str(cJSON* item, const std::string& fallback = "") static std::string item_to_str(WINPR_JSON* item, const std::string& fallback = "")
{ {
if (!item || !cJSON_IsString(item)) if (!item || !WINPR_JSON_IsString(item))
return fallback; return fallback;
auto str = cJSON_GetStringValue(item); auto str = WINPR_JSON_GetStringValue(item);
if (!str) if (!str)
return {}; return {};
return str; return str;
@ -390,7 +389,7 @@ static std::string item_to_str(cJSON* item, const std::string& fallback = "")
std::string sdl_get_pref_string(const std::string& key, const std::string& fallback) std::string sdl_get_pref_string(const std::string& key, const std::string& fallback)
{ {
#if defined(CJSON_FOUND) #if defined(WINPR_JSON_FOUND)
auto item = get_item(key); auto item = get_item(key);
return item_to_str(item, fallback); return item_to_str(item, fallback);
#else #else
@ -400,11 +399,11 @@ std::string sdl_get_pref_string(const std::string& key, const std::string& fallb
bool sdl_get_pref_bool(const std::string& key, bool fallback) bool sdl_get_pref_bool(const std::string& key, bool fallback)
{ {
#if defined(CJSON_FOUND) #if defined(WINPR_JSON_FOUND)
auto item = get_item(key); auto item = get_item(key);
if (!item || !cJSON_IsBool(item)) if (!item || !WINPR_JSON_IsBool(item))
return fallback; return fallback;
return cJSON_IsTrue(item); return WINPR_JSON_IsTrue(item);
#else #else
return fallback; return fallback;
#endif #endif
@ -412,11 +411,11 @@ bool sdl_get_pref_bool(const std::string& key, bool fallback)
int64_t sdl_get_pref_int(const std::string& key, int64_t fallback) int64_t sdl_get_pref_int(const std::string& key, int64_t fallback)
{ {
#if defined(CJSON_FOUND) #if defined(WINPR_JSON_FOUND)
auto item = get_item(key); auto item = get_item(key);
if (!item || !cJSON_IsNumber(item)) if (!item || !WINPR_JSON_IsNumber(item))
return fallback; return fallback;
auto val = cJSON_GetNumberValue(item); auto val = WINPR_JSON_GetNumberValue(item);
return static_cast<int64_t>(val); return static_cast<int64_t>(val);
#else #else
return fallback; return fallback;
@ -426,15 +425,15 @@ int64_t sdl_get_pref_int(const std::string& key, int64_t fallback)
std::vector<std::string> sdl_get_pref_array(const std::string& key, std::vector<std::string> sdl_get_pref_array(const std::string& key,
const std::vector<std::string>& fallback) const std::vector<std::string>& fallback)
{ {
#if defined(CJSON_FOUND) #if defined(WINPR_JSON_FOUND)
auto item = get_item(key); auto item = get_item(key);
if (!item || !cJSON_IsArray(item)) if (!item || !WINPR_JSON_IsArray(item))
return fallback; return fallback;
std::vector<std::string> values; std::vector<std::string> values;
for (int x = 0; x < cJSON_GetArraySize(item); x++) for (int x = 0; x < WINPR_JSON_GetArraySize(item); x++)
{ {
auto cur = cJSON_GetArrayItem(item, x); auto cur = WINPR_JSON_GetArrayItem(item, x);
values.push_back(item_to_str(cur)); values.push_back(item_to_str(cur));
} }

View File

@ -248,23 +248,9 @@ if(FAAC_FOUND)
endif() endif()
if (WITH_AAD) if (WITH_AAD)
if (NOT cJSON_FOUND) if (NOT WITH_WINPR_JSON)
find_package(PkgConfig REQUIRED) message(FATAL_ERROR "Trying to build -DWITH_AAD=ON but WITH_WINPR_JSON is not defined")
pkg_check_modules(CJSON libcjson)
endif() endif()
if (NOT CJSON_LIBRARIES OR NOT CJSON_INCLUDE_DIRS)
find_path(CJSON_INCLUDE_DIRS
NAMES cjson/cJSON.h
REQUIRED
)
find_library(CJSON_LIBRARIES
NAMES cjson
REQUIRED
)
endif()
freerdp_library_add(${CJSON_LIBRARIES})
include_directories(${CJSON_INCLUDE_DIRS})
endif() endif()
if(WITH_NEON) if(WITH_NEON)
@ -424,10 +410,7 @@ set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
include(pkg-config-install-prefix) include(pkg-config-install-prefix)
set(FREERDP_REQUIRES_PRIVATE "") set(FREERDP_REQUIRES_PRIVATE "")
if(cJSON_FOUND)
string(APPEND FREERDP_REQUIRES_PRIVATE " libcjson")
list(APPEND FREERDP_PC_PRIVATE_LIBS "-lcjson")
endif()
if(WITH_SMARTCARD_EMULATE) if(WITH_SMARTCARD_EMULATE)
string(APPEND FREERDP_REQUIRES_PRIVATE " zlib") string(APPEND FREERDP_REQUIRES_PRIVATE " zlib")
list(APPEND FREERDP_PC_PRIVATE_LIBS "-lz") list(APPEND FREERDP_PC_PRIVATE_LIBS "-lz")

View File

@ -1,8 +1,6 @@
include(CMakeFindDependencyMacro) include(CMakeFindDependencyMacro)
find_dependency(WinPR @FREERDP_VERSION@) find_dependency(WinPR @FREERDP_VERSION@)
if("@cJSON_FOUND@" AND NOT "@BUILD_SHARED_LIBS@")
find_dependency(cJSON)
endif()
if("@WITH_SMARTCARD_EMULATE@" AND NOT "@BUILD_SHARED_LIBS@") if("@WITH_SMARTCARD_EMULATE@" AND NOT "@BUILD_SHARED_LIBS@")
find_dependency(ZLIB) find_dependency(ZLIB)
endif() endif()

View File

@ -29,6 +29,7 @@
#include <freerdp/utils/aad.h> #include <freerdp/utils/aad.h>
#include <winpr/crypto.h> #include <winpr/crypto.h>
#include <winpr/json.h>
#include "transport.h" #include "transport.h"
@ -78,18 +79,18 @@ static SSIZE_T stream_sprintf(wStream* s, WINPR_FORMAT_ARG const char* fmt, ...)
return rc2; return rc2;
} }
static BOOL json_get_object(wLog* wlog, cJSON* json, const char* key, cJSON** obj) static BOOL json_get_object(wLog* wlog, WINPR_JSON* json, const char* key, WINPR_JSON** obj)
{ {
WINPR_ASSERT(json); WINPR_ASSERT(json);
WINPR_ASSERT(key); WINPR_ASSERT(key);
if (!cJSON_HasObjectItem(json, key)) if (!WINPR_JSON_HasObjectItem(json, key))
{ {
WLog_Print(wlog, WLOG_ERROR, "[json] does not contain a key '%s'", key); WLog_Print(wlog, WLOG_ERROR, "[json] does not contain a key '%s'", key);
return FALSE; return FALSE;
} }
cJSON* prop = cJSON_GetObjectItem(json, key); WINPR_JSON* prop = WINPR_JSON_GetObjectItem(json, key);
if (!prop) if (!prop)
{ {
WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NULL", key); WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NULL", key);
@ -99,80 +100,45 @@ static BOOL json_get_object(wLog* wlog, cJSON* json, const char* key, cJSON** ob
return TRUE; return TRUE;
} }
#if defined(USE_CJSON_COMPAT) static BOOL json_get_number(wLog* wlog, WINPR_JSON* json, const char* key, double* result)
static double cJSON_GetNumberValue(const cJSON* const prop)
{
#ifndef NAN
#ifdef _WIN32
#define NAN sqrt(-1.0)
#define COMPAT_NAN_UNDEF
#else
#define NAN 0.0 / 0.0
#define COMPAT_NAN_UNDEF
#endif
#endif
if (!cJSON_IsNumber(prop))
return NAN;
char* val = cJSON_GetStringValue(prop);
if (!val)
return NAN;
errno = 0;
char* endptr = NULL;
double dval = strtod(val, &endptr);
if (val == endptr)
return NAN;
if (endptr != NULL)
return NAN;
if (errno != 0)
return NAN;
return dval;
#ifdef COMPAT_NAN_UNDEF
#undef NAN
#endif
}
#endif
static BOOL json_get_number(wLog* wlog, cJSON* json, const char* key, double* result)
{ {
BOOL rc = FALSE; BOOL rc = FALSE;
cJSON* prop = NULL; WINPR_JSON* prop = NULL;
if (!json_get_object(wlog, json, key, &prop)) if (!json_get_object(wlog, json, key, &prop))
return FALSE; return FALSE;
if (!cJSON_IsNumber(prop)) if (!WINPR_JSON_IsNumber(prop))
{ {
WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NOT a NUMBER", key); WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NOT a NUMBER", key);
goto fail; goto fail;
} }
*result = cJSON_GetNumberValue(prop); *result = WINPR_JSON_GetNumberValue(prop);
rc = TRUE; rc = TRUE;
fail: fail:
return rc; return rc;
} }
static BOOL json_get_const_string(wLog* wlog, cJSON* json, const char* key, const char** result) static BOOL json_get_const_string(wLog* wlog, WINPR_JSON* json, const char* key,
const char** result)
{ {
BOOL rc = FALSE; BOOL rc = FALSE;
WINPR_ASSERT(result); WINPR_ASSERT(result);
*result = NULL; *result = NULL;
cJSON* prop = NULL; WINPR_JSON* prop = NULL;
if (!json_get_object(wlog, json, key, &prop)) if (!json_get_object(wlog, json, key, &prop))
return FALSE; return FALSE;
if (!cJSON_IsString(prop)) if (!WINPR_JSON_IsString(prop))
{ {
WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NOT a STRING", key); WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NOT a STRING", key);
goto fail; goto fail;
} }
const char* str = cJSON_GetStringValue(prop); const char* str = WINPR_JSON_GetStringValue(prop);
if (!str) if (!str)
WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NULL", key); WLog_Print(wlog, WLOG_ERROR, "[json] object for key '%s' is NULL", key);
*result = str; *result = str;
@ -182,7 +148,7 @@ fail:
return rc; return rc;
} }
static BOOL json_get_string_alloc(wLog* wlog, cJSON* json, const char* key, char** result) static BOOL json_get_string_alloc(wLog* wlog, WINPR_JSON* json, const char* key, char** result)
{ {
const char* str = NULL; const char* str = NULL;
if (!json_get_const_string(wlog, json, key, &str)) if (!json_get_const_string(wlog, json, key, &str))
@ -194,20 +160,6 @@ static BOOL json_get_string_alloc(wLog* wlog, cJSON* json, const char* key, char
return *result != NULL; return *result != NULL;
} }
#if defined(USE_CJSON_COMPAT)
cJSON* cJSON_ParseWithLength(const char* value, size_t buffer_length)
{
// Check for string '\0' termination.
const size_t slen = strnlen(value, buffer_length);
if (slen >= buffer_length)
{
if (value[buffer_length] != '\0')
return NULL;
}
return cJSON_Parse(value);
}
#endif
static INLINE const char* aad_auth_result_to_string(DWORD code) static INLINE const char* aad_auth_result_to_string(DWORD code)
{ {
#define ERROR_CASE(cd, x) \ #define ERROR_CASE(cd, x) \
@ -232,7 +184,7 @@ static BOOL aad_get_nonce(rdpAad* aad)
BYTE* response = NULL; BYTE* response = NULL;
long resp_code = 0; long resp_code = 0;
size_t response_length = 0; size_t response_length = 0;
cJSON* json = NULL; WINPR_JSON* json = NULL;
if (!freerdp_http_request("https://login.microsoftonline.com/common/oauth2/v2.0/token", if (!freerdp_http_request("https://login.microsoftonline.com/common/oauth2/v2.0/token",
"grant_type=srv_challenge", &resp_code, &response, &response_length)) "grant_type=srv_challenge", &resp_code, &response, &response_length))
@ -250,7 +202,7 @@ static BOOL aad_get_nonce(rdpAad* aad)
goto fail; goto fail;
} }
json = cJSON_ParseWithLength((const char*)response, response_length); json = WINPR_JSON_ParseWithLength((const char*)response, response_length);
if (!json) if (!json)
{ {
WLog_Print(aad->log, WLOG_ERROR, "Failed to parse nonce response"); WLog_Print(aad->log, WLOG_ERROR, "Failed to parse nonce response");
@ -264,7 +216,7 @@ static BOOL aad_get_nonce(rdpAad* aad)
fail: fail:
free(response); free(response);
cJSON_Delete(json); WINPR_JSON_Delete(json);
return ret; return ret;
} }
@ -536,12 +488,12 @@ static int aad_parse_state_initial(rdpAad* aad, wStream* s)
const size_t jlen = Stream_GetRemainingLength(s); const size_t jlen = Stream_GetRemainingLength(s);
const char* ts_nonce = NULL; const char* ts_nonce = NULL;
int ret = -1; int ret = -1;
cJSON* json = NULL; WINPR_JSON* json = NULL;
if (!Stream_SafeSeek(s, jlen)) if (!Stream_SafeSeek(s, jlen))
goto fail; goto fail;
json = cJSON_ParseWithLength(jstr, jlen); json = WINPR_JSON_ParseWithLength(jstr, jlen);
if (!json) if (!json)
goto fail; goto fail;
@ -550,7 +502,7 @@ static int aad_parse_state_initial(rdpAad* aad, wStream* s)
ret = aad_send_auth_request(aad, ts_nonce); ret = aad_send_auth_request(aad, ts_nonce);
fail: fail:
cJSON_Delete(json); WINPR_JSON_Delete(json);
return ret; return ret;
} }
@ -559,14 +511,14 @@ static int aad_parse_state_auth(rdpAad* aad, wStream* s)
int rc = -1; int rc = -1;
double result = 0; double result = 0;
DWORD error_code = 0; DWORD error_code = 0;
cJSON* json = NULL; WINPR_JSON* json = NULL;
const char* jstr = Stream_PointerAs(s, char); const char* jstr = Stream_PointerAs(s, char);
const size_t jlength = Stream_GetRemainingLength(s); const size_t jlength = Stream_GetRemainingLength(s);
if (!Stream_SafeSeek(s, jlength)) if (!Stream_SafeSeek(s, jlength))
goto fail; goto fail;
json = cJSON_ParseWithLength(jstr, jlength); json = WINPR_JSON_ParseWithLength(jstr, jlength);
if (!json) if (!json)
goto fail; goto fail;
@ -583,7 +535,7 @@ static int aad_parse_state_auth(rdpAad* aad, wStream* s)
aad->state = AAD_STATE_FINAL; aad->state = AAD_STATE_FINAL;
rc = 1; rc = 1;
fail: fail:
cJSON_Delete(json); WINPR_JSON_Delete(json);
return rc; return rc;
} }
@ -846,10 +798,10 @@ BOOL aad_is_supported(void)
char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t length) char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t length)
{ {
char* token = NULL; char* token = NULL;
cJSON* access_token_prop = NULL; WINPR_JSON* access_token_prop = NULL;
const char* access_token_str = NULL; const char* access_token_str = NULL;
cJSON* json = cJSON_ParseWithLength(data, length); WINPR_JSON* json = WINPR_JSON_ParseWithLength(data, length);
if (!json) if (!json)
{ {
WLog_Print(log, WLOG_ERROR, "Failed to parse access token response [got %" PRIuz " bytes", WLog_Print(log, WLOG_ERROR, "Failed to parse access token response [got %" PRIuz " bytes",
@ -857,14 +809,14 @@ char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t len
goto cleanup; goto cleanup;
} }
access_token_prop = cJSON_GetObjectItem(json, "access_token"); access_token_prop = WINPR_JSON_GetObjectItem(json, "access_token");
if (!access_token_prop) if (!access_token_prop)
{ {
WLog_Print(log, WLOG_ERROR, "Response has no \"access_token\" property"); WLog_Print(log, WLOG_ERROR, "Response has no \"access_token\" property");
goto cleanup; goto cleanup;
} }
access_token_str = cJSON_GetStringValue(access_token_prop); access_token_str = WINPR_JSON_GetStringValue(access_token_prop);
if (!access_token_str) if (!access_token_str)
{ {
WLog_Print(log, WLOG_ERROR, "Invalid value for \"access_token\""); WLog_Print(log, WLOG_ERROR, "Invalid value for \"access_token\"");
@ -874,7 +826,7 @@ char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t len
token = _strdup(access_token_str); token = _strdup(access_token_str);
cleanup: cleanup:
cJSON_Delete(json); WINPR_JSON_Delete(json);
return token; return token;
} }
#endif #endif

View File

@ -32,18 +32,6 @@ typedef enum
#include <freerdp/api.h> #include <freerdp/api.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#ifdef WITH_AAD
#include <cjson/cJSON.h>
#if CJSON_VERSION_MAJOR == 1
#if CJSON_VERSION_MINOR <= 7
#if CJSON_VERSION_PATCH < 13
#define USE_CJSON_COMPAT
#endif
#endif
#endif
#endif
FREERDP_LOCAL BOOL aad_is_supported(void); FREERDP_LOCAL BOOL aad_is_supported(void);
FREERDP_LOCAL int aad_client_begin(rdpAad* aad); FREERDP_LOCAL int aad_client_begin(rdpAad* aad);
@ -56,8 +44,4 @@ FREERDP_LOCAL void aad_free(rdpAad* aad);
WINPR_ATTR_MALLOC(aad_free, 1) WINPR_ATTR_MALLOC(aad_free, 1)
FREERDP_LOCAL rdpAad* aad_new(rdpContext* context, rdpTransport* transport); FREERDP_LOCAL rdpAad* aad_new(rdpContext* context, rdpTransport* transport);
#if defined(USE_CJSON_COMPAT)
FREERDP_API cJSON* cJSON_ParseWithLength(const char* value, size_t buffer_length);
#endif
#endif /* FREERDP_LIB_CORE_AAD_H */ #endif /* FREERDP_LIB_CORE_AAD_H */

View File

@ -53,10 +53,7 @@
#include "../utils.h" #include "../utils.h"
#include "../redirection.h" #include "../redirection.h"
//#define WITH_AAD #include <winpr/json.h>
#ifdef WITH_AAD
#include <cjson/cJSON.h>
#endif
#include <string.h> #include <string.h>
@ -296,10 +293,10 @@ static char* arm_create_request_json(rdpArm* arm)
WINPR_ASSERT(arm); WINPR_ASSERT(arm);
cJSON* json = cJSON_CreateObject(); WINPR_JSON* json = WINPR_JSON_CreateObject();
if (!json) if (!json)
goto arm_create_cleanup; goto arm_create_cleanup;
cJSON_AddStringToObject( WINPR_JSON_AddStringToObject(
json, "application", json, "application",
freerdp_settings_get_string(arm->context->settings, FreeRDP_RemoteApplicationProgram)); freerdp_settings_get_string(arm->context->settings, FreeRDP_RemoteApplicationProgram));
@ -313,14 +310,14 @@ static char* arm_create_request_json(rdpArm* arm)
freerdp_settings_get_uint32(arm->context->settings, FreeRDP_LoadBalanceInfoLength); freerdp_settings_get_uint32(arm->context->settings, FreeRDP_LoadBalanceInfoLength);
memcpy(lbi, freerdp_settings_get_pointer(arm->context->settings, FreeRDP_LoadBalanceInfo), len); memcpy(lbi, freerdp_settings_get_pointer(arm->context->settings, FreeRDP_LoadBalanceInfo), len);
cJSON_AddStringToObject(json, "loadBalanceInfo", lbi); WINPR_JSON_AddStringToObject(json, "loadBalanceInfo", lbi);
cJSON_AddNullToObject(json, "LogonToken"); WINPR_JSON_AddNullToObject(json, "LogonToken");
cJSON_AddNullToObject(json, "gatewayLoadBalancerToken"); WINPR_JSON_AddNullToObject(json, "gatewayLoadBalancerToken");
message = cJSON_PrintUnformatted(json); message = WINPR_JSON_PrintUnformatted(json);
arm_create_cleanup: arm_create_cleanup:
if (json) if (json)
cJSON_Delete(json); WINPR_JSON_Delete(json);
free(lbi); free(lbi);
return message; return message;
} }
@ -529,17 +526,17 @@ out:
* base64.b64decode( base64.b64decode(input).decode('utf-16') ) * base64.b64decode( base64.b64decode(input).decode('utf-16') )
* in python * in python
*/ */
static BOOL arm_pick_base64Utf16Field(const cJSON* json, const char* name, BYTE** poutput, static BOOL arm_pick_base64Utf16Field(const WINPR_JSON* json, const char* name, BYTE** poutput,
size_t* plen) size_t* plen)
{ {
*poutput = NULL; *poutput = NULL;
*plen = 0; *plen = 0;
const cJSON* node = cJSON_GetObjectItemCaseSensitive(json, name); WINPR_JSON* node = WINPR_JSON_GetObjectItemCaseSensitive(json, name);
if (!node || !cJSON_IsString(node)) if (!node || !WINPR_JSON_IsString(node))
return TRUE; return TRUE;
char* nodeValue = cJSON_GetStringValue(node); const char* nodeValue = WINPR_JSON_GetStringValue(node);
if (!nodeValue) if (!nodeValue)
return TRUE; return TRUE;
@ -600,27 +597,27 @@ static BOOL arm_pick_base64Utf16Field(const cJSON* json, const char* name, BYTE*
static BOOL arm_treat_azureInstanceNetworkMetadata(const char* metadata, rdpSettings* settings) static BOOL arm_treat_azureInstanceNetworkMetadata(const char* metadata, rdpSettings* settings)
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
cJSON* json = cJSON_Parse(metadata); WINPR_JSON* json = WINPR_JSON_Parse(metadata);
if (!json) if (!json)
{ {
WLog_ERR(TAG, "invalid azureInstanceNetworkMetadata"); WLog_ERR(TAG, "invalid azureInstanceNetworkMetadata");
return FALSE; return FALSE;
} }
const cJSON* iface = cJSON_GetObjectItem(json, "interface"); WINPR_JSON* iface = WINPR_JSON_GetObjectItem(json, "interface");
if (!iface) if (!iface)
{ {
ret = TRUE; ret = TRUE;
goto out; goto out;
} }
if (!cJSON_IsArray(iface)) if (!WINPR_JSON_IsArray(iface))
{ {
WLog_ERR(TAG, "expecting interface to be an Array"); WLog_ERR(TAG, "expecting interface to be an Array");
goto out; goto out;
} }
int interfaceSz = cJSON_GetArraySize(iface); size_t interfaceSz = WINPR_JSON_GetArraySize(iface);
if (interfaceSz == 0) if (interfaceSz == 0)
{ {
WLog_WARN(TAG, "no addresses in azure instance metadata"); WLog_WARN(TAG, "no addresses in azure instance metadata");
@ -628,32 +625,32 @@ static BOOL arm_treat_azureInstanceNetworkMetadata(const char* metadata, rdpSett
goto out; goto out;
} }
for (int i = 0; i < interfaceSz; i++) for (size_t i = 0; i < interfaceSz; i++)
{ {
const cJSON* interN = cJSON_GetArrayItem(iface, i); WINPR_JSON* interN = WINPR_JSON_GetArrayItem(iface, i);
if (!interN) if (!interN)
continue; continue;
const cJSON* ipv4 = cJSON_GetObjectItem(interN, "ipv4"); WINPR_JSON* ipv4 = WINPR_JSON_GetObjectItem(interN, "ipv4");
if (!ipv4) if (!ipv4)
continue; continue;
const cJSON* ipAddress = cJSON_GetObjectItem(ipv4, "ipAddress"); WINPR_JSON* ipAddress = WINPR_JSON_GetObjectItem(ipv4, "ipAddress");
if (!ipAddress || !cJSON_IsArray(ipAddress)) if (!ipAddress || !WINPR_JSON_IsArray(ipAddress))
continue; continue;
int naddresses = cJSON_GetArraySize(ipAddress); size_t naddresses = WINPR_JSON_GetArraySize(ipAddress);
for (int j = 0; j < naddresses; j++) for (size_t j = 0; j < naddresses; j++)
{ {
const cJSON* adressN = cJSON_GetArrayItem(ipAddress, j); WINPR_JSON* adressN = WINPR_JSON_GetArrayItem(ipAddress, j);
if (!adressN) if (!adressN)
continue; continue;
const cJSON* publicIpNode = cJSON_GetObjectItem(adressN, "publicIpAddress"); WINPR_JSON* publicIpNode = WINPR_JSON_GetObjectItem(adressN, "publicIpAddress");
if (!publicIpNode || !cJSON_IsString(publicIpNode)) if (!publicIpNode || !WINPR_JSON_IsString(publicIpNode))
continue; continue;
char* publicIp = cJSON_GetStringValue(publicIpNode); const char* publicIp = WINPR_JSON_GetStringValue(publicIpNode);
if (publicIp && strlen(publicIp) && if (publicIp && strlen(publicIp) &&
freerdp_settings_set_string(settings, FreeRDP_RedirectionTargetFQDN, publicIp)) freerdp_settings_set_string(settings, FreeRDP_RedirectionTargetFQDN, publicIp))
{ {
@ -667,11 +664,11 @@ static BOOL arm_treat_azureInstanceNetworkMetadata(const char* metadata, rdpSett
ret = TRUE; ret = TRUE;
out: out:
cJSON_Delete(json); WINPR_JSON_Delete(json);
return ret; return ret;
} }
static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const cJSON* json) static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const WINPR_JSON* json)
{ {
BOOL ret = TRUE; BOOL ret = TRUE;
BYTE* cert = NULL; BYTE* cert = NULL;
@ -681,12 +678,12 @@ static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const cJSON* jso
do do
{ {
/* redirectedAuthGuid */ /* redirectedAuthGuid */
const cJSON* redirectedAuthGuidNode = WINPR_JSON* redirectedAuthGuidNode =
cJSON_GetObjectItemCaseSensitive(json, "redirectedAuthGuid"); WINPR_JSON_GetObjectItemCaseSensitive(json, "redirectedAuthGuid");
if (!redirectedAuthGuidNode || !cJSON_IsString(redirectedAuthGuidNode)) if (!redirectedAuthGuidNode || !WINPR_JSON_IsString(redirectedAuthGuidNode))
break; break;
char* redirectedAuthGuid = cJSON_GetStringValue(redirectedAuthGuidNode); const char* redirectedAuthGuid = WINPR_JSON_GetStringValue(redirectedAuthGuidNode);
if (!redirectedAuthGuid) if (!redirectedAuthGuid)
break; break;
@ -750,34 +747,35 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
WINPR_ASSERT(arm->context); WINPR_ASSERT(arm->context);
WINPR_ASSERT(message); WINPR_ASSERT(message);
cJSON* json = cJSON_ParseWithLength(message, len); WINPR_JSON* json = WINPR_JSON_ParseWithLength(message, len);
BOOL status = FALSE; BOOL status = FALSE;
if (!json) if (!json)
return FALSE; return FALSE;
rdpSettings* settings = arm->context->settings; rdpSettings* settings = arm->context->settings;
const cJSON* gwurl = cJSON_GetObjectItemCaseSensitive(json, "gatewayLocation"); WINPR_JSON* gwurl = WINPR_JSON_GetObjectItemCaseSensitive(json, "gatewayLocation");
if (cJSON_IsString(gwurl) && (gwurl->valuestring != NULL)) const char* gwurlstr = WINPR_JSON_GetStringValue(gwurl);
if (gwurlstr != NULL)
{ {
WLog_DBG(TAG, "extracted target url %s", gwurl->valuestring); WLog_DBG(TAG, "extracted target url %s", gwurlstr);
if (!freerdp_settings_set_string(settings, FreeRDP_GatewayUrl, gwurl->valuestring)) if (!freerdp_settings_set_string(settings, FreeRDP_GatewayUrl, gwurlstr))
status = FALSE; status = FALSE;
else else
status = TRUE; status = TRUE;
} }
const cJSON* serverNameNode = cJSON_GetObjectItem(json, "redirectedServerName"); WINPR_JSON* serverNameNode = WINPR_JSON_GetObjectItem(json, "redirectedServerName");
if (serverNameNode) if (serverNameNode)
{ {
char* serverName = cJSON_GetStringValue(serverNameNode); const char* serverName = WINPR_JSON_GetStringValue(serverNameNode);
if (serverName) if (serverName)
status = freerdp_settings_set_string(settings, FreeRDP_ServerHostname, serverName); status = freerdp_settings_set_string(settings, FreeRDP_ServerHostname, serverName);
} }
const cJSON* azureMeta = cJSON_GetObjectItem(json, "azureInstanceNetworkMetadata"); WINPR_JSON* azureMeta = WINPR_JSON_GetObjectItem(json, "azureInstanceNetworkMetadata");
if (azureMeta && cJSON_IsString(azureMeta)) if (azureMeta && WINPR_JSON_IsString(azureMeta))
{ {
if (!arm_treat_azureInstanceNetworkMetadata(cJSON_GetStringValue(azureMeta), settings)) if (!arm_treat_azureInstanceNetworkMetadata(WINPR_JSON_GetStringValue(azureMeta), settings))
{ {
WLog_ERR(TAG, "error when treating azureInstanceNetworkMetadata"); WLog_ERR(TAG, "error when treating azureInstanceNetworkMetadata");
} }
@ -791,7 +789,7 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
status = arm_fill_rdstls(arm, settings, json); status = arm_fill_rdstls(arm, settings, json);
} }
cJSON_Delete(json); WINPR_JSON_Delete(json);
return status; return status;
} }
@ -822,10 +820,10 @@ static BOOL arm_handle_bad_request(rdpArm* arm, const HttpResponse* response, BO
WLog_DBG(TAG, "Got HTTP Response data: %s", msg); WLog_DBG(TAG, "Got HTTP Response data: %s", msg);
cJSON* json = cJSON_ParseWithLength(msg, len); WINPR_JSON* json = WINPR_JSON_ParseWithLength(msg, len);
if (json == NULL) if (json == NULL)
{ {
const char* error_ptr = cJSON_GetErrorPtr(); const char* error_ptr = WINPR_JSON_GetErrorPtr();
if (error_ptr != NULL) if (error_ptr != NULL)
{ {
WLog_ERR(TAG, "NullPoException: %s", error_ptr); WLog_ERR(TAG, "NullPoException: %s", error_ptr);
@ -833,23 +831,24 @@ static BOOL arm_handle_bad_request(rdpArm* arm, const HttpResponse* response, BO
} }
} }
const cJSON* gateway_code_str = cJSON_GetObjectItemCaseSensitive(json, "Code"); WINPR_JSON* gateway_code_obj = WINPR_JSON_GetObjectItemCaseSensitive(json, "Code");
if (!cJSON_IsString(gateway_code_str) || (gateway_code_str->valuestring == NULL)) const char* gw_code_str = WINPR_JSON_GetStringValue(gateway_code_obj);
if (gw_code_str == NULL)
{ {
WLog_ERR(TAG, "Response has no \"Code\" property"); WLog_ERR(TAG, "Response has no \"Code\" property");
http_response_log_error_status(WLog_Get(TAG), WLOG_ERROR, response); http_response_log_error_status(WLog_Get(TAG), WLOG_ERROR, response);
goto fail; goto fail;
} }
if (strcmp(gateway_code_str->valuestring, "E_PROXY_ORCHESTRATION_LB_SESSIONHOST_DEALLOCATED") == if (strcmp(gw_code_str, "E_PROXY_ORCHESTRATION_LB_SESSIONHOST_DEALLOCATED") == 0)
0)
{ {
*retry = TRUE; *retry = TRUE;
const cJSON* message = cJSON_GetObjectItemCaseSensitive(json, "Message"); WINPR_JSON* message = WINPR_JSON_GetObjectItemCaseSensitive(json, "Message");
if (!cJSON_IsString(message) || !message->valuestring) const char* msgstr = WINPR_JSON_GetStringValue(message);
if (!msgstr)
WLog_WARN(TAG, "Starting your VM. It may take up to 5 minutes"); WLog_WARN(TAG, "Starting your VM. It may take up to 5 minutes");
else else
WLog_WARN(TAG, "%s", message->valuestring); WLog_WARN(TAG, "%s", msgstr);
} }
else else
{ {
@ -859,7 +858,7 @@ static BOOL arm_handle_bad_request(rdpArm* arm, const HttpResponse* response, BO
rc = TRUE; rc = TRUE;
fail: fail:
cJSON_Delete(json); WINPR_JSON_Delete(json);
return rc; return rc;
} }