* @brief Implementation of external libcynara-creds-dbus API
*/
-
#include <attributes/attributes.h>
#include <string>
#include <string.h>
#include <cynara-error.h>
#include <log/log.h>
+#include <Credentials.h>
+#include <creds-inner.h>
+
namespace {
const char dbusName[] = "org.freedesktop.DBus";
const char dbusInterface[] = "org.freedesktop.DBus";
const char dbusMethod[] = "GetConnectionCredentials";
-struct Credentials
-{
- Credentials() : m_pid(0), m_isPidSet(false), m_uid(0), m_isUidSet(false),
- m_securityLabel(nullptr), m_isSecuritySet(false) {
+class DBusCredentials : public Credentials {
+public:
+ DBusCredentials() : m_pid(0), m_uid(0), m_securityLabel(nullptr) {}
- }
int init(DBusConnection *connection, const char *uniqueId) {
DBusMessageIter args_iter, arr_iter, pair_iter, var_iter;
- m_message = dbus_message_new_method_call(dbusName, dbusObject, dbusInterface, dbusMethod);
- if (m_message == nullptr)
+ LOGW("Attempting to initialize DBusCredentials");
+ DBusMessage *message = dbus_message_new_method_call(dbusName, dbusObject, dbusInterface, dbusMethod);
+ if (message == nullptr)
return CYNARA_API_OUT_OF_MEMORY;
- if (!dbus_message_append_args(m_message, DBUS_TYPE_STRING, &uniqueId, DBUS_TYPE_INVALID))
+ if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &uniqueId, DBUS_TYPE_INVALID))
return CYNARA_API_UNKNOWN_ERROR;
LOGW("Calling %s on %s", dbusMethod, dbusName);
- m_reply = dbus_connection_send_with_reply_and_block(connection, m_message,
- DBUS_TIMEOUT_USE_DEFAULT, nullptr);
+ DBusMessage *reply = dbus_connection_send_with_reply_and_block(connection, message,
+ DBUS_TIMEOUT_USE_DEFAULT, nullptr);
LOGW("%s returned", dbusMethod);
- if (m_reply == nullptr)
+ if (reply == nullptr)
return CYNARA_API_UNKNOWN_ERROR;
- if (!dbus_message_iter_init(m_reply, &args_iter) ||
+ if (!dbus_message_iter_init(reply, &args_iter) ||
dbus_message_iter_get_arg_type(&args_iter) != DBUS_TYPE_ARRAY ||
dbus_message_iter_get_element_type(&args_iter) != DBUS_TYPE_DICT_ENTRY)
return CYNARA_API_UNKNOWN_ERROR;
}
dbus_message_iter_next(&arr_iter);
}
+
+ dbus_message_unref(message);
+ dbus_message_unref(reply);
+
return CYNARA_API_SUCCESS;
}
- ~Credentials() {
+ virtual ~DBusCredentials() {
free(m_securityLabel);
- dbus_message_unref(m_message);
- dbus_message_unref(m_reply);
}
- bool isPidSet(void) const { return m_isPidSet; }
- bool isUidSet(void) const { return m_isUidSet; }
- bool isSecurityLabelSet(void) const { return m_isSecuritySet; }
+ pid_t getPid(void) const { return m_pid; }
+ char *getPidStr(void) const {
+ return strdup(std::to_string(m_pid).c_str());
+ }
+ char *getUidStr(void) const {
+ return strdup(std::to_string(m_uid).c_str());
+ }
+ char *getSecurityLabel(void) const {
+ return strdup(m_securityLabel);
+ }
+private:
dbus_uint32_t m_pid;
- bool m_isPidSet;
dbus_uint32_t m_uid;
- bool m_isUidSet;
char *m_securityLabel;
- bool m_isSecuritySet;
-private:
- DBusMessage *m_message = nullptr;
- DBusMessage *m_reply = nullptr;
};
} // namespace anonymous
CYNARA_API
-int cynara_creds_dbus_get_client(DBusConnection *connection, const char *uniqueName,
- enum cynara_client_creds method, char **client) {
- int ret;
-
- if (connection == nullptr || uniqueName == nullptr || client == nullptr)
+int cynara_creds_dbus_get(DBusConnection *connection, const char *uniqueName,
+ const enum cynara_client_creds *pClientMethod, char **client,
+ const enum cynara_user_creds *pUserMethod, char **user,
+ pid_t *pid) {
+ if (connection == nullptr || uniqueName == nullptr) {
return CYNARA_API_INVALID_PARAM;
-
- if (method == cynara_client_creds::CLIENT_METHOD_DEFAULT) {
- ret = cynara_creds_get_default_client_method(&method);
- if (ret != CYNARA_API_SUCCESS)
- return ret;
}
- Credentials credentials;
- LOGW("Attempting to initialize Credentials");
- ret = credentials.init(connection, uniqueName);
- if (ret != CYNARA_API_SUCCESS)
+ DBusCredentials credentials;
+ int ret = credentials.init(connection, uniqueName);
+ if (ret != CYNARA_API_SUCCESS) {
return ret;
-
- switch (method) {
- case cynara_client_creds::CLIENT_METHOD_SMACK:
- if (!credentials.isSecurityLabelSet())
- return CYNARA_API_UNKNOWN_ERROR;
- *client = strdup(credentials.m_securityLabel);
- if (*client == nullptr)
- return CYNARA_API_OUT_OF_MEMORY;
- break;
- case cynara_client_creds::CLIENT_METHOD_PID:
- if (!credentials.isPidSet())
- return CYNARA_API_UNKNOWN_ERROR;
- *client = strdup(std::to_string(credentials.m_pid).c_str());
- if (*client == nullptr)
- return CYNARA_API_OUT_OF_MEMORY;
- break;
- default:
- return CYNARA_API_METHOD_NOT_SUPPORTED;
}
- LOGW("cynara_creds_dbus_get_client returns %d", ret);
+
+ ret = cynara_creds_inner_get(credentials, pClientMethod, client,
+ pUserMethod, user, pid);
+
+ LOGW("cynara_creds_dbus_get returns %d", ret);
return ret;
}
CYNARA_API
-int cynara_creds_dbus_get_user(DBusConnection *connection, const char *uniqueName,
- enum cynara_user_creds method, char **user) {
- int ret;
-
- if (connection == nullptr || uniqueName == nullptr || user == nullptr)
+int cynara_creds_dbus_get_default(DBusConnection *connection, const char *uniqueName,
+ char **client, char **user, pid_t *pid) {
+ if (connection == nullptr || uniqueName == nullptr) {
return CYNARA_API_INVALID_PARAM;
-
- if (method == cynara_user_creds::USER_METHOD_DEFAULT) {
- ret = cynara_creds_get_default_user_method(&method);
- if (ret != CYNARA_API_SUCCESS)
- return ret;
}
- Credentials credentials;
- ret = credentials.init(connection, uniqueName);
- if (ret != CYNARA_API_SUCCESS)
+ DBusCredentials credentials;
+ int ret = credentials.init(connection, uniqueName);
+ if (ret != CYNARA_API_SUCCESS) {
return ret;
-
- switch (method) {
- case cynara_user_creds::USER_METHOD_UID:
- if (!credentials.isUidSet())
- return CYNARA_API_UNKNOWN_ERROR;
- *user = strdup(std::to_string(credentials.m_uid).c_str());
- if (*user == nullptr)
- return CYNARA_API_OUT_OF_MEMORY;
- break;
- case cynara_user_creds::USER_METHOD_GID:
- return CYNARA_API_METHOD_NOT_SUPPORTED;
- default:
- return CYNARA_API_METHOD_NOT_SUPPORTED;
}
+
+ ret = cynara_creds_inner_get_default(credentials, client, user, pid);
+ LOGW("cynara_creds_dbus_get_default returns %d", ret);
return ret;
}
CYNARA_API
-int cynara_creds_dbus_get_pid(DBusConnection *connection, const char *uniqueName, pid_t *pid) {
- if (connection == nullptr || uniqueName == nullptr || pid == nullptr)
- return CYNARA_API_INVALID_PARAM;
-
- Credentials credentials;
- int ret = credentials.init(connection, uniqueName);
- if (ret != CYNARA_API_SUCCESS)
- return ret;
-
- if (!credentials.isPidSet())
- return CYNARA_API_UNKNOWN_ERROR;
+int cynara_creds_dbus_get_client(DBusConnection *connection, const char *uniqueName,
+ enum cynara_client_creds method, char **client) {
+ int ret = cynara_creds_dbus_get(connection, uniqueName, &method, client, nullptr,
+ nullptr, nullptr);
+ LOGW("cynara_creds_dbus_get_client returns %d", ret);
+ return ret;
+}
- *pid = credentials.m_pid;
+CYNARA_API
+int cynara_creds_dbus_get_user(DBusConnection *connection, const char *uniqueName,
+ enum cynara_user_creds method, char **user) {
+ int ret = cynara_creds_dbus_get(connection, uniqueName, nullptr, nullptr, &method,
+ user, nullptr);
+ LOGW("cynara_creds_dbus_get_user returns %d", ret);
+ return ret;
+}
+CYNARA_API
+int cynara_creds_dbus_get_pid(DBusConnection *connection, const char *uniqueName, pid_t *pid) {
+ int ret = cynara_creds_dbus_get(connection, uniqueName, nullptr, nullptr, nullptr,
+ nullptr, pid);
+ LOGW("cynara_creds_dbus_get_pid returns %d", ret);
return ret;
}
extern "C" {
#endif
+/**
+ * \par Description:
+ * Creates a client identification string, user identification string with default methods
+ * from Cynara configuration file, or PID identification. Client is a process identified
+ * by the unique name at the other side of the dbus connection. User is an executor of
+ * process at the other side of the socket. User can fetch any of the three, function will fail
+* only when none of the client, user or pid are requested.
+ *
+ * \par Purpose:
+ * Client and user identification strings are required for cynara_check() and
+ * cynara_async_create_request() functions. PID may be used for client_session creation with
+ * cynara_helper_session_from_pid() function from libcynara-helper-session library.
+ * Client_session is needed for cynara_check() and cynara_async_create_request() functions.
+ *
+ * \par Typical use case:
+ * The function is called before the call of cynara_check() or cynara_async_create_request()
+ * function. Returned PID may be used to create client_session using function
+ * cynara_helper_session_from_pid(). Returned strings are used as client, user and pid parameters
+ * in cynara_check() or cynara_async_create_request() function.
+ * Strings are released with g_free() function when they are no longer needed.
+ *
+ * \par Method of function operation:
+ * The function generates client string, user string and PID by calling a method from
+ * DBus Interface ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus").
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread safety:
+ * This function is NOT thread-safe. If functions from described API are called by multithreaded
+ * application from different threads, they must be put into mutex protected critical section.
+ *
+ * \par Important notes:
+ * Memory for returned all strings should be freed with g_free().
+ * Allocated strings are returned only, when function succeeds.
+ *
+ * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages
+ * \param[in] uniqueName DBus identifier of the client
+ * \param[out] client Placeholder for allocated string containing client id
+ * \param[out] user Placeholder for allocated string containing client id
+ * \param[out] pid Placeholder for PID returned by function
+ *
+ * \return CYNARA_API_SUCCESS on success
+ * \return CYNARA_API_INVALID_PARAM when all client, user and pid are NULL or uniqueName
+ * and connection have wrong value (i.e NULL or non-existing)
+ * or given method is NULL for identifier thas is not.
+ * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or
+ * there are errors in configuration file
+ * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported
+ */
+int cynara_creds_dbus_get_default(DBusConnection *connection, const char *uniqueName,
+ char **client, char **user, pid_t *pid);
+
+/**
+ * \par Description:
+ * Creates a client identification string with given method, user identification string with
+ * given method, or PID identification. Client is a process identified by the unique name
+ * at the other side of the dbus connection. User is an executor of process at the other side
+ * of socket. User can fetch any of the three, function will fail only when none of the client,
+ * user or pid are requested.
+ *
+ * \par Purpose:
+ * Client and user identification strings are required for cynara_check() and
+ * cynara_async_create_request() functions. PID may be used for client_session creation with
+ * cynara_helper_session_from_pid() function from libcynara-helper-session library.
+ * Client_session is needed for cynara_check() and cynara_async_create_request() functions.
+ *
+ * \par Typical use case:
+ * The function is called before the call of cynara_check() or cynara_async_create_request()
+ * function. Returned PID may be used to create client_session using function
+ * cynara_helper_session_from_pid(). Returned strings are used as client, user and pid
+ * parameters in cynara_check() or cynara_async_create_request() function.
+ * Strings are released with g_free() function when they are no longer needed.
+ *
+ * \par Method of function operation:
+ * The function generates client string, user string and PID by calling a method from
+ * DBus Interface ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus").
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread safety:
+ * This function is NOT thread-safe. If functions from described API are called by multithreaded
+ * application from different threads, they must be put into mutex protected critical section.
+ *
+ * \par Important notes:
+ * Memory for returned all strings should be freed with g_free().
+ * Allocated strings are returned only, when function succeeds.
+ * If methods are CLIENT_METHOD_DEFAULT or USER_METHOD_DEFAULT, then it will be chosen based on
+ * Cynara configuration file.
+ *
+ * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages
+ * \param[in] uniqueName DBus identifier of the client
+ * \param[in] pClientMethod Pointer to method of client identifier creation
+ * \param[out] client Placeholder for allocated string containing client id
+ * \param[in] pUserMethod Pointer to method of user identifier creation
+ * \param[out] user Placeholder for allocated string containing client id
+ * \param[out] pid Placeholder for PID returned by function
+ *
+ * \return CYNARA_API_SUCCESS on success
+ * \return CYNARA_API_INVALID_PARAM when all client, user and pid are NULL or uniqueName
+ * and connection have wrong value (i.e NULL or non-existing)
+ * or given method is NULL for identifier thas is not.
+ * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or
+ * there are errors in configuration file
+ * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported
+ */
+int cynara_creds_dbus_get(DBusConnection *connection, const char *uniqueName,
+ const enum cynara_client_creds *pClientMethod, char **client,
+ const enum cynara_user_creds *pUserMethod, char **user,
+ pid_t *pid);
+
/**
* \par Description:
* Creates a client identification string with given method. Client is a process identified by the