Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
Lennart Poettering lenn...@poettering.net writes: On Mon, 20.10.14 12:43, Jan Synacek (jsyna...@redhat.com) wrote: When setting any of those using set-x11-keymap, check that their values are available on the system. --- src/locale/localectl.c | 208 + 1 file changed, 139 insertions(+), 69 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3690f9f..0caf467 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -53,6 +53,14 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_convert = true; +enum keymap_state { +NONE, +MODELS = 1 0, +LAYOUTS = 1 1, +VARIANTS = 1 2, +OPTIONS = 1 3 +}; Hmm, why is this a bitfield? Do I get this patch right and you are trying to match the passed arguments to all models/layouts/variants/options all the time? This means if a layout happens to have the same name as a model then things will be ambiguous? I really don't like this I must say. Basic idea was that get_x11_keymaps_internal() gets a flag that says what kind of information should be parsed and returned from /usr/share/X11/xkb/rules/base.lst. If only a layout needs to be specified, then fetch just layouts. If a layout, model and options all get specified, fetch all of them in one go. If I left the function as it was, it would require multiple passes to validate layouts, models and options together. And yes, there's ambiguity in that solution. I didn't come up with anything better, I'm not even sure if this has a proper solution without using X libraries, which is IMO unthinkable in this case. If you have a better idea, I'll be happy to rework this solution with something better. Or mabye I am not following what you are doing here? Can you elaborate? Also, this validating really be done on the server side, not on the client side, to take full effect. Doing the listing/completion thing on the client-side appears OK since it's really more a help to the user, nothing that validates stuff. But if we want to validate input here, we should really do it on the server-side, in localed, especially as localed and localectl might run on different systems and not share the same map list. Doing this on the server side makes sense. It didn't occur to me before. I saw code that already parsed the local xkb rules, so I just improved on that. Also, in case of a failed validation, it's probably better to just warn the user and go on, as mentioned earlier in this thread. So, if would it make sense to implement the server-side validation functionality? Would the DBus API need to be changed? Any other ideas? Lennart Cheers, -- Jan Synacek Software Engineer, Red Hat signature.asc Description: PGP signature ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
On Thu, 23.10.14 16:22, Jan Synacek (jsyna...@redhat.com) wrote: Hmm, why is this a bitfield? Do I get this patch right and you are trying to match the passed arguments to all models/layouts/variants/options all the time? This means if a layout happens to have the same name as a model then things will be ambiguous? I really don't like this I must say. Basic idea was that get_x11_keymaps_internal() gets a flag that says what kind of information should be parsed and returned from /usr/share/X11/xkb/rules/base.lst. If only a layout needs to be specified, then fetch just layouts. If a layout, model and options all get specified, fetch all of them in one go. If I left the function as it was, it would require multiple passes to validate layouts, models and options together. Well, one option would be to make the function take all four items and check them all in one go. Doing the listing/completion thing on the client-side appears OK since it's really more a help to the user, nothing that validates stuff. But if we want to validate input here, we should really do it on the server-side, in localed, especially as localed and localectl might run on different systems and not share the same map list. Doing this on the server side makes sense. It didn't occur to me before. I saw code that already parsed the local xkb rules, so I just improved on that. Also, in case of a failed validation, it's probably better to just warn the user and go on, as mentioned earlier in this thread. So, if would it make sense to implement the server-side validation functionality? Would the DBus API need to be changed? Any other ideas? I think we should just move the parsing/validation of the maps file from localectl into some file src/share/xkb-util.[ch] or so, and then use it for listing things on the client side, and for validation on the server side. Something similar we already did for the locales stuff which we moved to src/share/locale-util.[ch] (though that was arguably a simpler case, since returning a simple strv for the locales works well...) Lennart -- Lennart Poettering, Red Hat ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
Ran Benita ran...@gmail.com writes: On Fri, Oct 17, 2014 at 02:02:13PM +0200, Jan Synacek wrote: When setting any of those using set-x11-keymap, check that their values are available on the system. I have only skimmed this patch, but generally: 1. There can only be one model. 2. There can be multiple layouts and variants, comma separated. E.g., layout=us,il variant=,lyx. The amount of layouts and variants should match (or the variants can be empty), but most stuff you throw at it will be accepted though. 3. There can be multiple comma-separated options. Do you handle input like layout=us,il variant=,lyx correctly? Ran Nope, I didn't realize that. I'll send a better version of the patch. The parsing won't be perfect, though. With setxkbmap, I can do the following without any error: # setxkbmap us,cz lyx ctrl:nocaps -model idontexist # echo $? 0 Note that there is no lyx variant for either us or cz. Also, the number of layouts and variants *doesn't* match and the model doesn't exist as well. (That's probably what you meant by the last sentence in 2., I'm just restating it to be clear). Cheers, -- Jan Synacek Software Engineer, Red Hat signature.asc Description: PGP signature ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
When setting any of those using set-x11-keymap, check that their values are available on the system. --- src/locale/localectl.c | 208 + 1 file changed, 139 insertions(+), 69 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3690f9f..0caf467 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -53,6 +53,14 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_convert = true; +enum keymap_state { +NONE, +MODELS = 1 0, +LAYOUTS = 1 1, +VARIANTS = 1 2, +OPTIONS = 1 3 +}; + static void pager_open_if_enabled(void) { if (arg_no_pager) @@ -350,59 +358,12 @@ static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) { return 0; } -static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) { -_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; -const char *layout, *model, *variant, *options; -int r; - -assert(bus); -assert(args); - -if (n 5) { -log_error(Too many arguments.); -return -EINVAL; -} - -polkit_agent_open_if_enabled(); - -layout = args[1]; -model = n 2 ? args[2] : ; -variant = n 3 ? args[3] : ; -options = n 4 ? args[4] : ; - -r = sd_bus_call_method( -bus, -org.freedesktop.locale1, -/org/freedesktop/locale1, -org.freedesktop.locale1, -SetX11Keyboard, -error, -NULL, -bb, layout, model, variant, options, - arg_convert, arg_ask_password); -if (r 0) -log_error(Failed to set keymap: %s, bus_error_message(error, -r)); - -return r; -} - -static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { +static int get_x11_keymaps_internal(char ***list, enum keymap_state look_for, const char *layout) +{ _cleanup_fclose_ FILE *f = NULL; -_cleanup_strv_free_ char **list = NULL; char line[LINE_MAX]; -enum { -NONE, -MODELS, -LAYOUTS, -VARIANTS, -OPTIONS -} state = NONE, look_for; -int r; - -if (n 2) { -log_error(Too many arguments.); -return -EINVAL; -} +enum keymap_state state = NONE; +int r = 0; f = fopen(/usr/share/X11/xkb/rules/base.lst, re); if (!f) { @@ -410,17 +371,6 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { return -errno; } -if (streq(args[0], list-x11-keymap-models)) -look_for = MODELS; -else if (streq(args[0], list-x11-keymap-layouts)) -look_for = LAYOUTS; -else if (streq(args[0], list-x11-keymap-variants)) -look_for = VARIANTS; -else if (streq(args[0], list-x11-keymap-options)) -look_for = OPTIONS; -else -assert_not_reached(Wrong parameter); - FOREACH_LINE(line, f, break) { char *l, *w; @@ -444,12 +394,12 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { continue; } -if (state != look_for) +if (!(state look_for)) continue; w = l + strcspn(l, WHITESPACE); -if (n 1) { +if (layout) { char *e; if (*w == 0) @@ -465,23 +415,143 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { *e = 0; -if (!streq(w, args[1])) +if (!streq(w, layout)) continue; } else *w = 0; - r = strv_extend(list, l); + r = strv_extend(list, l); if (r 0) return log_oom(); } -if (strv_isempty(list)) { +if (strv_isempty(*list)) { log_error(Couldn't find any entries.); return -ENOENT; } -strv_sort(list); -strv_uniq(list); +strv_sort(*list); +strv_uniq(*list); + +return r; +} + +static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) { +_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; +_cleanup_strv_free_ char **list = NULL, **layouts = NULL, **variants = NULL, **options = NULL; +char **it; +const char *layouts_arg, *variants_arg, *options_arg; +
Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
On Mon, 20.10.14 12:43, Jan Synacek (jsyna...@redhat.com) wrote: When setting any of those using set-x11-keymap, check that their values are available on the system. --- src/locale/localectl.c | 208 + 1 file changed, 139 insertions(+), 69 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3690f9f..0caf467 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -53,6 +53,14 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_convert = true; +enum keymap_state { +NONE, +MODELS = 1 0, +LAYOUTS = 1 1, +VARIANTS = 1 2, +OPTIONS = 1 3 +}; Hmm, why is this a bitfield? Do I get this patch right and you are trying to match the passed arguments to all models/layouts/variants/options all the time? This means if a layout happens to have the same name as a model then things will be ambiguous? I really don't like this I must say. Or mabye I am not following what you are doing here? Can you elaborate? Also, this validating really be done on the server side, not on the client side, to take full effect. Doing the listing/completion thing on the client-side appears OK since it's really more a help to the user, nothing that validates stuff. But if we want to validate input here, we should really do it on the server-side, in localed, especially as localed and localectl might run on different systems and not share the same map list. Lennart -- Lennart Poettering, Red Hat ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
On Mon, Oct 20, 2014 at 11:15:14AM +0200, Jan Synacek wrote: Ran Benita ran...@gmail.com writes: On Fri, Oct 17, 2014 at 02:02:13PM +0200, Jan Synacek wrote: When setting any of those using set-x11-keymap, check that their values are available on the system. I have only skimmed this patch, but generally: 1. There can only be one model. 2. There can be multiple layouts and variants, comma separated. E.g., layout=us,il variant=,lyx. The amount of layouts and variants should match (or the variants can be empty), but most stuff you throw at it will be accepted though. 3. There can be multiple comma-separated options. Do you handle input like layout=us,il variant=,lyx correctly? Ran Nope, I didn't realize that. I'll send a better version of the patch. The parsing won't be perfect, though. With setxkbmap, I can do the following without any error: # setxkbmap us,cz lyx ctrl:nocaps -model idontexist # echo $? 0 Note that there is no lyx variant for either us or cz. Also, the number of layouts and variants *doesn't* match and the model doesn't exist as well. (That's probably what you meant by the last sentence in 2., I'm just restating it to be clear). Right, these settings are pretty permissive. But you reminded me - it is probably not a good idea to entirely abort the operation if the provided arguments don't validate. That's because the XKB rules file (/usr/share/X11/xkb/rules/) support wildcards, as you noticed with the idontexist model. These are then passed along, and some of them are in fact valid as far as I remember, just not mentioned in the base.lst file. So I think this should be a warning, not an error. If the user knows what he intended, he can ignore the error. Otherwise he will correct the error. Not ideal, but better than preventing legal values. ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
When setting any of those using set-x11-keymap, check that their values are available on the system. --- src/locale/localectl.c | 179 ++--- 1 file changed, 110 insertions(+), 69 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3690f9f..79bc2d0 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -53,6 +53,14 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_convert = true; +enum keymap_state { +NONE, +MODELS = 1 0, +LAYOUTS = 1 1, +VARIANTS = 1 2, +OPTIONS = 1 3 +}; + static void pager_open_if_enabled(void) { if (arg_no_pager) @@ -350,59 +358,12 @@ static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) { return 0; } -static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) { -_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; -const char *layout, *model, *variant, *options; -int r; - -assert(bus); -assert(args); - -if (n 5) { -log_error(Too many arguments.); -return -EINVAL; -} - -polkit_agent_open_if_enabled(); - -layout = args[1]; -model = n 2 ? args[2] : ; -variant = n 3 ? args[3] : ; -options = n 4 ? args[4] : ; - -r = sd_bus_call_method( -bus, -org.freedesktop.locale1, -/org/freedesktop/locale1, -org.freedesktop.locale1, -SetX11Keyboard, -error, -NULL, -bb, layout, model, variant, options, - arg_convert, arg_ask_password); -if (r 0) -log_error(Failed to set keymap: %s, bus_error_message(error, -r)); - -return r; -} - -static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { +static int get_x11_keymaps_internal(char ***list, enum keymap_state look_for, const char *layout) +{ _cleanup_fclose_ FILE *f = NULL; -_cleanup_strv_free_ char **list = NULL; char line[LINE_MAX]; -enum { -NONE, -MODELS, -LAYOUTS, -VARIANTS, -OPTIONS -} state = NONE, look_for; -int r; - -if (n 2) { -log_error(Too many arguments.); -return -EINVAL; -} +enum keymap_state state = NONE; +int r = 0; f = fopen(/usr/share/X11/xkb/rules/base.lst, re); if (!f) { @@ -410,17 +371,6 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { return -errno; } -if (streq(args[0], list-x11-keymap-models)) -look_for = MODELS; -else if (streq(args[0], list-x11-keymap-layouts)) -look_for = LAYOUTS; -else if (streq(args[0], list-x11-keymap-variants)) -look_for = VARIANTS; -else if (streq(args[0], list-x11-keymap-options)) -look_for = OPTIONS; -else -assert_not_reached(Wrong parameter); - FOREACH_LINE(line, f, break) { char *l, *w; @@ -444,12 +394,12 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { continue; } -if (state != look_for) +if (!(state look_for)) continue; w = l + strcspn(l, WHITESPACE); -if (n 1) { +if (layout) { char *e; if (*w == 0) @@ -465,23 +415,114 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { *e = 0; -if (!streq(w, args[1])) +if (!streq(w, layout)) continue; } else *w = 0; - r = strv_extend(list, l); + r = strv_extend(list, l); if (r 0) return log_oom(); } -if (strv_isempty(list)) { +if (strv_isempty(*list)) { log_error(Couldn't find any entries.); return -ENOENT; } -strv_sort(list); -strv_uniq(list); +strv_sort(*list); +strv_uniq(*list); + +return r; +} + +static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) { +_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; +_cleanup_strv_free_ char **list = NULL; +const char *layout, *model, *variant, *options; +enum keymap_state look_for; +int r; + +assert(bus); +
Re: [systemd-devel] [PATCH 2/2] localectl: verify layout, model, variant and options
On Fri, Oct 17, 2014 at 02:02:13PM +0200, Jan Synacek wrote: When setting any of those using set-x11-keymap, check that their values are available on the system. I have only skimmed this patch, but generally: 1. There can only be one model. 2. There can be multiple layouts and variants, comma separated. E.g., layout=us,il variant=,lyx. The amount of layouts and variants should match (or the variants can be empty), but most stuff you throw at it will be accepted though. 3. There can be multiple comma-separated options. Do you handle input like layout=us,il variant=,lyx correctly? Ran --- src/locale/localectl.c | 179 ++--- 1 file changed, 110 insertions(+), 69 deletions(-) diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 3690f9f..79bc2d0 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -53,6 +53,14 @@ static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_convert = true; +enum keymap_state { +NONE, +MODELS = 1 0, +LAYOUTS = 1 1, +VARIANTS = 1 2, +OPTIONS = 1 3 +}; + static void pager_open_if_enabled(void) { if (arg_no_pager) @@ -350,59 +358,12 @@ static int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) { return 0; } -static int set_x11_keymap(sd_bus *bus, char **args, unsigned n) { -_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; -const char *layout, *model, *variant, *options; -int r; - -assert(bus); -assert(args); - -if (n 5) { -log_error(Too many arguments.); -return -EINVAL; -} - -polkit_agent_open_if_enabled(); - -layout = args[1]; -model = n 2 ? args[2] : ; -variant = n 3 ? args[3] : ; -options = n 4 ? args[4] : ; - -r = sd_bus_call_method( -bus, -org.freedesktop.locale1, -/org/freedesktop/locale1, -org.freedesktop.locale1, -SetX11Keyboard, -error, -NULL, -bb, layout, model, variant, options, - arg_convert, arg_ask_password); -if (r 0) -log_error(Failed to set keymap: %s, bus_error_message(error, -r)); - -return r; -} - -static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { +static int get_x11_keymaps_internal(char ***list, enum keymap_state look_for, const char *layout) +{ _cleanup_fclose_ FILE *f = NULL; -_cleanup_strv_free_ char **list = NULL; char line[LINE_MAX]; -enum { -NONE, -MODELS, -LAYOUTS, -VARIANTS, -OPTIONS -} state = NONE, look_for; -int r; - -if (n 2) { -log_error(Too many arguments.); -return -EINVAL; -} +enum keymap_state state = NONE; +int r = 0; f = fopen(/usr/share/X11/xkb/rules/base.lst, re); if (!f) { @@ -410,17 +371,6 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { return -errno; } -if (streq(args[0], list-x11-keymap-models)) -look_for = MODELS; -else if (streq(args[0], list-x11-keymap-layouts)) -look_for = LAYOUTS; -else if (streq(args[0], list-x11-keymap-variants)) -look_for = VARIANTS; -else if (streq(args[0], list-x11-keymap-options)) -look_for = OPTIONS; -else -assert_not_reached(Wrong parameter); - FOREACH_LINE(line, f, break) { char *l, *w; @@ -444,12 +394,12 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { continue; } -if (state != look_for) +if (!(state look_for)) continue; w = l + strcspn(l, WHITESPACE); -if (n 1) { +if (layout) { char *e; if (*w == 0) @@ -465,23 +415,114 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) { *e = 0; -if (!streq(w, args[1])) +if (!streq(w, layout)) continue; } else *w = 0; - r = strv_extend(list, l); + r = strv_extend(list, l); if (r 0) return log_oom();