summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-05-05 16:37:34 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-05-05 16:37:34 -0400
commit2e8b6fa0282e229d743aa2ceefbfe789e5e1b0b9 (patch)
tree21177446586258699a1bd58906d90e2d6d89eab9
parent7e2610fb01367ce66af6cd0b5ae48be0413ec0a5 (diff)
Actually check user in the EXTERNAL authentication mechanism
-rw-r--r--gdbus/gdbusauthmechanismexternal.c153
1 files changed, 81 insertions, 72 deletions
diff --git a/gdbus/gdbusauthmechanismexternal.c b/gdbus/gdbusauthmechanismexternal.c
index aceeade..8884ed5 100644
--- a/gdbus/gdbusauthmechanismexternal.c
+++ b/gdbus/gdbusauthmechanismexternal.c
@@ -25,6 +25,7 @@
#include <glib/gi18n.h>
#include "gdbusauthmechanismexternal.h"
+#include "gcredentials.h"
#include "gdbuserror.h"
#include "gdbusenumtypes.h"
@@ -184,6 +185,56 @@ mechanism_server_get_state (GDBusAuthMechanism *mechanism)
return m->priv->state;
}
+static gboolean
+data_matches_credentials (const gchar *data,
+ GCredentials *credentials)
+{
+ gboolean match;
+
+ match = FALSE;
+
+ if (credentials == NULL)
+ goto out;
+
+ if (data == NULL || strlen (data) == 0)
+ goto out;
+
+#if defined(G_OS_UNIX)
+ {
+ gint64 alleged_uid;
+ gchar *endp;
+
+ /* on UNIX, this is the uid as a string in base 10 */
+ alleged_uid = g_ascii_strtoll (data, &endp, 10);
+ if (*endp == '\0')
+ {
+ if (g_credentials_has_unix_user (credentials) &&
+ g_credentials_get_unix_user (credentials) == alleged_uid)
+ {
+ match = TRUE;
+ }
+ }
+ }
+#elif defined(G_OS_WIN32)
+ {
+ const gchar *alleged_sid;
+
+ /* on Win32, this is the User SID */
+ alleged_sid = data;
+ if (g_credentials_has_windows_user (credentials) &&
+ g_strcmp0 (g_credentials_get_windows_user (credentials), alleged_sid) == 0)
+ {
+ match = TRUE;
+ }
+ }
+#else
+#warning Dont know how to read credentials on this OS. Please implement.
+#endif
+
+ out:
+ return match;
+}
+
static void
mechanism_server_initiate (GDBusAuthMechanism *mechanism,
const gchar *initial_response,
@@ -194,17 +245,23 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism,
g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
g_return_if_fail (!m->priv->is_server && !m->priv->is_client);
+ m->priv->is_server = TRUE;
+
if (initial_response != NULL)
{
- g_debug ("EXTERNAL: initial_response was `%s'", initial_response);
- g_debug ("EXTERNAL: credentials `%p'", _g_dbus_auth_mechanism_get_credentials (G_DBUS_AUTH_MECHANISM (mechanism)));
+ if (data_matches_credentials (initial_response, _g_dbus_auth_mechanism_get_credentials (mechanism)))
+ {
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
+ }
+ else
+ {
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
+ }
+ }
+ else
+ {
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
}
-
- m->priv->is_server = TRUE;
-
- /* TODO: actually check that the credentials match */
- m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
- //m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
}
static void
@@ -218,8 +275,14 @@ mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
g_return_if_fail (m->priv->is_server && !m->priv->is_client);
g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
- /* can never end up here because we are never in the WAITING_FOR_DATA state */
- g_assert_not_reached ();
+ if (data_matches_credentials (data, _g_dbus_auth_mechanism_get_credentials (mechanism)))
+ {
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
+ }
+ else
+ {
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
+ }
}
static gchar *
@@ -277,70 +340,13 @@ mechanism_client_get_state (GDBusAuthMechanism *mechanism)
return m->priv->state;
}
-#ifdef G_OS_WIN32
-#include <windows.h>
-
-/* Declarations missing in mingw's headers */
-extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
-extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
-
-static gchar *
-_get_win32_sid (void)
-{
- HANDLE process_token = INVALID_HANDLE_VALUE;
- TOKEN_USER *token_user = NULL;
- DWORD n;
- PSID psid;
- int retval = FALSE;
- gchar *sid;
- gchar *ret;
-
- ret = NULL;
-
- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
- {
- g_warning ("OpenProcessToken failed", GetLastError ());
- goto failed;
- }
-
- if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n) && GetLastError () != ERROR_INSUFFICIENT_BUFFER) ||
- ((token_user = alloca (n)) == NULL) ||
- !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
- {
- g_warning ("GetTokenInformation failed", GetLastError ());
- goto failed;
- }
-
- psid = token_user->User.Sid;
- if (!IsValidSid (psid))
- {
- g_warning ("Invalid SID");
- goto failed;
- }
-
- if (!ConvertSidToStringSidA (psid, &sid))
- {
- g_warning ("Invalid SID");
- goto failed;
- }
-
- ret = g_strdup (sid);
- LocalFree (sid);
-
-failed:
- if (process_token != INVALID_HANDLE_VALUE)
- CloseHandle (process_token);
-
- return ret;
-}
-#endif
-
static gchar *
mechanism_client_initiate (GDBusAuthMechanism *mechanism,
gsize *out_initial_response_len)
{
GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
gchar *initial_response;
+ GCredentials *credentials;
g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL);
@@ -350,14 +356,17 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism,
*out_initial_response_len = -1;
+ credentials = _g_dbus_auth_mechanism_get_credentials (mechanism);
+ g_assert (credentials != NULL);
+
/* return the uid */
#if defined(G_OS_UNIX)
- initial_response = g_strdup_printf ("%d", geteuid ());
+ initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, g_credentials_get_unix_user (credentials));
#elif defined(G_OS_WIN32)
- initial_response = _get_win32_sid ();
+ initial_response = g_strdup_printf ("%s", g_credentials_get_windows_user ());
#else
- initial_response = NULL;
-#error TODO
+#warning Dont know how to send credentials on this OS. Please implement.
+ m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
#endif
return initial_response;
}