Commit Graph

2188 Commits

Author SHA1 Message Date
Bernhard Miklautz
ed36f55f3e Merge pull request #4088 from akallabeth/file_api_64bit_fixes
fseeko and ftello for 64bit file support.
2017-08-16 10:04:13 +02:00
Armin Novak
c3d4b7d262 fseeko and ftello for 64bit file support. 2017-08-14 08:42:49 +02:00
Armin Novak
82d9ebc380 Fixed FileSetFilePointer warnings 2017-08-10 16:56:20 +02:00
MartinHaimberger
80ed23779f Merge pull request #4076 from akallabeth/SetFilePointer_fix
Set file pointer fix
2017-08-09 10:35:37 +02:00
Armin Novak
7d7e5487ab Fixed SetFilePointer, added SetFilePointerEx 2017-08-08 10:51:50 +02:00
Jura Sasek
a84c5cbfb9 Sun keyboard 2017-08-04 13:09:32 +02:00
Mike Gabriel
dc075fb133 Fix warning in man pages
"warning: can't find macro file `www.tmac))'""`"
2017-08-03 08:41:50 +02:00
Mike Gabriel
c045bddf3f Fix typos in some error messages 2017-08-03 08:38:05 +02:00
David Fort
c84065f40c Merge pull request #4069 from yurashek/master
Build on Solaris
2017-08-02 09:53:38 +02:00
Valery Kartel
9bf9ff9e8a Fix build with LibreSSL 2017-07-26 17:12:14 +03:00
Bernhard Miklautz
f23e10f64b clipboard: fix possible invalid memory access
Fix an possible issue found by Sébastien Duquette.
2017-07-20 09:35:42 +02:00
Armin Novak
0490aeb018 Fixed clang malloc integer overflow warnings. 2017-07-20 09:29:48 +02:00
dodo040
2f22e679e0 fix format code 2017-07-19 13:16:08 +02:00
dodo040
4e055453ab fix smartcard argument parsing 2017-07-19 13:16:08 +02:00
dodo040
722e927c64 redirect specific smartcard readers 2017-07-19 13:16:08 +02:00
akallabeth
f0fb219580 Merge pull request #4041 from wayk/PathMakePathA
Fixed PathMakePathA (returned true even if it can't create the last f…
2017-07-17 12:26:48 +02:00
Robert Corrigan
005c4df9b0 Update time zone data to July 2017 2017-07-14 17:16:08 -04:00
François Dubois
2a1fde25c8 Fixed PathMakePathA (returned true even if it can't create the last folder of the path) 2017-07-12 14:47:08 -04:00
Norbert Federa
36b8f54c5e Fixed a few compiler warnings 2017-07-10 17:52:05 +02:00
Olivier Blin
d65c2a90ea Fix clipboard POSIX build because of basename conflict
FreeRDP/winpr/libwinpr/clipboard/posix.c:397:20: error: conflicting types for ‘basename’
 static const char* basename(const char* name)
                    ^
In file included from FreeRDP/winpr/include/winpr/collections.h:25:0,
                 from FreeRDP/winpr/libwinpr/clipboard/posix.c:37:
/usr/include/string.h:599:14: note: previous declaration of ‘basename’ was here
 extern char *basename (const char *__filename) __THROW __nonnull ((1));
2017-07-05 18:48:37 +02:00
weizhenwei
fa1c65b656 refactor to remove duplicate code and replace free+malloc with realloc 2017-06-22 10:21:20 +08:00
weizhenwei
64fce8717f fix memroy leak of fd at FindFirstFileW() 2017-06-21 15:26:28 +08:00
David Fort
5ef9232703 Merge pull request #3905 from ilammy/x11-cliprdr/file-clipping
Local-to-remote file clipping for xfreerdp
2017-06-07 21:20:34 +02:00
ilammy
987d7dd886 winpr/file: add missing NULL check
ValidFileNameComponent() has been missing a NULL check for its argument.
It's pretty obvious that NULL is not a valid file name component.
2017-05-24 23:19:39 +03:00
ilammy
a85cf1b749 wClipboard: drop WITH_DEBUG_WCLIPBOARD option
This preprocessor definition has been initially intended to disable some
computationally expensive logging, however it turned out that there is
not much computation involved in the resulting implementation of new
wClipboard subsystems. Therefore we do not actually need the compilation
option, the logs can be filtered by "com.winpr.wclipboard.*" tag at
runtime if necessary. So drop the WITH_DEBUG_WCLIPBOARD CMake option and
convert all detailed logs to use WLOG_TRACE level via WLog_VRB macro.
2017-05-24 23:17:33 +03:00
Jura Sasek
4edb5cf7e6 Build for Solaris 2017-05-24 04:27:01 -07:00
David Fort
48163a27db Merge pull request #3906 from akallabeth/addin_cast_fix
Addin cast fix
2017-05-22 11:12:05 +02:00
davewheel
4bfb4dddbf Add a callback to provide NTLM hashes on server-side
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)
2017-05-18 14:24:24 +02:00
Armin Novak
620b1ea603 Added 64bit file support flag for linux. 2017-05-10 14:58:12 +02:00
Armin Novak
4ba7670e43 Fixed right shift on 32bit platforms. 2017-05-04 09:20:10 +02:00
David Fort
677c4e2105 Merge pull request #3919 from akallabeth/rdpdr_hotplug_fix
Fixed hotplug mount locations.
2017-04-27 14:11:51 +02:00
Armin Novak
d1e7ce9ce0 Fixed FindFirstFileA, do not strip trailing slash 2017-04-27 08:59:21 +02:00
Armin Novak
dafa6cef67 Fixed memory corruption in Find*FileW 2017-04-27 08:31:53 +02:00
ilammy
843ab1c234 winpr: fix field names of FILEDESCRIPTOR struct
The file name field is actually called cFileName on Windows. Use this
name in WinPR's struct definition as well for compatibility.
2017-04-21 14:13:52 +03:00
ilammy
d341973247 winpr: include Windows headers in <winpr/shell.h>
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>.)
2017-04-21 00:44:46 +03:00
Armin Novak
920a76d57e Fix #3922: Use stat insead of lstat 2017-04-19 08:28:00 +02:00
Robert Corrigan
97c5494b98 Update timezone data to Apr 2017 2017-04-18 16:15:13 -04:00
Norbert Federa
736675aa01 Merge pull request #3901 from akallabeth/openssl_1_1_no_legacy
Fixed OpenSSL 1.1 no legacy compile issues.
2017-04-11 15:00:30 +02:00
Armin Novak
4e32334621 Added error return in GetFileAttributesExA. 2017-04-11 11:34:11 +02:00
Armin Novak
b0289e3ed8 Fixed cast warnings. 2017-04-10 10:39:01 +02:00
ilammy
44b04cafef wClipboard: disallow Windows reserved names
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.
2017-04-09 03:17:07 +03:00
ilammy
458c042b53 wClipboard: track sequence numbers of file lists
One important point in the cliprdr protocol is that the peers are not
allowed to request file sizes and ranges if the clipboard content
changes. File locking should be used to gain this ability. However, our
file list is still accessible after new data is set into wClipboard.

Catch this error by storing the sequence number of the file list when it
is set and checking that it is still in effect at the time when the
client requests file sizes or ranges. There is a small chance of false
positives when the sequence number overflows, but I guess we can safely
ignore it.
2017-04-09 03:15:49 +03:00
ilammy
092e870d2a wClipboard/posix: implement file range retrieval
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).
2017-04-09 03:15:49 +03:00
ilammy
33719d24ce wClipboard/posix: implement file size retrieval
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.
2017-04-09 03:15:49 +03:00
ilammy
28afbe61f9 wClipboard/posix: basic delegate interface
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.
2017-04-09 03:15:49 +03:00
ilammy
6c6b122a37 wClipboard/posix: add directories to file list
text/uri-list contains only the files which were immediately selected by
the user. However, we need to enumerate *all* files and directories to
be pasted in CLIPRDR_FILELIST. Thus we need to walk through the
directories and add their content to the file list as well.

We use readdir() function to traverse the directory entries. It has more
sane interface than readdir_r(), but lacks (standardized) thread-safety
guarantees.  However, most C liraries guarantee that so we can use it.
There is no compile-time check because it cannot be made robust. You
deserve a crash here if you are using a C library developed by people
who cannot keep their unhealthy addiction to global state under control.

Note that recursive traversal is also a good opportunity to maintain
good remote names. We just need to concatenate the directory paths and
file names correctly.

However, this recursion has one caveat: it is not bounded, so if the
file system contains a loop then we will crash due to a stack overflow.
We could track symlink loops (and hardlinks too if we try hard) to avoid
the crash, but I think it's not a common thing to do so we can ignore
this possibility.
2017-04-09 03:15:49 +03:00
ilammy
33e80849a8 wClipboard/posix: add local files to file list
Finally we can add a file to the file list once we have got its local
file name decoded. The interesting part here is what we use for the
remote name.

Suppose the user has selected two files in different directories. In
this case we end up receiving a text/uri-list like this:

  file:///home/bob/foo/a
  file:///home/bob/bar/b

We'd expect to see "a" and "b" pasted into the remote session, so that's
what we should use for the remote names: the base names of the files.
These are the parts from the end up to the last directory delimiter.

One tricky point here is that Windows expects the file names to be
encoded in Unicode, but POSIX does not specify any particular encoding
for file names. Operating systems and file systems generally handle the
file names as mostly opaque bytes strings and do not really care what
encoding is used there. There is no portable API to get the encoding,
it's entirely up to the users and the software they use to correctly
interpret the file names. But we need to do something here.

As of 2017, the most widely used encoding for file names is UTF-8. While
there are marginal communities which stick to codepages for legacy
reasons, we can safely assume that most of the time the file names will
be encoded in UTF-8. In fact, popular desktop environments like GNOME
also assume this. So that's what we will do here as well.
2017-04-09 03:15:49 +03:00
ilammy
50038bb725 wClipboard/posix: decode percent-encoding
Nothing really interesting here, it's exactly what it says on the tin.
The percent-encoding is specified by RFC 3986. And we take care to
detect invalid encodings.
2017-04-09 03:15:49 +03:00
ilammy
64e1073044 wClipboard/posix: parse text/uri-list format
Now we start handling the actual format data. As the first step we need
to convert the text/uri-list data into the list of file names. Each file
or directory the user selects to copy is represented with a URI, and the
whole list looks like this:

  file:///home/bob/text-file
  file:///home/bob/a-directory
  file:///home/bob/white%20space

The MIME format is actually specified by RFC 2483. As said in the
comments, we allow some slack for other applications: they can use
singular LF and CR as line terminators, and we also will handle missing
terminator for the last line (some applications actually do this, but I
can't recall which ones at the moment).

We will handle only the file:// URI scheme because these refer to local
filesystem paths. It is possible for text/uri-list to contain URIs with
other schemes when the user selects files from remote filesystems (like
an FTP server or an SMB share connect to from a file manager). We cannot
pass such paths to open() and for some reason the file managers use the
remote URIs even when the remote filesystems are actually mapped to the
local filesystem via FUSE. Therefore we restrict ourselves to handling
only file://.
2017-04-09 03:15:48 +03:00
ilammy
09e73a00cb wClipboard/posix: conversion to FILEDESCRIPTORs
Now we do the actual conversion of a list of struct posix_files into an
array of FILEDESCRIPTORs. In order to correctly fill in the fields we
need to know the size of the file and whether it is a directory. This
can be looked up by stat() call. Do this during struct posix_file
construction and cache the values for later use (we will need them).

Define _FILE_OFFSET_BITS to make off_t a 64-bit value and to call
appropriate functions when we write stat() in the code. FILEDESCRIPTOR
and cliprdr protocol expect the file sizes to be 64-bit so we can
provide accurate information with that. Take care to define it before
including any system headers ("config.h" contains only defines).

Also take care to not overrun the file name buffer. Windows has a hard
cap of 260 Unicode characters for the full file name, including the
terminating null character.
2017-04-09 03:15:48 +03:00