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); m->priv->is_client = TRUE; m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED; *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 ("%" G_GINT64_FORMAT, (gint64) g_credentials_get_unix_user (credentials, NULL)); #elif defined(G_OS_WIN32) #warning Dont know how to send credentials on this OS. The EXTERNAL D-Bus authentication mechanism will not work. m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; #endif return initial_response; }
static void receive_credentials_cb (GObject *source, GAsyncResult *result, gpointer user_data) { TpStreamTubeChannel *self = user_data; GSocketConnection *conn = (GSocketConnection *) source; GCredentials *creds; guchar byte; uid_t uid; GError *error = NULL; creds = tp_unix_connection_receive_credentials_with_byte_finish (conn, result, &byte, &error); if (creds == NULL) { DEBUG ("Failed to receive credentials: %s", error->message); g_error_free (error); return; } uid = g_credentials_get_unix_user (creds, &error); if (uid != geteuid ()) { DEBUG ("Wrong credentials received (user: %u)", uid); return; } credentials_received (self, conn, byte); g_object_unref (creds); }
gboolean gl_util_can_read_user_journal (void) { GFile *file; GFileInfo *info; gint ret; gchar *path; gchar ids[33]; gchar *filename; gchar *uid; uid_t user_id; sd_id128_t machine; GError *error = NULL; GCredentials *credentials; credentials = g_credentials_new (); user_id = g_credentials_get_unix_user (credentials, &error); if (error != NULL) { g_debug ("Unable to get uid: %s", error->message); g_error_free (error); } uid = g_strdup_printf ("%d", user_id); filename = g_strconcat ("/user-", uid, ".journal", NULL); ret = sd_id128_get_machine (&machine); if (ret < 0) { g_critical ("Error getting machine id: %s", g_strerror (-ret)); } sd_id128_to_string (machine, ids); path = g_build_filename ("/var/log/journal", ids, filename, NULL); file = g_file_new_for_path (path); info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_free (uid); g_free (path); g_free (filename); g_object_unref (file); g_object_unref (credentials); if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) { g_object_unref (info); return TRUE; } else { g_object_unref (info); return FALSE; } }
gint gl_util_get_uid (void) { GCredentials *creds; uid_t uid; creds = g_credentials_new (); uid = g_credentials_get_unix_user (creds, NULL); g_object_unref (creds); return uid; }
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_get_unix_user (credentials, NULL) == alleged_uid) { match = TRUE; } } } #else /* TODO: Dont know how to compare credentials on this OS. Please implement. */ #endif out: return match; }
static gboolean read_netlink_messages (GSocket *socket, GIOCondition condition, gpointer user_data) { GNetworkMonitorNetlink *nl = user_data; GInputVector iv; gssize len; GSocketControlMessage **cmsgs = NULL; gint num_cmsgs = 0, i, flags; GError *error = NULL; GCredentials *creds; uid_t sender; struct nlmsghdr *msg; struct rtmsg *rtmsg; struct rtattr *attr; gsize attrlen; guint8 *dest, *gateway; gboolean retval = TRUE; iv.buffer = NULL; iv.size = 0; flags = MSG_PEEK | MSG_TRUNC; len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1, NULL, NULL, &flags, NULL, &error); if (len < 0) { g_warning ("Error on netlink socket: %s", error->message); g_error_free (error); if (nl->priv->dump_networks) finish_dump (nl); return FALSE; } iv.buffer = g_malloc (len); iv.size = len; len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1, &cmsgs, &num_cmsgs, NULL, NULL, &error); if (len < 0) { g_warning ("Error on netlink socket: %s", error->message); g_error_free (error); if (nl->priv->dump_networks) finish_dump (nl); return FALSE; } if (num_cmsgs != 1 || !G_IS_UNIX_CREDENTIALS_MESSAGE (cmsgs[0])) goto done; creds = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (cmsgs[0])); sender = g_credentials_get_unix_user (creds, NULL); if (sender != 0) goto done; msg = (struct nlmsghdr *) iv.buffer; for (; len > 0; msg = NLMSG_NEXT (msg, len)) { if (!NLMSG_OK (msg, (size_t) len)) { g_warning ("netlink message was truncated; shouldn't happen..."); retval = FALSE; goto done; } switch (msg->nlmsg_type) { case RTM_NEWROUTE: case RTM_DELROUTE: rtmsg = NLMSG_DATA (msg); if (rtmsg->rtm_family != AF_INET && rtmsg->rtm_family != AF_INET6) continue; if (rtmsg->rtm_type == RTN_UNREACHABLE) continue; attrlen = NLMSG_PAYLOAD (msg, sizeof (struct rtmsg)); attr = RTM_RTA (rtmsg); dest = gateway = NULL; while (RTA_OK (attr, attrlen)) { if (attr->rta_type == RTA_DST) dest = RTA_DATA (attr); else if (attr->rta_type == RTA_GATEWAY) gateway = RTA_DATA (attr); attr = RTA_NEXT (attr, attrlen); } if (dest || gateway) { if (msg->nlmsg_type == RTM_NEWROUTE) add_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway); else remove_network (nl, rtmsg->rtm_family, rtmsg->rtm_dst_len, dest, gateway); queue_request_dump (nl); } break; case NLMSG_DONE: finish_dump (nl); goto done; case NLMSG_ERROR: { struct nlmsgerr *e = NLMSG_DATA (msg); g_warning ("netlink error: %s", g_strerror (-e->error)); } retval = FALSE; goto done; default: g_warning ("unexpected netlink message %d", msg->nlmsg_type); retval = FALSE; goto done; } } done: for (i = 0; i < num_cmsgs; i++) g_object_unref (cmsgs[i]); g_free (cmsgs); g_free (iv.buffer); if (!retval && nl->priv->dump_networks) finish_dump (nl); return retval; }