aboutsummaryrefslogtreecommitdiffstats
path: root/src/agl-identity-binding.c
diff options
context:
space:
mode:
authorRaquel Medina <raquel.medina@konsulko.com>2019-02-15 17:10:40 +0200
committerRaquel Medina <raquel.medina@konsulko.com>2019-02-18 05:41:52 +0200
commit8f64868f9edd313eaee9a73abc3f79110da5f132 (patch)
treef3ac89b3a3dfa2a201186e93cb7c00357d29fec3 /src/agl-identity-binding.c
parentd164f55eb32887db04fd2b263345a93b6f0d87e8 (diff)
binding: identity: fix segfault & update to v3 forgerock binding calls
On user login via nfc, the identity service segfaults on nfc event processing. Fix segfault, update forgerock compilation unit to use binding V3 call methods and review the identity agent baseline to remove unused code / tidy up. Bug-AGL: SPEC-2158 Change-Id: Ic87e630e9d028ba22937468375631b8e908011f8 Signed-off-by: Raquel Medina <raquel.medina@konsulko.com>
Diffstat (limited to 'src/agl-identity-binding.c')
-rw-r--r--src/agl-identity-binding.c245
1 files changed, 148 insertions, 97 deletions
diff --git a/src/agl-identity-binding.c b/src/agl-identity-binding.c
index 70c195c..f246ea9 100644
--- a/src/agl-identity-binding.c
+++ b/src/agl-identity-binding.c
@@ -16,6 +16,7 @@
*/
#define _GNU_SOURCE
+#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
@@ -29,15 +30,21 @@
#include "agl-forgerock.h"
+static afb_api_t this_api;
static afb_event_t event;
+
static json_object *current_identity;
/* default vin corresponds to Toyota Camry 2016, 429 */
static const char default_vin[] = "4T1BF1FK5GU260429";
static char *vin;
-/***** configuration ********************************************/
+afb_api_t get_local_api(void)
+{
+ return this_api;
+}
+/***** configuration from file **********************************/
static struct json_object *readjson(int fd)
{
char *buffer;
@@ -50,12 +57,7 @@ static struct json_object *readjson(int fd)
buffer = alloca((size_t)(s.st_size)+1);
if (read(fd, buffer, (size_t)s.st_size) == (ssize_t)s.st_size) {
buffer[s.st_size] = 0;
- //AFB_API_NOTICE(afbBindingV3root, "Config file: %s", buffer);
result = json_tokener_parse(buffer);
- //if (!result)
- //{
- // AFB_API_ERROR(afbBindingV3root, "Config file is not a valid JSON: %s", json_tokener_error_desc(json_tokener_get_error(NULL)));
- //}
}
}
close(fd);
@@ -66,7 +68,7 @@ static struct json_object *readjson(int fd)
static struct json_object *get_global_config(const char *name, const char *locale)
{
int fd = afb_daemon_rootdir_open_locale(name, O_RDONLY, locale);
- if (fd < 0) AFB_API_ERROR(afbBindingV3root, "Config file not found: %s", name);
+ if (fd < 0) AFB_API_ERROR(this_api, "Config file not found: %s", name);
return fd < 0 ? NULL : readjson(fd);
}
@@ -83,7 +85,8 @@ static void confsetstr(struct json_object *conf, const char *name,
const char *s;
char *p;
- s = conf && json_object_object_get_ex(conf, name, &v) ? json_object_get_string(v) : def;
+ s = conf && json_object_object_get_ex(conf, name, &v) ?
+ json_object_get_string(v) : def;
p = *value;
if (s && p != s) {
*value = strdup(s);
@@ -108,11 +111,16 @@ static void readconfig()
/****************************************************************/
-static struct json_object *make_event_object(const char *name, const char *id, const char *nick)
+static struct json_object *make_event_object(const char *name,
+ const char *id,
+ const char *nick)
{
- struct json_object *object = json_object_new_object();
+ struct json_object *object;
- /* TODO: errors */
+ if (!name || !id )
+ return NULL;
+
+ object = json_object_new_object();
json_object_object_add(object, "eventName", json_object_new_string(name));
json_object_object_add(object, "accountid", json_object_new_string(id));
if (nick)
@@ -127,39 +135,44 @@ static int send_event_object(const char *name, const char *id, const char *nick)
static void do_login(struct json_object *desc)
{
- if (current_identity == NULL && desc == NULL) return; // Switching from NULL to NULL -> do nothing
+ /* if switching from NULL to NULL -> do nothing */
+ if (current_identity == NULL && desc == NULL) return;
+
+ /* if switching from one user to the same user -> do nothing */
if (current_identity && desc)
{
const char* a = json_object_to_json_string(current_identity);
const char* b = json_object_to_json_string(desc);
if (strcmp(a, b) == 0)
{
- AFB_API_NOTICE(afbBindingV3root, "Reloging of the same user.");
- return; // Switching from one user to the same user -> do nothing
+ AFB_API_NOTICE(this_api, "re-logging the same user!");
+ return;
}
}
struct json_object *object;
- /* switching the user */
- AFB_API_INFO(afbBindingV3root, "Switching to user %s",
+ /* switching to a different user */
+ AFB_API_INFO(this_api, "Switching to user %s",
desc ? json_object_to_json_string(desc) : "null");
object = current_identity;
current_identity = json_object_get(desc);
json_object_put(object);
if (!json_object_object_get_ex(desc, "name", &object))
- object = 0;
- send_event_object("login", !object ? "null" : json_object_get_string(object)? : "?", 0);
+ object = NULL;
+ send_event_object("login",
+ !object ? "null" : json_object_get_string(object)? : "?",
+ 0);
}
static void do_logout()
{
struct json_object *object;
- AFB_API_INFO(afbBindingV3root, "Switching to no user");
+ AFB_API_INFO(this_api, "Switching to no user");
object = current_identity;
- current_identity = 0;
+ current_identity = NULL;
json_object_put(object);
send_event_object("logout", "null", 0);
@@ -168,50 +181,12 @@ static void do_logout()
static void on_forgerock_data(struct json_object *data, const char *error)
{
if (error) {
- AFB_API_ERROR(afbBindingV3root, "Can't get data: %s", error);
+ AFB_API_ERROR(this_api, "Can't get data: %s", error);
} else {
do_login(data);
}
}
-/****************************************************************/
-
-static void subscribe (afb_req_t request)
-{
- if (afb_req_subscribe(request, event)) {
- AFB_REQ_ERROR(request, "subscribe error");
- afb_req_reply(request, NULL, "failed", "subscribtion failed");
- }
- else
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void unsubscribe (afb_req_t request)
-{
- afb_req_unsubscribe(request, event);
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void logout (afb_req_t request)
-{
- do_logout();
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void fake_login (afb_req_t request)
-{
- struct json_object *desc = afb_req_json(request);
- do_logout();
- if (desc)
- do_login(desc);
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void get (afb_req_t request)
-{
- afb_req_reply(request, json_object_get(current_identity), NULL, NULL);
-}
-
static void on_nfc_subscribed(void *closure, struct json_object *result,
const char *error, const char *info,
afb_api_t api)
@@ -225,48 +200,77 @@ static void on_nfc_subscribed(void *closure, struct json_object *result,
static int service_init(afb_api_t api)
{
struct json_object *jrequest = NULL;
+ int ret;
- agl_forgerock_setcb(on_forgerock_data);
+ this_api = api;
- event = afb_api_make_event(api, "event");
- if (!afb_event_is_valid(event)) {
- AFB_API_ERROR(api, "Failed to create event");
- return -1;
+ ret = afb_api_require_api(this_api, "nfc", 1);
+ if (ret < 0) {
+ AFB_API_ERROR(this_api, "nfc api not available");
+ goto out;
}
-
- readconfig();
- if (afb_api_require_api(api, "nfc", 1))
- return -1;
+ ret = afb_api_require_api(this_api, "persistence", 1);
+ if (ret < 0) {
+ AFB_API_ERROR(this_api, "persistence api not available");
+ goto out;
+ }
- if (afb_api_require_api(api, "persistence", 1))
- return -1;
+ event = afb_api_make_event(this_api, "event");
+ if (!afb_event_is_valid(event)) {
+ AFB_API_ERROR(this_api, "Failed to create event");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ readconfig();
+ agl_forgerock_setcb(on_forgerock_data);
jrequest = json_object_new_object();
json_object_object_add(jrequest, "value", json_object_new_string("presence"));
-
afb_api_call(api, "nfc", "subscribe", jrequest, on_nfc_subscribed, NULL);
- return 0;
+out:
+ return ret;
}
static void on_nfc_target_add(struct json_object *object)
{
- struct json_object * json_uid;
+ struct json_object *json_status;
+ struct json_object *json_uid;
const char *uid;
+
+ if (!object) {
+ AFB_API_ERROR(this_api, "nfc/presence empty args");
+ goto out;
+ }
+
+ if (!json_object_object_get_ex(object, "status", &json_status)) {
+ AFB_API_ERROR(this_api, "nfc/presence missing status");
+ goto out;
+ }
+
+ if (strncmp(json_object_get_string(json_status), "detected", 8)) {
+ AFB_API_WARNING(this_api, "Not a tag detected event!");
+ goto out;
+ }
+
if (json_object_object_get_ex(object, "uid", &json_uid))
{
uid = json_object_get_string(json_uid);
- AFB_API_NOTICE(afbBindingV3root,
+ AFB_API_NOTICE(this_api,
"nfc tag detected, call forgerock with vincode=%s and key=%s",
vin ? vin : default_vin, uid);
- send_event_object("incoming", uid, uid);
+
agl_forgerock_download_request(vin ? vin : default_vin, "nfc", uid);
}
- else AFB_API_ERROR(afbBindingV3root,
- "nfc target add event is received but no UID found: %s",
- json_object_to_json_string(object));
+ else
+ AFB_API_ERROR(this_api,
+ "nfc tag detected event but no UID found: %s",
+ json_object_to_json_string(object));
+out:
+ return;
}
static void onevent(afb_api_t api, const char *event, struct json_object *object)
@@ -277,9 +281,61 @@ static void onevent(afb_api_t api, const char *event, struct json_object *object
on_nfc_target_add(object);
return;
}
+
AFB_API_WARNING(api, "Unhandled event: %s", event);
}
+/****************************************************************/
+
+static void subscribe (afb_req_t request)
+{
+ if (afb_req_subscribe(request, event)) {
+ AFB_REQ_ERROR(request, "subscribe to identity event failed");
+ afb_req_reply(request, NULL, "failed", "subscribe error");
+ return;
+ }
+
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void unsubscribe (afb_req_t request)
+{
+ if (afb_req_unsubscribe(request, event)) {
+ AFB_REQ_ERROR(request, "unsubscribe to identity event failed");
+ afb_req_reply(request, NULL, "failed", "unsubscribe error");
+ return;
+ }
+
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void logout (afb_req_t request)
+{
+ do_logout();
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+/*
+ * verb "fake_login" intended for testing: force sending a login event
+ */
+static void fake_login (afb_req_t request)
+{
+ struct json_object *desc = afb_req_json(request);
+ do_logout();
+ if (desc)
+ do_login(desc);
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void get (afb_req_t request)
+{
+ afb_req_reply(request, json_object_get(current_identity), NULL, NULL);
+}
+
+/*
+ * verb "fake_auth" intended for testing: trigger authentication on the
+ * provided data (e.g same args as per the "nfc/presence" event)
+ */
static void fake_auth(afb_req_t req)
{
struct json_object* req_object;
@@ -294,18 +350,15 @@ static void fake_auth(afb_req_t req)
AFB_REQ_ERROR(req, "bad request: %s",
json_object_get_string(req_object));
afb_req_reply(req, NULL, "Missing arg", NULL);
+ return;
}
- else {
- const char* kind = json_object_get_string(kind_object);
- const char* key = json_object_get_string(key_object);
- AFB_REQ_NOTICE(req, "kind: %s, key: %s", kind, key);
-
- send_event_object("incoming", key, key);
- agl_forgerock_download_request(vin ? vin : default_vin, kind, key);
+ const char* kind = json_object_get_string(kind_object);
+ const char* key = json_object_get_string(key_object);
- afb_req_reply(req, NULL, NULL, "fake auth success!");
- }
+ AFB_REQ_NOTICE(req, "kind: %s, key: %s", kind, key);
+ agl_forgerock_download_request(vin ? vin : default_vin, kind, key);
+ afb_req_reply(req, NULL, NULL, "fake auth success!");
}
/*
@@ -314,31 +367,29 @@ static void fake_auth(afb_req_t req)
*/
const afb_verb_t verbs[]=
{
- {.verb = "subscribe" , .callback = subscribe , .auth = NULL,
+ {.verb = "subscribe" , .callback = subscribe ,
.info = "subscribe to events" , .session = AFB_SESSION_NONE },
- {.verb = "unsubscribe", .callback = unsubscribe , .auth = NULL,
+ {.verb = "unsubscribe", .callback = unsubscribe ,
.info = "unsubscribe to events" , .session = AFB_SESSION_NONE },
- {.verb = "fake-login" , .callback = fake_login , .auth = NULL,
+ {.verb = "fake-login" , .callback = fake_login ,
.info = "fake a login" , .session = AFB_SESSION_NONE },
- {.verb = "logout" , .callback = logout , .auth = NULL,
+ {.verb = "logout" , .callback = logout ,
.info = "log the current user out", .session = AFB_SESSION_NONE },
- {.verb = "get" , .callback = get , .auth = NULL,
+ {.verb = "get" , .callback = get ,
.info = "get data" , .session = AFB_SESSION_NONE },
- {.verb = "fake-auth" , .callback = fake_auth , .auth = NULL,
+ {.verb = "fake-auth" , .callback = fake_auth ,
.info = "fake an authentication" , .session = AFB_SESSION_NONE },
- {NULL}
+ { }
};
const afb_binding_t afbBindingExport =
{
.api = "identity",
- .specification = NULL,
+ .specification = "Identity-agent API",
.info = "AGL identity service",
.verbs = verbs,
- .preinit = NULL,
.init = service_init,
.onevent = onevent,
- .noconcurrency = 0
};
/* vim: set colorcolumn=80: */