CMakeLists.txt: bump minimum cmake version
[project/ubus.git] / ubusd_event.c
index 6d0ae3014d7e5ef69254d94ff6579e8a98fca308..15932a9f4535a110d89962cc5dc7b54face60382 100644 (file)
@@ -35,10 +35,9 @@ static void ubusd_delete_event_source(struct event_source *evs)
 
 void ubusd_event_cleanup_object(struct ubus_object *obj)
 {
-       struct event_source *ev;
+       struct event_source *ev, *tmp;
 
-       while (!list_empty(&obj->events)) {
-               ev = list_first_entry(&obj->events, struct event_source, list);
+       list_for_each_entry_safe(ev, tmp, &obj->events, list) {
                ubusd_delete_event_source(ev);
        }
 }
@@ -64,6 +63,9 @@ static int ubusd_alloc_event_pattern(struct ubus_client *cl, struct blob_attr *m
        bool partial = false;
        int len;
 
+       if (!msg)
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
        blobmsg_parse(evr_policy, EVREG_LAST, attr, blob_data(msg), blob_len(msg));
        if (!attr[EVREG_OBJECT] || !attr[EVREG_PATTERN])
                return UBUS_STATUS_INVALID_ARGUMENT;
@@ -88,6 +90,9 @@ static int ubusd_alloc_event_pattern(struct ubus_client *cl, struct blob_attr *m
                len--;
        }
 
+       if (pattern[0] && ubusd_acl_check(cl, pattern, NULL, UBUS_ACL_LISTEN))
+               return UBUS_STATUS_PERMISSION_DENIED;
+
        ev = calloc(1, sizeof(*ev) + len + 1);
        if (!ev)
                return UBUS_STATUS_NO_DATA;
@@ -103,8 +108,6 @@ static int ubusd_alloc_event_pattern(struct ubus_client *cl, struct blob_attr *m
        return 0;
 }
 
-typedef struct ubus_msg_buf *(*event_fill_cb)(void *priv, const char *id);
-
 static void ubusd_send_event_msg(struct ubus_msg_buf **ub, struct ubus_client *cl,
                                 struct ubus_object *obj, const char *id,
                                 event_fill_cb fill_cb, void *cb_priv)
@@ -131,25 +134,19 @@ static void ubusd_send_event_msg(struct ubus_msg_buf **ub, struct ubus_client *c
        *objid_ptr = htonl(obj->id.id);
 
        (*ub)->hdr.seq = ++event_seq;
-       ubus_msg_send(obj->client, *ub, false);
-}
-
-static bool strmatch_len(const char *s1, const char *s2, int *len)
-{
-       for (*len = 0; s1[*len] == s2[*len]; (*len)++)
-               if (!s1[*len])
-                       return true;
-
-       return false;
+       ubus_msg_send(obj->client, *ub);
 }
 
-static int ubusd_send_event(struct ubus_client *cl, const char *id,
-                           event_fill_cb fill_cb, void *cb_priv)
+int ubusd_send_event(struct ubus_client *cl, const char *id,
+                    event_fill_cb fill_cb, void *cb_priv)
 {
        struct ubus_msg_buf *ub = NULL;
        struct event_source *ev;
        int match_len = 0;
 
+       if (ubusd_acl_check(cl, id, NULL, UBUS_ACL_SEND))
+               return UBUS_STATUS_PERMISSION_DENIED;
+
        obj_event_seq++;
 
        /*
@@ -162,7 +159,7 @@ static int ubusd_send_event(struct ubus_client *cl, const char *id,
                int cur_match_len;
                bool full_match;
 
-               full_match = strmatch_len(id, key, &cur_match_len);
+               full_match = ubus_strmatch_len(id, key, &cur_match_len);
                if (cur_match_len < match_len)
                        break;
 
@@ -172,7 +169,7 @@ static int ubusd_send_event(struct ubus_client *cl, const char *id,
                        if (!ev->partial)
                                continue;
 
-                       if (match_len != strlen(key))
+                       if (match_len != (int) strlen(key))
                                continue;
                }
 
@@ -215,6 +212,9 @@ static int ubusd_forward_event(struct ubus_client *cl, struct blob_attr *msg)
        struct blob_attr *attr[EVMSG_LAST];
        const char *id;
 
+       if (!msg)
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
        blobmsg_parse(ev_policy, EVMSG_LAST, attr, blob_data(msg), blob_len(msg));
        if (!attr[EVMSG_ID] || !attr[EVMSG_DATA])
                return UBUS_STATUS_INVALID_ARGUMENT;