From b5bd40e1e68b739307e20e19d2164c5b370846df Mon Sep 17 00:00:00 2001 From: José Bollo Date: Thu, 3 Oct 2019 14:33:21 +0200 Subject: Isolate compatibility with old cynara MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compatibility items of the old cynara librarie are separated and isolated. The option WITH_CYNARA_COMPAT activates it or not. Change-Id: Iba77c97d8df31f5f515b57411487943192451ac6 Signed-off-by: José Bollo --- compat/CMakeLists.txt | 21 + compat/include/CMakeLists.txt | 19 + compat/include/cynara/cynara-admin-types.h | 91 ++++ compat/include/cynara/cynara-admin.h | 460 ++++++++++++++++++ compat/include/cynara/cynara-agent.h | 256 ++++++++++ compat/include/cynara/cynara-client-async.h | 645 ++++++++++++++++++++++++ compat/include/cynara/cynara-client-plugin.h | 75 +++ compat/include/cynara/cynara-client.h | 305 ++++++++++++ compat/include/cynara/cynara-creds-commons.h | 132 +++++ compat/include/cynara/cynara-creds-dbus.h | 171 +++++++ compat/include/cynara/cynara-creds-gdbus.h | 167 +++++++ compat/include/cynara/cynara-creds-self.h | 121 +++++ compat/include/cynara/cynara-creds-socket.h | 161 ++++++ compat/include/cynara/cynara-error.h | 148 ++++++ compat/include/cynara/cynara-limits.h | 35 ++ compat/include/cynara/cynara-monitor.h | 421 ++++++++++++++++ compat/include/cynara/cynara-plugin.h | 106 ++++ compat/include/cynara/cynara-policy-types.h | 48 ++ compat/include/cynara/cynara-session.h | 73 +++ compat/pkgconfig/CMakeLists.txt | 41 ++ compat/pkgconfig/cynara-compat.pc.in | 5 + compat/pkgconfig/link-to-cynara-compat.pc | 1 + compat/src/CMakeLists.txt | 47 ++ compat/src/export-cynara-compat.map | 8 + compat/src/lib-compat.c | 699 +++++++++++++++++++++++++++ compat/src/main-test-old-cynara.c | 317 ++++++++++++ 26 files changed, 4573 insertions(+) create mode 100644 compat/CMakeLists.txt create mode 100644 compat/include/CMakeLists.txt create mode 100644 compat/include/cynara/cynara-admin-types.h create mode 100644 compat/include/cynara/cynara-admin.h create mode 100644 compat/include/cynara/cynara-agent.h create mode 100644 compat/include/cynara/cynara-client-async.h create mode 100644 compat/include/cynara/cynara-client-plugin.h create mode 100644 compat/include/cynara/cynara-client.h create mode 100644 compat/include/cynara/cynara-creds-commons.h create mode 100644 compat/include/cynara/cynara-creds-dbus.h create mode 100644 compat/include/cynara/cynara-creds-gdbus.h create mode 100644 compat/include/cynara/cynara-creds-self.h create mode 100644 compat/include/cynara/cynara-creds-socket.h create mode 100644 compat/include/cynara/cynara-error.h create mode 100644 compat/include/cynara/cynara-limits.h create mode 100644 compat/include/cynara/cynara-monitor.h create mode 100644 compat/include/cynara/cynara-plugin.h create mode 100644 compat/include/cynara/cynara-policy-types.h create mode 100644 compat/include/cynara/cynara-session.h create mode 100644 compat/pkgconfig/CMakeLists.txt create mode 100644 compat/pkgconfig/cynara-compat.pc.in create mode 120000 compat/pkgconfig/link-to-cynara-compat.pc create mode 100644 compat/src/CMakeLists.txt create mode 100644 compat/src/export-cynara-compat.map create mode 100644 compat/src/lib-compat.c create mode 100644 compat/src/main-test-old-cynara.c (limited to 'compat') diff --git a/compat/CMakeLists.txt b/compat/CMakeLists.txt new file mode 100644 index 0000000..02af4a1 --- /dev/null +++ b/compat/CMakeLists.txt @@ -0,0 +1,21 @@ +########################################################################### +# Copyright (C) 2018 "IoT.bzh" +# +# author: José Bollo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +add_subdirectory(src) +add_subdirectory(include) +add_subdirectory(pkgconfig) diff --git a/compat/include/CMakeLists.txt b/compat/include/CMakeLists.txt new file mode 100644 index 0000000..6553f89 --- /dev/null +++ b/compat/include/CMakeLists.txt @@ -0,0 +1,19 @@ +########################################################################### +# Copyright (C) 2018 "IoT.bzh" +# +# author: José Bollo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +INSTALL(DIRECTORY cynara DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}) diff --git a/compat/include/cynara/cynara-admin-types.h b/compat/include/cynara/cynara-admin-types.h new file mode 100644 index 0000000..95d27b9 --- /dev/null +++ b/compat/include/cynara/cynara-admin-types.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * \file src/include/cynara-admin-types.h + * \author Lukasz Wojciechowski + * \author Aleksander Zdyb + * \author Zofia Abramowska + * \author Oskar Switalski + * \version 1.0 + * \brief This file contains structs and consts for cynara admin. + */ + +#ifndef CYNARA_ADMIN_TYPES_H +#define CYNARA_ADMIN_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \struct cynara_admin_policy + * \brief Defines single policy + */ +struct cynara_admin_policy { + char *bucket; /**< Name of bucket, in which policy is placed */ + + char *client; /**< Identifier of client (application) */ + char *user; /**< Identifier of user */ + char *privilege; /**< Privilege name */ + + int result; /**< Result of policy */ + char *result_extra; /**< Not always used, may contain some additional result data + like e.g. name of bucket in case result == CYNARA_ADMIN_BUCKET */ +}; + +/** + * \struct cynara_admin_policy_descr + * \brief Describes policy of type given with result + */ + +struct cynara_admin_policy_descr { + int result; /**< Result of policy to describe */ + char *name; /**< Descriptive name of given policy result */ +}; + +/** + * \name Wildcard + * Can replace client, user or privilege name. + * WILDCARD matches any string during check procedure from libcynara-client. + */ +#define CYNARA_ADMIN_WILDCARD "*" + +/** + * \name Name of Default Bucket + * Default bucket - the one that check starts in. + * Default bucket cannot be removed, although its default policy + * (which originally is set to DENY) can be changed. + */ +#define CYNARA_ADMIN_DEFAULT_BUCKET "" + +/** + * \name Any + * Can replace client, user or privilege name. + * ANY matches any string (including WILDCARD) during: + * + * * policy removal with cynara_admin_erase() function + * * listing policies from a single bucket. + * + * Using ANY as default policy for bucket or as policy type of inserted policy record + * is forbidden and will cause CYNARA_API_INVALID_PARAM error. + */ +#define CYNARA_ADMIN_ANY "#" + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_ADMIN_TYPES_H */ diff --git a/compat/include/cynara/cynara-admin.h b/compat/include/cynara/cynara-admin.h new file mode 100644 index 0000000..a0ab0c9 --- /dev/null +++ b/compat/include/cynara/cynara-admin.h @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * \file src/include/cynara-admin.h + * \author Lukasz Wojciechowski + * \author Zofia Abramowska + * \author Oskar Switalski + * \version 1.0 + * \brief This file contains administration APIs of cynara available with libcynara-admin. + * \example cynara-admin.example + */ + +#ifndef CYNARA_ADMIN_H +#define CYNARA_ADMIN_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \struct cynara_admin + * Forward declaration of structure allowing initialization of library + * and usage of all libcynara-admin API functions + */ +struct cynara_admin; + +/** + * \brief Initialize cynara-admin structure. + * + * \par Description: + * Initialize cynara-admin library. + * Creates structure used in following API calls. + * + * \par Purpose: + * This function must be invoked prior to other admin API calls. It creates structure needed by + * other cynara-admin library API functions. + * + * \par Typical use case: + * Once before a service can call other cynara-admin library functions. + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success creates cynara_admin + * structure and stores pointer to this structure at memory address passed in pp_cynara_admin + * parameter. + * + * \par Sync (or) async: + * This is a synchronous API. + * + * \par Important notes: + * Structure cynara_admin created by cynara_admin_initialize() call should be released with + * cynara_admin_finish(). + * + * \param[out] pp_cynara_admin address of pointer for created cynara_admin structure. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin); + +/** + * \brief Release cynara-admin structure. + * + * \par Description: + * Destroys structure created with cynara_admin_initialize() function. + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-admin library. + * + * \par Typical use case: + * Function should be called once, when done with cynara-admin library API usage. + * + * \par Method of function operation: + * This API releases inner library structures and destroys cynara_admin structure. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * No invocations of cynara-admin library API functions are allowed after call to + * cynara_admin_finish(). + * + * \param[in] p_cynara_admin cynara_admin structure created in cynara_admin_initialize(). + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_finish(struct cynara_admin *p_cynara_admin); + +/** + * \brief Insert, update or delete policies in cynara database. + * + * \par Description: + * Manages policies in cynara. + * + * \par Purpose: + * This API should be used to insert, update or delete policies in cynara. + * + * \par Typical use case: + * Enables privileged services to alter policies by adding, updating or removing records. + * + * \par Method of function operation: + * \parblock + * Policies are arranged into buckets. Every policy is defined in context of some bucket identified + * with bucket field (string). A bucket consists of policies identified with tripple: (client, user, + * privilege), which is a (unique) key within considered bucket. + * + * Every policy can be one of two types: simple or bucket-pointing policy. + * + * * Simple policies have result field with value of CYNARA_ADMIN_DENY or CYNARA_ADMIN_ALLOW. + * result_extra field should be NULL in this case. + * * Bucket-pointing policies have result field with value of CYNARA_ADMIN_BUCKET and name of + * bucket they point to in result_extra field. + * + * + * Type of operation, which is run for every record (single policy) is defined by result field in + * cynara_admin_policy structure. + * + * * In case of CYNARA_ADMIN_DENY or CYNARA_ADMIN_ALLOW a simple policy is updated or inserted into + * cynara database. + * * In case of CYNARA_ADMIN_BUCKET, a bucket-pointing policy is updated or inserted into cynara + * database. + * * In case of CYNARA_ADMIN_DELETE, a policy is removed from cynara database. + * + * One call of cynara_admin_set_policies() can manage many different policies in different buckets. + * However, considered buckets must exist before referring to them in policies. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * \parblock + * When plugin API will be specified, there will be more valid types to pass as result. + * Numerical values of defines CYNARA_ADMIN_... may change, so usage of defines names is strongly + * recommended. + * + * Policies size cannot exceed CYNARA_MAX_VECTOR_SIZE excluding last null element and string members + * length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be returned. + * \endparblock + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] policies NULL terminated array of pointers to policy structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies); + +/** + * \brief Add, remove or update buckets in cynara database. + * + * \par Description: + * Adds new, updates or removes existing bucket for policies in cynara. + * + * \par Purpose: + * This API should be used to add, remove or update buckets. + * + * \par Typical use case: + * Enables privileged services to alter policies database by adding, updating or removing buckets. + * + * \par Method of function operation: + * \parblock + * Every bucket has a default policy. During search, if no policy matches the searched key (client, + * user, privilege), default policy is returned. + + * Operation run on a single bucket defined with bucket parameter. + + * Operation parameter defines what should happen with bucket. In case of: + * * CYNARA_ADMIN_DENY, a bucket is inserted or updated with CYNARA_ADMIN_DENY default policy; + * * CYNARA_ADMIN_ALLOW, a bucket is inserted or updated with CYNARA_ADMIN_ALLOW default policy; + * * CYNARA_ADMIN_DELETE, a bucket is removed with all policies that were kept in it. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * \parblock + * When plugin API will be specified, there will be more valid types to pass as operation / default + * policy. Numerical values of defines CYNARA_ADMIN_... may change, so usages of provided consts is + * strongly recommended. + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * + * Default bucket identified with CYNARA_ADMIN_DEFAULT_BUCKET exists always. Its default policy + * is preset to DENY (can be altered, however). Default bucket cannot be removed. + * + * Extra parameter will be used to pass additional data to cynara extensions to build more complex + * policies, such as ALLOW but for 5 minutes only, or ALLOW if user confirms. + * \endparblock + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] bucket bucket name + * \param[in] operation type of operation (default policy or CYNARA_ADMIN_DELETE) + * \param[in] extra additional data for default policy (will be available with cynara extensions) + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, int operation, + const char *extra); + +/** + * \brief Raw check client and user access for given privilege without using plugins extensions. + * + * \par Description: + * Raw check client and user access for given privilege without using plugins extensions. + * + * \par Purpose: + * This API should be used to check type of matching policy for check request + * + * \par Typical use case: + * Administrator of cynara want to know, what would cynara return to client, if asked about given + * access. + * + * \par Method of function operation: + * \parblock + * Function works almost the same way as cynara_check() client function. + * The differences are: + * * user must specify bucket, from which search would be started (in case of cynara_check() + * it is always the default bucket) + * * user can specify if search should be recursive: disabling recursive check will constrain search + * to single bucket only, ignoring all policies leading to other buckets (in case of + * cynara_check() search is always recursive) + * * when matching policy in cynara is found, its result is returned without being interpreted by + * plugin extensions. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * \parblock + * (*result_extra) may be set to NULL, if extra data are not used in matched policy + * If (*result_extra) is not NULL, it contains a string allocated by cynara admin library + * with malloc(3) function and must be released with free(3) function. + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * \endparblock + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] start_bucket name of bucket where search would start. + * \param[in] recursive FALSE (== 0) : single bucket search; + * TRUE (!= 0) : search does not ignore policies leading to another buckets. + * \param[in] client application or process identifier. + * \param[in] user user running client. + * \param[in] privilege privilege that is a subject of a check. + * \param[out] result placeholder for matched policy type. + * \param[out] result_extra placeholder for matched policy additional data (see Important Notes!). + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra); + +/** + * \brief Lists policies from single bucket in cynara database. + * + * \par Description: + * Lists filtered cynara policies from single bucket. + * + * \par Purpose: + * This API should be used to list policies from single bucket. + * + * \par Typical use case: + * List all policies matching defined filter. + * + * \par Method of function operation: + * \parblock + * Policies are arranged into buckets. Every bucket contains set of policies. Each of policies are + * identified with triple {client, user, privilege}. Function lists all policies from single bucket + * with matching client, user and privilege names. + * + * CYNARA_ADMIN_ANY can be used to match any client, user or privilege, e.g. + * + * List with parameters: {client = CYNARA_ADMIN_ANY, user = "alice", privilege = CYNARA_ADMIN_ANY} + * will match all policies related to "alice", so will match {"app1", "alice", "gps"} and + * {CYNARA_ADMIN_WILDCARD, "alice", "sms"}, but won't match {"app3", CYNARA_ADMIN_WILDCARD, "call"}. + * + * List with parameters: {client = "calculator", user = CYNARA_ADMIN_WILDCARD, + * privilege = CYNARA_ADMIN_ANY} will match {"calculator", CYNARA_ADMIN_WILDCARD, "sms"} but won't + * match {CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_WILDCARD, "sms"} nor {"calculator", "bob", "sms"} + * + * Matching policies are returned as NULL terminated array of pointers to cynara_admin_policy + * structures. + * + * If any of: bucket, client, user, privilege, policies is NULL then CYNARA_API_INVALID_PARAM + * is returned. + * + * If there is no bucket with given name CYNARA_API_BUCKET_NOT_FOUND is returned. + * + * In case of successful call CYNARA_API_SUCCESS is returned and *policies points to newly created + * array of pointers to struct cynara_admin_policy. It is responsibility of caller to release: + * + * * all non-NULL const char* pointers in all cynara_admin_policy structures; + * * all pointers to cynara_admin_policy structures kept in *policies array; + * * *policies array itself. + * + * All allocation made by cynara admin library are done with malloc(3) function and must be released + * with free(3) function. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] bucket name. + * \param[in] client filter for client name. + * \param[in] user filter for user name. + * \param[in] privilege filter for privilege. + * \param[out] policies placeholder for NULL terminated array of pointers to policy structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket, + const char *client, const char *user, const char *privilege, + struct cynara_admin_policy ***policies); + +/** + * \brief Erase policies matching filter from cynara database. + * + * \par Description: + * Erase policies matching filter from cynara database. + * + * \par Purpose: + * This API should be used to erase multiple policies with some common key part, + * e.g. all policies related to given user. + * + * \par Typical use case: + * Erase all policies matching defined filter. + * + * \par Method of function operation: + * \parblock + * Policies are arranged into buckets. Every bucket contains set of policies. Each of policies are + * identified with triple {client, user, privilege}. Function erases all policies with matching + * client, user and privilege names. + * + * There are two modes: + * * non-recursive (recursive parameter set to 0) - when policies are erased only from single bucket + * * recursive (recursive parameter set to 1) when policies are removed from given start_bucket and + * all nested buckets. + * + * CYNARA_ADMIN_ANY can be used to match any client, user or privilege, e.g. + * + * Erase with parameters: {client = CYNARA_ADMIN_ANY, user = "alice", privilege = CYNARA_ADMIN_ANY} + * will match all policies related to "alice", so will match {"app1", "alice", "gps"} and + * {CYNARA_ADMIN_WILDCARD, "alice", "sms"}, but won't match {"app3", CYNARA_ADMIN_WILDCARD, "call"}. + * + * Erase with parameters: {client = "calculator", user = CYNARA_ADMIN_WILDCARD, + * privilege = CYNARA_ADMIN_ANY} will match {"calculator", CYNARA_ADMIN_WILDCARD, "sms"} but won't + * match {CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_WILDCARD, "sms"} nor {"calculator", "bob", "sms"} + * + * If any of: start_bucket, client, user, privilege, policies is NULL then CYNARA_API_INVALID_PARAM + * is returned. + * + * If there is no bucket with given name CYNARA_API_BUCKET_NOT_FOUND is returned. + * + * In case of successful call CYNARA_API_SUCCESS is returned. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Important notes: + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] start_bucket name of bucket where erase would start. + * \param[in] recursive FALSE (== 0) : erase is not recursive (single bucket erase); \n + * TRUE (!= 0) : erase follows all policies leading to nested buckets + * \param[in] client filter for client name. + * \param[in] user filter for user name. + * \param[in] privilege filter for privilege. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_erase(struct cynara_admin *p_cynara_admin, + const char *start_bucket, int recursive, + const char *client, const char *user, const char *privilege); + +/** + * \brief Lists available policies with their name description. + * + * \par Description: + * + * Lists available cynara policy results with name description. + * + * \par Purpose: + * This API should be used to list all available policy results + * (also from cynara extension plugins). + * + * \par Typical use case: + * Gathering information about possible policy results and presenting them to user (using name + * attribute of description). Result can be passed to cynara_admin_set_policies(). + * + * \par Method of function operation: + * \parblock + * Policies are based on policy result number. Policies can be built in (like primitives: ALLOW, + * DENY...) or can be loaded from cynara plugin extensions. This API gives possibility of checking, + * which of these result exist in current cynara server and can be presented to user in a readable + * way (of course additional translation may be needed). + * + * Descriptions of existing policy results are returned as NULL terminated array of pointers of + * cynara_admin_policy_descr structures. + * + * Example output could be {{0, "Deny"}, {11, "AskUser"}, {65535, "Allow"}, NULL} + * + * In case of successful call CYNARA_API_SUCCESS is returned and *descriptions points + * to newly created array of pointers to struct cynara_admin_policy_descr. It is responsibility + * of caller to release: + * + * * all non-NULL char* pointers in all cynara_admin_policy_descr structures; + * * all pointers to cynara_admin_policy_descr structures kept in *descriptions array; + * * *descriptions array itself. + * + * All allocation made by cynara admin library are done with malloc(3) function and must be released + * with free(3) function. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[out] descriptions placeholder for NULL terminated array of pointers of + * description structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_ADMIN_H */ diff --git a/compat/include/cynara/cynara-agent.h b/compat/include/cynara/cynara-agent.h new file mode 100644 index 0000000..3e6d4f0 --- /dev/null +++ b/compat/include/cynara/cynara-agent.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-agent.h + * @author Adam Malinowski + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains agent APIs available with libcynara-agent. + */ + +#ifndef CYNARA_AGENT_H +#define CYNARA_AGENT_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint16_t cynara_agent_req_id; +typedef struct cynara_agent cynara_agent; + +/** + * \enum cynara_agent_msg_type + * Values specifying type of message. + * + * \var cynara_agent_msg_type::CYNARA_MSG_TYPE_ACTION + * Message of this type indicates its content is a request for performing an action or response to + * such request. + * + * \var cynara_agent_msg_type::CYNARA_MSG_TYPE_CANCEL + * Message of this type indicates its content is a request for canceling action or response to such + * request. + */ +typedef enum { + CYNARA_MSG_TYPE_ACTION, + CYNARA_MSG_TYPE_CANCEL +} cynara_agent_msg_type; + +/** + * \par Description: + * Initialize cynara-agent structure. + * Create structure used in following API calls. + * + * \par Purpose: + * This API must be used prior to calling other agent API functions. + * + * \par Typical use case: + * Once before other agent API functions are called. + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success returns cynara_agent + * structure. + * + * \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 protected critical section. + * + * \par Important notes: + * Structure cynara_agent created by this function should be released with cynara_agent_finish(). + * + * \param[out] pp_cynara_agent Place holder for created cynara_agent structure. + * \param[in] p_agent_type Type (name) of agent used by cynara for communication agent<->plugin. + * + * \return CYNARA_API_SUCCESS on success, or error code on error. + */ +int cynara_agent_initialize(cynara_agent **pp_cynara_agent, const char *p_agent_type); + +/** + * \par Description: + * Destroy structure created with cynara_agent_initialize(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-agent library. + * + * \par Typical use case: + * Once after connection to cynara is not needed. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_agent structure. Connection to + * cynara service is closed. + * + * \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 protected critical section. + * + * \par Important notes: + * No other call to cynara-agent library should be made after call to cynara_agent_finish() except + * cynara_agent_initialize(). + * + * \param[in] p_cynara_agent cynara_agent structure. If NULL, then the call has no effect. + */ +int cynara_agent_finish(cynara_agent *p_cynara_agent); + +/** + * \par Description: + * Get request from cynara service. + * + * \par Purpose: + * This API should be used to get request from cynara service. Request is generated by corresponding + * plugin loaded into cynara service. + * + * \par Typical use case: + * Agent waits for request from cynara service. Request may be either ask for performing agent + * specific action or ask for canceling such action. Agent calls this function when is ready to + * perform or cancel an action. + * + * \par Method of function operation: + * \parblock + * Function reads data incoming from cynara service and if at least one complete request is ready + * then returns with CYNARA_API_SUCCESS code. Request type, request id and specific + * plugin data are stored in given arguments. Function returns exactly one request. If there are + * more then one requests ready to get then one must call this function multiple times. + * + * This function is blocking which means that if there is no request from cynara service it will not + * return. On success, buffer for plugin specific data is allocated and size is set. Developer is + * responsible for freeing this memory using free() function. + * \endparblock + * + * \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 protected critical section. + * + * \par Important notes: + * \parblock + * Call to cynara_agent_get_request() needs cynara_agent structure to be created first. + * Use cynara_agent_initialize() before calling this function. + * + * After CYNARA_API_ACCESS_DENIED error is returned agent should be terminated or at least should + * not invoke neither cynara_agent_get_request() nor cynara_agent_put_response() functions. + * \endparblock + * + * \param[in] p_cynara_agent cynara_agent structure. + * \param[out] req_type Request type, demand an action or cancel this action. + * \param[out] req_id Request identifier used to pair with answer #cynara_agent_put_response() and + * cancel request. + * \param[out] data Plugin specific data. Buffer is allocated in this function and developer is + * responsible for freeing it using free() function. Buffer is filled with data + * from corresponding plugin. If there is no enough memory for data + * CYNARA_API_OUT_OF_MEMORY is returned and all arguments remain untouched. + * \param[out] data_size Size of plugin data (bytes count). In case of out of memory this value + * stays untouched. + * + * \return CYNARA_API_SUCCESS on successfully read request, + * CYNARA_API_INTERRUPTED when cynara_agent_cancel_waiting() is called during waiting, + * or negative error code otherwise. + */ +int cynara_agent_get_request(cynara_agent *p_cynara_agent, cynara_agent_msg_type *req_type, + cynara_agent_req_id *req_id, void **data, size_t *data_size); + +/** + * \par Description: + * Send response to cynara service. + * + * \par Purpose: + * This API should be used to send response to cynara service. + * + * \par Typical use case: + * Agent calls this function when is ready to answer request for action or cancel request. + * + * \par Method of function operation: + * Function sends data to cynara service. Data contains answer for previously got question. + * Answer may be of type CYNARA_MSG_TYPE_ACTION or CYNARA_MSG_TYPE_CANCEL. Type is + * CYNARA_MSG_TYPE_ACTION when request for an action was processed and answer is ready, or + * CYNARA_MSG_TYPE_CANCEL when processing request for an action was interrupted by cancel request. + * Agent must send exactly one response per one request and cancel. If request is processed before + * cancel message arrives the agent sends action response. If cancel arrives before action request + * is processed then agent sends cancel response and drops processing related action. + * Request id in response must be the same as request id in corresponding request. + * + * \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 protected critical section. + * + * \par Important notes: + * Call to cynara_agent_get_request() needs cynara_agent structure to be created first. + * Use cynara_agent_initialize() before calling this function. Also successful call to + * cynara_agent_get_request() is needed before calling this function. + * + * \param[in] p_cynara_agent cynara_agent structure. + * \param[in] resp_type Response type - see Method of operation for details. + * \param[in] req_id Request identifier obtained from request. + * \param[in] data Plugin specific data. If necessary agent should fill this buffer with data + * directed to plugin. + * \param[in] data_size Size of plugin data (bytes count). + * + * \return CYNARA_API_SUCCESS on successfully read request, or negative error code otherwise. + */ +int cynara_agent_put_response(cynara_agent *p_cynara_agent, const cynara_agent_msg_type resp_type, + const cynara_agent_req_id req_id, const void *data, + const size_t data_size); + +/** + * \par Description: + * Break from waiting for cynara service request using cynara_agent_get_request(). + * + * \par Purpose: + * This API should be used when cynara_agent_get_request() is blocked and before calling + * cynara_agent_finish(). + * + * \par Typical use case: + * Agent calls this API, when it wants to gracefully quit. + * + * \par Method of function operation: + * Function notifies cynara_agent_get_request() to stop waiting for request from cynara. + * Then cynara_agent_get_request() returns CYNARA_API_INTERRUPTED and no request is fetched. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function can be used only together with cynara_agent_get_request(), otherwise should + * be treaded as NOT thread safe. + * + * \par Important notes: + * Call to cynara_agent_cancel_waiting() needs cynara_agent structure to be created first and + * cynara_agent_get_request() running. + * Use cynara_agent_initialize() before calling this function. + * + * \param[in] p_cynara_agent cynara_agent structure. + * \return CYNARA_API_SUCCESS on successful waiting cancel, or negative error code otherwise. + */ +int cynara_agent_cancel_waiting(cynara_agent *p_cynara_agent); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_AGENT_H */ diff --git a/compat/include/cynara/cynara-client-async.h b/compat/include/cynara/cynara-client-async.h new file mode 100644 index 0000000..78a1313 --- /dev/null +++ b/compat/include/cynara/cynara-client-async.h @@ -0,0 +1,645 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-client-async.h + * @author Zofia Abramowska + * @author Marcin Niesluchowski + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains asynchronous client APIs of Cynara available + * with libcynara-client-asynchronous. + * @example cynara-client-async.example + */ + +#ifndef CYNARA_CLIENT_ASYNC_H +#define CYNARA_CLIENT_ASYNC_H + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint16_t cynara_check_id; +typedef struct cynara_async cynara_async; +typedef struct cynara_async_configuration cynara_async_configuration; + +/** + * \enum cynara_async_status + * Values indicating the status of connected cynara socket. + * + * \var cynara_async_status::CYNARA_STATUS_FOR_READ + * Wait for read events on socket. + * + * \var cynara_async_status::CYNARA_STATUS_FOR_RW + * Wait for both read and write events on socket. + */ +typedef enum { + CYNARA_STATUS_FOR_READ, + CYNARA_STATUS_FOR_RW +} cynara_async_status; + +/** + * \enum cynara_async_call_cause + * Values indicating the reason of cynara_response_callback call. + * + * \var cynara_async_call_cause::CYNARA_CALL_CAUSE_ANSWER + * Callback was called due to response to previous cynara_async_create_request() or + * cynara_async_create_simple_request() call. + * + * \var cynara_async_call_cause::CYNARA_CALL_CAUSE_CANCEL + * Callback was called due to request cancellation with cynara_async_cancel_request() call. + * + * \var cynara_async_call_cause::CYNARA_CALL_CAUSE_FINISH + * Callback was called due to cynara_async_finish() call. + * + * \var cynara_async_call_cause::CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE + * Callback was called due to service not available. + */ +typedef enum { + CYNARA_CALL_CAUSE_ANSWER, + CYNARA_CALL_CAUSE_CANCEL, + CYNARA_CALL_CAUSE_FINISH, + CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE +} cynara_async_call_cause; + +/** + * \brief Response_callback is registered once in cynara_async_create_request() or + * cynara_async_create_simple_request() and will be triggered exactly once in 4 kinds of situations: + * + * -# after response is received from cynara service (CYNARA_CALL_CAUSE_ANSWER) + * -# when request is canceled with cynara_async_cancel_request() (CYNARA_CALL_CAUSE_CANCEL) + * -# when request was pending for response, but cynara_async_finish() was called + * (CYNARA_CALL_CAUSE_FINISH) + * -# when connection to cynara service was broken and cannot be established again - probably cynara + * is unoperational (CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE) + * + * API functions called during this callback with CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE + * or CYNARA_CALL_CAUSE_FINISH cause will return CYNARA_API_OPERATION_NOT_ALLOWED. + * cynara_async_finish() will be ignored if called from within this callback. + * + * \param[in] check_id Number identifying check request. Number is generated in + * cynara_async_create_request() or cynara_async_create_simple_request() + * and returned to user. It can be used to match response with sent request. + * Number is valid since cynara_async_create_request() call or + * cynara_async_create_simple_request() call till callback call. + * After that the number can be reused by cynara to run new request. + * \param[in] cause Cause of triggering this callback. + * \param[in] response Response for created request. Should be ignored if cause is not + * an answer to request (cause != CYNARA_CALL_CAUSE_ANSWER). + * \param[in] user_response_data User specific data - passed to cynara library in + * cynara_async_cancel_request() is being only remembered by library. + * Cynara library does not take any actions on this pointer, + * except for giving it back to user in cynara_response_callback. + * After that cynara forgets this data. + */ +typedef void (*cynara_response_callback) (cynara_check_id check_id, cynara_async_call_cause cause, + int response, void *user_response_data); + +/** + * \brief Callback used by cynara async API when status of cynara socket is changed in + * cynara_async_initialize(), cynara_async_check_cache(), cynara_async_create_request(), + * cynara_async_create_simple_request(), cynara_async_process(), cynara_async_cancel_request() + * or cynara_async_finish(). + * + * File descriptor changes every time cynara library connects or disconnects cynara service. + * Status change is triggered when check_request or cancel needs to be send to + * cynara service or sending data has finished and there is nothing more to send to cynara + * service. + * + * Note, that provided file descriptor is used internally by libcynara-client-async + * so user should not use it in other way than waiting on it in event loop. + * In particular user should not write to, read from or close this fd. + * CYNARA_API_OPERATION_NOT_ALLOWED will be returned for every api function called in this callback. + * cynara_async_finish() will be ignored if called from within this callback. + * + * \param[in] old_fd Old descriptor which should be unregistered from event loop, + * Special value -1 is used when callback is called after first + * successful connect. + * \param[in] new_fd New descriptor which should be registered in event loop, + * Special value -1 is used when cynara_async_finish() is called and + * cynara is disconnected. In this case status should be ignored. + * \param[in] status Status indicating which events should be awaited on socket + * \param[in] user_status_data User specific data - passed to cynara library in + * cynara_async_initialize() is being only remembered by library. + * Cynara library does not take any actions on this pointer, + * except for giving it back to user in cynara_status_callback. + * Data should be valid at least until cynara_async_finish() is called. + */ +typedef void (*cynara_status_callback) (int old_fd, int new_fd, cynara_async_status status, + void *user_status_data); + +/** + * \par Description: + * Initialize cynara_async_configuration. Create structure used in following configuration + * API calls. + * + * \par Purpose: + * For configuration parameter to be used in cynara async initialization function, this API must be + * called before any other cynara async configuration API function. + * It will create cynara_async_configuration structure, an optional parameter of cynara async + * initialization. + * + * \par Typical use case: + * Once before setting parameters of cynara async configuration and passing to + * cynara_async_initialize(). + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success returns pointer + * to created cynara_async_configuration structure. + * + * \par Sync (or) Async: + * This as 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 protected critical section. + * + * \par Important notes: + * Structure cynara_async_configuration created by cynara_async_configuration_create() call + * should be released with cynara_async_configuration_destroy(). + * Structure cynara_async_configuration should be destroyed after passing it to + * cynara_async_initialize(). + * + * \param[out] pp_conf Placeholder for created cynara_async_configuration structure. + * + * \return CYNARA_API_SUCCESS on success + * \return negative error code on error + */ +int cynara_async_configuration_create(cynara_async_configuration **pp_conf); + +/** + * \par Description: + * Release cynara_async_configuration structure created with cynara_async_configuration_create(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara_async_configuration. + * + * \par Typical use case: + * Once cynara_async_configuration is not needed. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_async_configuration structure. + * + * \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 protected critical section. + * + * \param[in] p_conf cynara_async_configuration structure. If NULL, the call has no effect. + */ +void cynara_async_configuration_destroy(cynara_async_configuration *p_conf); + +/** + * \par Description: + * Set client cache size. + * + * \par Purpose: + * This API is used to change default number of cached responses returned from cynara. + * + * \par Typical use case: + * Once before setting parameters of cynara async configuration and passing to + * cynara_async_initialize(). + * + * \par Method of function operation: + * This API initializes cache with given capacity. + * + * \par Sync (or) Async: + * This as 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 protected critical section. + * + * \par Important notes: + * After passing cynara_async_configuration to cynara_async_initialize() calling this API will have + * no effect. + * + * \param[in] p_conf cynara_async_configuration structure pointer. + * \param[in] cache_size Cache size to be set. + * + * \return CYNARA_API_SUCCESS on success + * \return negative error code on error + */ +int cynara_async_configuration_set_cache_size(cynara_async_configuration *p_conf, + size_t cache_size); + +/** + * \par Description: + * Initialize cynara-async-client library with given configuration. Create structure used in + * following API calls and register callback and user_status_data for + * further cynara async API calls. + * + * \par Purpose: + * This API must be used prior to calling any other cynara async API function. + * It will create cynara_async structure required for any other cynara async API calls. + * + * \par Typical use case: + * Once before entering event loop and before any other cynara async API is called. + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success + * returns cynara_async structure. + * + * \par Sync (or) Async: + * This is an 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 protected critical section. + * + * \par Important notes: + * Structure cynara_async created by cynara_async_initialize() call should be released + * with cynara_async_finish(). + * + * \param[out] pp_cynara Placeholder for created cynara_async structure. + * \param[in] p_conf Configuration for cynara-async-client library. + * NULL should be used for default configuration. + * Configuration management functions will be added later. + * Configuration will be able to specify e.g. size of cache used by library + * for holding checks results. + * \param[in] callback Function called when connection is started. + * If NULL, no callback will be called, when status changes. + * \param[in] user_status_data User specific data, passed to callback is being only remembered + * by library. Cynara library does not take any actions on this pointer, + * except for giving it back to user in cynara_status_callback. + * Data should be valid at least until cynara_async_finish() is called. + * Can be NULL. + * + * \return CYNARA_API_SUCCESS on success + * \return negative error code on error + */ +int cynara_async_initialize(cynara_async **pp_cynara, const cynara_async_configuration *p_conf, + cynara_status_callback callback, void *user_status_data); + +/** + * \par Description: + * Release cynara-async-client library and destroy structure created with cynara_async_initialize(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-async-client library. + * + * \par Typical use case: + * Once after connection to cynara is not needed. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_async structure. Connection to + * cynara server is closed. Upon disconnecting this will trigger cynara_status_callback callback + * with -1 as new_fd param so client can unregister file descriptor connected with cynara. It will + * also trigger cynara_response_callback callback for each created request with + * cynara_async_call_cause::CYNARA_CALL_CAUSE_FINISH as cause param. + * + * \par Sync (or) Async: + * This is an asynchronous 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 protected critical section. + * + * \par Important notes: + * No other call to cynara-async-client library should be made after call to cynara_async_finish(). + * cynara_async_finish() called from within cynara_response_callback or cynara_status_callback will + * be ignored. + * + * \param[in] p_cynara cynara_async structure. If NULL, then the call has no effect. + */ +void cynara_async_finish(cynara_async *p_cynara); + +/** + * \par Description: + * Check access to given privilege for specified user, client and client_session in cache. + * + * \par Purpose: + * This API should be used to check if cache holds information about access of user, + * running application identified as clients to a privilege. + * This API should be used for fast check in cache. + * + * \par Typical use case: + * A service wants to check in cache, if a client requesting access to some privilege + * has proper rights. + * + * \par Method of function operation: + * Client (a process / application) requesting access to a privilege is running as some user. + * For such triple (client, user, privilege) a cache is checked. + * If cache is invalid it is cleared and call returns same as access not found. + * Additional parameter client_session + * may be used to distinguish between client session (e.g. for allowing access only for this + * particular application launch). Empty string "" can be used, when session differentiation + * is not needed. + * + * \par Sync (or) Async: + * This is an 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 protected critical section. + * + * \par Important notes: + * \parblock + * Call to cynara_async_check_cache() needs cynara_async structure to be created first. + * Use cynara_async_initialize() before calling this function. cynara_async_check_cache() called + * from within cynara_status_callback or cynara_response_callback with + * CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE or CYNARA_CALL_CAUSE_FINISH cause will return + * CYNARA_API_OPERATION_NOT_ALLOWED. + * + * Socket status may occasionally be changed to CYNARA_STATUS_FOR_RW, to ensure + * that cynara_async_process() is triggered in event loop after socket is ready to send + * monitor logs to Cynara service. + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * \endparblock + * + * \param[in] p_cynara cynara_async structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Client defined session. + * \param[in] user User of running client. + * \param[in] privilege Privilege that is a subject of a check. + * + * \return CYNARA_API_ACCESS_ALLOWED on checked access allowed + * \return CYNARA_API_ACCESS_DENIED on checked access denied + * \return CYNARA_API_CACHE_MISS on access not in cache + * \return other negative error code on error + */ +int cynara_async_check_cache(cynara_async *p_cynara, const char *client, const char *client_session, + const char *user, const char *privilege); + +/** + * \par Description: + * Creates access check request to cynara service for client, user accessing given privilege. + * Set callback and user_response_data to be called and passed when request processing is finished. + * + * \par Purpose: + * This API should be used to create check request for client identified by a triple + * (client, user, privilege) in custom defined session. + * Response can be received with cynara_async_process(). + * Check id is returned to pair request with response for canceling purposes. + * + * \par Typical use case: + * When cynara_async_check_cache() returned CYNARA_API_CACHE_MISS, so cynara service + * has to be asked, if a client requesting access to some privilege has proper rights. + * To receive matching response client sets callback and specifies arbitrary data to be passed + * to this callback. + * + * \par Method of function operation: + * \parblock + * Client (a process / application) requesting access to a privilege is running as some user. + * For such triple (client, user, privilege) a request event is created and added to pending + * requests for cynara_async_process() to process. + * + * Socket status will be changed to CYNARA_STATUS_FOR_RW, to ensure that cynara_async_process() + * will be triggered in event loop after socket is ready to send request to cynara service. + * After request is sent and there is nothing more to send to cynara service, status will change + * back to CYNARA_STATUS_FOR_READ. Status changes are delivered with cynara_status_callback. + * When function is successfully called unique check_id is returned. It is used for matching + * generated request with response, that will be received by registered callback. + * + * Because check_id is coded as 16-bit unsigned integer, there can be only 2^16 = 65536 pending + * requests. When response callback is called either because of getting answer or because + * of cancel check_id used for that request is released and can be reused by cynara library. + * When maximum of pending requests is reached cynara_async_create_request() fails with + * CYNARA_API_MAX_PENDING_REQUESTS error code. + * \endparblock + * + * \par Sync (or) Async: + * This is an asynchronous 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 protected critical section. + * + * \par Important notes: + * \parblock + * Call cynara_async_create_request() needs cynara_async structure to be created first with + * cynara_async_initialize(). + * Call cynara_async_cancel_request() to cancel pending request. + * Call cynara_async_process() to receive response. + * + * It is guaranteed that if cynara_async_create_request() function succeeds (CYNARA_API_SUCCESS) + * a callback will be called exactly once and that it will receive user_response_data. + * + * If function fails (returns negative error code) request won't be generated and won't be pending, + * callback function won't be ever called and user_response_data won't be remembered by library. + * + * Also no check_id will be generated and *p_check_id value should be ignored. + * cynara_async_create_request() called from within cynara_status_callback or + * cynara_response_callback with CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE or CYNARA_CALL_CAUSE_FINISH + * cause will return CYNARA_API_OPERATION_NOT_ALLOWED. + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH ,otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * \endparblock + * + * \param[in] p_cynara cynara_async structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Client defined session. + * \param[in] user User of running client. + * \param[in] privilege Privilege that is a subject of a check. + * \param[out] p_check_id Placeholder for check id. If NULL, then no check_id is returned. + * \param[in] callback Function called when matching response is received. + * If NULL then no callback will be called when response, cancel, finish + * or service not availble error happens. + * \param[in] user_response_data User specific data, passed to callback is being only remembered + * by library. Cynara library does not take any actions on this pointer, + * except for giving it back to user in cynara_response_callback. + * Can be NULL. + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_MAX_PENDING_REQUESTS on too much pending requests + * \return other negative error code on error + */ +int cynara_async_create_request(cynara_async *p_cynara, const char *client, + const char *client_session, const char *user, const char *privilege, + cynara_check_id *p_check_id, cynara_response_callback callback, + void *user_response_data); + +/** + * \par Description: + * Creates simple access check request to cynara service for (potential) permission to take some + * action or access a resource. + * Set callback and user_response_data to be called and passed when request processing is finished. + * + * \par Purpose: + * This API should be used for a quick check if a user running application identified as client + * has access to a given privilege. + * Response can be received with cynara_async_process(). + * Check id is returned to pair request with response for canceling purposes. + * + * \par Typical use case: + * An application may use this API to check if it has (potential) permission to take some action + * or access resource in future (permissions may rarely change). The typical use would be to disable + * or hide some of functionalities if they probably could not be used anyways. + * + * \par Method of function operation: + * \parblock + * This function is very similar to cynara_async_create_request() with the difference, that in case + * of answer not being one of CYNARA_API_PERMISSION_DENIED or CYNARA_API_PERMISSION_ALLOWED, + * no external application will be consulted. Instead, CYNARA_API_ACCESS_NOT_RESOLVED is returned + * by a callback, meaning, that only creating full request through cynara_async_create_request() API + * would yield eventual answer. + * + * If access permission cannot be acquired without usage of external agents, callback can be + * called with CYNARA_CALL_CAUSE_ANSWER and response value being CYNARA_API_ACCESS_NOT_RESOLVED. + * \endparblock + * + * \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: + * \parblock + * Call cynara_async_create_simple_request() needs cynara_async structure to be created first + * with cynara_async_initialize(). + * Call cynara_async_cancel_request() to cancel pending request. + * Call cynara_async_process() to send request and receive response. + * + * The answer will be taken from cynara's database without consulting any external applications. + * If the answer cannot be resolved in one of CYNARA_API_ACCESS_ALLOWED or + * CYNARA_API_ACCESS_DENIED without communicating with external application, response returned + * through callback will have value CYNARA_API_ACCESS_NOT_RESOLVED. + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * \endparblock + * + * \param[in] p_cynara cynara_async structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Client defined session. + * \param[in] user User of running client. + * \param[in] privilege Privilege that is a subject of a check. + * \param[out] p_check_id Placeholder for check id. If NULL, then no check_id is returned. + * \param[in] callback Function called when matching response is received. + * If NULL then no callback will be called when response, cancel, finish + * or service not availble error happens. + * \param[in] user_response_data User specific data, passed to callback is being only stored by + * library. Cynara library does not take any actions on this pointer, except for giving + * it back to user in cynara_response_callback. + * Can be NULL. + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_MAX_PENDING_REQUESTS on too much pending requests + * \return other negative error code on error + */ +int cynara_async_create_simple_request(cynara_async *p_cynara, const char *client, + const char *client_session, const char *user, + const char *privilege, cynara_check_id *p_check_id, + cynara_response_callback callback, void *user_response_data); + +/** + * \par Description: + * Process events that appeared on cynara socket. + * + * \par Purpose: + * Process events after they appear on cynara socket. + * + * \par Typical use case: + * After request was queued with cynara_async_create_request() or + * cynara_async_create_simple_request() this API will return response. + * When event loop will return readiness on cynara socket, client should use this API. + * + * \par Method of function operation: + * \parblock + * This API sends pending requests, receives all responses and reacts when cynara + * has disconnected. If cynara has disconnected all values in cache become invalid. During these + * operations status of cynara socket may change, so cynara_status_callback callback will be + * triggered to indicate these changes. cynara_response_callback callback will be triggered with + * cynara_async_call_cause::CYNARA_CALL_CAUSE_ANSWER as cause param when response is available. + * + * If cynara has disconnected it will be triggered with + * cynara_async_call_cause::CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE as cause param. + * \endparblock + * + * \par Sync (or) Async: + * This is an asynchronous 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 protected critical section. + * + * \par Important notes: + * Call to cynara_async_process() requires initialized cynara_async structure. For this use + * cynara_async_initialize(). cynara_async_process() called from within cynara_status_callback or + * cynara_response_callback with CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE or CYNARA_CALL_CAUSE_FINISH + * cause will return CYNARA_API_OPERATION_NOT_ALLOWED. + * + * \param[in] p_cynara cynara_async structure. + * + * \return CYNARA_API_SUCCESS on success + * \return negative error code on error + */ +int cynara_async_process(cynara_async *p_cynara); + +/** + * \par Description: + * Cancel request created by cynara_async_create_request() or cynara_async_create_simple_request(). + * + * \par Purpose: + * This API should be used to cancel pending check request, + * created by cynara_async_create_request() or cynara_async_create_simple_request(). + * + * \par Typical use case: + * When cynara client is no longer interested in receiving an answer. + * Same check_id value should be used to identify proper request as was generated during + * request creation with cynara_async_create_request() or cynara_async_create_simple_request(). + * + * \par Method of function operation: + * \parblock + * Cancels request created by cynara_async_create_request() or cynara_async_create_simple_request() + * call. + * + * cynara_status_callback callback may be triggered to be able to send cancel to cynara. + * cynara_response_callback callback will be triggered with with + * cynara_async_call_cause::CYNARA_CALL_CAUSE_CANCEL as cause param. + * + * If given id is not valid (was not requested or response callback was already delivered) + * cynara_async_cancel_request() returns CYNARA_API_INVALID_PARAM. + * \endparblock + * + * \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 protected critical section. + * + * \par Important notes: + * Call to cynara_async_cancel_request() needs cynara_async structure to be created first. For this + * use cynara_async_initialize(). cynara_async_cancel_request() called from within + * cynara_status_callback or cynara_response_callback with CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE + * or CYNARA_CALL_CAUSE_FINISH cause will return CYNARA_API_OPERATION_NOT_ALLOWED. + * + * \param[in] p_cynara cynara_async structure. + * \param[in] check_id Check id to be cancelled + * + * \return CYNARA_API_SUCCESS on success + * \return negative error code on error + */ +int cynara_async_cancel_request(cynara_async *p_cynara, cynara_check_id check_id); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CLIENT_ASYNC_H */ diff --git a/compat/include/cynara/cynara-client-plugin.h b/compat/include/cynara/cynara-client-plugin.h new file mode 100644 index 0000000..70000e6 --- /dev/null +++ b/compat/include/cynara/cynara-client-plugin.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-client-plugin.h + * @author Zofia Abramowska + * @author Oskar Switalski + * @version 1.0 + * @brief This file defines cynara client side of external plugin interface - + * ClientPluginInterface. + */ + +#ifndef CYNARACLIENTPLUGIN_H_ +#define CYNARACLIENTPLUGIN_H_ + +#include + +#include +#include +#include + +namespace Cynara { + +class ClientPluginInterface; +typedef std::shared_ptr ClientPluginInterfacePtr; + +/** + * A class defining external plugins interface. + * + * These plugins work inside of cynara client library. They interpret + * PolicyResult returned by cynara in terms of: + * * cacheability - tells, whether value should be cached (for e.g. policyType like + * ALLOW_ONCE should not be cached) + * * usability - whether cache entry can still be used (for e.g. policy allowing access for + * given type) + * * value - translates PolicyResult to CYNARA_API_ACCESS_ALLOWED or CYNARA_API_ACCESS_DENIED + * + * Plugin implementing ClientPluginInterface must implement ExternalPluginInterface. + * Creation/destruction functions with signatures compatible to Cynara::create_t and + * Cynara::destroy_t must be provided as factories of ClientPluginInterface. + */ +class ClientPluginInterface : public ExternalPluginInterface { +public: + /** + * Return entry cacheability + */ + virtual bool isCacheable(const ClientSession &session, const PolicyResult &result) = 0; + /** + * Return entry usability + */ + virtual bool isUsable(const ClientSession &session, const ClientSession &prevSession, + bool &updateSession, PolicyResult &result) = 0; + /** + * Translate PolicyResult to CYNARA_API_ACCESS_ALLOWED or CYNARA_API_ACCESS_DENIED + */ + virtual int toResult(const ClientSession &session, PolicyResult &result) = 0; + + virtual ~ClientPluginInterface() {}; +}; + +} + +#endif // CYNARACLIENTPLUGIN_H_ diff --git a/compat/include/cynara/cynara-client.h b/compat/include/cynara/cynara-client.h new file mode 100644 index 0000000..d1388ec --- /dev/null +++ b/compat/include/cynara/cynara-client.h @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2014-2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-client.h + * @author Lukasz Wojciechowski + * @author Zofia Abramowska + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains client APIs of Cynara available with libcynara-client. + * @example cynara-client.example + */ + +#ifndef CYNARA_CLIENT_H +#define CYNARA_CLIENT_H + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct cynara cynara; +typedef struct cynara_configuration cynara_configuration; + +/** + * \par Description: + * Initialize cynara_configuration. Create structure used in following configuration + * API calls. + * + * \par Purpose: + * For configuration parameter to be used in cynara_initialize() function, this API must be + * called before any other cynara configuration API function. + * It will create cynara_configuration structure, an optional parameter of cynara initialization. + * + * \par Typical use case: + * Once before setting parameters of cynara configuration and passing to + * cynara_initialize(). + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success returns pointer + * to created cynara_configuration structure. + * + * \par Sync (or) Async: + * This as 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 protected critical section. + * + * \par Important notes: + * Structure cynara_configuration created by cynara_configuration_create() call + * should be released with cynara_configuration_destroy(). + * Structure cynara_configuration should be destroyed after passing it to + * cynara_initialize(). + * + * \param[out] pp_conf Placeholder for created cynara_configuration structure. + * + * \return CYNARA_API_SUCCESS on success + * or negative error code on error. + */ +int cynara_configuration_create(cynara_configuration **pp_conf); + +/** + * \par Description: + * Release cynara_configuration structure created with cynara_configuration_create(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara_configuration. + * + * \par Typical use case: + * Once cynara_configuration is not needed. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_configuration structure. + * + * \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 protected critical section. + * + * \param[in] p_conf cynara_configuration structure. If NULL, the call has no effect. + */ +void cynara_configuration_destroy(cynara_configuration *p_conf); + +/** + * \par Description: + * Set client cache size. + * + * \par Purpose: + * This API is used to change default number of cached responses returned from cynara. + * + * \par Typical use case: + * Once after cynara_configuration is created with cynara_configuration_create() + * and before passing configuration to cynara_initialize(). + * + * \par Method of function operation: + * This API initializes cache with given capacity. + * + * \par Sync (or) Async: + * This as 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 protected critical section. + * + * \par Important notes: + * After passing cynara_configuration to cynara_initialize() calling this API will have + * no effect. + * + * \param[in] p_conf cynara_configuration structure pointer. + * \param[in] cache_size Cache size to be set. + * + * \return CYNARA_API_SUCCESS on success + * or negative error code on error. + */ +int cynara_configuration_set_cache_size(cynara_configuration *p_conf, size_t cache_size); + +/** + * \par Description: + * Initialize cynara-client library with given configuration. + * Create structure used in following API calls. + * + * \par Purpose: + * This API must be used by prior calling cynara_check() function. + * + * \par Typical use case: + * Once before a service can call cynara_check(). + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success + * creates and returns cynara structure. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Thread-safeness: + * 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: + * Structure cynara created by cynara_initialize() call should be released with cynara_finish(). + * + * \param[out] pp_cynara Place holder for created cynara structure. + * \param[in] p_conf Configuration for cynara-client library. NULL for default parameters. + * [TODO define and describe functions for custom parameters]. + * + * \return CYNARA_API_SUCCESS on success, or error code on error. + */ +int cynara_initialize(cynara **pp_cynara, const cynara_configuration *p_conf); + +/** + * \par Description: + * Release cynara-client library and destroy structure created with cynara_initialize(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-client library. + * + * \par Typical use case: + * Once after last call to cynara_check(). + * + * \par Method of function operation: + * This API releases inner library structures and destroys cynara structure. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Thread-safeness: + * 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: + * No other call to libcynara-client should be made after call to cynara_finish(). + * + * \param[in] p_cynara Cynara structure. + * + * \return CYNARA_API_SUCCESS on success, or error code on error. + */ +int cynara_finish(cynara *p_cynara); + +/** + * \par Description: + * Check client, user access for given privilege. + * + * \par Purpose: + * This API should be used to check if a user running application identified as client + * has access to a privilege. + * + * \par Typical use case: + * A service want to ask trusted process (Cynara), if a client demanding access to some privilege + * has proper rights. + * + * \par Method of function operation: + * Client (a process / application) demanding access to a privilege is running as some user. + * For such triple an access to a privilege is checked by calling cynara. + * Depending on defined policy, an external application may be launched to ask user a question, + * e.g. if [s]he wants to allow client to use a privilege. Additional parameter client_session + * may be used to distinguish between client session (e.g. for allowing access only for this + * particular application launch). + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Thread-safeness: + * 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: + * \parblock + * An external application may be launched to allow user interaction in granting or denying access. + * + * Call to cynara_check() needs cynara structure to be created first with call to + * cynara_initialize(). + * + * String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise CYNARA_API_INVALID_PARAM will be + * returned. + * \endparblock + * + * \param[in] p_cynara Cynara structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Session of client (connection, launch). + * \param[in] user User running client. + * \param[in] privilege Privilege that is a subject of a check.. + * + * \return CYNARA_API_ACCESS_ALLOWED on access allowed, CYNARA_API_ACCESS_DENIED on access denial + * or other error code on error. + */ +int cynara_check(cynara *p_cynara, const char *client, const char *client_session, const char *user, + const char *privilege); + +/** + * \par Description: + * Check for (potential) permission to take some action or access a resource. + * + * \par Purpose: + * This API should be used for a quick check if a user running application identified as client + * has access to a given privilege. + * + * \par Typical use case: + * An application may use this API to check, if it has (potential) permission to take some action + * or access resource in future (permissions may rarely change). The typical use would be to disable + * or hide some of functionalities, if they probably could not be used anyways. + * + * \par Method of function operation: + * This function is very similar to cynara_check() with the difference, that in case of answer not + * being one of CYNARA_API_ACCESS_DENIED or CYNARA_API_ACCESS_ALLOWED, no external application will + * be consulted. Instead, CYNARA_API_ACCESS_NOT_RESOLVED is returned, meaning, that only running + * full cynara_check() API would yield eventual answer. + * Similarly, like in cynara_check(), argument client_session can be used to distinguish client + * sessions and grant possibility to yield answer from cache. + * + * \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: + * \parblock + * The answer will be taken from Cynara's database without consulting any external applications. + * If the answer cannot be resolved in one of CYNARA_API_PERMISSION_DENIED or + * CYNARA_API_PERMISSION_ALLOWED without communicating with external application the API will return + * CYNARA_API_ACCESS_NOT_RESOLVED. + * + * Call to cynara_simple_check() needs cynara structure to be created first with call to + * cynara_initialize(). String length cannot exceed CYNARA_MAX_ID_LENGTH, otherwise + * CYNARA_API_INVALID_PARAM will be returned. + * \endparblock + * + * \param[in] p_cynara Cynara structure. + * \param[in] client Application or process identifier. + * \param[in] client_session Session of client (connection, launch). + * \param[in] user User running client. + * \param[in] privilege Privilege that is a subject of a check. + * + * \return CYNARA_API_ACCESS_ALLOWED on access allowed, CYNARA_API_ACCESS_DENIED on access denial, + * CYNARA_API_ACCESS_NOT_RESOLVED when decision is not known without usage of external plugins or + * agents or negative error code on error. + */ +int cynara_simple_check(cynara *p_cynara, const char *client, const char *client_session, + const char *user, const char *privilege); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CLIENT_H */ diff --git a/compat/include/cynara/cynara-creds-commons.h b/compat/include/cynara/cynara-creds-commons.h new file mode 100644 index 0000000..81b9784 --- /dev/null +++ b/compat/include/cynara/cynara-creds-commons.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-creds-commons.h + * @author Lukasz Wojciechowski + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains common APIs for Cynara credentials helper. + */ + +#ifndef CYNARA_CREDS_COMMONS_H +#define CYNARA_CREDS_COMMONS_H + +#include + +enum cynara_client_creds { + CLIENT_METHOD_SMACK, + CLIENT_METHOD_PID, + + CLIENT_METHOD_DEFAULT = 0xFFFF, +}; + +enum cynara_user_creds { + USER_METHOD_UID, + USER_METHOD_GID, + + USER_METHOD_DEFAULT = 0xFFFF, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Gets the system default method value for client feature used in cynara-creds. + * + * \par Purpose: + * Functions cynara_creds_dbus_get_client() and cynara_creds_socket_get_client() take a method + * parameter, which determines a kind of process feature (i.e PID, SMACK label) returned by them. + * The described function provides implementation for obtaining a system default value + * for this parameter. + * + * \par Typical use case: + * The function might be called before cynara_creds_dbus_get_client() + * and cynara_creds_socket_get_client(), when functions shall be invoked with system default + * value of method parameter. + * + * \par Method of function operation: + * When this function is called for the first time it reads and returns the value of client_default + * parameter from /etc/cynara/creds.conf file. + * Returned value is cached so subsequent calls will not consult file again but use cached value. + * This also means that after the initial call any changes in the file will be ignored for the + * remaining lifetime of the process. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is thread-safe. + * + * \param[out] method Placeholder for system default client feature + * (like CLIENT_METHOD_SMACK, CLIENT_METHOD_PID) + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY if there is error in memory allocation + * \return CYNARA_API_UNKNOWN_ERROR if there is other error + * + */ +int cynara_creds_get_default_client_method(enum cynara_client_creds *method); + +/** + * \par Description: + * Gets the system default method value for user feature used in cynara-creds. + * + * \par Purpose: + * Functions cynara_creds_dbus_get_user() and cynara_creds_socket_get_user() take a method + * parameter, which determines a kind of process feature (i.e UID, GID) returned by them. + * The described function provides implementation for obtaining a system default value + * for this parameter. + * + * \par Typical use case: + * The function might be called before cynara_creds_dbus_get_user() + * and cynara_creds_socket_get_user() when functions shall be invoked with system default + * value of method parameter. + * + * \par Method of function operation: + * When this function is called for the first time it reads and returns the value of user_default + * parameter from /etc/cynara/creds.conf file. + * Returned value is cached so subsequent calls will not consult file again but use cached value. + * This also means that after the initial call any changes in the file will be ignored for the + * remaining lifetime of the process. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is thread-safe. + * + * \param[out] method Placeholder for system default user feature + * (like USER_METHOD_UID, USER_METHOD_GID) + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY if there is error in memory allocation + * \return CYNARA_API_UNKNOWN_ERROR if there is other error + */ +int cynara_creds_get_default_user_method(enum cynara_user_creds *method); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CREDS_COMMONS_H */ diff --git a/compat/include/cynara/cynara-creds-dbus.h b/compat/include/cynara/cynara-creds-dbus.h new file mode 100644 index 0000000..04af96f --- /dev/null +++ b/compat/include/cynara/cynara-creds-dbus.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-creds-dbus.h + * @author Lukasz Wojciechowski + * @author Radoslaw Bartosiak + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains Cynara credentials helper APIs for dbus clients. + * @example cynara-creds-dbus.example + */ + +#ifndef CYNARA_CREDS_DBUS_H +#define CYNARA_CREDS_DBUS_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Creates a client identification string with given method. Client is a process identified by the + * unique name at the other side of the dbus connection. + * + * \par Purpose: + * Client identification string is required 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 string is used as client parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates client string 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 client string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is CLIENT_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] method Method of client identifier creation + * \param[out] client Placeholder for allocated string containing client id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when client is NULL or uniqueName or client has wrong + * value (i.e NULL or non-existing) + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_client(DBusConnection *connection, const char *uniqueName, + enum cynara_client_creds method, char **client); + +/** + * \par Description: + * Creates a user identification string with given method. User is an executor of process + * at the other side of socket. + * + * \par Purpose: + * User identification string is required 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 string is used as user parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates user string 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 user string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is 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 invoked by the user + * \param[in] method Method of client identifier creation + * \param[out] user Placeholder for allocated string containing user id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when user is NULL or connection is not valid DBus connection or + * uniqueName does not represent a process conected to the DBus + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_user(DBusConnection *connection, const char *uniqueName, + enum cynara_user_creds method, char **user); + +/** + * \par Description: + * Return PID of a proces identified by the unique name at the other side of the dbus connection. + * + * \par Purpose: + * 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_helper_session_from_pid() function. + * + * \par Method of function operation: + * The function reads PID of the peer by calling a method from DBus Interface + * ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus") + * with "GetConnectionUnixProcessID" argument. + * + * \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. + * + * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages + * \param[in] uniqueName DBus identifier of the client invoked by the user + * \param[out] pid Placeholder for PID returned by function + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when socket_fd is not valid connected socket descriptor + * \return CYNARA_API_UNKNOWN_ERROR when system function fails in incredible situation + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_pid(DBusConnection *connection, const char *uniqueName, pid_t *pid); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CREDS_DBUS_H */ diff --git a/compat/include/cynara/cynara-creds-gdbus.h b/compat/include/cynara/cynara-creds-gdbus.h new file mode 100644 index 0000000..2334e45 --- /dev/null +++ b/compat/include/cynara/cynara-creds-gdbus.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-creds-gdbus.h + * @author Jacek Bukarewicz + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains Cynara credentials helper APIs for gdbus clients. + * @example cynara-creds-gdbus.example + */ + +#ifndef CYNARA_CREDS_GDBUS_H +#define CYNARA_CREDS_GDBUS_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Creates a client identification string with given method. Client is a process identified by the + * unique name at the other side of the dbus connection. + * + * \par Purpose: + * Client identification string is required 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 string is used as client parameter in cynara_check() or + * cynara_async_create_request() function. String is released with g_free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates client string 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 user string should be freed with g_free(). + * Allocated string is returned only, when function succeeds. + * If method is CLIENT_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] method Method of client identifier creation + * \param[out] client Placeholder for allocated string containing client id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when client is NULL or uniqueName or client has wrong + * value (i.e NULL or non-existing) + * \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_gdbus_get_client(GDBusConnection *connection, const gchar *uniqueName, + enum cynara_client_creds method, gchar **client); + +/** + * \par Description: + * Creates a user identification string with given method. User is an executor of process + * at the other side of socket. + * + * \par Purpose: + * User identification string is required 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 string is used as user parameter in cynara_check() or + * cynara_async_create_request() function. String is released with g_free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates user string 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 user string should be freed with g_free(). + * Allocated string is returned only, when function succeeds. + * If method is 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 invoked by the user + * \param[in] method Method of client identifier creation + * \param[out] user Placeholder for allocated string containing user id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when user is NULL or connection is not valid DBus connection or + * uniqueName does not represent a process conected to the DBus + * \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_gdbus_get_user(GDBusConnection *connection, const gchar *uniqueName, + enum cynara_user_creds method, gchar **user); + +/** + * \par Description: + * Return PID of a process identified by the unique name at the other side of the dbus connection. + * + * \par Purpose: + * 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_helper_session_from_pid() function. + * + * \par Method of function operation: + * The function reads PID of the peer by calling a method from DBus Interface + * ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus") + * with "GetConnectionUnixProcessID" argument. + * + * \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. + * + * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages + * \param[in] uniqueName DBus identifier of the client invoked by the user + * \param[out] pid Placeholder for PID returned by function + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when one of parameters is not valid + * \return CYNARA_API_UNKNOWN_ERROR when function fails because of unknown error + */ +int cynara_creds_gdbus_get_pid(GDBusConnection *connection, const gchar *uniqueName, pid_t *pid); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CREDS_GDBUS_H */ diff --git a/compat/include/cynara/cynara-creds-self.h b/compat/include/cynara/cynara-creds-self.h new file mode 100644 index 0000000..580a19d --- /dev/null +++ b/compat/include/cynara/cynara-creds-self.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-creds-self.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file contains Cynara credentials helper APIs for current process + * @example cynara-creds-self.example + */ + +#ifndef CYNARA_CREDS_SELF_H +#define CYNARA_CREDS_SELF_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Creates a client identification string with given method. Client is a current process. + * + * \par Purpose: + * Client identification string is required 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 string is used as client parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates client string using current process context. + * + * \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 client string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is CLIENT_METHOD_DEFAULT then it will be chosen based on Cynara configuration file. + * + * \param[in] method Method of client identifier creation + * \param[out] client Placeholder for allocated string containing client id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when client is NULL + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_self_get_client(enum cynara_client_creds method, char **client); + +/** + * \par Description: + * Creates a user identification string with given method. User is current process. + * + * \par Purpose: + * User identification string is required 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 string is used as user parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates user string using current process context. + * + * \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 user string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is USER_METHOD_DEFAULT then it will be chosen based on Cynara configuration file. + * + * \param[in] method Method of user identifier creation + * \param[out] user Placeholder for allocated string containing user id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when user is NULL + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_self_get_user(enum cynara_user_creds method, char **user); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CREDS_SELF_H */ diff --git a/compat/include/cynara/cynara-creds-socket.h b/compat/include/cynara/cynara-creds-socket.h new file mode 100644 index 0000000..fe5cbdb --- /dev/null +++ b/compat/include/cynara/cynara-creds-socket.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-creds-socket.h + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb + * @author Lukasz Wojciechowski + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains Cynara credentials helper APIs for socket clients. + * @example cynara-creds-socket.example + */ + +#ifndef CYNARA_CREDS_SOCKET_H +#define CYNARA_CREDS_SOCKET_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Creates a client identification string with given method. Client is a process at the other + * side of socket. + * + * \par Purpose: + * Client identification string is required 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 string is used as client parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates client string using SO_PEERCRED on socket. + * + * \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 client string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is CLIENT_METHOD_DEFAULT then it will be chosen based on Cynara configuration file. + * + * \param[in] socket_fd Descriptor of open connected UNIX socket + * \param[in] method Method of client identifier creation + * \param[out] client Placeholder for allocated string containing client id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when client is NULL or socket_fd is not valid connected socket + * descriptor + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_socket_get_client(int socket_fd, enum cynara_client_creds method, char **client); + +/** + * \par Description: + * Creates a user identification string with given method. User is an executor of process + * at the other side of socket. + * + * \par Purpose: + * User identification string is required 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 string is used as user parameter in cynara_check() or + * cynara_async_create_request() function. String is released with free() function when it is no + * longer needed. + * + * \par Method of function operation: + * The function generates user string using SO_PEERCRED on socket. + * + * \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 user string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * If method is USER_METHOD_DEFAULT then it will be chosen based on Cynara configuration file. + * + * \param[in] socket_fd Descriptor of open connected UNIX socket + * \param[in] method Method of user identifier creation + * \param[out] user Placeholder for allocated string containing user id + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when user is NULL or socket_fd is not valid connected socket + * descriptor + * \return CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * \return CYNARA_API_CONFIGURATION_ERROR if the configuration file can not be opened or + * there are errors in configuration file + * \return CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_socket_get_user(int socket_fd, enum cynara_user_creds method, char **user); + +/** + * \par Description: + * Return PID of process at the other side of socket. + * + * \par Purpose: + * PID may be used for client_session creation with cynara_session_from_pid() function + * from libcynara-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_session_from_pid() function. + * + * \par Method of function operation: + * The function reads PID of peer using SO_PEERCRED on socket. + * + * \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. + * + * \param[in] socket_fd Descriptor of open connected UNIX socket + * \param[out] pid Placeholder for pid + * + * \return CYNARA_API_SUCCESS on success + * \return CYNARA_API_INVALID_PARAM when socket_fd is not valid connected socket descriptor + * \return CYNARA_API_UNKNOWN_ERROR when system function fails in incredible situation + */ +int cynara_creds_socket_get_pid(int socket_fd, pid_t *pid); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_CREDS_SOCKET_H */ diff --git a/compat/include/cynara/cynara-error.h b/compat/include/cynara/cynara-error.h new file mode 100644 index 0000000..8316f1d --- /dev/null +++ b/compat/include/cynara/cynara-error.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-error.h + * @author Lukasz Wojciechowski + * @author Zofia Abramowska + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains error codes returned by APIs of Cynara. + */ + +#ifndef CYNARA_ERROR_H +#define CYNARA_ERROR_H + +#include + +/** + * \name Return Codes + * Exported by the foundation API. Return codes beginning with negative codes indicate an error. + * @{ +*/ + +/*! \brief indicating that API call was interrupted by user*/ +#define CYNARA_API_INTERRUPTED 4 + +/*! \brief indicating access that cannot be resolved without further actions*/ +#define CYNARA_API_ACCESS_NOT_RESOLVED 3 + +/*! \brief indicating access that was checked is allowed */ +#define CYNARA_API_ACCESS_ALLOWED 2 + +/*! \brief indicating that access that was checked is denied */ +#define CYNARA_API_ACCESS_DENIED 1 + +/*! \brief indicating the result of the one specific API is successful */ +#define CYNARA_API_SUCCESS 0 + +/*! \brief indicating that value is not present in cache */ +#define CYNARA_API_CACHE_MISS -1 + +/*! \brief indicating that pending requests reached maximum */ +#define CYNARA_API_MAX_PENDING_REQUESTS -2 + +/*! \brief indicating system is running out of memory state */ +#define CYNARA_API_OUT_OF_MEMORY -3 + +/*! \brief indicating the API's parameter is malformed */ +#define CYNARA_API_INVALID_PARAM -4 + +/*! \brief indicating that service is not available */ +#define CYNARA_API_SERVICE_NOT_AVAILABLE -5 + +/*! \brief indicating that provided method is not supported by library */ +#define CYNARA_API_METHOD_NOT_SUPPORTED -6 + +/*! \brief cynara service does not allow to perform requested operation */ +#define CYNARA_API_OPERATION_NOT_ALLOWED -7 + +/*! \brief cynara service failed to perform requested operation */ +#define CYNARA_API_OPERATION_FAILED -8 + +/*! \brief cynara service hasn't found requested bucket */ +#define CYNARA_API_BUCKET_NOT_FOUND -9 + +/*! \brief indicating an unknown error */ +#define CYNARA_API_UNKNOWN_ERROR -10 + +/*! \brief indicating configuration error */ +#define CYNARA_API_CONFIGURATION_ERROR -11 + +/*! \brief indicating invalid parameter in command-line */ +#define CYNARA_API_INVALID_COMMANDLINE_PARAM -12 + +/*! \brief indicating that provided buffer is too short */ +#define CYNARA_API_BUFFER_TOO_SHORT -13 + +/*! \brief indicating that database is corrupted */ +#define CYNARA_API_DATABASE_CORRUPTED -14 + +/*! \brief indicating that user doesn't have enough permission to perform action */ +#define CYNARA_API_PERMISSION_DENIED -15 +/** @}*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Returns the error string in the user-supplied buffer buf of length buflen. + * + * \par Purpose: + * This function populates passed argument buf with a string that describes the error code + * passed in the argument errnum, possibly using the LC_MESSAGES part of the current locale + * to select the appropriate language. + * + * \par Typical use case: + * Once after any of API functions returns negative value (if the error message is to be presented + * to the user). + * + * \par Method of function operation: + * This function copies error string to memory pointed by argument buf along with termination + * character ('\0'). + * + * \par Sync (or) async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is thread-safe as long as setlocale() is not invoked concurrently. + * + * \par Important notes: + * This function copies error string to memory pointed by argument buf only if the buffer is + * of sufficient size (indicated by argument buflen). User is responsible for allocating sufficient + * memory for both error string and termination character ('\0'). + * Moreover, the user must not invoke setlocale() concurrently with this function, because results + * are unspecified. + * + * \param[in] errnum error number + * \param[out] buf buffer for error message + * \param[in] buflen buffer size + * + * \return CYNARA_API_SUCCESS on success, CYNARA_API_BUFFER_TOO_SHORT, if error message couldn't fit + * into allocated buffer, or CYNARA_API_INVALID_PARAM if errnum is not a valid error number + * or argument buf is NULL. + * + * \brief Obtain error message from error number. + */ +int cynara_strerror(int errnum, char *buf, size_t buflen); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_ERROR_H */ diff --git a/compat/include/cynara/cynara-limits.h b/compat/include/cynara/cynara-limits.h new file mode 100644 index 0000000..f4e98c1 --- /dev/null +++ b/compat/include/cynara/cynara-limits.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-limits.h + * @author Rafal Krypa + * @version 1.0 + * @brief This file contains limits for parameter sizes of Cynara APIs. + */ + +#ifndef CYNARA_LIMITS_H +#define CYNARA_LIMITS_H + +/*! \brief Maximum length of text identifier accepted by Cynara */ +#define CYNARA_MAX_ID_LENGTH 4096 + +/*! \brief Maximum size of vector accepted by Cynara */ +#define CYNARA_MAX_VECTOR_SIZE 4096 + +/*! \brief Maximum size of monitor entries buffer accepted by Cynara */ +#define CYNARA_MAX_MONITOR_BUFFER_SIZE 65535 + +#endif /* CYNARA_LIMITS_H */ diff --git a/compat/include/cynara/cynara-monitor.h b/compat/include/cynara/cynara-monitor.h new file mode 100644 index 0000000..ce7b8d0 --- /dev/null +++ b/compat/include/cynara/cynara-monitor.h @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-monitor.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief This file contains client APIs of Cynara monitoring. + */ + +#ifndef CYNARA_MONITOR_H +#define CYNARA_MONITOR_H + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct cynara_monitor_configuration cynara_monitor_configuration; +typedef struct cynara_monitor cynara_monitor; +typedef struct cynara_monitor_entry cynara_monitor_entry; + +/** + * \par Description: + * Initializes cynara_monitor_configuration. Creates structure used in following configuration + * API calls. + * + * \par Purpose: + * For configuration parameter to be used in cynara_monitor_initialize() function, this API must be + * called before any other Cynara monitor configuration API function. + * It will create cynara_monitor_configuration structure, an optional parameter + * of Cynara monitor initialization. + * + * \par Typical use case: + * Once before setting parameters of Cynara monitor configuration and passing to + * cynara_monitor_initialize(). + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success returns pointer + * to created cynara_monitor_configuration structure. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * \parblock + * This function is NOT thread-safe. If this function is called simultaneously with other functions + * from described API in different threads, they must be put into protected critical section. + * + * \par Important notes: + * Structure cynara_monitor_configuration created by cynara_monitor_configuration_create() call + * should be released with cynara_monitor_configuration_destroy(). + * Structure cynara_monitor_configuration should be destroyed after passing it to + * cynara_monitor_initialize(). + * \endparblock + * + * \param[out] pp_conf Placeholder for created cynara_monitor_configuration structure. + * + * \return CYNARA_API_SUCCESS on success + * or negative error code on error. + */ +int cynara_monitor_configuration_create(cynara_monitor_configuration **pp_conf); + +/** + * \par Description: + * Releases cynara_monitor_configuration structure created + * with cynara_monitor_configuration_create(). + * + * \par Purpose: + * This API should be used to clean up after usage of cynara_monitor_configuration. + * + * \par Typical use case: + * Once cynara_monitor_configuration is not needed. + * + * \par Method of function operation: + * This API releases inner library structure and destroys cynara_monitor_configuration structure. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If this function is called simultaneously with other functions + * from described API in different threads, they must be put into protected critical section. + * + * \param[in] p_conf cynara_monitor_configuration structure. If NULL, the call has no effect. + */ +void cynara_monitor_configuration_destroy(cynara_monitor_configuration *p_conf); + +/** + * \par Description: + * Set monitor entries buffer size. + * + * \par Purpose: + * This API is used to change default number of monitor entries stored on server side + * before returning them to client of libcynara-monitor. Buffer size cannot exceed value + * of CYNARA_MAX_MONITOR_BUFFER_SIZE, otherwise CYNARA_API_INPUT_PARAM will be returned. + * + * \par Typical use case: + * Once after cynara_configuration is created with cynara_monitor_configuration_create() + * and before passing configuration to cynara_monitor_configuration(). + * + * \par Method of function operation: + * This API initializes buffer with given capacity. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safety: + * This function is NOT thread-safe. If this function is called simultaneously with other functions + * from described API in different threads, they must be put into protected critical section. + * + * \par Important notes: + * After passing cynara_configuration to cynara_monitor_initialize() calling this API will have + * no effect. + * + * If buffer size is not set with cynara_monitor_configuration_set_buffer_size(), + * a default size will be taken. + * \endparblock + * + * \param[in] p_conf cynara_monitor_configuration structure pointer. + * \param[in] buffer_size buffer size to be set. + * + * \return CYNARA_API_SUCCESS on success + * or negative error code on error. + */ +int cynara_monitor_configuration_set_buffer_size(cynara_monitor_configuration *p_conf, + size_t buffer_size); + +/** + * \par Description: + * Initializes cynara-monitor library with given configuration. + * Creates structure used in following API calls. + * + * \par Purpose: + * This API must be used by prior calling cynara_monitor_entries_get() function. + * + * \par Typical use case: + * Once before a service can call cynara_monitor_entries_get(). + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success + * creates cynara_monitor structure. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Thread-safeness: + * This function is NOT thread-safe. If this function is called simultaneously with other functions + * from described API in different threads, they must be put into protected critical section. + * + * \par Important notes: + * Structure cynara_monitor created by cynara_monitor_initialize() call should be released + * with cynara_monitor_finish(). + * + * \param[out] pp_cynara_monitor Placeholder for created cynara_monitor structure. + * \param[in] p_conf Configuration for cynara-monitor library. NULL for default parameters. + * + * \return CYNARA_API_SUCCESS on success, or error code on error. + */ +int cynara_monitor_initialize(cynara_monitor **pp_cynara_monitor, + const cynara_monitor_configuration *p_conf); + +/** + * \par Description: + * Releases cynara-monitor library and destroys structure created with cynara_monitor_initialize(). + * + * \par Purpose: + * This API should be used to clean up after the usage of cynara-monitor library. + * + * \par Typical use case: + * Once after last call to cynara_monitor_entries_get(). + * + * \par Method of function operation: + * This API releases inner library structures and destroys cynara_monitor structure. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Thread-safeness: + * This function is NOT thread-safe. If this function is called simultaneously with other functions + * from described API in different threads, they must be put into protected critical section. + * + * \par Important notes: + * No other call to libcynara-monitor should be made after call to cynara_monitor_finish(). + * This function cannot be called, if cynara_monitor_entries_get() haven't returned yet. + * + * \param[in] p_cynara_monitor Cynara monitor structure. + * + * \return CYNARA_API_SUCCESS on success, or error code on error. + */ +int cynara_monitor_finish(cynara_monitor *p_cynara_monitor); + +/** + * \brief Returns monitor entries. + * + * \par Description: + * + * Returns all available monitor entries right after the size of buffer reaches set limit. + * + * \par Purpose: + * This API should be used to get available monitor entries. + * + * \par Typical use case: + * Gathering information about possible accesses checked in Cynara by individual services. + * + * \par Method of function operation: + * \parblock + * Each call to cynara_check() made by individual services are logged. The logs can be obtained + * by privileged clients with usage of libcynara-monitor (this API). + * + * In case of successful call CYNARA_API_SUCCESS is returned and *monitor_entries points + * to newly created array of pointers to cynara_monitor_entry. It is responsibility + * of the caller to release entries with cynara_monitor_entries_free(). + * + * The function blocks until the size of buffer reaches set limit or cynara_monitor_entries_flush() + * is called from another thread. + * \endparblock + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \par Important notes: + * Although this function is thread-safe, no multiple calls are allowed. + * + * \param[in] p_cynara_monitor cynara_monitor structure. + * \param[out] monitor_entries placeholder for NULL terminated array of pointers to + * monitor_entries structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_monitor_entries_get(cynara_monitor *p_cynara_monitor, + cynara_monitor_entry ***monitor_entries); + +/** + * \brief Makes cynara_monitor_entries_get() return immediately. + * + * \par Description: + * + * When called from another thread, makes cynara_monitor_entries_get() return immediately. + * + * \par Purpose: + * This API should be used to make cynara_monitor_entries_get() return immediately. + * + * \par Typical use case: + * User of libcynara-monitor wants to immediately get get monitor entries and/or make + * cynara_monitor_entries_get() return without waiting for full batch of entries. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \param[in] p_cynara_monitor cynara_monitor structure. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + */ +int cynara_monitor_entries_flush(cynara_monitor *p_cynara_monitor); + +/** + * \brief Releases monitor entries. + * + * \par Description: + * + * Releases monitor entries obtained with cynara_monitor_entries_get(). + * + * \par Purpose: + * This API should be used to release array of cynara_monitor_entry obtained + * with cynara_monitor_entries_get. + * + * \par Typical use case: + * When user obtained all needed data from the entries and won't be accessing the + * memory any more. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \param[in] monitor_entries NULL terminated array of cynara_monitor_entry to be released. + */ +void cynara_monitor_entries_free(cynara_monitor_entry **monitor_entries); + +/** + * \brief Gets client from monitor_entry + * + * \par Description: + * Gives access to client field of monitor_entry given as a parameter. + * Please refer to cynara_check() in cynara-client.h for more information on client field. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \par Important notes: + * The returned pointer is valid as long as given monitor_entry is. + * + * \param[in] monitor_entry cynara_monitor_entry to be accessed. + * + * \return valid const char * pointer or NULL in case of error. + */ +const char *cynara_monitor_entry_get_client(const cynara_monitor_entry *monitor_entry); + +/** + * \brief Gets user from monitor_entry + * + * \par Description: + * Gives access to user field of monitor_entry given as a parameter. + * Please refer to cynara_check() in cynara-client.h for more information on user field. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \par Important notes: + * The returned pointer is valid as long as given monitor_entry is. + * + * \param[in] monitor_entry cynara_monitor_entry to be accessed. + * + * \return valid const char * pointer or NULL in case of error. + */ +const char *cynara_monitor_entry_get_user(const cynara_monitor_entry *monitor_entry); + +/** + * \brief Gets privilege from monitor_entry + * + * \par Description: + * Gives access to privilege field of monitor_entry given as a parameter. + * Please refer to cynara_check() in cynara-client.h for more information on privilege field. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \par Important notes: + * The returned pointer is valid as long as given monitor_entry is. + * + * \param[in] monitor_entry cynara_monitor_entry to be accessed. + * + * \return valid const char * pointer or NULL in case of error. + */ +const char *cynara_monitor_entry_get_privilege(const cynara_monitor_entry *monitor_entry); + +/** + * \brief Gets result from monitor_entry + * + * \par Description: + * Gives access to result field of monitor_entry given as a parameter. + * In case of successful get, the result is one of CYNARA_API_ACCESS_ALLOWED + * or CYNARA_API_ACCESS_DENIED. In case of error a negative code error is returned. + * Please refer to cynara-error.h for more information. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \param[in] monitor_entry cynara_monitor_entry to be accessed. + * + * \return CYNARA_API_ACCESS_ALLOWED on access allowed, CYNARA_API_ACCESS_DENIED on access denial + * or other error code on error. + */ +int cynara_monitor_entry_get_result(const cynara_monitor_entry *monitor_entry); + +/** + * \brief Gets timestamp from monitor_entry + * + * \par Description: + * Gives access to timestamp field of monitor_entry given as a parameter. + * This is the time of cynara_check() being invoked. Please refer to cynara-client.h + * for more information about cynara_check(). + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread-safeness: + * This function is thread-safe. + * + * \par Important notes: + * The returned pointer is valid as long as given monitor_entry is. + * + * \param[in] monitor_entry cynara_monitor_entry to be accessed. + * + * \return valid const istruct timspec * pointer or NULL in case of error. + */ +const struct timespec *cynara_monitor_entry_get_timestamp( + const cynara_monitor_entry *monitor_entry); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_MONITOR_H */ diff --git a/compat/include/cynara/cynara-plugin.h b/compat/include/cynara/cynara-plugin.h new file mode 100644 index 0000000..747966f --- /dev/null +++ b/compat/include/cynara/cynara-plugin.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file src/include/cynara-plugin.h + * @author Zofia Abramowska + * @author Oskar Switalski + * @version 1.0 + * @brief This file defines cynara service side of external plugin interface - + * ServicePluginInterface + */ + +#ifndef CYNARA_PLUGIN_H_ +#define CYNARA_PLUGIN_H_ + +#include +#include +#include + +#include +#include +#include +#include + +namespace Cynara { + +//These typedefs will be defined in external headers +typedef std::string PluginData; +typedef std::string AgentType; + +class ServicePluginInterface; +typedef std::shared_ptr ServicePluginInterfacePtr; + +/** + * A class defining external plugins interface. + * These plugins work inside of cynara and either can produce + * response through check instantly or require communication + * with given type of agent. Agent must be registered through + * cynara-agent API. + * + * Plugin implementing ServicePluginInterface must implement ExternalPluginInterface. + * Creation/destruction functions with signatures compatible to Cynara::create_t and + * Cynara::destroy_t must be provided as factories of ServicePluginInterface. + */ + +class ServicePluginInterface : public ExternalPluginInterface { +public: + /** + * Enum indicating status of calling plugin method. + */ + enum class PluginStatus { + SUCCESS, /**< update() finished successfully */ + ANSWER_READY, /**< check() returns answer immediately through argument */ + ANSWER_NOTREADY, /**< check() cannot return answer immediately, + communication with agent is required */ + ERROR /**< either check() or update() fails */ + }; + + /** + * Asks plugin, what kind of permission does client, user and privilege has. + * + * @param[in] client + * @param[in] user + * @param[in] privilege + * @param[out] result Immediate response (if available) + * @param[out] requiredAgent When ANSWER_NOTREADY, required AgentType to communicate with + * @param[out] pluginData Additional data, that will be passed to agent + * @return PluginStatus In case of success - either ANSWER_READY or ANSWER_NOTREADY, + * in case of error - ERROR + */ + virtual PluginStatus check(const std::string &client, const std::string &user, + const std::string &privilege, PolicyResult &result, + AgentType &requiredAgent, PluginData &pluginData) noexcept = 0; + + /** + * Updates response returned by agent + * @param[in] client + * @param[in] user + * @param[in] privilege + * @param[in] agentData Additional data, passed from agent + * @param[out] result Response interpreted from agent + * @return PluginStatus In case of success - SUCCESS, in case of error - ERROR + */ + virtual PluginStatus update(const std::string &client, const std::string &user, + const std::string &privilege, const PluginData &agentData, + PolicyResult &result) noexcept = 0; + + virtual ~ServicePluginInterface() {}; + +}; + +} // namespace Cynara + +#endif /* CYNARA_PLUGIN_H_ */ diff --git a/compat/include/cynara/cynara-policy-types.h b/compat/include/cynara/cynara-policy-types.h new file mode 100644 index 0000000..bd74b5a --- /dev/null +++ b/compat/include/cynara/cynara-policy-types.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * \file src/include/cynara-policy-types.h + * \author Lukasz Wojciechowski + * \version 1.0 + * \brief This file contains policy types / operations definitions. + */ + +#ifndef CYNARA_POLICY_TYPES_H +#define CYNARA_POLICY_TYPES_H + +/** + * \name Operation Codes + * Operation codes that define action type to be taken + * @{ + */ + +/*! \brief a policy or bucket should be removed */ +#define CYNARA_ADMIN_DELETE -1 + +/*! \brief set policy result or bucket's default policy to DENY */ +#define CYNARA_ADMIN_DENY 0 + +/*! \brief set bucket's default policy to NONE */ +#define CYNARA_ADMIN_NONE 1 + +/*! \brief set policy to point into another bucket */ +#define CYNARA_ADMIN_BUCKET 0xFFFE + +/*! \brief set policy result or bucket's default policy to ALLOW */ +#define CYNARA_ADMIN_ALLOW 0xFFFF +/** @}*/ + +#endif /* CYNARA_POLICY_TYPES_H */ diff --git a/compat/include/cynara/cynara-session.h b/compat/include/cynara/cynara-session.h new file mode 100644 index 0000000..1c76bce --- /dev/null +++ b/compat/include/cynara/cynara-session.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/include/cynara-session.h + * @author Aleksander Zdyb + * @author Radoslaw Bartosiak + * @author Lukasz Wojciechowski + * @author Oskar Switalski + * @version 1.0 + * @brief This file contains Cynara session helper APIs. + * @example cynara-session.example + */ + +#ifndef CYNARA_SESSION_H +#define CYNARA_SESSION_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \par Description: + * Creates a client session string based on pid and time of creation of client process + * + * \par Purpose: + * This function can be used to create session string identifier used in cynara_check() + * and cynara_async_create_request() functions defined in client libraries. + * + * \par Typical use case: + * The function is called before the call of cynara_check() or cynara_async_create_request() + * function. Returned string is used as client_session param in cynara_check() or + * cynara_async_create_request() function. String is released with free() function. + * + * \par Method of function operation: + * The function generates client session based on the pid and start time of the client process. + * Time is acquired from /proc/PID directory. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is thread-safe. + * + * \par Important notes: + * Memory for returned string is obtained with malloc(), and should be freed with free(). + * + * \param[in] client_pid client application process identifier (PID). + * + * \return session string on success + * \return NULL on error + */ +char *cynara_session_from_pid(pid_t client_pid); + +#ifdef __cplusplus +} +#endif + +#endif /* CYNARA_SESSION_H */ diff --git a/compat/pkgconfig/CMakeLists.txt b/compat/pkgconfig/CMakeLists.txt new file mode 100644 index 0000000..6707a22 --- /dev/null +++ b/compat/pkgconfig/CMakeLists.txt @@ -0,0 +1,41 @@ +########################################################################### +# Copyright (C) 2018 "IoT.bzh" +# +# author: José Bollo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +configure_file(cynara-compat.pc.in cynara-compat.pc @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cynara-compat.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +foreach(item cynara-admin.pc + cynara-agent.pc + cynara-client-async.pc + cynara-client.pc + cynara-commons.pc + cynara-creds-commons.pc + cynara-creds-dbus.pc + cynara-creds-gdbus.pc + cynara-creds-self.pc + cynara-creds-socket.pc + cynara-monitor.pc + cynara-plugin.pc + cynara-session.pc) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/link-to-cynara-compat.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + RENAME ${item}) +endforeach(item) + diff --git a/compat/pkgconfig/cynara-compat.pc.in b/compat/pkgconfig/cynara-compat.pc.in new file mode 100644 index 0000000..c698b3a --- /dev/null +++ b/compat/pkgconfig/cynara-compat.pc.in @@ -0,0 +1,5 @@ +Name: cynara +Description: cynara package +Version: @CYNARA_VERSION@ +Libs: -L@CMAKE_INSTALL_FULL_LIBDIR@ -lcynara-compat +Cflags: -I@CMAKE_INSTALL_FULL_INCLUDEDIR@ -I@CMAKE_INSTALL_FULL_INCLUDEDIR@/cynara diff --git a/compat/pkgconfig/link-to-cynara-compat.pc b/compat/pkgconfig/link-to-cynara-compat.pc new file mode 120000 index 0000000..e8bb0ec --- /dev/null +++ b/compat/pkgconfig/link-to-cynara-compat.pc @@ -0,0 +1 @@ +cynara-compat.pc \ No newline at end of file diff --git a/compat/src/CMakeLists.txt b/compat/src/CMakeLists.txt new file mode 100644 index 0000000..3bda2da --- /dev/null +++ b/compat/src/CMakeLists.txt @@ -0,0 +1,47 @@ +########################################################################### +# Copyright (C) 2018 "IoT.bzh" +# +# author: José Bollo +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +add_compile_definitions(_GNU_SOURCE) + +########################################### +# build and install libcynara-compat +########################################### +add_library(cynara-compat SHARED lib-compat.c) +target_include_directories(cynara-compat PUBLIC ../include) +set_target_properties(cynara-compat + PROPERTIES + VERSION ${CYNARA_VERSION} + SOVERSION ${CYNARA_SOVERSION} +) +target_link_libraries(cynara-compat + PRIVATE cynara-client +) +target_link_options(cynara-compat + PRIVATE + -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export-cynara-compat.map +) +install(TARGETS cynara-compat LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) + +########################################### +# build and install test-old-cynara +########################################### +add_executable(test-old-cynara main-test-old-cynara.c) +target_link_libraries(test-old-cynara cynara-compat) +install(TARGETS test-old-cynara + RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) + diff --git a/compat/src/export-cynara-compat.map b/compat/src/export-cynara-compat.map new file mode 100644 index 0000000..7b482f3 --- /dev/null +++ b/compat/src/export-cynara-compat.map @@ -0,0 +1,8 @@ +{ +global: + cynara_*; +local: + *; +}; + + diff --git a/compat/src/lib-compat.c b/compat/src/lib-compat.c new file mode 100644 index 0000000..63696fe --- /dev/null +++ b/compat/src/lib-compat.c @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/******************************************************************************/ +/******************************************************************************/ +/* COMPATIBILITY LAYER TO PREVIOUS CYNARA */ +/******************************************************************************/ +/******************************************************************************/ +/* +cynara_admin_initialize(&m_CynaraAdmin), +cynara_admin_finish(m_CynaraAdmin); +cynara_admin_set_policies(m_CynaraAdmin, pp_policies.data()), +cynara_admin_list_policies(m_CynaraAdmin, bucketName.c_str(), appId.c_str(), +cynara_admin_erase(m_CynaraAdmin, bucketName.c_str(), static_cast(recursive), +cynara_admin_check(m_CynaraAdmin, bucket.c_str(), recursive, label.c_str(), + +cynara_initialize(&m_Cynara, nullptr), +cynara_finish(m_Cynara); +cynara_check(m_Cynara, +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef CYNARA_ADMIN_ASK +# define CYNARA_ADMIN_ASK 11 +#endif + +#include "rcyn-client.h" + +/******************** ADMIN ********************************/ + +static int from_status(int rc) +{ + switch (-rc) { + case 0: rc = CYNARA_API_SUCCESS; break; + case ENOMEM: rc = CYNARA_API_OUT_OF_MEMORY; break; + case ENOTSUP: rc = CYNARA_API_METHOD_NOT_SUPPORTED; break; + case ENOENT: rc = CYNARA_API_CACHE_MISS; break; + default: rc = CYNARA_API_UNKNOWN_ERROR; break; + } + return rc; +} + +static int from_check_status(int rc) +{ + switch (rc) { + case 0: rc = CYNARA_API_ACCESS_DENIED; break; + case 1: rc = CYNARA_API_ACCESS_ALLOWED; break; + case -EEXIST: rc = CYNARA_API_ACCESS_NOT_RESOLVED; break; + default: rc = from_status(rc); break; + } + return rc; +} + +static int from_value(const char *value) +{ + if (!strcmp(value, "yes")) + return CYNARA_ADMIN_ALLOW; + if (!strcmp(value, "ask")) + return CYNARA_ADMIN_ASK; + return CYNARA_ADMIN_DENY; +} + +static const char *to_value(int value) +{ + switch(value) { + case CYNARA_ADMIN_DENY: + case CYNARA_ADMIN_NONE: + case CYNARA_ADMIN_BUCKET: return "no"; + case CYNARA_ADMIN_ALLOW: return "yes"; + case CYNARA_ADMIN_ASK: return "ask"; + } + return "?"; +} + +/************************************ ERROR ****************************************/ + +static const struct { + int num; + const char *text; +} error_descriptions[] = { + { CYNARA_API_INTERRUPTED, "API call was interrupted by user" }, + { CYNARA_API_ACCESS_NOT_RESOLVED, "access cannot be resolved without further actions" }, + { CYNARA_API_ACCESS_ALLOWED, "access that was checked is allowed" }, + { CYNARA_API_ACCESS_DENIED, "access that was checked is denied" }, + { CYNARA_API_SUCCESS, "successful" }, + { CYNARA_API_CACHE_MISS, "value is not present in cache" }, + { CYNARA_API_MAX_PENDING_REQUESTS, "pending requests reached maximum" }, + { CYNARA_API_OUT_OF_MEMORY, "system is running out of memory" }, + { CYNARA_API_INVALID_PARAM, "parameter is malformed" }, + { CYNARA_API_SERVICE_NOT_AVAILABLE, "service is not available" }, + { CYNARA_API_METHOD_NOT_SUPPORTED, "method is not supported by library" }, + { CYNARA_API_OPERATION_NOT_ALLOWED, "not allowed to perform requested operation" }, + { CYNARA_API_OPERATION_FAILED, "failed to perform requested operation" }, + { CYNARA_API_BUCKET_NOT_FOUND, "service hasn't found requested bucket" }, + { CYNARA_API_UNKNOWN_ERROR, "unknown error" }, + { CYNARA_API_CONFIGURATION_ERROR, "configuration error" }, + { CYNARA_API_INVALID_COMMANDLINE_PARAM, "invalid parameter in command-line" }, + { CYNARA_API_BUFFER_TOO_SHORT, "provided buffer is too short" }, + { CYNARA_API_DATABASE_CORRUPTED, "database is corrupted" }, + { CYNARA_API_PERMISSION_DENIED, "user doesn't have enough permission to perform action" }, +}; + +int cynara_strerror(int errnum, char *buf, size_t buflen) +{ + int i = (int)(sizeof error_descriptions / sizeof *error_descriptions); + while(i) { + if (error_descriptions[--i].num == errnum) { + if (strlen(error_descriptions[i].text) >= buflen) + return CYNARA_API_BUFFER_TOO_SHORT; + if (buf == NULL) + break; + strcpy(buf, error_descriptions[i].text); + return CYNARA_API_SUCCESS; + } + } + return CYNARA_API_INVALID_PARAM; +} + +/******************** ADMIN ********************************/ + +struct cynara_admin; + +int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) +{ + return from_status(rcyn_open((rcyn_t**)pp_cynara_admin, rcyn_Admin, 1, 0)); +} + +int cynara_admin_finish(struct cynara_admin *p_cynara_admin) +{ + rcyn_close((rcyn_t*)p_cynara_admin); + return CYNARA_API_SUCCESS; +} + +int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const struct cynara_admin_policy *const *policies) +{ + int rc, rc2; + const struct cynara_admin_policy *p; + rcyn_key_t key; + rcyn_value_t value; + + key.session = "*"; + value.expire = 0; + rc = rcyn_enter((rcyn_t*)p_cynara_admin); + if (rc == 0) { + p = *policies; + while (rc == 0 && p != NULL) { + key.client = p->client; + key.user = p->user; + key.permission = p->privilege; + if (p->result == CYNARA_ADMIN_DELETE) + rc = rcyn_drop((rcyn_t*)p_cynara_admin, &key); + else if (p->result != CYNARA_ADMIN_BUCKET && p->result != CYNARA_ADMIN_NONE) { + value.value = to_value(p->result); + rc = rcyn_set((rcyn_t*)p_cynara_admin, &key, &value); + } + p = *++policies; + } + rc2 = rcyn_leave((rcyn_t*)p_cynara_admin, rc == 0); + if (rc == 0) + rc = rc2; + } + return rc; +} + +static void check_cb( + void *closure, + const rcyn_key_t *key, + const rcyn_value_t *value +) { + *((int*)closure) = from_value(value->value); +} + +int cynara_admin_check(struct cynara_admin *p_cynara_admin, + const char *start_bucket, const int recursive, + const char *client, const char *user, const char *privilege, + int *result, char **result_extra) +{ + rcyn_key_t key = { client, "*", user, privilege }; + if (result_extra) + *result_extra = NULL; + *result = CYNARA_ADMIN_DENY; + return from_status(rcyn_get((rcyn_t*)p_cynara_admin, &key, check_cb, result)); +} + +struct list_data +{ + struct cynara_admin_policy **policies; + const char *bucket; + unsigned count; + int error; +}; + +static void list_cb( + void *closure, + const rcyn_key_t *key, + const rcyn_value_t *value +) { + struct list_data *data = closure; + struct cynara_admin_policy *pol; + + if (data->error) + return; + + pol = calloc(1, sizeof *pol); + if (pol == NULL) + goto error; + + pol->bucket = strdup(data->bucket ?: ""); + pol->client = strdup(key->client); + pol->user = strdup(key->user); + pol->privilege = strdup(key->permission); + if (pol->bucket == NULL || pol->client == NULL || pol->user == NULL || pol->privilege == NULL) + goto error; + + pol->result = from_value(value->value); + pol->result_extra = 0; + closure = realloc(data->policies, (data->count + 1) * sizeof *data->policies); + if (closure == NULL) + goto error; + + (data->policies = closure)[data->count++] = pol; + return; +error: + if (pol) { + free(pol->bucket); + free(pol->client); + free(pol->user); + free(pol->privilege); + free(pol); + } + data->error = -ENOMEM; + +} + +int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket, + const char *client, const char *user, const char *privilege, + struct cynara_admin_policy ***policies) +{ + int rc; + struct list_data data; + rcyn_key_t key = { client, "*", user, privilege }; + + data.policies = NULL; + data.bucket = bucket && strcmp(bucket, "#") && strcmp(bucket, "*") ? bucket : NULL; + data.count = 0; + data.error = 0; + rc = rcyn_get((rcyn_t*)p_cynara_admin, &key, list_cb, &data); + if (rc == 0 && data.error != 0) + rc = data.error; + if (rc == 0 && !data.error) { + if ((*policies = realloc(data.policies, (data.count + 1) * sizeof *data.policies)) != NULL) + policies[0][data.count] = NULL; + else + rc = -ENOMEM; + } + if (rc) { + while(data.count) + free(data.policies[--data.count]); + free(data.policies); + *policies = NULL; + } + return from_status(rc); +} + +int cynara_admin_erase(struct cynara_admin *p_cynara_admin, + const char *start_bucket, int recursive, + const char *client, const char *user, const char *privilege) +{ + int rc, rc2; + rcyn_key_t key = { client, "*", user, privilege }; + + rc = rcyn_enter((rcyn_t*)p_cynara_admin); + if (rc == 0) { + rc = rcyn_drop((rcyn_t*)p_cynara_admin, &key); + rc2 = rcyn_leave((rcyn_t*)p_cynara_admin, rc == 0); + if (rc == 0) + rc = rc2; + } + return from_status(rc); +} + + +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions) +{ + struct cynara_admin_policy_descr **d = malloc(4 * sizeof *d), *s; + if (d) { + d[0] = malloc(sizeof *s); + d[1] = malloc(sizeof *s); + d[2] = malloc(sizeof *s); + d[3] = NULL; + if (d[0] != NULL && d[1] != NULL && d[2] != NULL) { + d[0]->name = strdup("Deny"); + d[1]->name = strdup("AskUser"); + d[2]->name = strdup("Allow"); + if (d[0]->name != NULL && d[1]->name != NULL && d[2]->name != NULL) { + d[0]->result = CYNARA_ADMIN_DENY; + d[1]->result = CYNARA_ADMIN_ASK; + d[2]->result = CYNARA_ADMIN_ALLOW; + *descriptions = d; + return CYNARA_API_SUCCESS; + } + free(d[0]->name); + free(d[1]->name); + free(d[2]->name); + } + free(d[0]); + free(d[1]); + free(d[2]); + } + *descriptions = NULL; + return CYNARA_API_OUT_OF_MEMORY; +} + +/************************************* CLIENT-ASYNC **************************************/ +struct cynara_async_configuration { uint32_t szcache; }; + +int cynara_async_configuration_create(cynara_async_configuration **pp_conf) +{ + *pp_conf = malloc(sizeof(cynara_async_configuration)); + if (*pp_conf == NULL) + return CYNARA_API_OUT_OF_MEMORY; + (*pp_conf)->szcache = 0; + return CYNARA_API_SUCCESS; +} + +void cynara_async_configuration_destroy(cynara_async_configuration *p_conf) +{ + free(p_conf); +} + +int cynara_async_configuration_set_cache_size(cynara_async_configuration *p_conf, + size_t cache_size) +{ + p_conf->szcache = cache_size > 1000000 ? 1000000 : (uint32_t)cache_size; + return CYNARA_API_SUCCESS; +} + +struct reqasync +{ + struct reqasync *next; + cynara_async *cynasync; + cynara_response_callback callback; + void *user_response_data; + cynara_check_id id; + bool canceled; +}; + +struct cynara_async +{ + rcyn_t *rcyn; + cynara_status_callback callback; + void *user_status_data; + struct reqasync *reqs; + cynara_check_id ids; +}; + +static int async_control_cb(void *closure, int op, int fd, uint32_t events) +{ + cynara_async *p_cynara = closure; + cynara_async_status s = (events & EPOLLOUT) ? CYNARA_STATUS_FOR_RW : CYNARA_STATUS_FOR_READ; + switch(op) { + case EPOLL_CTL_ADD: + p_cynara->callback(-1, fd, s, p_cynara->user_status_data); + break; + case EPOLL_CTL_MOD: + p_cynara->callback(fd, fd, s, p_cynara->user_status_data); + break; + case EPOLL_CTL_DEL: + p_cynara->callback(fd, -1, 0, p_cynara->user_status_data); + break; + } + return 0; +} + +int cynara_async_initialize(cynara_async **pp_cynara, const cynara_async_configuration *p_conf, + cynara_status_callback callback, void *user_status_data) +{ + int ret; + cynara_async *p_cynara; + + p_cynara = malloc(sizeof *p_cynara); + if (p_cynara == NULL) + ret = CYNARA_API_OUT_OF_MEMORY; + else { + ret = from_status(rcyn_open(&p_cynara->rcyn, rcyn_Check, p_conf ? p_conf->szcache : 1, 0)); + if (ret != CYNARA_API_SUCCESS) + free(p_cynara); + else { + p_cynara->callback = callback; + p_cynara->user_status_data = user_status_data; + p_cynara->reqs = NULL; + p_cynara->ids = 0; + rcyn_async_setup(p_cynara->rcyn, async_control_cb, p_cynara); + *pp_cynara = p_cynara; + } + } + return ret; +} + +void cynara_async_finish(cynara_async *p_cynara) +{ + struct reqasync *req; + + for(req = p_cynara->reqs ; req ; req = req->next) { + if (!req->canceled) { + req->callback(req->id, CYNARA_CALL_CAUSE_FINISH, 0, req->user_response_data); + req->canceled = true; + } + } + + rcyn_close(p_cynara->rcyn); + + while((req = p_cynara->reqs)) { + p_cynara->reqs = req->next; + free(req); + } + free(p_cynara); +} + +int cynara_async_check_cache(cynara_async *p_cynara, const char *client, const char *client_session, + const char *user, const char *privilege) +{ + int rc; + rcyn_key_t key = { client, client_session, user, privilege }; + rc = from_check_status(rcyn_cache_check(p_cynara->rcyn, &key)); + return rc; +} + +static void reqcb(void *closure, int status) +{ + struct reqasync *req = closure, **p; + + p = &req->cynasync->reqs; + while(*p && *p != req) + p = &(*p)->next; + if (*p) + *p = req->next; + + if (!req->canceled) + req->callback(req->id, CYNARA_CALL_CAUSE_ANSWER, from_check_status(status), req->user_response_data); + + free(req); +} + +static int create_reqasync(cynara_async *p_cynara, const char *client, + const char *client_session, const char *user, const char *privilege, + cynara_check_id *p_check_id, cynara_response_callback callback, + void *user_response_data, bool simple) +{ + int rc; + struct reqasync *req; + rcyn_key_t key = { client, client_session, user, privilege }; + + req = malloc(sizeof *req); + if (req == NULL) + return CYNARA_API_OUT_OF_MEMORY; + + req->next = p_cynara->reqs; + req->cynasync = p_cynara; + req->callback = callback; + req->user_response_data = user_response_data; + req->id = ++p_cynara->ids; + req->canceled = false; + + rc = rcyn_async_check(p_cynara->rcyn, &key, simple, reqcb, req); + if (rc == 0) + p_cynara->reqs = req; + else + free(req); + return from_status(rc); +} + +int cynara_async_create_request(cynara_async *p_cynara, const char *client, + const char *client_session, const char *user, const char *privilege, + cynara_check_id *p_check_id, cynara_response_callback callback, + void *user_response_data) +{ + int rc; + rc = create_reqasync(p_cynara, client, client_session, user, privilege, p_check_id, callback, user_response_data, false); + return rc; +} + +int cynara_async_create_simple_request(cynara_async *p_cynara, const char *client, + const char *client_session, const char *user, + const char *privilege, cynara_check_id *p_check_id, + cynara_response_callback callback, void *user_response_data) +{ + int rc; + rc = create_reqasync(p_cynara, client, client_session, user, privilege, p_check_id, callback, user_response_data, true); + return rc; +} + + +int cynara_async_process(cynara_async *p_cynara) +{ + int rc; + rc = rcyn_async_process(p_cynara->rcyn); + return rc; +} + +int cynara_async_cancel_request(cynara_async *p_cynara, cynara_check_id check_id) +{ + struct reqasync *req = p_cynara->reqs; + + while(req && req->id != check_id) + req = req->next; + if (req && !req->canceled) { + req->canceled = true; + req->callback(req->id, CYNARA_CALL_CAUSE_CANCEL, 0, req->user_response_data); + } + return CYNARA_API_SUCCESS; +} + +/************************************* CLIENT **************************************/ + +struct cynara_configuration { uint32_t szcache; }; + +int cynara_configuration_create(cynara_configuration **pp_conf) +{ + *pp_conf = malloc(sizeof(cynara_configuration)); + if (*pp_conf == NULL) + return CYNARA_API_OUT_OF_MEMORY; + (*pp_conf)->szcache = 0; + return CYNARA_API_SUCCESS; +} + +void cynara_configuration_destroy(cynara_configuration *p_conf) +{ + free(p_conf); +} + +int cynara_configuration_set_cache_size(cynara_configuration *p_conf, + size_t cache_size) +{ + p_conf->szcache = cache_size > 1000000 ? 1000000 : (uint32_t)cache_size; + return CYNARA_API_SUCCESS; +} + +int cynara_initialize(cynara **pp_cynara, const cynara_configuration *p_conf) +{ + return from_status(rcyn_open((rcyn_t**)pp_cynara, rcyn_Check, p_conf ? p_conf->szcache : 1, 0)); +} + +int cynara_finish(cynara *p_cynara) +{ + rcyn_close((rcyn_t*)p_cynara); + return CYNARA_API_SUCCESS; +} + +int cynara_check(cynara *p_cynara, const char *client, const char *client_session, const char *user, + const char *privilege) +{ + rcyn_key_t key = { client, client_session, user, privilege }; + return from_check_status(rcyn_check((rcyn_t*)p_cynara, &key)); +} + +int cynara_simple_check(cynara *p_cynara, const char *client, const char *client_session, + const char *user, const char *privilege) +{ + rcyn_key_t key = { client, client_session, user, privilege }; + return from_check_status(rcyn_test((rcyn_t*)p_cynara, &key)); +} + +/************************************* CREDS... & SESSION *********************************/ +#define MAX_LABEL_LENGTH 1024 + +#if !defined(DEFAULT_PEERSEC_LABEL) +# define DEFAULT_PEERSEC_LABEL "NoLabel" +#endif + +int cynara_creds_get_default_client_method(enum cynara_client_creds *method) +{ + *method = CLIENT_METHOD_SMACK; + return CYNARA_API_SUCCESS; +} + +int cynara_creds_get_default_user_method(enum cynara_user_creds *method) +{ + *method = USER_METHOD_UID; + return CYNARA_API_SUCCESS; +} + +int cynara_creds_self_get_client(enum cynara_client_creds method, char **client) +{ + char label[MAX_LABEL_LENGTH + 1]; + int len, fd; + + label[0] = 0; + fd = open("/proc/self/current/attr", O_RDONLY); + if (fd >= 0) { + len = (int)read(fd, label, sizeof label - 1); + label[len >= 0 ? len : 0] = 0; + close(fd); + } + return (*client = strdup(label[0] ? label : DEFAULT_PEERSEC_LABEL)) + ? CYNARA_API_SUCCESS : CYNARA_API_OUT_OF_MEMORY; +} + +int cynara_creds_self_get_user(enum cynara_user_creds method, char **user) +{ + return asprintf(user, "%ld", (long)getuid()) > 0 + ? CYNARA_API_SUCCESS : CYNARA_API_OUT_OF_MEMORY; +} + +int cynara_creds_socket_get_client(int fd, enum cynara_client_creds method, char **client) +{ + int rc; + socklen_t length; + struct ucred ucred; + char label[MAX_LABEL_LENGTH + 1]; + + /* get the credentials */ + length = (socklen_t)(sizeof ucred); + rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length); + if (rc < 0 || length != (socklen_t)(sizeof ucred) || !~ucred.uid) + return CYNARA_API_OPERATION_FAILED; + + /* get the security label */ + length = (socklen_t)(sizeof label); + rc = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, label, &length); + if (rc < 0 || length > (socklen_t)(sizeof label)) + return CYNARA_API_OPERATION_FAILED; + + return (*client = strdup(label)) + ? CYNARA_API_SUCCESS : CYNARA_API_OUT_OF_MEMORY; +} + + + +int cynara_creds_socket_get_user(int fd, enum cynara_user_creds method, char **user) +{ + int rc; + socklen_t length; + struct ucred ucred; + + /* get the credentials */ + length = (socklen_t)(sizeof ucred); + rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length); + if (rc < 0 || length != (socklen_t)(sizeof ucred) || !~ucred.uid) + return CYNARA_API_OPERATION_FAILED; + return asprintf(user, "%ld", (long)ucred.uid) > 0 + ? CYNARA_API_SUCCESS : CYNARA_API_OUT_OF_MEMORY; +} + + + +int cynara_creds_socket_get_pid(int fd, pid_t *pid) +{ + int rc; + socklen_t length; + struct ucred ucred; + + /* get the credentials */ + length = (socklen_t)(sizeof ucred); + rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length); + if (rc < 0 || length != (socklen_t)(sizeof ucred) || !~ucred.uid) + return CYNARA_API_OPERATION_FAILED; + *pid = ucred.pid; + return CYNARA_API_SUCCESS; +} + +char *cynara_session_from_pid(pid_t client_pid) +{ + char *r; + + return asprintf(&r, "%ld", (long)client_pid) < 0 ? NULL : r; +} + diff --git a/compat/src/main-test-old-cynara.c b/compat/src/main-test-old-cynara.c new file mode 100644 index 0000000..ccc3baa --- /dev/null +++ b/compat/src/main-test-old-cynara.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define STD 0 +#define TEST 1 +#define CACHE 2 + +#define STRFY(x) #x +#define CKEX(x) ckex((x),STD,__LINE__,STRFY(x)) +#define TEEX(x) ckex((x),TEST,__LINE__,STRFY(x)) +#define CAEX(x) ckex((x),CACHE,__LINE__,STRFY(x)) + +struct cynara_admin *admin; +struct cynara_async_configuration *aconf; +struct cynara_async *aclient; +struct cynara_configuration *conf; +struct cynara *client; +char buffer[4000]; +int bufill; +char *str[40]; +int nstr; +int pollfd; +int pending; +int ending; + +#define BUCKET "BUCK" + +void ckex(int rc, int type, int line, const char *x) +{ + int err = 1; + switch(type) { + case STD: + err = (rc != CYNARA_API_SUCCESS); + break; + case TEST: + err = (rc != CYNARA_API_ACCESS_DENIED + && rc != CYNARA_API_ACCESS_ALLOWED + && rc != CYNARA_API_ACCESS_NOT_RESOLVED); + break; + case CACHE: + err = (rc != CYNARA_API_ACCESS_DENIED + && rc != CYNARA_API_ACCESS_ALLOWED + && rc != CYNARA_API_ACCESS_NOT_RESOLVED + && rc != CYNARA_API_CACHE_MISS); + break; + } + if (err) { + char buffer[200]; + cynara_strerror(rc, buffer, 200); + printf("ERROR(%d) %s by %s line %d\n", rc, buffer, x, line); + exit(1); + } + printf("SUCCESS[%d] %s\n", rc, x); +} + +int is(const char *first, const char *second, int mincount) +{ + return nstr >= mincount + 2 + && !strcmp(first, str[0]) + && !strcmp(second, str[1]); +} + +void adm_list(char *cli, char *usr, char *perm) +{ + int i; + struct cynara_admin_policy **policies; + CKEX(cynara_admin_list_policies(admin, BUCKET, cli, usr, perm, &policies)); + i = 0; + while(policies[i]) { + printf("%s %s %s %s %d %s\n", + policies[i]->bucket, + policies[i]->client, + policies[i]->user, + policies[i]->privilege, + policies[i]->result, + policies[i]->result_extra ?: ""); + free(policies[i]->bucket); + free(policies[i]->client); + free(policies[i]->user); + free(policies[i]->privilege); + free(policies[i]->result_extra); + free(policies[i]); + i++; + } + free(policies); +} + +void adm_check(char *cli, char *usr, char *perm) +{ + char *rs; + int ri; + + CKEX(cynara_admin_check(admin, BUCKET, 1, cli, usr, perm, &ri, &rs)); + printf("got %d %s \n", ri, rs ?: "NULL"); +} + +void adm_set() +{ + struct cynara_admin_policy **policies, *p; + int n, i; + + n = (nstr - 2) / 4; + policies = malloc((1 + n) * sizeof *policies + n * sizeof **policies); + policies[n] = NULL; + p = (struct cynara_admin_policy*)(&policies[n + 1]); + for (i = 0 ; i < n ; i++, p++) { + policies[i] = p; + p->bucket = BUCKET; + p->client = str[2 + i * 4 + 0]; + p->user = str[2 + i * 4 + 1]; + p->privilege = str[2 + i * 4 + 2]; + p->result = atoi(str[2 + i * 4 + 3]); + p->result_extra = NULL; + } + CKEX(cynara_admin_set_policies(admin, (const struct cynara_admin_policy *const *)policies)); + free(policies); +} + +void adm_erase(char *cli, char *usr, char *perm) +{ + CKEX(cynara_admin_erase(admin, BUCKET, 1, cli, usr, perm)); +} + +void adm_desc() +{ + int i; + struct cynara_admin_policy_descr **d; + CKEX(cynara_admin_list_policies_descriptions(admin, &d)); + i = 0; + while(d[i]) { + printf("desc[%d] %d -> %s\n", i, d[i]->result, d[i]->name); + free(d[i]->name); + free(d[i]); + i++; + } + free(d); +} + +void asy_cache(char *cli, char *ses, char *usr, char *perm) +{ + CAEX(cynara_async_check_cache(aclient, cli, ses, usr, perm)); +} + +void asyncb(cynara_check_id check_id, cynara_async_call_cause cause, + int response, void *user_response_data) +{ + printf("RECEIVE %d %d\n", cause, response); + pending--; + if (ending && !pending) + exit(0); +} + +void asy_check(char *cli, char *ses, char *usr, char *perm, int simple) +{ + pending++; + if (simple) + CKEX(cynara_async_create_simple_request(aclient, cli, ses, usr, perm, NULL, asyncb, NULL)); + else + CKEX(cynara_async_create_request(aclient, cli, ses, usr, perm, NULL, asyncb, NULL)); +} + +void syn_check(char *cli, char *ses, char *usr, char *perm, int simple) +{ + if (simple) + TEEX(cynara_simple_check(client, cli, ses, usr, perm)); + else + TEEX(cynara_check(client, cli, ses, usr, perm)); +} + +void asyncstscb(int old_fd, int new_fd, cynara_async_status status, void *data) +{ + struct epoll_event ev; + + memset(&ev, 0, sizeof ev); + ev.data.fd = new_fd; + ev.events = (status == CYNARA_STATUS_FOR_RW ? EPOLLOUT : 0)|EPOLLIN; + if (old_fd == new_fd) { + if (new_fd != -1) + epoll_ctl(pollfd, EPOLL_CTL_MOD, new_fd, &ev); + } else { + if (old_fd != -1) + epoll_ctl(pollfd, EPOLL_CTL_DEL, old_fd, &ev); + if (new_fd != -1) + epoll_ctl(pollfd, EPOLL_CTL_ADD, new_fd, &ev); + } +} + +int action() +{ + if (is("admin", "listall", 0)) + adm_list("#", "#", "#"); + else if (is("admin", "list", 3)) + adm_list(str[2], str[3], str[4]); + else if (is("admin", "check", 3)) + adm_check(str[2], str[3], str[4]); + else if (is("admin", "set", 4)) + adm_set(); + else if (is("admin", "erase", 3)) + adm_erase(str[2], str[3], str[4]); + else if (is("admin", "desc", 0)) + adm_desc(); + else if (is("async", "cache", 4)) + asy_cache(str[2], str[3], str[4], str[5]); + else if (is("async", "check", 4)) + asy_check(str[2], str[3], str[4], str[5], 0); + else if (is("async", "test", 4)) + asy_check(str[2], str[3], str[4], str[5], 1); + else if (is("sync", "check", 4)) + syn_check(str[2], str[3], str[4], str[5], 0); + else if (is("sync", "test", 4)) + syn_check(str[2], str[3], str[4], str[5], 1); + else if (nstr > 0 && !strcmp(str[0], "exit")) + return 1; + else if (nstr > 0 && str[0][0] != '#') + printf("ERROR bad input\n"); + return 0; +} + +int main(int ac, char **av) +{ + struct epoll_event ev; + char *p; + int rc; + + pollfd = epoll_create(10); + memset(&ev, 0, sizeof ev); + ev.data.fd = 0; + ev.events = EPOLLIN; + epoll_ctl(pollfd, EPOLL_CTL_ADD, 0, &ev); + + CKEX(cynara_admin_initialize(&admin)); + + CKEX(cynara_async_configuration_create(&aconf)); + CKEX(cynara_async_configuration_set_cache_size(aconf, 1000)); + CKEX(cynara_async_initialize(&aclient, aconf, asyncstscb, NULL)); + cynara_async_configuration_destroy(aconf); + + CKEX(cynara_configuration_create(&conf)); + CKEX(cynara_configuration_set_cache_size(conf, 1000)); + CKEX(cynara_initialize(&client, conf)); + cynara_configuration_destroy(conf); + + fcntl(0, F_SETFL, O_NONBLOCK); + bufill = 0; + for(;;) { + memset(&ev, 0, sizeof ev); + epoll_wait(pollfd, &ev, 1, -1); + + if (ev.data.fd == 0) { + if (ev.events & EPOLLIN) { + rc = (int)sizeof buffer - bufill; + rc = (int)read(0, buffer, rc); + if (rc == 0) + break; + if (rc > 0) { + bufill += rc; + while((p = memchr(buffer, '\n', bufill))) { + /* process one line */ + *p++ = 0; + str[nstr = 0] = strtok(buffer, " \t"); + while(str[nstr]) + str[++nstr] = strtok(NULL, " \t"); + if (action()) + goto terminate; + /* next line if any */ + bufill -= (int)(p - buffer); + if (!bufill) + break; + memmove(buffer, p, bufill); + } + } + } + if (ev.events & EPOLLHUP) { + if (!pending) + break; + epoll_ctl(pollfd, EPOLL_CTL_DEL, 0, &ev); + ending = 1; + } + } + else { + cynara_async_process(aclient); + } + + } +terminate: + cynara_finish(client); + cynara_async_finish(aclient); + cynara_admin_finish(admin); +} + -- cgit 1.2.3-korg