static const struct blobmsg_policy dump_policy[__RPC_DUMP_MAX] = {
[RPC_DUMP_SID] = { .name = "ubus_rpc_session", .type = BLOBMSG_TYPE_STRING },
[RPC_DUMP_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 },
- [RPC_DUMP_EXPIRES] = { .name = "expires", .type = BLOBMSG_TYPE_INT32 },
+ [RPC_DUMP_EXPIRES] = { .name = "expires", .type = BLOBMSG_TYPE_INT64 },
[RPC_DUMP_DATA] = { .name = "data", .type = BLOBMSG_TYPE_TABLE },
};
blobmsg_add_string(&buf, "ubus_rpc_session", ses->id);
blobmsg_add_u32(&buf, "timeout", ses->timeout);
- blobmsg_add_u32(&buf, "expires", uloop_timeout_remaining(&ses->t) / 1000);
+ blobmsg_add_u64(&buf, "expires", uloop_timeout_remaining64(&ses->t) / 1000);
if (acls) {
c = blobmsg_open_table(&buf, "acls");
char *crypt_hash;
/* password is not set */
- if (!hash || !*hash || !strcmp(hash, "!") || !strcmp(hash, "x"))
+ if (!hash || !*hash)
{
return true;
}
crypt_hash = crypt(password, hash);
- return !strcmp(crypt_hash, hash);
+ return (crypt_hash && !strcmp(crypt_hash, hash));
}
static struct uci_section *
struct uci_element *e;
struct uci_ptr ptr = { .package = "rpcd" };
+ if (!uci_lookup_ptr(uci, &ptr, NULL, false) && ptr.p) {
+ uci_unload(uci, ptr.p);
+ ptr.flags = 0;
+ ptr.p = NULL;
+ }
+
uci_load(uci, ptr.package, &p);
if (!p)
if (uci_lookup_ptr(uci, &ptr, NULL, true))
continue;
+ if (!ptr.o)
+ continue;
+
if (ptr.o->type != UCI_TYPE_STRING)
continue;
if (uci_lookup_ptr(uci, &ptr, NULL, true))
continue;
+ if (!ptr.o)
+ continue;
+
if (ptr.o->type != UCI_TYPE_STRING)
continue;
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;
blobmsg_for_each_attr(data, tb[RPC_DUMP_DATA], rem) {
rpc_session_set(ses, data);
+ if (blobmsg_type(data) != BLOBMSG_TYPE_STRING)
+ continue;
+
if (!strcmp(blobmsg_name(data), "username"))
user = blobmsg_get_string(data);
}
avl_insert(&sessions, &ses->avl);
- uloop_timeout_set(&ses->t, blobmsg_get_u32(tb[RPC_DUMP_EXPIRES]) * 1000);
+ uloop_timeout_set(&ses->t, blobmsg_get_u64(tb[RPC_DUMP_EXPIRES]) * 1000);
return true;
}
};
static struct ubus_object_type session_type =
- UBUS_OBJECT_TYPE("luci-rpc-session", session_methods);
+ UBUS_OBJECT_TYPE("rpcd-plugin-session", session_methods);
static struct ubus_object obj = {
.name = "session",