diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c index 99552cbcf..56201712c 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.c +++ b/wpa_supplicant/dbus/dbus_new_helpers.c @@ -997,6 +997,174 @@ static int is_signature_correct(DBusMessage *message, } +static DBusMessage * properties_get_all(DBusMessage *message, char *interface, + struct wpa_dbus_object_desc *obj_dsc) +{ + if (os_strcmp(dbus_message_get_signature(message), "s") != 0) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + return get_all_properties(message, interface, + obj_dsc->properties); +} + + +static DBusMessage * properties_get(DBusMessage *message, + struct wpa_dbus_property_desc *dsc) +{ + if (os_strcmp(dbus_message_get_signature(message), "ss")) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + if (dsc->access != W && dsc->getter) + return dsc->getter(message, dsc->user_data); + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is write-only"); +} + + +static DBusMessage * properties_set(DBusMessage *message, + struct wpa_dbus_property_desc *dsc) +{ + if (os_strcmp(dbus_message_get_signature(message), "ssv")) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + + if (dsc->access != R && dsc->setter) + return dsc->setter(message, dsc->user_data); + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Property is read-only"); +} + + +static DBusMessage * +properties_get_or_set(DBusMessage *message, DBusMessageIter *iter, + char *interface, + struct wpa_dbus_object_desc *obj_dsc) +{ + struct wpa_dbus_property_desc *property_dsc; + char *property; + const char *method; + + method = dbus_message_get_member(message); + property_dsc = obj_dsc->properties; + + /* Second argument: property name (DBUS_TYPE_STRING) */ + if (!dbus_message_iter_next(iter) || + dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + dbus_message_iter_get_basic(iter, &property); + + while (property_dsc) { + /* compare property names and + * interfaces */ + if (!os_strncmp(property_dsc->dbus_property, property, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && + !os_strncmp(property_dsc->dbus_interface, interface, + WPAS_DBUS_INTERFACE_MAX)) + break; + + property_dsc = property_dsc->next; + } + if (property_dsc == NULL) { + wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s", + interface, property, + dbus_message_get_path(message)); + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "No such property"); + } + + if (os_strncmp(WPA_DBUS_PROPERTIES_GET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) == 0) + return properties_get(message, property_dsc); + + return properties_set(message, property_dsc); +} + + +static DBusMessage * properties_handler(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc) +{ + DBusMessageIter iter; + char *interface; + const char *method; + + method = dbus_message_get_member(message); + dbus_message_iter_init(message, &iter); + + if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || + !os_strncmp(WPA_DBUS_PROPERTIES_SET, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || + !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { + /* First argument: interface name (DBUS_TYPE_STRING) */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + { + return dbus_message_new_error(message, + DBUS_ERROR_INVALID_ARGS, + NULL); + } + + dbus_message_iter_get_basic(&iter, &interface); + + if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { + /* GetAll */ + return properties_get_all(message, interface, obj_dsc); + } + /* Get or Set */ + return properties_get_or_set(message, &iter, interface, + obj_dsc); + } + return dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, + NULL); +} + + +static DBusMessage * msg_method_handler(DBusMessage *message, + struct wpa_dbus_object_desc *obj_dsc) +{ + struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods; + const char *method; + const char *msg_interface; + + method = dbus_message_get_member(message); + msg_interface = dbus_message_get_interface(message); + + /* try match call to any registered method */ + while (method_dsc) { + /* compare method names and interfaces */ + if (!os_strncmp(method_dsc->dbus_method, method, + WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && + !os_strncmp(method_dsc->dbus_interface, msg_interface, + WPAS_DBUS_INTERFACE_MAX)) + break; + + method_dsc = method_dsc->next; + } + if (method_dsc == NULL) { + wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s", + msg_interface, method, + dbus_message_get_path(message)); + return dbus_message_new_error(message, + DBUS_ERROR_UNKNOWN_METHOD, NULL); + } + + if (!is_signature_correct(message, method_dsc)) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + NULL); + } + + return method_dsc->method_handler(message, + method_dsc->handler_argument); +} + + /** * message_handler - Handles incoming DBus messages * @connection: DBus connection on which message was received @@ -1008,8 +1176,8 @@ static int is_signature_correct(DBusMessage *message, * of the special cases i.e. introspection call or properties get/getall/set * methods and handles it. Else it iterates over registered methods list * and tries to match method's name and interface to those read from message - * If appropriate method was found it's handler function is called and - * response is sent. Otherwise the DBUS_ERROR_UNKNOWN_METHOD error message + * If appropriate method was found its handler function is called and + * response is sent. Otherwise, the DBUS_ERROR_UNKNOWN_METHOD error message * will be sent. */ static DBusHandlerResult message_handler(DBusConnection *connection, @@ -1019,17 +1187,15 @@ static DBusHandlerResult message_handler(DBusConnection *connection, const char *method; const char *path; const char *msg_interface; - -#define MESSAGE_UNHANDLED (DBusMessage *) 1 - - DBusMessage *reply = MESSAGE_UNHANDLED; + DBusMessage *reply; /* get method, interface and path the message is addressed to */ method = dbus_message_get_member(message); path = dbus_message_get_path(message); msg_interface = dbus_message_get_interface(message); if (!method || !path || !msg_interface) - goto out; + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + wpa_printf(MSG_MSGDUMP, "dbus: %s.%s (%s)", msg_interface, method, path); @@ -1039,162 +1205,23 @@ static DBusHandlerResult message_handler(DBusConnection *connection, !os_strncmp(WPA_DBUS_INTROSPECTION_INTERFACE, msg_interface, WPAS_DBUS_INTERFACE_MAX)) reply = introspect(message, obj_dsc); - else if (!strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface, - WPAS_DBUS_INTERFACE_MAX)) { + else if (!os_strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface, + WPAS_DBUS_INTERFACE_MAX)) { /* if message is properties method call */ - DBusMessageIter iter; - char *interface; - char *property; - - dbus_message_iter_init(message, &iter); - - if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || - !os_strncmp(WPA_DBUS_PROPERTIES_SET, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) || - !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { - /* First argument: interface name (DBUS_TYPE_STRING) */ - if (dbus_message_iter_get_arg_type(&iter) != - DBUS_TYPE_STRING) { - reply = dbus_message_new_error( - message, DBUS_ERROR_INVALID_ARGS, - NULL); - goto out; - } - - dbus_message_iter_get_basic(&iter, &interface); - - /* GetAll */ - if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { - if (os_strcmp(dbus_message_get_signature( - message), "s")) - reply = dbus_message_new_error( - message, - DBUS_ERROR_INVALID_ARGS, NULL); - else - reply = get_all_properties( - message, interface, - obj_dsc->properties); - } else { - /* Get or Set */ - struct wpa_dbus_property_desc *property_dsc; - property_dsc = obj_dsc->properties; - - /* Second argument: property name - * (DBUS_TYPE_STRING) */ - if (!dbus_message_iter_next(&iter) || - dbus_message_iter_get_arg_type(&iter) != - DBUS_TYPE_STRING) { - reply = dbus_message_new_error( - message, - DBUS_ERROR_INVALID_ARGS, NULL); - goto out; - } - dbus_message_iter_get_basic(&iter, &property); - - while (property_dsc) { - /* compare property names and - * interfaces */ - if (!os_strncmp(property_dsc->dbus_property, - property, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && - !os_strncmp(property_dsc->dbus_interface, interface, - WPAS_DBUS_INTERFACE_MAX)) - break; - - property_dsc = property_dsc->next; - } - if (property_dsc) { - /* Get */ - if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) { - if (os_strcmp(dbus_message_get_signature(message), "ss")) - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, NULL); - else if (property_dsc->access != W && - property_dsc->getter) - reply = property_dsc->getter(message, - property_dsc->user_data); - else - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - "Property is write-only"); - } else { - /* Set */ - if (os_strcmp(dbus_message_get_signature(message), "ssv")) - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, NULL); - else if (property_dsc->access != R && - property_dsc->setter) { - reply = property_dsc->setter - (message, property_dsc->user_data); - } else { - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - "Property is read-only"); - } - } - } else { - wpa_printf(MSG_DEBUG, "no property handler for %s.%s\n" - "on %s", interface, property, path); - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - "No such property"); - } - } - } else { - reply = dbus_message_new_error( - message, DBUS_ERROR_UNKNOWN_METHOD, NULL); - goto out; - } + reply = properties_handler(message, obj_dsc); } else { - struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods; - - /* try match call to any registered method */ - while (method_dsc) { - /* compare method names and interfaces */ - if (!os_strncmp(method_dsc->dbus_method, method, - WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && - !os_strncmp(method_dsc->dbus_interface, - msg_interface, - WPAS_DBUS_INTERFACE_MAX)) - break; - - method_dsc = method_dsc->next; - } - if (method_dsc) { - if (is_signature_correct(message, method_dsc)) { - reply = method_dsc->method_handler( - message, method_dsc->handler_argument); - } else { - reply = dbus_message_new_error( - message, DBUS_ERROR_INVALID_ARGS, - NULL); - } - } else { - wpa_printf(MSG_DEBUG, "no method handler for %s.%s " - "on %s", msg_interface, method, path); - reply = dbus_message_new_error( - message, DBUS_ERROR_UNKNOWN_METHOD, NULL); - } + reply = msg_method_handler(message, obj_dsc); } -out: - /* If the message was handled, send back the reply */ - if (reply != MESSAGE_UNHANDLED) { - /* If handler succeed returning NULL, reply empty message */ - if (!reply) - reply = dbus_message_new_method_return(message); - if (reply) { - if (!dbus_message_get_no_reply(message)) - dbus_connection_send(connection, reply, NULL); - dbus_message_unref(reply); - } - return DBUS_HANDLER_RESULT_HANDLED; - } else - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* If handler succeed returning NULL, reply empty message */ + if (!reply) + reply = dbus_message_new_method_return(message); + if (reply) { + if (!dbus_message_get_no_reply(message)) + dbus_connection_send(connection, reply, NULL); + dbus_message_unref(reply); + } + return DBUS_HANDLER_RESULT_HANDLED; }