From 3d400c723b332915683e7b290406753b9cd4391d Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 15 Mar 2018 11:22:47 +0100 Subject: [PATCH] session: support reclaiming pending apply session Reclaim the pending apply session upon login when the username matches the current login. This is required to support apply-confirm-rollback workflow for ubus browser clients, since changing IPs requires re-login to the device due to cross domain restrictions. Signed-off-by: Jo-Philipp Wich --- include/rpcd/session.h | 2 ++ session.c | 35 ++++++++++++++++++++++++++++++++++- uci.c | 3 ++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/rpcd/session.h b/include/rpcd/session.h index 03fffd2..3815a43 100644 --- a/include/rpcd/session.h +++ b/include/rpcd/session.h @@ -36,6 +36,8 @@ #define RPC_SESSION_DIRECTORY "/var/run/rpcd/sessions" #define RPC_SESSION_ACL_DIR "/usr/share/rpcd/acl.d" +extern char apply_sid[RPC_SID_LEN + 1]; + struct rpc_session { struct avl_node avl; char id[RPC_SID_LEN + 1]; diff --git a/session.c b/session.c index 9668b52..3bef025 100644 --- a/session.c +++ b/session.c @@ -1085,6 +1085,31 @@ rpc_login_setup_acls(struct rpc_session *ses, struct uci_section *login) globfree(&gl); } +static struct rpc_session * +rpc_reclaim_apply_session(const char *expected_username) +{ + struct rpc_session_data *username; + struct rpc_session *ses; + + if (!apply_sid[0]) + return NULL; + + ses = rpc_session_get(apply_sid); + + if (!ses) + return NULL; + + username = avl_find_element(&ses->data, "username", username, avl); + + if (!username || blobmsg_type(username->attr) != BLOBMSG_TYPE_STRING) + return NULL; + + if (strcmp(blobmsg_get_string(username->attr), expected_username)) + return NULL; + + return ses; +} + static int rpc_handle_login(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -1122,7 +1147,15 @@ rpc_handle_login(struct ubus_context *ctx, struct ubus_object *obj, if (tb[RPC_L_TIMEOUT]) timeout = blobmsg_get_u32(tb[RPC_L_TIMEOUT]); - ses = rpc_session_create(timeout); + /* + * attempt to reclaim a pending apply session, but only accept it + * if the username matches, otherwise perform a new login + */ + + ses = rpc_reclaim_apply_session(blobmsg_get_string(tb[RPC_L_USERNAME])); + + if (!ses) + ses = rpc_session_create(timeout); if (!ses) { rv = UBUS_STATUS_UNKNOWN_ERROR; diff --git a/uci.c b/uci.c index bad9e16..91d4ba2 100644 --- a/uci.c +++ b/uci.c @@ -30,7 +30,8 @@ static struct blob_buf buf; static struct uci_context *cursor; static struct uloop_timeout apply_timer; static struct ubus_context *apply_ctx; -static char apply_sid[RPC_SID_LEN + 1]; + +char apply_sid[RPC_SID_LEN + 1]; enum { RPC_G_CONFIG, -- 2.25.1