[core,aad] move cJSON related parsing to core

hide cJSON parser from freerdp-client library, link privately
This commit is contained in:
Armin Novak 2023-10-20 12:40:57 +02:00 committed by Martin Fleisz
parent 9e361b613d
commit e56fcb45cb
5 changed files with 86 additions and 52 deletions

View File

@ -633,13 +633,6 @@ find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DE
find_package(cJSON) find_package(cJSON)
option(WITH_AAD "Compile with support for Azure AD authentication" ${cJSON_FOUND}) option(WITH_AAD "Compile with support for Azure AD authentication" ${cJSON_FOUND})
if (WITH_AAD)
if (NOT cJSON_FOUND)
find_package(PkgConfig REQUIRED)
pkg_check_modules(CJSON REQUIRED libcjson)
endif()
include_directories(${CJSON_INCLUDE_DIRS})
endif()
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" )

View File

@ -59,20 +59,8 @@
#endif #endif
#ifdef WITH_AAD #ifdef WITH_AAD
#include <cjson/cJSON.h>
#include <freerdp/utils/http.h> #include <freerdp/utils/http.h>
#include <freerdp/utils/aad.h>
#if CJSON_VERSION_MAJOR == 1
#if CJSON_VERSION_MINOR <= 7
#if CJSON_VERSION_PATCH < 13
#define USE_CJSON_COMPAT
#endif
#endif
#endif
#if defined(USE_CJSON_COMPAT)
extern cJSON* cJSON_ParseWithLength(const char* value, size_t buffer_length);
#endif
#endif #endif
#include <freerdp/log.h> #include <freerdp/log.h>
@ -1130,9 +1118,8 @@ BOOL client_common_get_access_token(freerdp* instance, const char* request, char
long resp_code = 0; long resp_code = 0;
BYTE* response = NULL; BYTE* response = NULL;
size_t response_length = 0; size_t response_length = 0;
cJSON* json = NULL;
cJSON* access_token_prop = NULL; wLog* log = WLog_Get(TAG);
const char* access_token_str = NULL;
if (!freerdp_http_request("https://login.microsoftonline.com/common/oauth2/v2.0/token", request, if (!freerdp_http_request("https://login.microsoftonline.com/common/oauth2/v2.0/token", request,
&resp_code, &response, &response_length)) &resp_code, &response, &response_length))
@ -1144,7 +1131,7 @@ BOOL client_common_get_access_token(freerdp* instance, const char* request, char
if (resp_code != HTTP_STATUS_OK) if (resp_code != HTTP_STATUS_OK)
{ {
char buffer[64] = { 0 }; char buffer[64] = { 0 };
wLog* log = WLog_Get(TAG);
WLog_Print(log, WLOG_ERROR, WLog_Print(log, WLOG_ERROR,
"Server unwilling to provide access token; returned status code %s", "Server unwilling to provide access token; returned status code %s",
freerdp_http_status_string_format(resp_code, buffer, sizeof(buffer))); freerdp_http_status_string_format(resp_code, buffer, sizeof(buffer)));
@ -1153,36 +1140,11 @@ BOOL client_common_get_access_token(freerdp* instance, const char* request, char
goto cleanup; goto cleanup;
} }
json = cJSON_ParseWithLength((const char*)response, response_length); *token = freerdp_utils_aad_get_access_token(log, response, response_length);
if (!json)
{
char buffer[64] = { 0 };
WLog_ERR(
TAG, "Failed to parse access token response [got %" PRIuz " bytes, response code %s",
response_length, freerdp_http_status_string_format(resp_code, buffer, sizeof(buffer)));
goto cleanup;
}
access_token_prop = cJSON_GetObjectItem(json, "access_token");
if (!access_token_prop)
{
WLog_ERR(TAG, "Response has no \"access_token\" property");
goto cleanup;
}
access_token_str = cJSON_GetStringValue(access_token_prop);
if (!access_token_str)
{
WLog_ERR(TAG, "Invalid value for \"access_token\"");
goto cleanup;
}
*token = _strdup(access_token_str);
if (*token) if (*token)
ret = TRUE; ret = TRUE;
cleanup: cleanup:
cJSON_Delete(json);
free(response); free(response);
return ret; return ret;
#else #else

View File

@ -0,0 +1,35 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Network Level Authentication (NLA)
*
* Copyright 2023 Armin Novak <anovak@thincast.com>
* Copyright 2023 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_UTILS_AAD_H
#define FREERDP_UTILS_AAD_H
#include <winpr/wlog.h>
#include <freerdp/api.h>
#include <freerdp/config.h>
#ifdef WITH_AAD
FREERDP_API char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t length);
#endif
#endif /* FREERDP_UTILS_AAD_H */

View File

@ -226,8 +226,14 @@ if(FAAC_FOUND)
include_directories(${FAAC_INCLUDE_DIRS}) include_directories(${FAAC_INCLUDE_DIRS})
endif() endif()
if(WITH_AAD) if (WITH_AAD)
freerdp_library_add_public(${CJSON_LIBRARIES}) if (NOT cJSON_FOUND)
find_package(PkgConfig REQUIRED)
pkg_check_modules(CJSON REQUIRED libcjson)
endif()
include_directories(${CJSON_INCLUDE_DIRS})
freerdp_library_add(${CJSON_LIBRARIES})
include_directories(${CJSON_INCLUDE_DIRS}) include_directories(${CJSON_INCLUDE_DIRS})
endif() endif()

View File

@ -26,6 +26,7 @@
#include <freerdp/crypto/privatekey.h> #include <freerdp/crypto/privatekey.h>
#include "../crypto/privatekey.h" #include "../crypto/privatekey.h"
#include <freerdp/utils/http.h> #include <freerdp/utils/http.h>
#include <freerdp/utils/aad.h>
#include <winpr/crypto.h> #include <winpr/crypto.h>
@ -830,3 +831,40 @@ BOOL aad_is_supported(void)
return FALSE; return FALSE;
#endif #endif
} }
#ifdef WITH_AAD
char* freerdp_utils_aad_get_access_token(wLog* log, const char* data, size_t length)
{
char* token = NULL;
cJSON* access_token_prop = NULL;
const char* access_token_str = NULL;
cJSON* json = cJSON_ParseWithLength(data, length);
if (!json)
{
WLog_Print(log, WLOG_ERROR, "Failed to parse access token response [got %" PRIuz " bytes",
length);
goto cleanup;
}
access_token_prop = cJSON_GetObjectItem(json, "access_token");
if (!access_token_prop)
{
WLog_Print(log, WLOG_ERROR, "Response has no \"access_token\" property");
goto cleanup;
}
access_token_str = cJSON_GetStringValue(access_token_prop);
if (!access_token_str)
{
WLog_Print(log, WLOG_ERROR, "Invalid value for \"access_token\"");
goto cleanup;
}
token = _strdup(access_token_str);
cleanup:
cJSON_Delete(json);
return token;
}
#endif