From 772811e76ff82184864aff8e29f29df7f0d64c88 Mon Sep 17 00:00:00 2001 From: "Jose M. Guisado" Date: Mon, 29 Nov 2021 15:48:48 +0100 Subject: #1065 Add support for client events ogServer supports events from clients in an agent mode (linux/windows). Client sends event information (eg. user login/logout) via a 103 Early Hints http response message. --- src/client.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/rest.c | 4 ++++ src/rest.h | 2 ++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/client.c b/src/client.c index 6c5743f..f56bffe 100644 --- a/src/client.c +++ b/src/client.c @@ -24,6 +24,67 @@ #include #include +static int og_status_session_toggle(struct og_client *cli) +{ + switch (cli->status) { + case OG_CLIENT_STATUS_LINUX: + cli->status = OG_CLIENT_STATUS_LINUX_SESSION; + break; + case OG_CLIENT_STATUS_LINUX_SESSION: + cli->status = OG_CLIENT_STATUS_LINUX; + break; + case OG_CLIENT_STATUS_WIN: + cli->status = OG_CLIENT_STATUS_WIN_SESSION; + break; + case OG_CLIENT_STATUS_WIN_SESSION: + cli->status = OG_CLIENT_STATUS_WIN; + break; + default: + syslog(LOG_ERR, "%s:%d: invalid toggle session for status %d\n", + __FILE__, __LINE__, cli->status); + return -1; + } + return 0; +} + +static int og_resp_early_hints(struct og_client *cli, json_t *data) +{ + const char *event, *action, *user; + const char *key; + json_t *value; + int err = 0; + + if (json_typeof(data) != JSON_OBJECT) + return -1; + + json_object_foreach(data, key, value) { + if (!strcmp(key, "event")) { + err = og_json_parse_string(value, &event); + if (err < 0) + return err; + } else if (!strcmp(key, "action")) { + err = og_json_parse_string(value, &action); + if (err < 0) + return err; + } else if (!strcmp(key, "user")) { + err = og_json_parse_string(value, &user); + if (err < 0) + return err; + } + } + + syslog(LOG_INFO, "Received event %s %s %s\n", event, action, user); + + if (strncmp(event, "session", strlen("session"))) + return -1; + + if (strncmp(action, "start", strlen("start")) && + strncmp(action, "stop", strlen("stop"))) + return -1; + + return og_status_session_toggle(cli); +} + static int og_resp_probe(struct og_client *cli, json_t *data) { const char *status = NULL; @@ -638,6 +699,9 @@ static int og_agent_http_response_code(const char *buf) } else if (!strncmp(buf, "HTTP/1.0 503 Service Unavailable", strlen("HTTP/1.0 503 Service Unavailable"))) { return 503; + } else if (!strncmp(buf, "HTTP/1.0 103 Early Hints", + strlen("HTTP/1.0 103 Early Hints"))) { + return 103; } return -1; @@ -653,6 +717,7 @@ int og_agent_state_process_response(struct og_client *cli) code = og_agent_http_response_code(cli->buf); switch (code) { + case 103: case 200: ret = 0; success = true; @@ -689,7 +754,7 @@ int og_agent_state_process_response(struct og_client *cli) break; } - if (code != 200) { + if (code != 200 && code != 103) { og_dbi_update_action(cli->last_cmd_id, success); cli->last_cmd_id = 0; return ret; @@ -711,6 +776,12 @@ int og_agent_state_process_response(struct og_client *cli) return -1; } + if (code == 103) { + err = og_resp_early_hints(cli, root); + json_decref(root); + return err; + } + switch (cli->last_cmd) { case OG_CMD_PROBE: err = og_resp_probe(cli, root); diff --git a/src/rest.c b/src/rest.c index 2768df4..d468830 100644 --- a/src/rest.c +++ b/src/rest.c @@ -126,8 +126,12 @@ static const char *og_client_status(const struct og_client *cli) return "VDI"; case OG_CLIENT_STATUS_LINUX: return "LINUX"; + case OG_CLIENT_STATUS_LINUX_SESSION: + return "LINUX-SESSION"; case OG_CLIENT_STATUS_WIN: return "WIN"; + case OG_CLIENT_STATUS_WIN_SESSION: + return "WIN-SESSION"; default: return "OFF"; } diff --git a/src/rest.h b/src/rest.h index 4efe5dc..6cbf224 100644 --- a/src/rest.h +++ b/src/rest.h @@ -17,7 +17,9 @@ enum og_client_status { OG_CLIENT_STATUS_BUSY, OG_CLIENT_STATUS_VIRTUAL, OG_CLIENT_STATUS_LINUX, + OG_CLIENT_STATUS_LINUX_SESSION, OG_CLIENT_STATUS_WIN, + OG_CLIENT_STATUS_WIN_SESSION, }; enum og_cmd_type { -- cgit v1.2.3-18-g5258