For higher level applications it is easier to translate known
strings instead of error codes. this function allows
to retrieve known string identifiers that can be translated.
Signed-off-by: Armin Novak <armin.novak@thincast.com>
Some os return an invalid/wrong character count if a string with
unknown symbols is printed to stdout.
Instead use the sprintf family and print to a buffer / determine
the required buffer size.
The file clipboard delegate needs a base URI to operate on for
systems that are not WIN32. Added that to the context and abort
conversion, if that is not set. (currently not fully implemented)
Since this function calls WLog_GetLogLevel anyway better only
export the API to allow internal checks to be modified in the
future without breaking API
It's sometime useful to create a stream aliasing a buffer on the stack, and
it's nice if we don't need some extra malloc for this.
Example use:
BYTE buffer[20];
wStream s;
Stream_StaticInit(&s, buffer, sizeof(buffer));
Stream_Write_UINT16(&s, 0xff01);
Stream_Free(&s, FALSE);
(we overwrite the password and pin arguments).
This implies changes in the argument parsing tests that now must pass a mutable argv
(copied from the statically declared test argvs).
Some other const inconsistency have been dealt with too.
When using pthread_once with destructors they are only called,
if each thread (including the main thread) is exited with pthread_exit.
Introducing winpr_exit as a wrapper for that purpose.
SCardAddReaderName isn't part of the SCard API.
Note: removing this also removes the possibility to redirect single
smartcard readers with /smartcard:READERNAME. However this features
wasn't implemented in a general way and will be re-added as part of
the smart card channel directly.
To be able to avoid password conversion if the password is already unicode
this change adds the sspi_SetAuthIdentityWithUnicodePassword() function
that is identical to sspi_SetAuthIdentity() except that the password is
used without further conversions in the Unicode identity.
FreeRDP aborts if OpenSSL operates in FIPS mode and +fipsmode is not
manually specified. Let's prevent the abortion and enable the necessary
options in that case automatically.
This option will ensure that NLA is disabled(since NTLM uses weak crypto algorithms), FIPS
encryption is enabled, and ensure fips mode is enabled for openssl.
Selectively override specific uses of MD5/RC4 with new API calls specifically tailored to override FIPS.
Add comments on why overriding the use of these algorithms under FIPS is acceptable for the locations where overrides happen.
Remove check of server proprietary certificate which was already being ignore to avoid use of MD5.
Initialize winpr openssl earlier to ensure fips mode is set before starting using any crypto algorithms.
Adds a callback that allows servers to compute NTLM hashes by themselves. The typical
use of this callback is to provide a function that gives precomputed hash values.
Sponsored by: Wheel Systems (http://www.wheelsystems.com)
This header file (currently) provides definitions of FILEDESCRIPTOR
structure and GetUserProfileDirectory() function. However, it does so
only when included on non-Windows platforms. The code which includes it
fails to build on Windows because the definitions are absent and it
causes weird compilation errors (like FILEDESCRIPTOR being treated as
the name of a function argument).
Inculde <shlobj.h> to get FILEDESCRIPTOR and <userenv.h> for the
GetUserProfileDirectory() function. (And hope that this will not
pull more Windows headers than we need in the files which include
<winpr/shell.h>.)
Another issue revealed during testing is that older Windows systems
cannot handle the reserved file names well. While Windows 8 and 10 are
fine (they silently abort the file transfer), using reserved names with
Windows 7 can flat out crash explorer.exe or result into weird error
messages like "fatal error: 0x00000000 ERROR_SUCCESS".
This is not required by MS-RDPECLIP specification, but we should try to
avoid this issue as not using reserved file names seems to be assumed
a common sense in Windows protocols.
The most convenient way to handle the issue would be on wClipboard level
so that WinPR's clients do not bother with it. We should prohibit the
reserved names from being used in FILEDESCRIPTOR, failing the conversion
if we see such a file.
POSIX subsystem (the only one at the moment) handles remote file names
in two places so move the Unicode conversion and the new validation
check into a separate function.
The reserved file name predicate is placed into <winpr/file.h> so that
it can be used in other places too. For example, other wClipboard local
file subsystems will need it. (It would be really nice to enforce this
check somewhere in the common code, so that the subsystems can't miss
it, but other places can miss some errors thus we're doing it here, as
early as possible.)
The predicate acts on separate file name components rather than full
file names because the backslash is a reserved character too. If we
process full file names this can result in phantom directory entry in
the remote file name. Not to say that handling ready-made components
spares us from splitting the full file name to extract them :)
The implementation is... a bit verbose, but that's fine by me. In the
absence of functions for case-insensitive wide string comparison and
the need to check for the [0-9] at the end of some file names this is
quite readable. Thanks to FAT and NTFS for being case-insensitive and
to MS-DOS for having reserved file names in the first place.
This is another bunch of callbacks which provide the file contents to
the clients. We jump through some extra hoops in order to have more
pleasant user experience.
Simple stuff goes first. The file offset (or position) is split into the
low and high parts because this is the format in which the clients
receive the request from the server. They can simply copy the values as
is into the struct without repackaging them (which we do instead in the
end to get a 64-bit off_t).
Another thing is that we try to minimize the number of lseek() calls and
to keep as few file descriptors open as possible. We cannot open all the
files at once as there could be thousands of them and we'll run out of
the allowed number of the fds. However, the server can (in theory)
request the file ranges randomly so we need to be prepared for that. One
way to do that would be to always open the file before reading and close
it immediately afterwards. A dead simple solution with an acceptable
performance, but... some file systems do not support seeking, such as
FTP directories mounted over FUSE. However, they handle sequential
reading just fine *and* the server requests the data sequentially most
of the time so we can exploit this.
Thus open the file only once, during the first range request and keep
it open until the server reads all the data. In order to know how much
data is left we keep an accurate account of all reads and maintain the
file offset ourselves. This also allows us to avoid calling lseek() when
the file offset will not be effectively changed. However, if the server
requests some weird offset then we have no choice and will attempt
seeking. Unfortunately, we cannot tell whether it is a genuine failure
or the file system just does not support seeking, so we do not handle
the error further. (One workaround would be to reopen the file and keep
reading it until we're at the correct offset.) In this way we can
support sequential-only file systems if the server requests the contents
sequentially (and it does).
Also note that we do an fstat() right after opening the file in order to
have an accurate value of file size, for this exact file descriptor we
will be using. We should have it filled it by now, but just in case...
There is one more thing to explain. The cbRequested field specifies the
maximum number of bytes the server can handle, not the required number.
Usually this is some power-of-two number like 64 KB, based on the size
of the files on the clipboard. This is why posix_file_read_perform()
does not attempt to fill the whole buffer by repeatedly calling read()
if it has read less data than requested. The server can handle underruns
just fine (and this spares us from special-casing the EOF condition).
This is an example of wClipboardDelegate method implementation. POSIX
subsystem uses synchronous methods, but the interface can be used for
asynchronous request processing as well. The client should call a
Client* callback to request some action and the wClipboard will process
the request and report the result by calling an approriate Clipboard*
callback. Usually there will be two callbacks: one for reporting success
and one to report errors.
All callbacks have at least two arguments: the wClipboardDelegate itself
to pass the system context, and the wClipboard*Request structure with
the arguments to pass the call context. The request context is also
passed to the result callbacks by wClipboard so that the client can
match up the result with its previous request.
The fields of wClipboard*Request structures are heavily influenced by
the MS-RDPECLIP spec and mirror the respective fields of
CLIPRDR_FILECONTENTS_REQUEST. wClipboard should not depend on
MS-RDPECLIP, that's the reason we don't use CLIPRDR_FILECONTENTS_REQUEST
directly. However, I believe that we should not have void* fields in the
request structs so that they can be easily copied around if needed.
This is why have the weird 'streamId' field there which has nothing to
do with wClipboard and will be used only by the clients when sending
replies to the server.
Return values of the callbacks are to be used for reporting errors with
processing the request or reply per se, not for errors encountered while
performing the action requested. Thus, for example, we return NO_ERROR
from posix_file_request_size() even when we fail to report the result to
the client, because we have successfully performed the request and do
not care if the client could not handle our reply for some reason.
Also note that setup_delegate() fills in dummy implementations of
Clipboard* reply callbacks so that we do not crash in case the client
does not fill them and do not have to perform paranoid NULL checks
before calling every single callback.
This is the thing which will be used by clients to request file sizes
and ranges from wClipboard and by wClipboard to report the results of
the requests to the clients.
wClipboard and the client will fill in the (currently absent) callbacks
with their implementations of the request-report interface and will be
using them accordingly.
Initially I thought that wClipbardDelegate would be dynamically
allocated by the client and set into wClipboard (as this would be the
case with a delegate interface implementation in OOP langauges), but
after some thought I ended up with storing the delegate in wClipboard
and using the 'void* custom' field for client-private data.
So the idea is for the subsystem to fill in its callbacks during
wClipboard construction and for the client to get access to
wClipboardDelegate with a getter and fill in its callbacks during its
clipboard initialization. The subsystem will use wClipboard* pointer to
access its data and the client will have its void* pointer to store its
context.
The flags are defined by MS-RDPECLIP 2.2.5.2.3.1 File Descriptor
(CLIPRDR_FILEDESCRIPTOR) as well as by 'File Attribute Constants'
in WinAPI reference [1].
The idea is to delegate FILEDESCRIPTOR format processing to WinPR
instead of cliprdr channel, so move the struct definition there. The
definition used by cliprdr protocol is identical but with some fields
treated as reserved.
The defintions are placed into <winpr/shell.h> as FileGroupDescriptorW
is a shell clipboard format.
Also remove the definition of CLIPRDR_FILELIST. The clients would be
using WinPR to handle the file clipping, so CLIPRDR_FILELIST does not
have to be handled explicitly. The clients will have serialization and
deserialization functions to handle CLIPRDR_FILELIST.
[1]: https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx
- fixed invalid, missing or additional arguments
- removed all type casts from arguments
- added missing (void*) typecasts for %p arguments
- use inttypes defines where appropriate
Undefined preprocessor macro in wtypes.h produces:
warning: "__ILP64__" is not defined [-Wundef]
This causes unnecessary hassle to people who compile their FreeRDP-based
applications with -Werror.
- winpr_HMAC_New() now just returnes the opaque WINPR_HMAC_CTX* pointer
which has to be passed to winpr_HMAC_Init() for (re)initialization
and since winpr_HMAC_Final() no more frees the context you always have to
use the new function winpr_HMAC_Free() once winpr_HMAC_New() has succeded
- winpr_Digest_New() now just returns the opaque WINPR_DIGEST_CTX* pointer
which has to be passed to winpr_Digest_Init() for (re)initialization
and since winpr_Digest_Final() no more frees the context you always have to
use the new function winpr_Digest_Free() once winpr_Digest_New() has succeded
iOS does not support Thread Local Storage.
Disabling it for now until a solution is found.
Print a compiler warning informing developers about this issue.
Global static variables do not work, if more than one instance
of an RDP client is running in the same process space.
Removed the varaibles where possible and replaced them with
thread local storage where necessary.
Depending on the windows target version (_WIN32_WINNT), the used
SDK and the build configuration the linker will see multiple
libraries exporting the same symbols.
To prevent ugly hacks (e.g. modifying cmake's default system
libraries or fragile library linking order chains) we prefix
these functions with "winpr_" and create corresponding defines
to keep the current api names.
pool:
- the winpr implementation fallback was not used on older windows editions
- drop useless and conflicting TP_CALLBACK_ENVIRON_V3
- fix race conditions by using use proper one-time initialization
- on win32 WinPR tried to load several pool/callback_environment functions
from kernel32.dll but since these are defined as inline functions in the
windows headers, no windows edition has ever exported them in any dll.
- removed callback_environment.c and added corresponding static inline
function to pool.h
- fix segfault in TestPoolWork: CloseThreadpoolWork() must not be called
if there is a cleanup group associated with the work object since calling
CloseThreadpoolCleanupGroupMember() already releases the work object
sync:
- The windows headers incorrectly define InitializeCriticalEx support if
_WIN32_WINNT >= 0x0403 instead of >= 0x0600 (Vista)
- created a compatible define to deal with this issue
The conversion macros don't work properly if input data doesn't point
to BYTE. Cast the input data to BYTE to avoid unexpected behavior and
to simplify usage of the macros.
https://github.com/FreeRDP/FreeRDP/issues/2520
There is a bug which causes that higher byte and lower byte contain
first byte of data and second byte of data is lost. The patch fixes
it similarly as it is done in Stream_Read_UINT16.
https://github.com/FreeRDP/FreeRDP/issues/2520
When nothing is declared, only export symbols defined
with WINPR_API or FREERDP_API defined.
Override this setting if BUILD_TESTING to allow tests
access to internal functions usually not exposed.
Extend winpr and client/common to support a new option "/buildconfig".
When used build the following build specific information is print:
* cmake options
* cflags
* compiler
* target architecture
* cmake build type
With this commit the "exported" components (usable with pkg-config and
cmake find module package)
* winpr - winpr library and headers
* freerdp - core library and headers
* freerdp-client - client specific library
* freerdp-server - server specific library
* rdtk - rdtk headers and library
To allow the installation of multiple different version (different major
number) the include files were moved into the respective sub folder:
freerdp -> freerdp{MAJOR}/freerdp (currently freerdp2/freerdp/)
winpr -> winpr{MAJOR}/winpr (currently winrp1/winpr/)
rdtk -> rdpk{MAJOR}/rdtk (currently rdtk0/rdtk/
The generated pkg-config and cmake find modules now also include the major
version number. Currently the following pkg-config are generated and
installed.
* winpr1
* freerdp2
* freerdp-server2
* freerdp-client2
* rdtk0
As cmake is able to handle multiple versions out of the box the
following can be used to find a specific module:
find_package(WinPR)
find_package(FreeRDP)
find_package(FreeRDP-Server)
find_package(FreeRDP-Client)
find_package(RdTk)
As cmake doesn't automatically resolve dependencies for packages it is
necessary to manually include the requirements. For example if
FreeRDP-Client is required WinPR and FreeRDP need to be included
(find_package) as well.
This commit also fixes the installation when STATIC_CHANNELS are built.
WITH STATIC_CHANNELS all channels are linked into libfreerdp-client, for
this all channels are generated as linker archive and linked together in
the final step. Before the intermediate linker archives were, although
not required and useful, installed. Same applies for server side
channels.
* only expose necessary functions and types in header
* don't expose appender internals
* add generic function WLog_ConfigureAppender to have the possibility
to configure appender specific settings
* detect appender availability if WLog_SetLogAppenderType or
WLog_Appender_New return FALSE or NULL respectively the appender isn't
available or the initialization failed. This is very useful for the
use with optional appenders.
* add Free to the appender interface. At the time of the Free the
appender is known and available so it can be called directly (instead
of calling the right function according to the type)
* make all appender internal function static
* all appenders return the generic wLogAppender type now. Typecasts
are internally done where necessary this abstracts the appenders more
cleanly
This appender allows to receive the logs over a network connection using UDP packets.
You can see the logs using a listening netcat, for example: nc -ul 127.0.0.1 20000.
* expose EnvironmentBlockToEnvpA
* cleanup includes in process.c
* removed unused "flag" variable in _CreateProcessExA
* make ProcessHandleCloseHandle static
wlog used to return an int but the only meaning
of the return value was:
* negative ... error
* 0 or positive ... success
but the positve returned value was 1 or some id of some
subsystem, nothing meaningful for the caller.
For a more meaningful returnvalue we now use BOOL.
If something goes wrong FALSE is returned.
winsock.h pulls in a lot of defines and dependencies that are not
required and partially unwanted in winpr's core (for parts that are not
related to network). In order to get rid of this dependency and have an
independent defines for extended winpr functions the WINPR_FD_* defines
are used internally (and for exposed functions). Where required, like in
WSAEventSelect, the FD_* is mapped to WINPR_FD_*.
Allows the WinPR HANDLE functions WaitForSingleObject and
WaitForMultipleObjects to signal in case of write events.
This is used by CreateFileDescriptor and SetEventFileDescriptor,
which got an API change accomodating for this new feature.
This patch contains:
* checks for malloc return value + treat callers;
* modified malloc() + ZeroMemory() to calloc();
* misc fixes of micro errors seen during the code audit:
** some invalid checks in gcc.c, also there were some possible
integer overflow. This is interesting because at the end the data are parsed
and freed directly, so it's a vulnerability in some kind of dead code (at least
useless);
** fixed usage of GetComputerNameExA with just one call, when 2 were used
in misc places. According to MSDN GetComputerNameA() is supposed to return
an error when called with NULL;
** there were a bug in the command line parsing of shadow;
** in freerdp_dynamic_channel_collection_add() the size of array was multiplied
by 4 instead of 2 on resize