The retry loop for acquiring the lock for the authentication cookie file
currently tries to acquire the lock for 0.5s, then gives up, assumes the
lock file is stale, and deletes it.
That’s great if the lock file *is* stale because it’s been left there by
a crashed process.
It’s not so great if the lock file just happens to have been there every
time this process checked, because the cookie file is highly contested
while (for example) running lots of parallel unit tests.
Check for that situation by comparing the mtime of the lock file and
continuing to retry if it’s changed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #1929
Continue to allow overriding the keyring dir, but don’t automatically
create it when running as root.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1432485
For interoperability with libdbus, we want to use compatible timeouts.
In particular, this fixes a spurious failure of the `gdbus-server-auth`
test caused by libdbus and gdbus choosing to expire the key (cookie) at
different times, as diagnosed by Thiago Macieira. Previously, the libdbus
client would decline to use keys older than 7 minutes, but the GDBus
server would not generate a new key until the old key was 10 minutes old.
For completeness, also adjust the other arbitrary timeouts in the
DBUS_COOKIE_SHA1 mechanism to be the same as in libdbus. To make it
easier to align with libdbus, create internal macros with the same names
and values used in dbus-keyring.c.
* maximum time a key can be in the future due to clock skew between
systems sharing a home directory
- spec says "a reasonable time in the future"
- was 1 day
- now 5 minutes
- MAX_TIME_TRAVEL_SECONDS
* time to generate a new key if the newest is older
- spec says "If no recent keys remain, the server may generate a new
key", but that isn't practical, because in reality we need a grace
period during which an old key will not be used for new authentication
attempts but old authentication attempts can continue (in practice both
libdbus and GDBus implemented this logic)
- was 10 minutes
- now 5 minutes
- NEW_KEY_TIMEOUT_SECONDS
* time to discard old keys
- spec says "the timeout can be fairly short"
- was 15 minutes
- now 7 minutes
- EXPIRE_KEYS_TIMEOUT_SECONDS
* time allowed for a client using an old key to authenticate, before
that key gets deleted
- was at least 5 minutes
- now at least 2 minutes
- at least (EXPIRE_KEYS_TIMEOUT_SECONDS - NEW_KEY_TIMEOUT_SECONDS)
Based on a merge request by Philip Withnall.
Fixes: #2164
Thanks: Philip Withnall
Thanks: Thiago Macieira
Signed-off-by: Simon McVittie <smcv@collabora.com>
Where applicable. Where the current use of `g_file_set_contents()` seems
the most appropriate, leave that in place.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1302
There’s no need to call `access()` and then `stat()` on the keyring
directory to check that it exists, is a directory, and has the right
permissions. Just call `stat()`.
This eliminates one potential TOCTTOU race in this code.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1954
There was a time-of-check-to-time-of-use (TOCTTOU) race in the keyring
lock code, where it would check the existence of the lock file using
`access()`, then proceed to call `open(O_CREAT | O_EXCL)` to try and
create the lock file once `access()` showed that it didn’t exist.
The problem is that, because this is happening in a shared directory
(`~/.dbus-keyrings`), another process could quite legitimately create
the lock file in the meantime.
Instead, unconditionally call `open()` and ignore errors from it (which
will be returned if the lock file already exists) until it succeeds (or
the code times out).
This eliminates the TOCTTOU race, and simplifies the timeout behaviour
so there aren’t two loops (check for existence, try to create)
happening. It brings this code in line with what dbus.git does (see
`_dbus_keyring_lock()`).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1954
If the directory is overridden, for example when running tests, the
parent directory of `.dbus-keyrings` (i.e. the fake `$HOME` directory)
might not exist. Create it automatically.
This should realistically not have an effect on non-test code.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1912
These can be hit in the tests (if multiple tests run in parallel are
racing for `~/.dbus-keyrings/org_gtk_gdbus_general.lock` for a prolonged
period) and will cause spurious test failures due to the use of
`G_DEBUG=fatal-warnings`.
Instead, allow the error messages to be inspected programmatically.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1912
Use either g_get_real_time() or g_date_time_new_now_local(). This means
we don’t need to worry about time_t being 32b in future (the year 2038
problem), and it makes the need for error handling a bit more explicit.
Improve the error handling in several cases.
Based on a patch by Niels De Graef
(https://gitlab.gnome.org/GNOME/glib/merge_requests/142).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1402
Fix various warnings regarding unused variables, duplicated
branches etc by adjusting the ifdeffery and some missing casts.
gnulib triggers -Wduplicated-branches in one of the copied files,
disable as that just makes updating the code harder.
The warning indicating missing features are made none fatal through
pragmas. They still show but don't abort the build.
https://bugzilla.gnome.org/show_bug.cgi?id=793729
Apparently Solaris defines statbuf fields as long when Linux doesn’t, in
some cases. Cast down to the type expected by the printf() format
placeholder.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://bugzilla.gnome.org/show_bug.cgi?id=749652
Setting a variable and then assigning it to itself avoids
-Wunused-but-set-variable but this specific trick is now caught by
-Wself-assign. Instead, actually use the value or don't bother
assigning it at all:
gdbusauthmechanismsha1.c: #ifdef a var decl to match its actual use use
gdbusauthmechanismsha1.c: call g_ascii_strtoll() in void context
https://bugzilla.gnome.org/show_bug.cgi?id=745723
Setting a variable and then assigning it to itself avoids
-Wunused-but-set-variable but this specific trick is now caught by
-Wself-assign. Instead, actually use the value or don't bother
assigning it at all:
gdbusauth.c: call g_data_input_stream_read_byte() in void context
gdbusauthmechanismsha1.c: value is actually used
gdbusmessage.c: use consistent preprocessor-token protection
gthreadedresolver.c: skip over bytes in data blob
httpd.c: do something useful with the value
https://bugzilla.gnome.org/show_bug.cgi?id=745723
Prevent the situation where errno is set by function A, then function B
is called (which is typically _(), but could be anything else) and it
overwrites errno, then errno is checked by the caller.
errno is a horrific API, and we need to be careful to save its value as
soon as a function call (which might set it) returns. i.e. Follow the
pattern:
int errsv, ret;
ret = some_call_which_might_set_errno ();
errsv = errno;
if (ret < 0)
puts (strerror (errsv));
This patch implements that pattern throughout GLib. There might be a few
places in the test code which still use errno directly. They should be
ported as necessary. It doesn’t modify all the call sites like this:
if (some_call_which_might_set_errno () && errno == ESOMETHING)
since the refactoring involved is probably more harmful than beneficial
there. It does, however, refactor other call sites regardless of whether
they were originally buggy.
https://bugzilla.gnome.org/show_bug.cgi?id=785577
In Windows development environments that have it, <unistd.h> is mostly
just a wrapper around several other native headers (in particular,
<io.h>, which contains read(), close(), etc, and <process.h>, which
contains getpid()). But given that some Windows dev environments don't
have <unistd.h>, everything that uses those functions on Windows
already needed to include the correct Windows header as well, and so
there is never any point to including <unistd.h> on Windows.
Also, remove some <unistd.h> includes (and a few others) that were
unnecessary even on unix.
https://bugzilla.gnome.org/show_bug.cgi?id=710519
As it turns out, we have examples of internal functions called
type_name_get_private() in the wild (especially among older libraries),
so we need to use a name for the per-instance private data getter
function that hopefully won't conflict with anything.
Back in the far-off twentieth century, it was normal on unix
workstations for U+0060 GRAVE ACCENT to be drawn as "‛" and for U+0027
APOSTROPHE to be drawn as "’". This led to the convention of using
them as poor-man's ‛smart quotes’ in ASCII-only text.
However, "'" is now universally drawn as a vertical line, and "`" at a
45-degree angle, making them an `odd couple' when used together.
Unfortunately, there are lots of very old strings in glib, and also
lots of new strings in which people have kept up the old tradition,
perhaps entirely unaware that it used to not look stupid.
Fix this by just using 'dumb quotes' everywhere.
https://bugzilla.gnome.org/show_bug.cgi?id=700746
This allows compilation with clang without errors, even when
-Wformat-nonliteral is active (as long as there are no real cases of
non literal formatting).
https://bugzilla.gnome.org/show_bug.cgi?id=691608
Non-technical users won't know that "stating" refers to stat(2), so we
just use "error when getting information" now.
Signed-off-by: Federico Mena Quintero <federico@gnome.org>
- Fix various #include issues
- Change #error to #warning for the EXTERNAL authentication mechanism.
It is not clear if this should work on Win32 at all.
- Call close() before unlink() for the SHA1 keyring
- Change #error to #warning so we don't forget to do
permission checking of the .dbus-keyrings directory
- Use Win32 SID for the SHA1 auth mech
- Apparently we can't use word 'interface' as an identifier
- Implement a _g_dbus_win32_get_user_sid() function. For now it's
private. Don't know if it should be public somewhere. Maybe in
a future GCredentials support for Win32? I don't know.
- GFileDescriptorBased is not available on Win32. So avoid using
it in GLocalFile stuff. Now, Win32 still uses GLocalFile + friends
(which works with file descriptors) so expose a private function
to get the fd for an OutputStream so things still work.
- Fixup gio.symbols
- Fixup tests/gdbus-peer.c so it builds
With this, at least things compile and the gdbus-peer.exe test case
passes. Which is a great start. I've tested this by cross-compiling on
a x86_64 Fedora 13 host using mingw32 and running the code on a 32-bit
Windows 7 box.
https://bugzilla.gnome.org/show_bug.cgi?id=619142
Signed-off-by: David Zeuthen <davidz@redhat.com>
Things compile and the test-suite passes. Still need to hook up
gio.symbols and docs. There are still a bunch of TODOs left in the
sources that needs to be addressed.
Signed-off-by: David Zeuthen <davidz@redhat.com>