}
static void
-rpc_session_set(struct rpc_session *ses, const char *key, struct blob_attr *val)
+rpc_session_set(struct rpc_session *ses, struct blob_attr *val)
{
struct rpc_session_data *data;
- data = avl_find_element(&ses->data, key, data, avl);
+ data = avl_find_element(&ses->data, blobmsg_name(val), data, avl);
if (data) {
avl_delete(&ses->data, &data->avl);
free(data);
if (!blobmsg_name(attr)[0])
continue;
- rpc_session_set(ses, blobmsg_name(attr), attr);
+ rpc_session_set(ses, attr);
}
return 0;
crypt_hash = crypt(password, hash);
- return !strcmp(crypt_hash, hash);
+ return (crypt_hash && !strcmp(crypt_hash, hash));
}
static struct uci_section *
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,
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;
rpc_login_setup_acls(ses, login);
- rpc_session_set(ses, "user", tb[RPC_L_USERNAME]);
+ rpc_session_set(ses, tb[RPC_L_USERNAME]);
rpc_session_dump(ses, ctx, req);
out:
ses->timeout = blobmsg_get_u32(tb[RPC_DUMP_TIMEOUT]);
blobmsg_for_each_attr(data, tb[RPC_DUMP_DATA], rem) {
- rpc_session_set(ses, blobmsg_name(data), data);
+ rpc_session_set(ses, data);
+
+ if (blobmsg_type(data) != BLOBMSG_TYPE_STRING)
+ continue;
if (!strcmp(blobmsg_name(data), "username"))
user = blobmsg_get_string(data);