Security:Cynara:ApplicationCredentials

From Tizen Wiki
Jump to: navigation, search

Application Credentials

Service asking Cynara for a check of privilege must pass an application context as one of arguments. This context is build with:

  • UID - id of user running an application;
  • SMACK label - for identifying application itself.

Service needs to gather this information before making the request. However there are many IPCs used to communicate application with service. This page is intended to show how to gather required info.

IPCs

D-Bus with GIO (GDBus)

Obtaining UID

   uid_t get_uid_for_unique_name(GDBusConnection *connection, const gchar *unique_name) {
       GError *error = NULL;
       GVariant *result = g_dbus_connection_call_sync(connection,
           "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
           "GetConnectionUnixUser", g_variant_new("(s)", unique_name), G_VARIANT_TYPE("(u)"),
           G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
   
       if (result != NULL) {
           uid_t uid;
           g_variant_get(result, "(u)", &uid);
           g_variant_unref(result);
           return uid;
       } else {
           // Handle error
           g_print("Error message: %s\n", error->message);
       }
   
       return 0;
   }

Obtaining Smack label

   typedef gchar SmackLabel[SMACK_LABEL_LEN]; /* SMACK_LABEL_LEN is defined in <sys/smack.h> */
   
   int get_smack_for_unique_name(GDBusConnection *connection, const char *unique_name, SmackLabel *smack_label) {
       GError *error = NULL;
       GVariant *result = g_dbus_connection_call_sync(connection,
       "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
       "GetConnectionSmackContext", g_variant_new("(s)", unique_name), G_VARIANT_TYPE("(s)"),
       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
   
       if (result != NULL) {
           gchar *label;
           g_variant_get(result, "(s)", &label);
           strcpy((char *)smack_label, label);
           g_free(label);
           g_variant_unref(result);
           return 0;
       } else {
           // Handle error
           g_print("Error message: %s\n", error->message);
       }
   
       return -1;
   }


D-Bus with GLib bindings

To obtain credentials of client, which is calling a method of some interface, one need to get client's unique name from DBusGMethodInvocation:

   const gchar *unique_name = dbus_g_method_get_sender(method_invocation_context);

There is a set of helper functions to obtain individual credentials (UID, Smack label and PID) by given unique name, presented below.

Obtaining UID

To obtain UID of client, which is calling a method of some interface, one need to get client's unique name from (DBusGMethodInvocation):

   uid_t get_uid_for_unique_name(DBusGConnection *conn, const char *unique_name) {
       DBusGProxy *proxy;
       GError *error = NULL;
       uid_t uid_ret;
   
       proxy = dbus_g_proxy_new_for_name(conn,
           "org.freedesktop.DBus",
           "/org/freedesktop/DBus",
          "org.freedesktop.DBus");
   
       int ret = dbus_g_proxy_call(proxy, "GetConnectionUnixUser",
           &error,
           G_TYPE_STRING, unique_name, G_TYPE_INVALID,
           G_TYPE_UINT, &uid_ret, G_TYPE_INVALID);
   
       return uid_ret;
   }

Obtaining Smack label

   typedef gchar SmackLabel[SMACK_LABEL_LEN]; /* SMACK_LABEL_LEN is defined in <sys/smack.h> */
   
   int get_smack_for_unique_name(DBusGConnection *conn, const char *unique_name, SmackLabel *smack_label) {
       DBusGProxy *proxy;
       GError *error = NULL;
       gchar *param_ret = NULL;
       
       proxy = dbus_g_proxy_new_for_name(conn,
           "org.freedesktop.DBus",
           "/org/freedesktop/DBus",
           "org.freedesktop.DBus");
       
       int ret = dbus_g_proxy_call(proxy, "GetConnectionSmackContext",
           &error,
           G_TYPE_STRING, unique_name, G_TYPE_INVALID,
           G_TYPE_STRING, &param_ret, G_TYPE_INVALID);
       
       if (error != NULL) {
           g_print("ERR: %s\n", error->message);
           return -1;
       }
   
       strcpy((char *)smack_label, param_ret);
       g_free(param_ret);
       return 0;
   }

Obtaining PID

   pid_t get_pid_for_unique_name(DBusGConnection *conn, const char *unique_name) {
       DBusGProxy *proxy;
       GError *error = NULL;
       pid_t param_ret;
   
       proxy = dbus_g_proxy_new_for_name(conn,
           "org.freedesktop.DBus",
           "/org/freedesktop/DBus",
           "org.freedesktop.DBus");
   
       int ret = dbus_g_proxy_call(proxy, "GetConnectionUnixProcessID",
           &error,
           G_TYPE_STRING, unique_name, G_TYPE_INVALID,
           G_TYPE_UINT, &param_ret, G_TYPE_INVALID);
   
       return param_ret;
   }

Unix domain sockets

Obtaining UID

PID, UID and GID of peer process can be obtained by calling getsockopt with SO_PEERCRED on client socket fd:

   typedef struct {
       pid_t pid;
       uid_t uid;
       gid_t gid;
   } PeerCredentials;
   
   PeerCredentials peer_cred;
   socklen_t cred_len = sizeof(PeerCredentials);
   getsockopt(cli_fd, SOL_SOCKET, SO_PEERCRED, &peer_cred, &cred_len);

Obtaining Smack label

Analogously, there is a SO_PEERSEC to obtain Smack label:

   typedef char SmackLabel[SMACK_LABEL_LEN]; /* SMACK_LABEL_LEN is defined in <sys/smack.h> */
   
   SmackLabel smack_label;
   socklen_t smack_label_len = sizeof(SmackLabel);
   getsockopt(cli_fd, SOL_SOCKET, SO_PEERSEC, &smack_label, &smack_label_len);

dbus over libdbus

todo

kdbus

Future D-Bus replacement for kdbus will be transparent to developers. For usage examples please refer to GDBus (recommended) or GLib sections.

0MQ

todo