/*
* uhttpd - Tiny single-threaded httpd
*
- * Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org>
+ * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#include <libubox/avl.h>
#include "uhttpd.h"
#include "plugin.h"
-#include "ubus-session.h"
static const struct uhttpd_ops *ops;
static struct config *_conf;
[RPC_ID] = { .name = "id", .type = BLOBMSG_TYPE_UNSPEC },
};
+enum {
+ SES_ACCESS,
+ __SES_MAX,
+};
+
+static const struct blobmsg_policy ses_policy[__SES_MAX] = {
+ [SES_ACCESS] = { .name = "access", .type = BLOBMSG_TYPE_BOOL },
+};
+
struct rpc_data {
struct blob_attr *id;
const char *method;
ops->request_done(cl);
}
-static void uh_ubus_send_request(struct client *cl, json_object *obj)
+static void uh_ubus_send_request(struct client *cl, json_object *obj, struct blob_attr *args)
{
struct dispatch *d = &cl->dispatch;
struct dispatch_ubus *du = &d->ubus;
- int ret;
+ struct blob_attr *cur;
+ static struct blob_buf req;
+ int ret, rem;
+
+ blob_buf_init(&req, 0);
+ blobmsg_for_each_attr(cur, args, rem)
+ blobmsg_add_blob(&req, cur);
blob_buf_init(&du->buf, 0);
memset(&du->req, 0, sizeof(du->req));
- ret = ubus_invoke_async(ctx, du->obj, du->func, buf.head, &du->req);
+ ret = ubus_invoke_async(ctx, du->obj, du->func, req.head, &du->req);
if (ret)
return uh_ubus_json_error(cl, ERROR_INTERNAL);
ops->request_done(cl);
}
+static void uh_ubus_allowed_cb(struct ubus_request *req, int type, struct blob_attr *msg)
+{
+ struct blob_attr *tb[__SES_MAX];
+ bool *allow = (bool *)req->priv;
+
+ if (!msg)
+ return;
+
+ blobmsg_parse(ses_policy, __SES_MAX, tb, blob_data(msg), blob_len(msg));
+
+ if (tb[SES_ACCESS])
+ *allow = blobmsg_get_bool(tb[SES_ACCESS]);
+}
+
+static bool uh_ubus_allowed(const char *sid, const char *obj, const char *fun)
+{
+ uint32_t id;
+ bool allow = false;
+ static struct blob_buf req;
+
+ if (ubus_lookup_id(ctx, "session", &id))
+ return false;
+
+ blob_buf_init(&req, 0);
+ blobmsg_add_string(&req, "sid", sid);
+ blobmsg_add_string(&req, "object", obj);
+ blobmsg_add_string(&req, "function", fun);
+
+ ubus_invoke(ctx, id, "access", req.head, uh_ubus_allowed_cb, &allow, 250);
+
+ return allow;
+}
+
static void uh_ubus_handle_request_object(struct client *cl, struct json_object *obj)
{
struct dispatch_ubus *du = &cl->dispatch.ubus;
- struct uh_ubus_session *ses;
struct rpc_data data = {};
enum rpc_error err = ERROR_PARSE;
goto error;
}
- ses = uh_ubus_session_get(du->sid);
- if (!ses) {
- err = ERROR_SESSION;
+ du->func = data.function;
+ if (ubus_lookup_id(ctx, data.object, &du->obj)) {
+ err = ERROR_OBJECT;
goto error;
}
- if (!uh_ubus_session_acl_allowed(ses, data.object, data.function)) {
+ if (!conf.ubus_noauth && !uh_ubus_allowed(du->sid, data.object, data.function)) {
err = ERROR_ACCESS;
goto error;
}
- du->func = data.function;
- if (ubus_lookup_id(ctx, data.object, &du->obj)) {
- err = ERROR_OBJECT;
- goto error;
- }
-
- uh_ubus_send_request(cl, obj);
+ uh_ubus_send_request(cl, obj, data.data);
return;
error:
}
ops->dispatch_add(&ubus_dispatch);
- if (ubus_session_api_init(ctx)) {
- fprintf(stderr, "Unable to initialize ubus session API\n");
- exit(1);
- }
uloop_done();
return 0;