Creating configuration model for Kismet

Introduction

Hi everybody!
I’m happy to announce that I have been chosen as a student working on GSoC „Improve Config file Upgrades” project for Debian (mentored by Dominique Dumont). Since it’s my first blog post, it’s time to introduce myself:
My name is Krzysztof Tyszecki and I’m third year CS student at Wroclaw University of Technology (faculty of Fundamental Problems of Technology). I’m using GNU/Linux since about 5 years (Gentoo Linux for about ~4 years, now Debian and Arch).
If after a few months you will simply forget about manually editing configuration files after upgrades, that will mean that this project had succeeded. Dominique nicely described some technical details in post at his blog.

The model

Since the project will use Config::Model, I was asked to create a simple model to familiarize myself with this tool. I decided to create one for my favorite wireless tool – Kismet. Kismet config file has the INI structure, as you may see on the snippet below:

# Version of Kismet config
version=2007.09.R1
# Name of server (Purely for organizational purposes)
servername=Kismet
# User to setid to (should be your normal user)
#suiduser=your_user_here
# Do we try to put networkmanager to sleep?  If you use NM, this is probably
# what you want to do, so that it will leave the interfaces alone while
# Kismet is using them.  This requires DBus support!
networkmanagersleep=true
# Sources are defined as:
# source=sourcetype,interface,name[,initialchannel]
# Source types and required drivers are listed in the README under the
# CAPTURE SOURCES section.
# The initial channel is optional, if hopping is not enabled it can be used
# to set the channel the interface listens on.
# YOU MUST CHANGE THIS TO BE THE SOURCE YOU WANT TO USE
source=none,none,addme
# Users outside the US might want to use this list:
# defaultchannels=IEEE80211b:1,7,13,2,8,3,14,9,4,10,5,11,6,12
defaultchannels=IEEE80211b:1,6,11,2,7,3,8,4,9,5,10
# 802.11g uses the same channels as 802.11b...
defaultchannels=IEEE80211g:1,6,11,2,7,3,8,4,9,5,10

Of course, it’s only a small part of the file. Since I didn’t manage to create a model using config-model-edit, I used Vim, after all a model is just a nice Perl data structure. Part of the results of my work are below:

[
  {
     'read_config' =>  [
                 {
                  'file' => 'kismet.conf',
                  'backend' => 'ini_file',
                  'config_dir' => '/etc/kismet'
                }
              ],
    'name' => 'Kismet',
    'element' => [
            'version',
            {
              'value_type' => 'uniline',
              'summary' => 'Version string',
              'type' => 'leaf',
            },
            'servername',
            {
              'value_type' => 'uniline',
              'summary' => 'Server name',
              'type' => 'leaf',
              'description' => 'Specifies the server name'
            },
            'suiduser',
            {
              'value_type' => 'uniline',
              'summary' => 'User to setid to',
              'type' => 'leaf'
            },
            'networkmanagersleep',
            {
              'value_type' => 'enum',
              'choice' => [ qw/true false/],
              'summary' => 'Try to put NM to sleep when launching Kismet',
              'type' => 'leaf',
              'description' => 'This feature requires  DBus support!'
            },
            'source',
            {
              'type' => 'leaf',
              'value_type' => 'uniline'
            },
            'configchannels',
            {
              'type' => 'leaf',
              'value_type' => 'uniline',
              'match' => 'IEEE80211(a|ab|b|g):(\d,)*\d'
            }
          ]
  },
];

The model is far from being complete, but from now, code for other variables can be easily added. Some variables should be also labeled as mandatory.

The problems

The biggest problem is that, as you may probably see, my model allows only one „source” and „configchannels” variable. It’s because the INI file backend doesn’t support repeated variables. If you run the following Perl code, you will see that Config::Tiny module used for INI parsing reports only one (last) instance of repeated variable:

#!/usr/bin/perl
use Config::Tiny;
use Data::Dumper;
print Dumper(Config::Tiny->new()->read('/etc/kismet/kismet.conf'));

Besides that, I didn’t found a way to check the correctness of the value other than regular expression yet. While regexps are powerful and it’s entirely possible to define constraints using only regexps – sometimes they’re just not the best choice. Ability to define a function that would perform the check would be great.

The GUI Editor

Dominique asked me for some feedback on config-model-edit, since I had a hard time using it. After loading a model created by hand, it’s easy to edit it using aforementioned tool, but creating one from scratch may be a hard task, especially if somebody is using config-model-edit for the first time.
After issuing command „config-model-edit -model Test” and clicking on the root node, user is presented with such screen:

conf-model-edit main window
config-model-edit main window

User can switch between ‚Edit’ and ‚View’ modes using right and left mouse buttons, respectively. This is a nice shortcut, but I think that having a button in UI for that would be a nice usability improvement. Well, after switching to edit mode, situation looks like this:
Editing a model
Editing a model

Color overlays are added by me. Let’s suppose that the user wants to add a configuration class. He clicks the „Add” button and sees an error message with random text:
Everything is obvious now!
Error message

It turns out, that he needs to enter the text in edit field and then hit „Add” (this button should be disabled if there’s nothing in the edit field). This is the biggest usability problem and this was the moment when I thought „Well, I’ll just use plain, old Vim”. Other problems, as seen by me:

  • „Move” and „Copy” (green overlay) buttons are related more to the list box than to the edit field. These buttons could be in a context menu for the list item.
  • If „Move” would be placed in the context menu, instead of renaming highlighted item to the contents of the edit field, it could turn on in-line editing for the list item (I’m not sure if Tk allows this).
  • In my humble opinion, „Rename” is a more suitable name for „Move” button.
  • „Copy” could make a copy of selected item, naming it „Copy #n of _item_” and turn on in-line editing on the newly added item.
  • „Delete selected” and „Remove All” (red) could be placed below the list box or in the context menu.
  • „Are you sure you want to delete all of the items” confirmation box after clicking „Remove All” would be nice.
  • In this case, „Info” box (yellow) takes a lot of space, and it’s contents are not essential.
  • The „keep” checkbox could be a part of the context menu for the edit field.

Of course, current UI may be good once you get used to it and may speedup the process of creating a model. But for a lot of people it can be unnatural and obnoxious. I’m aware that Tk may not be capable of some of proposed changes. Here’s the mockup of the interface as I would seen it (created using Qt Designer):

Quick and dirty mockup
Quick and dirty mockup

If Tk is limiting the GUI then maybe it would be a good idea to create GTK2 based one, since there are Perl bindings available?

    4 thoughts on “Creating configuration model for Kismet

    1. Thanks a bunch for taking the time to comment on the GUI. These are fair comments for real issues that need to be fixed.
      Before writing the GUI, I indeed thought about using a more modern toolkit than Tk, but, unfortunately, I lacked the time to learn other toolkits. I think that most of the issues mentioned can be fixed with Tk.
      Nervertheless, a GTK or Qt or Wx GUI is indeed a nice idea.
      All the best
      Thanks

    2. I’ve just release Config::Model::TkUI 1.307 that fixes most usability issues found by Krzysztof. Unfortunately, Perl/Tk does not provide Listbox with in-place editing so I’ve no easy solution beside a separate entry and a „rename” button.
      All the best

    3. Hi
      I’ve finally found the reason behind the randdom text displayed in the error window.
      In most of my code, I use Exception::Class to treat errors. So error in eval block will set $@ to an Exception::Class object instead of a plain string. Execption class have overloaded „” so when $@ is used in a string, it should do the right thing and call as_string method on the exception.
      I passed $@ to the -text option of Tk::Dialog. Most Tk is actually C code wrapped in XS. I guess that the stringification did not occur before the exception object was handled deep in the C code. So I guess that Tk::Dialog tries to display the inner C structure of the hash ref hidden behind the exception.
      Anyway, the fix is quite simple: explicitely use the as_string method with Tk::Dialog.
      E.g:

           if ($@) {
              $cw -> Dialog ( -title => 'Hash index error',
                             -text  => $@->as_string,
                            )
                -> Show ;
      

    Dodaj komentarz

    Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *