diff options
author | Jo-Philipp Wich <jo@mein.io> | 2018-03-15 11:22:47 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2018-03-15 12:29:15 +0100 |
commit | 3d400c723b332915683e7b290406753b9cd4391d (patch) | |
tree | 5474835cc3a79c0835b62cbbc03f45974f2f1cab | |
parent | f0f6f81edb56bd43b63ffde9eeb52efe1ce833b8 (diff) | |
download | rpcd-3d400c723b332915683e7b290406753b9cd4391d.tar.gz |
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 <jo@mein.io>
-rw-r--r-- | include/rpcd/session.h | 2 | ||||
-rw-r--r-- | session.c | 35 | ||||
-rw-r--r-- | 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]; @@ -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; @@ -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, |