Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,163 @@
/**
* 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
/** \defgroup AAD AAD related helper utilities
* \since version 3.0.0
*/
#include <winpr/wlog.h>
#include <winpr/json.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/config.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @enum AAD_WELLKNOWN_VALUES
* @brief Expected wellknown fields to be supported
* @since version 3.10.0
*/
typedef enum
{
AAD_WELLKNOWN_token_endpoint = 0,
AAD_WELLKNOWN_token_endpoint_auth_methods_supported,
AAD_WELLKNOWN_jwks_uri,
AAD_WELLKNOWN_response_modes_supported,
AAD_WELLKNOWN_subject_types_supported,
AAD_WELLKNOWN_id_token_signing_alg_values_supported,
AAD_WELLKNOWN_response_types_supported,
AAD_WELLKNOWN_scopes_supported,
AAD_WELLKNOWN_issuer,
AAD_WELLKNOWN_request_uri_parameter_supported,
AAD_WELLKNOWN_userinfo_endpoint,
AAD_WELLKNOWN_authorization_endpoint,
AAD_WELLKNOWN_device_authorization_endpoint,
AAD_WELLKNOWN_http_logout_supported,
AAD_WELLKNOWN_frontchannel_logout_supported,
AAD_WELLKNOWN_end_session_endpoint,
AAD_WELLKNOWN_claims_supported,
AAD_WELLKNOWN_kerberos_endpoint,
AAD_WELLKNOWN_tenant_region_scope,
AAD_WELLKNOWN_cloud_instance_name,
AAD_WELLKNOWN_cloud_graph_host_name,
AAD_WELLKNOWN_msgraph_host,
AAD_WELLKNOWN_rbac_url
} AAD_WELLKNOWN_VALUES;
/** Helper to retrieve the AAD access token from JSON input
*
* @param data The JSON to parse
* @param length The number of bytes of the JSON data
*
* @since version 3.0.0
*
* @return The token string or \b nullptr
*/
WINPR_ATTR_MALLOC(free, 1)
WINPR_ATTR_NODISCARD
FREERDP_API char* freerdp_utils_aad_get_access_token(wLog* log, const char* data,
size_t length);
/** Helper to stringify \ref AAD_WELLKNOWN_VALUES enum
*
* @param which The enum value to stringify
*
* @return The string representation of the enum value
* @since version 3.10.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_utils_aad_wellknwon_value_name(AAD_WELLKNOWN_VALUES which);
/** Helper to extract a string from AAD::wellknown JSON
*
* @param context The rdpContext to query for
* @param which The enum value of the field to query
* @return A constant string to be used for queries or \b nullptr in case it does not exist.
*
* @since version 3.10.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_utils_aad_get_wellknown_string(rdpContext* context,
AAD_WELLKNOWN_VALUES which);
/** Helper to extract a string from AAD::wellknown JSON
*
* @param context The rdpContext to query for
* @param which The raw string name of the field to query
* @return A constant string to be used for queries or \b nullptr in case it does not exist.
*
* @since version 3.10.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_utils_aad_get_wellknown_custom_string(rdpContext* context,
const char* which);
/** Helper to extract a \b WINPR_JSON object from AAD::wellknown JSON
*
* @param context The rdpContext to query for
* @param which The enum value of the field to query
* @return A \b WINPR_JSON object to be used for queries or \b nullptr in case it does not
* exist.
*
* @since version 3.10.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API WINPR_JSON* freerdp_utils_aad_get_wellknown_object(rdpContext* context,
AAD_WELLKNOWN_VALUES which);
/** Helper to extract a \b WINPR_JSON object from AAD::wellknown JSON
*
* @param context The rdpContext to query for
* @param which The raw string name of the field to query
* @return A \b WINPR_JSON object to be used for queries or \b nullptr in case it does not
* exist.
*
* @since version 3.10.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API WINPR_JSON* freerdp_utils_aad_get_wellknown_custom_object(rdpContext* context,
const char* which);
/** Helper to fetch a \b WINPR_JSON object from AAD/ARM::wellknown JSON
*
* @param log A logger instance to use
* @param base the base URL to connect to
* @param tenantid the tenant to use for the connection, use \b common for default
* @return A \b WINPR_JSON object to be used for queries or \b nullptr in case it does not
* exist.
*
* @since version 3.10.0
*/
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
WINPR_ATTR_NODISCARD
FREERDP_API WINPR_JSON* freerdp_utils_aad_get_wellknown(wLog* log, const char* base,
const char* tenantid);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_AAD_H */

View File

@@ -0,0 +1,57 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* RDPDR utility functions
*
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
* Copyright 2022 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_CLIPRDR_H
#define FREERDP_UTILS_CLIPRDR_H
#include <winpr/wtypes.h>
#include <winpr/stream.h>
#include <winpr/shell.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_ATTR_NODISCARD
FREERDP_API BOOL cliprdr_read_filedescriptor(wStream* s, FILEDESCRIPTORW* descriptor);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL cliprdr_write_filedescriptor(wStream* s, const FILEDESCRIPTORW* descriptor);
WINPR_ATTR_NODISCARD
FREERDP_API UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
FILEDESCRIPTORW** file_descriptor_array,
UINT32* file_descriptor_count);
WINPR_ATTR_NODISCARD
FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length);
WINPR_ATTR_NODISCARD
FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count,
BYTE** format_data, UINT32* format_data_length);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* GFX Utils - Helper functions converting something to string
*
* Copyright 2023 Armin Novak <armin.novak@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_DRDYNVC_H
#define FREERDP_UTILS_DRDYNVC_H
#include <winpr/wtypes.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_ATTR_NODISCARD
FREERDP_API const char* drdynvc_get_packet_type(BYTE cmd);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,121 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Helper functions to parse encoded types into regular ones
*
* Copyright 2023 Pascal Nowack <Pascal.Nowack@gmx.de>
*
* 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_ENCODED_TYPES_H
#define FREERDP_UTILS_ENCODED_TYPES_H
/** \file Encoded Types helpers
* \since version 3.0.0
*/
#include <freerdp/api.h>
#include <winpr/stream.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** Maximum value of a 4 byte signed integer
* \since version 3.5.0
*/
#define FREERDP_FOUR_BYTE_SIGNED_INT_MAX 0x1FFFFFFFl
/** Minimum value of a 4 byte signed integer
* \since version 3.5.0
*/
#define FREERDP_FOUR_BYTE_SIGNED_INT_MIN -0x1FFFFFFFl
/** Maximum value of a 4 byte float
* \since version 3.5.0
*/
#define FREERDP_FOUR_BYTE_FLOAT_MAX 0x3FFFFFF
/** Minimum value of a 4 byte float
* \since version 3.5.0
*/
#define FREERDP_FOUR_BYTE_FLOAT_MIN -0x3FFFFFF
/** Read a 4 byte signed integer from a stream and store the decoded value
*
* @param s The steam to read from
* @param value A pointer to an INT32 to hold the result
*
* @since version 3.0.0
*
* @return \b TRUE for successful reading, \b FALSE otherwise
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_read_four_byte_signed_integer(wStream* s, INT32* value);
/** Write a 4 byte signed integer to a stream
*
* @param s The steam to read from
* @param value The INT32 value to encode and write
*
* @since version 3.4.0
*
* @return \b TRUE for successful writing, \b FALSE otherwise
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_write_four_byte_signed_integer(wStream* s, INT32 value);
/** Read a 4 byte float from a stream and store the decoded value
*
* @param s The steam to read from
* @param value A pointer to a double to hold the result
*
* @since version 3.0.0
*
* @return \b TRUE for successful reading, \b FALSE otherwise
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_read_four_byte_float(wStream* s, double* value);
/** Read a 4 byte float from a stream and store the decoded value and exponent
*
* @param s The steam to read from
* @param value A pointer to a double to hold the result
* @param exp A pointer to a BYTE to hold the exponent result
*
* @since version 3.5.0
*
* @return \b TRUE for successful reading, \b FALSE otherwise
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_read_four_byte_float_exp(wStream* s, double* value, BYTE* exp);
/** Write a 4 byte float to a stream
*
* @param s The steam to read from
* @param value The float value to encode and write
*
* @since version 3.4.0
*
* @return \b TRUE for successful writing, \b FALSE otherwise
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_write_four_byte_float(wStream* s, double value);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_ENCODED_TYPES_H */

View File

@@ -0,0 +1,52 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* GFX Utils - Helper functions converting something to string
*
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
* Copyright 2022 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_GFX_H
#define FREERDP_UTILS_GFX_H
#include <winpr/wtypes.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Stringification utility for rdpgfx capability versions
* @param capsVersion A capability version integer
* @return The string representation of the capabilities
* @since version 3.9.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API const char* rdpgfx_caps_version_str(UINT32 capsVersion);
WINPR_ATTR_NODISCARD
FREERDP_API const char* rdpgfx_get_cmd_id_string(UINT16 cmdId);
WINPR_ATTR_NODISCARD
FREERDP_API const char* rdpgfx_get_codec_id_string(UINT16 codecId);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,133 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* common helper utilities
*
* Copyright 2024 Armin Novak <anovak@thincast.com>
* Copyright 2024 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.
*/
#pragma once
#include <winpr/wtypes.h>
#include <winpr/json.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @brief Return the absolute path of a configuration file (the path of the configuration
* directory if \b filename is \b nullptr)
*
* @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 The absolute path of the desired configuration or \b nullptr in case of failure. Use
* \b free to clean up the allocated string.
*
*
* @since version 3.9.0
*/
WINPR_ATTR_MALLOC(free, 1)
WINPR_ATTR_NODISCARD
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 nullptr in case of any failure.
* @since version 3.16.0
*/
WINPR_ATTR_MALLOC(WINPR_JSON_Delete, 1)
WINPR_ATTR_NODISCARD
FREERDP_API WINPR_JSON* freerdp_GetJSONConfigFile(BOOL system, const char* filename);
/** @brief set \b vendor and \b product information for an application
*
* This sets the application details for an application instance. These values determine where
* to look for configuration files and other vendor/product specific settings data.
* This function recursively also sets \ref freerdp_setApplicationDetails with a 'vendor' string
* of 'vendor/product', a 'product' string of WINPR_PRODUCT_STRING (build time constant) and a
* 'version' of -1. This limits the length of \b vendor + \b product to \b MAX_PATH or less..
*
* @note When calling this function, the compile time options \b
* FREERDP_USE_VENDOR_PRODUCT_CONFIG_DIR and \b WITH_FULL_CONFIG_PATH are ignored and the config
* path will always have the format 'vendor/product' or 'vendor/product1' (1 for the actual
* version set)
*
* @param vendor A vendor name to use. Must not be \b nullptr. Must not contain forbidden
* filesystem symbols for any os. Must be less than \b MAX_PATH bytes.
* @param product A product name to use. Must not be \b nullptr. Must not contain forbidden
* filesystem symbols for any os. Must be less than \b MAX_PATH bytes.
* @param version An optional versioning value to append to paths to settings. Use \b -1 to
* disable.
*
* @return \b TRUE if set successfully, \b FALSE in case of any error.
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD BOOL freerdp_setApplicationDetails(const char* vendor,
const char* product,
SSIZE_T version);
/** @brief Get the current \b vendor string of the application. Defaults to \ref
* FREERDP_VENDOR_STRING
*
* @return The current string set as \b vendor.
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* freerdp_getApplicationDetailsVendor(void);
/** @brief Get the current \b product string of the application. Defaults to \ref
* FREERDP_PRODUCT_STRING
*
* @return The current string set as \b product.
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* freerdp_getApplicationDetailsProduct(void);
/** @brief Get the current \b version of the application. Defaults to \ref FREERDP_API_VERSION
* if \b WITH_RESOURCE_VERSIONING is defined, otherwise \b -1
*
* @return The current number set as \b version
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD SSIZE_T freerdp_getApplicationDetailsVersion(void);
/** @brief Get the current details of the application.
* Defaults to \b <Vendor>-<Product><Version> if \b WITH_RESOURCE_VERSIONING is defined,
* \b <Vendor>-<Product> if <Vendor> does not equal <Product> and <Product> otherwise.
*
* @return The current application details as string.
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* freerdp_getApplicationDetailsString(void);
/** @brief Get the current details of the application. Wide character version.
* See \ref freerdp_getApplicationDetailsString for details.
*
* @return The current application details as string.
* @since version 3.23.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const WCHAR* freerdp_getApplicationDetailsStringW(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,88 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2023 Isaac Klein <fifthdegree@protonmail.com>
*
* 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_HTTP_H
#define FREERDP_UTILS_HTTP_H
#include <freerdp/api.h>
typedef enum
{
HTTP_STATUS_CONTINUE = 100,
HTTP_STATUS_SWITCH_PROTOCOLS = 101,
HTTP_STATUS_OK = 200,
HTTP_STATUS_CREATED = 201,
HTTP_STATUS_ACCEPTED = 202,
HTTP_STATUS_PARTIAL = 203,
HTTP_STATUS_NO_CONTENT = 204,
HTTP_STATUS_RESET_CONTENT = 205,
HTTP_STATUS_PARTIAL_CONTENT = 206,
HTTP_STATUS_WEBDAV_MULTI_STATUS = 207,
HTTP_STATUS_AMBIGUOUS = 300,
HTTP_STATUS_MOVED = 301,
HTTP_STATUS_REDIRECT = 302,
HTTP_STATUS_REDIRECT_METHOD = 303,
HTTP_STATUS_NOT_MODIFIED = 304,
HTTP_STATUS_USE_PROXY = 305,
HTTP_STATUS_REDIRECT_KEEP_VERB = 307,
HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_DENIED = 401,
HTTP_STATUS_PAYMENT_REQ = 402,
HTTP_STATUS_FORBIDDEN = 403,
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_BAD_METHOD = 405,
HTTP_STATUS_NONE_ACCEPTABLE = 406,
HTTP_STATUS_PROXY_AUTH_REQ = 407,
HTTP_STATUS_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CONFLICT = 409,
HTTP_STATUS_GONE = 410,
HTTP_STATUS_LENGTH_REQUIRED = 411,
HTTP_STATUS_PRECOND_FAILED = 412,
HTTP_STATUS_REQUEST_TOO_LARGE = 413,
HTTP_STATUS_URI_TOO_LONG = 414,
HTTP_STATUS_UNSUPPORTED_MEDIA = 415,
HTTP_STATUS_RETRY_WITH = 449,
HTTP_STATUS_SERVER_ERROR = 500,
HTTP_STATUS_NOT_SUPPORTED = 501,
HTTP_STATUS_BAD_GATEWAY = 502,
HTTP_STATUS_SERVICE_UNAVAIL = 503,
HTTP_STATUS_GATEWAY_TIMEOUT = 504,
HTTP_STATUS_VERSION_NOT_SUP = 505
} FREERDP_HTTP_STATUS;
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_http_request(const char* url, const char* body, long* status_code,
BYTE** response, size_t* response_length);
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_http_status_string(long status);
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_http_status_string_format(long status, char* buffer,
size_t size);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_HTTP_H */

View File

@@ -0,0 +1,84 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Passphrase Handling Utils
*
* Copyright 2011 Shea Levy <shea@shealevy.com>
*
* 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_PASSPHRASE_H
#define FREERDP_UTILS_PASSPHRASE_H
#include <stdlib.h>
#include <stdio.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @brief Read a single character from a stream.
* This function will check \ref freerdp_shall_disconnect_context and abort when the session
* terminates.
*
* The function will abort on any of <ctrl>+[cdz] or end of stream conditions as well as when
* the RDP session terminates
*
* @param context The RDP context to work on
* @param stream the \ref FILE to read the data from
*
* @return The character read or \ref EOF in case of any failures
*/
WINPR_ATTR_NODISCARD
FREERDP_API int freerdp_interruptible_getc(rdpContext* context, FILE* stream);
/** @brief read a line from \ref stream with (optinal) default value that can be manipulated.
* This function will check \ref freerdp_shall_disconnect_context and abort when the session
* terminates.
*
* @param context The RDP context to work on
* @param lineptr on input a suggested default value, on output the result. Must be an allocated
* string on input, free the memory later with \ref free
* @param size on input the \ref strlen of the suggested default, on output \ref strlen of the
* result
* @param stream the \ref FILE to read the data from
*
* @return \b -1 in case of failure, otherwise \ref strlen of the result
*/
WINPR_ATTR_NODISCARD
FREERDP_API SSIZE_T freerdp_interruptible_get_line(rdpContext* context, char** lineptr,
size_t* size, FILE* stream);
/** @brief similar to \ref freerdp_interruptible_get_line but disables echo to terminal.
*
* @param context The RDP context to work on
* @param prompt The prompt to show to the user
* @param buf A pointer to a buffer that will receive the output
* @param bufsiz The size of the buffer in bytes
* @param from_stdin \b 0 if a terminal is expected, != 0 if data is read from stdin
*
* @return A pointer to \ref buf containing the password or \ref nullptr in case of an error.
*/
WINPR_ATTR_NODISCARD
FREERDP_API const char* freerdp_passphrase_read(rdpContext* context, const char* prompt,
char* buf, size_t bufsiz, int from_stdin);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_PASSPHRASE_H */

View File

@@ -0,0 +1,92 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* pcap File Format Utils
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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_PCAP_H
#define FREERDP_UTILS_PCAP_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
UINT32 magic_number; /* magic number */
UINT16 version_major; /* major version number */
UINT16 version_minor; /* minor version number */
INT32 thiszone; /* GMT to local correction */
UINT32 sigfigs; /* accuracy of timestamps */
UINT32 snaplen; /* max length of captured packets, in octets */
UINT32 network; /* data link type */
} pcap_header;
typedef struct
{
UINT32 ts_sec; /* timestamp seconds */
UINT32 ts_usec; /* timestamp microseconds */
UINT32 incl_len; /* number of octets of packet saved in file */
UINT32 orig_len; /* actual length of packet */
} pcap_record_header;
typedef struct s_pcap_record pcap_record;
struct s_pcap_record
{
pcap_record_header header;
union
{
void* data;
const void* cdata;
};
UINT32 length;
pcap_record* next;
};
typedef struct rdp_pcap rdpPcap;
FREERDP_API void pcap_close(rdpPcap* pcap);
WINPR_ATTR_MALLOC(pcap_close, 1)
WINPR_ATTR_NODISCARD
FREERDP_API rdpPcap* pcap_open(const char* name, BOOL write);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, const void* data, size_t length);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL pcap_has_next_record(const rdpPcap* pcap);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record);
FREERDP_API void pcap_flush(rdpPcap* pcap);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_PCAP_H */

View File

@@ -0,0 +1,145 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* POD arrays
*
* Copyright 2022 David Fort <contact@hardening-consulting.com>
*
* 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_POD_ARRAYS_H_
#define FREERDP_UTILS_POD_ARRAYS_H_
#include <winpr/wtypes.h>
#include <winpr/assert.h>
#ifdef __cplusplus
extern "C"
{
#endif
#define POD_ARRAYS_IMPL(T, TLOWER) \
typedef struct \
{ \
T* values; \
size_t nvalues; \
} Array##T; \
typedef BOOL Array##T##Cb(T* v, void* data); \
\
static inline void array_##TLOWER##_init(Array##T* a) \
{ \
WINPR_ASSERT(a); \
a->values = nullptr; \
a->nvalues = 0; \
} \
\
WINPR_ATTR_NODISCARD \
static inline size_t array_##TLOWER##_size(const Array##T* a) \
{ \
WINPR_ASSERT(a); \
return a->nvalues; \
} \
\
WINPR_ATTR_NODISCARD \
static inline T* array_##TLOWER##_data(const Array##T* a) \
{ \
WINPR_ASSERT(a); \
return a->values; \
} \
\
WINPR_ATTR_NODISCARD \
static inline const T* array_##TLOWER##_cdata(const Array##T* a) \
{ \
WINPR_ASSERT(a); \
return (const T*)a->values; \
} \
\
WINPR_ATTR_NODISCARD \
static inline T array_##TLOWER##_get(const Array##T* a, size_t idx) \
{ \
WINPR_ASSERT(a); \
WINPR_ASSERT(a->nvalues > idx); \
return a->values[idx]; \
} \
\
static inline void array_##TLOWER##_set(Array##T* a, size_t idx, T v) \
{ \
WINPR_ASSERT(a); \
WINPR_ASSERT(a->nvalues > idx); \
a->values[idx] = v; \
} \
\
WINPR_ATTR_NODISCARD \
static inline BOOL array_##TLOWER##_append(Array##T* a, T v) \
{ \
WINPR_ASSERT(a); \
T* tmp = realloc(a->values, sizeof(T) * (a->nvalues + 1)); \
if (!tmp) \
return FALSE; \
\
tmp[a->nvalues] = v; \
a->values = tmp; \
a->nvalues++; \
return TRUE; \
} \
\
WINPR_ATTR_NODISCARD \
static inline BOOL array_##TLOWER##_contains(const Array##T* a, T v) \
{ \
WINPR_ASSERT(a); \
\
for (UINT32 i = 0; i < a->nvalues; i++) \
{ \
if (memcmp(&a->values[i], &v, sizeof(T)) == 0) \
return TRUE; \
} \
\
return FALSE; \
} \
\
WINPR_ATTR_NODISCARD \
static inline BOOL array_##TLOWER##_foreach(Array##T* a, Array##T##Cb cb, void* data) \
{ \
WINPR_ASSERT(a); \
for (size_t i = 0; i < a->nvalues; i++) \
{ \
if (!cb(&a->values[i], data)) \
return FALSE; \
} \
\
return TRUE; \
} \
\
static inline void array_##TLOWER##_reset(Array##T* a) \
{ \
WINPR_ASSERT(a); \
a->nvalues = 0; \
} \
\
static inline void array_##TLOWER##_uninit(Array##T* a) \
{ \
WINPR_ASSERT(a); \
free(a->values); \
\
a->values = nullptr; \
a->nvalues = 0; \
}
POD_ARRAYS_IMPL(UINT16, uint16)
POD_ARRAYS_IMPL(UINT32, uint32)
POD_ARRAYS_IMPL(UINT64, uint64)
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_POD_ARRAYS_H_ */

View File

@@ -0,0 +1,102 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Profiler Utils
*
* Copyright 2011 Stephen Erisman
*
* 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_PROFILER_H
#define FREERDP_UTILS_PROFILER_H
#include <freerdp/api.h>
#include <freerdp/utils/stopwatch.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct S_PROFILER PROFILER;
FREERDP_API void profiler_free(PROFILER* profiler);
WINPR_ATTR_MALLOC(profiler_free, 1)
WINPR_ATTR_NODISCARD
FREERDP_API PROFILER* profiler_create(const char* name);
FREERDP_API void profiler_enter(PROFILER* profiler);
FREERDP_API void profiler_exit(PROFILER* profiler);
FREERDP_API void profiler_print_header(void);
FREERDP_API void profiler_print(PROFILER* profiler);
FREERDP_API void profiler_print_footer(void);
#ifdef WITH_PROFILER
#define PROFILER_RENAME(prof, name) \
do \
{ \
profiler_free(prof); \
prof = profiler_create(name); \
} while (0);
#define PROFILER_DEFINE(prof) PROFILER* prof;
#define PROFILER_CREATE(prof, name) prof = profiler_create(name);
#define PROFILER_FREE(prof) profiler_free(prof);
#define PROFILER_ENTER(prof) profiler_enter(prof);
#define PROFILER_EXIT(prof) profiler_exit(prof);
#define PROFILER_PRINT_HEADER profiler_print_header();
#define PROFILER_PRINT(prof) profiler_print(prof);
#define PROFILER_PRINT_FOOTER profiler_print_footer();
#else
#define PROFILER_RENAME(prof, name) \
do \
{ \
} while (0);
#define PROFILER_DEFINE(prof)
#define PROFILER_CREATE(prof, name) \
do \
{ \
} while (0);
#define PROFILER_FREE(prof) \
do \
{ \
} while (0);
#define PROFILER_ENTER(prof) \
do \
{ \
} while (0);
#define PROFILER_EXIT(prof) \
do \
{ \
} while (0);
#define PROFILER_PRINT_HEADER \
do \
{ \
} while (0);
#define PROFILER_PRINT(prof) \
do \
{ \
} while (0);
#define PROFILER_PRINT_FOOTER \
do \
{ \
} while (0);
#endif
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_PROFILER_H */

View File

@@ -0,0 +1,46 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* RDP Proxy Utils
*
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
* Copyright 2022 Adrian Vollmer <adrian.vollmer@syss.de>
*
* 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_PROXY_UTILS_H
#define FREERDP_PROXY_UTILS_H
#include <freerdp/api.h>
#include <freerdp/settings.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @brief parse a proxy environment variable string and populate settings from it
*
* @param settings the settings to populate, must not be \b nullptr
* @param uri_in the proxy string to parse, must not be \b nullptr
*
* @return \b TRUE if parsed successfully
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL proxy_parse_uri(rdpSettings* settings, const char* uri_in);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_PROXY_UTILS_H */

View File

@@ -0,0 +1,118 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* RDPDR utility functions
*
* Copyright 2021 Armin Novak <armin.novak@thincast.com>
* Copyright 2021 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_RDPDR_H
#define FREERDP_UTILS_RDPDR_H
#include <winpr/stream.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
UINT32 DeviceType;
UINT32 DeviceId;
char PreferredDosName[8];
UINT32 DeviceDataLength;
BYTE* DeviceData;
} RdpdrDevice;
typedef struct
{
UINT16 CapabilityType;
UINT16 CapabilityLength;
UINT32 Version;
} RDPDR_CAPABILITY_HEADER;
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_component_string(UINT16 component);
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_packetid_string(UINT16 packetid);
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_irp_string(UINT32 major);
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_cap_type_string(UINT16 capability);
FREERDP_API LONG scard_log_status_error(const char* tag, const char* what, LONG status);
/** @brief log a smartcard related issue with a wLog
*
* @param log The logger to use
* @param what The module affected
* @param status The status to log
*
* @return The \ref status logged
* @since version 3.16.0
*/
FREERDP_API LONG scard_log_status_error_wlog(wLog* log, const char* what, LONG status);
FREERDP_API WINPR_ATTR_NODISCARD const char* scard_get_ioctl_string(UINT32 ioControlCode,
BOOL funcName);
FREERDP_API WINPR_ATTR_NODISCARD BOOL rdpdr_write_iocompletion_header(wStream* out,
UINT32 DeviceId,
UINT32 CompletionId,
NTSTATUS ioStatus);
FREERDP_API void rdpdr_dump_received_packet(wLog* log, DWORD lvl, wStream* out,
const char* custom);
FREERDP_API void rdpdr_dump_send_packet(wLog* log, DWORD lvl, wStream* out, const char* custom);
FREERDP_API WINPR_ATTR_NODISCARD UINT rdpdr_read_capset_header(wLog* log, wStream* s,
RDPDR_CAPABILITY_HEADER* header);
FREERDP_API WINPR_ATTR_NODISCARD UINT
rdpdr_write_capset_header(wLog* log, wStream* s, const RDPDR_CAPABILITY_HEADER* header);
/** @brief convert a constant of type \ref RDPDR_CAPS_IRP_MJ to string
*
* @param ioCode1 A \ref RDPDR_CAPS_IRP_MJ value
* @return A string representation of the constant or \b RDPDR_IRP_MJ_UNKNOWN for unknown
* values
*
* @since version 3.21.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_irp_val2str(UINT32 ioCode1);
/** @brief convert a mask of \ref RDPDR_CAPS_IRP_MJ type values to string
*
* @param ioCode1Mask A \ref RDPDR_CAPS_IRP_MJ value
* @param buffer A pointer to a buffer that can hold the string representation
* @param len The length of the buffer in bytes.
* @return A string representation of the constant mask or \b nullptr in case the buffer is too
* small
*
* @since version 3.21.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_irp_mask2str(UINT32 ioCode1Mask,
char* buffer, size_t len);
/** @brief Convert a single \ref FreeRDP_RDPDR_DTYP to string
*
* @param type The value to convert
* @return A constant string representation of \ref type or the string \b
* UNKNOWN for an invalid value
* @since version 3.22.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* rdpdr_device_type_string(UINT32 type);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,138 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2014 Thincast Technologies GmbH
* Copyright 2014 Hardening <contact@hardening-consulting.com>
*
* 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_RINGBUFFER_H
#define FREERDP_UTILS_RINGBUFFER_H
#include <winpr/wtypes.h>
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @brief ring buffer meta data */
typedef struct
{
size_t initialSize;
size_t freeSize;
size_t size;
size_t readPtr;
size_t writePtr;
BYTE* buffer;
} RingBuffer;
/** @brief a piece of data in the ring buffer, exactly like a glibc iovec */
typedef struct
{
size_t size;
const BYTE* data;
} DataChunk;
/**
* initialise a ringbuffer
*
* @param initialSize the initial capacity of the ringBuffer
* @return if the initialisation was successful
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL ringbuffer_init(RingBuffer* ringbuffer, size_t initialSize);
/**
* destroys internal data used by this ringbuffer
*
* @param ringbuffer A pointer to the ringbuffer
*/
FREERDP_API void ringbuffer_destroy(RingBuffer* ringbuffer);
/**
* computes the space used in this ringbuffer
*
* @param ringbuffer A pointer to the ringbuffer
* @return the number of bytes stored in that ringbuffer
*/
WINPR_ATTR_NODISCARD
FREERDP_API size_t ringbuffer_used(const RingBuffer* ringbuffer);
/** returns the capacity of the ring buffer
*
* @param ringbuffer A pointer to the ringbuffer
* @return the capacity of this ring buffer
*/
WINPR_ATTR_NODISCARD
FREERDP_API size_t ringbuffer_capacity(const RingBuffer* ringbuffer);
/** writes some bytes in the ringbuffer, if the data doesn't fit, the ringbuffer
* is resized automatically
*
* @param ringbuffer the ringbuffer
* @param ptr a pointer on the data to add
* @param sz the size of the data to add
* @return if the operation was successful, it could fail in case of OOM during realloc()
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL ringbuffer_write(RingBuffer* ringbuffer, const BYTE* ptr, size_t sz);
/** ensures that we have sz bytes available at the write head, and return a pointer
* on the write head
*
* @param ringbuffer the ring buffer
* @param sz the size to ensure
* @return a pointer on the write head, or nullptr in case of OOM
*/
WINPR_ATTR_NODISCARD
FREERDP_API BYTE* ringbuffer_ensure_linear_write(RingBuffer* ringbuffer, size_t sz);
/** move ahead the write head in case some byte were written directly by using
* a pointer retrieved via ringbuffer_ensure_linear_write(). This function is
* used to commit the written bytes. The provided size should not exceed the
* size ensured by ringbuffer_ensure_linear_write()
*
* @param ringbuffer the ring buffer
* @param sz the number of bytes that have been written
* @return if the operation was successful, FALSE is sz is too big
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL ringbuffer_commit_written_bytes(RingBuffer* ringbuffer, size_t sz);
/** peeks the buffer chunks for sz bytes and returns how many chunks are filled.
* Note that the sum of the resulting chunks may be smaller than sz.
*
* @param ringbuffer the ringbuffer
* @param chunks an array of data chunks that will contain data / size of chunks
* @param sz the requested size
* @return the number of chunks used for reading sz bytes
*/
WINPR_ATTR_NODISCARD
FREERDP_API int ringbuffer_peek(const RingBuffer* ringbuffer, DataChunk chunks[2], size_t sz);
/** move ahead the read head in case some byte were read using ringbuffer_peek()
* This function is used to commit the bytes that were effectively consumed.
*
* @param ringbuffer the ring buffer
* @param sz the number of bytes to read
*/
FREERDP_API void ringbuffer_commit_read_bytes(RingBuffer* ringbuffer, size_t sz);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_RINGBUFFER_H */

View File

@@ -0,0 +1,65 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Signal handling
*
* Copyright 2011 Shea Levy <shea@shealevy.com>
*
* 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_SIGNAL_H
#define FREERDP_UTILS_SIGNAL_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef void (*freerdp_signal_handler_t)(int signum, const char* signame, void* context);
WINPR_ATTR_NODISCARD
FREERDP_API int freerdp_handle_signals(void);
/** \brief registers a cleanup handler for non fatal signals.
*
* This allows cleaning up resources like with \b atexit but for signals.
*
* \param context a context for the clenaup handler.
* \param handler the function to call on cleanup. Must not be \b nullptr
*
* \return \b TRUE if registered successfully, \b FALSE otherwise.
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_add_signal_cleanup_handler(void* context,
freerdp_signal_handler_t handler);
/** \brief unregisters a cleanup handler for non fatal signals.
*
* This allows removal of a cleanup handler for signals.
*
* \param context a context for the clenaup handler.
* \param handler the function to call on cleanup. Must not be \b nullptr
*
* \return \b TRUE if unregistered successfully, \b FALSE otherwise.
*/
FREERDP_API BOOL freerdp_del_signal_cleanup_handler(void* context,
freerdp_signal_handler_t handler);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_SIGNAL_H */

View File

@@ -0,0 +1,76 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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_CHANNEL_SMARTCARD_CALL_H
#define FREERDP_CHANNEL_SMARTCARD_CALL_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <freerdp/api.h>
#include <freerdp/settings.h>
#include <freerdp/channels/scard.h>
#include <freerdp/utils/smartcard_operations.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct s_scard_call_context scard_call_context;
FREERDP_API void smartcard_call_context_free(scard_call_context* ctx);
WINPR_ATTR_MALLOC(smartcard_call_context_free, 1)
WINPR_ATTR_NODISCARD
FREERDP_API scard_call_context* smartcard_call_context_new(const rdpSettings* settings);
FREERDP_API BOOL smartcard_call_context_signal_stop(scard_call_context* ctx, BOOL reset);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL smartcard_call_context_add(scard_call_context* ctx, const char* name);
FREERDP_API BOOL smartcard_call_cancel_context(scard_call_context* ctx, SCARDCONTEXT context);
FREERDP_API BOOL smartcard_call_cancel_all_context(scard_call_context* ctx);
FREERDP_API BOOL smartcard_call_release_context(scard_call_context* ctx, SCARDCONTEXT context);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL smartcard_call_is_configured(scard_call_context* ctx);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL smarcard_call_set_callbacks(scard_call_context* ctx, void* userdata,
void* (*fn_new)(void*, SCARDCONTEXT),
void (*fn_free)(void*));
WINPR_ATTR_NODISCARD
FREERDP_API void* smartcard_call_get_context(scard_call_context* ctx, SCARDCONTEXT hContext);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_irp_device_control_call(scard_call_context* ctx, wStream* out,
NTSTATUS* pIoStatus,
SMARTCARD_OPERATION* operation);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_CHANNEL_SMARTCARD_CALL_H */

View File

@@ -0,0 +1,99 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smartcard Device Service Virtual Channel
*
* Copyright 2011 O.S. Systems Software Ltda.
* Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
*
* 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_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#define FREERDP_CHANNEL_SMARTCARD_OPERATIONS_MAIN_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/smartcard.h>
#include <freerdp/api.h>
#include <freerdp/channels/scard.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
union
{
Handles_Call handles;
Long_Call lng;
Context_Call context;
ContextAndStringA_Call contextAndStringA;
ContextAndStringW_Call contextAndStringW;
ContextAndTwoStringA_Call contextAndTwoStringA;
ContextAndTwoStringW_Call contextAndTwoStringW;
EstablishContext_Call establishContext;
ListReaderGroups_Call listReaderGroups;
ListReaders_Call listReaders;
GetStatusChangeA_Call getStatusChangeA;
LocateCardsA_Call locateCardsA;
LocateCardsW_Call locateCardsW;
LocateCards_ATRMask locateCardsATRMask;
LocateCardsByATRA_Call locateCardsByATRA;
LocateCardsByATRW_Call locateCardsByATRW;
GetStatusChangeW_Call getStatusChangeW;
GetReaderIcon_Call getReaderIcon;
GetDeviceTypeId_Call getDeviceTypeId;
Connect_Common_Call connect;
ConnectA_Call connectA;
ConnectW_Call connectW;
Reconnect_Call reconnect;
HCardAndDisposition_Call hCardAndDisposition;
State_Call state;
Status_Call status;
SCardIO_Request scardIO;
Transmit_Call transmit;
GetTransmitCount_Call getTransmitCount;
Control_Call control;
GetAttrib_Call getAttrib;
SetAttrib_Call setAttrib;
ReadCache_Common readCache;
ReadCacheA_Call readCacheA;
ReadCacheW_Call readCacheW;
WriteCache_Common writeCache;
WriteCacheA_Call writeCacheA;
WriteCacheW_Call writeCacheW;
} call;
UINT32 ioControlCode;
UINT32 completionID;
UINT32 deviceID;
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
const char* ioControlCodeName;
UINT32 outputBufferLength; /** @since version 3.13.0 */
} SMARTCARD_OPERATION;
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId,
UINT32 FileId,
SMARTCARD_OPERATION* operation);
FREERDP_API void smartcard_operation_free(SMARTCARD_OPERATION* op, BOOL allocated);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_OPERATIONS_H */

View File

@@ -0,0 +1,241 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Smart Card Structure Packing
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2020 Armin Novak <armin.novak@thincast.com>
* Copyright 2020 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_CHANNEL_SMARTCARD_CLIENT_PACK_H
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/smartcard.h>
#include <freerdp/api.h>
#include <freerdp/channels/scard.h>
#define SMARTCARD_COMMON_TYPE_HEADER_LENGTH 8
#define SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH 8
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_write_size_align(wStream* s, size_t size, UINT32 alignment);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_read_size_align(wStream* s, size_t size, UINT32 alignment);
WINPR_ATTR_NODISCARD
FREERDP_API SCARDCONTEXT smartcard_scard_context_native_from_redir(REDIR_SCARDCONTEXT* context);
FREERDP_API void smartcard_scard_context_native_to_redir(REDIR_SCARDCONTEXT* context,
SCARDCONTEXT hContext);
WINPR_ATTR_NODISCARD
FREERDP_API SCARDHANDLE smartcard_scard_handle_native_from_redir(REDIR_SCARDHANDLE* handle);
FREERDP_API void smartcard_scard_handle_native_to_redir(REDIR_SCARDHANDLE* handle,
SCARDHANDLE hCard);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_common_type_header(wStream* s);
FREERDP_API void smartcard_pack_common_type_header(wStream* s);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_private_type_header(wStream* s);
FREERDP_API void smartcard_pack_private_type_header(wStream* s, UINT32 objectBufferLength);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_establish_context_call(wStream* s,
EstablishContext_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_establish_context_return(wStream* s,
const EstablishContext_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_context_call(wStream* s, Context_Call* call,
const char* name);
FREERDP_API void smartcard_trace_long_return(const Long_Return* ret, const char* name);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_list_reader_groups_call(wStream* s,
ListReaderGroups_Call* call,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_list_reader_groups_return(wStream* s,
const ListReaderGroups_Return* ret,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_list_readers_return(wStream* s, const ListReaders_Return* ret,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG
smartcard_unpack_context_and_two_strings_a_call(wStream* s, ContextAndTwoStringA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG
smartcard_unpack_context_and_two_strings_w_call(wStream* s, ContextAndTwoStringW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_context_and_string_a_call(wStream* s,
ContextAndStringA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_context_and_string_w_call(wStream* s,
ContextAndStringW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_locate_cards_return(wStream* s, const LocateCards_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_locate_cards_w_return(wStream* s, const LocateCardsW_Call* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_connect_a_call(wStream* s, ConnectA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_connect_w_call(wStream* s, ConnectW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_connect_return(wStream* s, const Connect_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_reconnect_return(wStream* s, const Reconnect_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_hcard_and_disposition_call(wStream* s,
HCardAndDisposition_Call* call,
const char* name);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_status_change_a_call(wStream* s,
GetStatusChangeA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_status_change_w_call(wStream* s,
GetStatusChangeW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_get_status_change_return(wStream* s,
const GetStatusChange_Return* ret,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_state_call(wStream* s, State_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_state_return(wStream* s, const State_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_status_return(wStream* s, const Status_Return* ret,
BOOL unicode);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_get_attrib_return(wStream* s, const GetAttrib_Return* ret,
DWORD dwAttrId, DWORD cbAttrCallLen);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_control_call(wStream* s, Control_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_control_return(wStream* s, const Control_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_transmit_return(wStream* s, const Transmit_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s,
LocateCardsByATRA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s,
LocateCardsByATRW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_read_cache_return(wStream* s, const ReadCache_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_transmit_count_call(wStream* s,
GetTransmitCount_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_get_transmit_count_return(wStream* s,
const GetTransmitCount_Return* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_reader_icon_call(wStream* s, GetReaderIcon_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_get_reader_icon_return(wStream* s,
const GetReaderIcon_Return* ret);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_unpack_get_device_type_id_call(wStream* s,
GetDeviceTypeId_Call* call);
WINPR_ATTR_NODISCARD
FREERDP_API LONG smartcard_pack_device_type_id_return(wStream* s,
const GetDeviceTypeId_Return* ret);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_CHANNEL_SMARTCARD_CLIENT_PACK_H */

View File

@@ -0,0 +1,66 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Logging in with smartcards
*
* Copyright 2022 David Fort <contact@hardening-consulting.com>
*
* 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_SMARTCARDLOGON_H
#define FREERDP_UTILS_SMARTCARDLOGON_H
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/crypto/certificate.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct SmartcardKeyInfo_st SmartcardKeyInfo;
typedef struct SmartcardCertInfo_st
{
LPWSTR csp;
LPWSTR reader;
rdpCertificate* certificate;
char* pkinitArgs;
UINT32 slotId;
char* keyName;
WCHAR* containerName;
char* upn;
char* userHint;
char* domainHint;
char* subject;
char* issuer;
BYTE sha1Hash[20];
SmartcardKeyInfo* key_info;
} SmartcardCertInfo;
WINPR_ATTR_NODISCARD
FREERDP_API BOOL smartcard_enumerateCerts(const rdpSettings* settings,
SmartcardCertInfo*** scCerts, size_t* retCount,
BOOL gateway);
WINPR_ATTR_NODISCARD
FREERDP_API BOOL smartcard_getCert(const rdpContext* context, SmartcardCertInfo** cert,
BOOL gateway);
FREERDP_API void smartcardCertInfo_Free(SmartcardCertInfo* pscCert);
FREERDP_API void smartcardCertList_Free(SmartcardCertInfo** pscCert, size_t count);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_SMARTCARDLOGON_H */

View File

@@ -0,0 +1,58 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Stopwatch Utils
*
* Copyright 2011 Stephen Erisman
*
* 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_STOPWATCH_H
#define FREERDP_UTILS_STOPWATCH_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
UINT64 start;
UINT64 end;
UINT64 elapsed;
UINT32 count;
} STOPWATCH;
FREERDP_API void stopwatch_free(STOPWATCH* stopwatch);
WINPR_ATTR_MALLOC(stopwatch_free, 1)
WINPR_ATTR_NODISCARD
FREERDP_API STOPWATCH* stopwatch_create(void);
FREERDP_API void stopwatch_start(STOPWATCH* stopwatch);
FREERDP_API void stopwatch_stop(STOPWATCH* stopwatch);
FREERDP_API void stopwatch_reset(STOPWATCH* stopwatch);
WINPR_ATTR_NODISCARD
FREERDP_API double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch);
FREERDP_API void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, UINT32* sec,
UINT32* usec);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_STOPWATCH_H */

View File

@@ -0,0 +1,85 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* String Utils - Helper functions converting something to string
*
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
* Copyright 2022 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_STRING_H
#define FREERDP_UTILS_STRING_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
WINPR_ATTR_NODISCARD
FREERDP_API const char* rdp_redirection_flags_to_string(UINT32 flags, char* buffer,
size_t size);
WINPR_ATTR_NODISCARD
FREERDP_API const char* rdp_cluster_info_flags_to_string(UINT32 flags, char* buffer,
size_t size);
/** @brief extracts <key>=<value> pairs from a string
*
* @param str The string to extract data from, must not be \b nullptr
* @param pkey A pointer to store the key value, must not be \b nullptr
* @param pvalue A pointer to store the value, must not be \b nullptr
*
* @return \b TRUE if successfully extracted, \b FALSE if no matching data was found
*
* @since version 3.9.0
*/
WINPR_ATTR_NODISCARD
FREERDP_API BOOL freerdp_extract_key_value(const char* str, UINT32* pkey, UINT32* pvalue);
/** @brief Convert \ref FreeRDP_DesktopRotationFlags to string
*
* @param flags The value to convert
* @return A constant string representation of \ref flags or the string \b ORIENTATION_UNKNOWN
* for an invalid value
* @since version 3.22.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char*
freerdp_desktop_rotation_flags_to_string(UINT32 flags);
/** @brief Convert a single \ref RDPINPUT_CONTACT_FLAGS to string
*
* @param flags The value to convert
* @return A constant string representation of \ref flag or the string \b
* RDPINPUT_CONTACT_FLAG_UNKNOWN for an invalid value
* @since version 3.22.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* freerdp_input_touch_state_string(DWORD flags);
/** @brief Convert a single \ref FreeRDP_OrderSupportFlags to string
*
* @param type The value to convert
* @return A constant string representation of \ref type or the string \b
* UNKNOWN for an invalid value
* @since version 3.22.0
*/
FREERDP_API WINPR_ATTR_NODISCARD const char* freerdp_order_support_flags_string(UINT8 type);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_STRING_H */