Eugeni's blog

One blog to rule them all. Kinda.

Browsing the topic devel

One of the most asked features for msec was to provide a “summary” screen, which could show the current state of system security to the user without making him go through all the possible security options and system tools.

Since today, this features was added to msecgui, showing the summary for three of the most important parts of system security: the firewall status, security overview and status of system updates.

Summary screen for msec

Of course, we all know that it is cooker version, and it is by no means final point on the UI design and functionalities :) . And, as usual, comments are more than welcome!

As promised in one of the past blog posts, a few more news about msec.

Since 2009.1, msec was supporting an arbitrary number of custom security levels, providing two levels by default: standard, focused on casual desktops, and secure, focused on security-concerned machines. Clearly, this was not covering all the possible use cases, and, while it was possible to create custom security levels for different users needs, few users actually dared to do so.

Starting with 2010.1, msec will provide a larger number of custom, task-oriented security levels. Among such levels, initially are the netbook (focused on low-end machines, running mostly on batteries, with a single local user and no remote accesses); fileserver (focused on a network server, such as SAMBA, NFS, or a database server, where only authenticated users are allowed), and webserver (focused on a web-facing server, attending unauthenticated and unknown users). The idea is to allow users to focus on their specific tasks (e.g., creating a web server, or configuring the netbook), without going too deep into the configuration options.

The msecgui UI was also improved to support those levels, among with user-created custom levels:

Msec levels selection, including the provided levels among with user-created ones

Besides those changes, the UI was simplified a bit thanks to a great cooker discussion and comments from Fabrice Facorat (and will be further improved in newer versions), the support for configuring the log retention period was introduced, and a few bugs were fixed.

More changes are still to be implemented in msec, but I thought that the ones I described in this post are interesting enough to deserve a new msec release.

Stay tuned for future updates!

I just noticed this days that, according to smartctl, the hard disk on my notebook has reached 365 days on Power_On_Hours variable. As the notebook itself has almost 2 years of age (I bought it in March of 2008), it is almost a double birthday-combo :) .

However, at this age, it is obvious that the hard disk of the notebook was not prepared to endure such challenges nicely. Both of its speed (5400 RPMs), durability, capacity, and so on were targeted on a more light use.

On the other hand, the system has 3GB of RAM, which is more than enough for most of my tasks. So after some thinking, I’ve been using some small script to automatically improve the system performance by offloading the most I/O-consuming stuff to RAM for the past few months.

How does it works? Simple. I have a small script which grabs content of a disk directory which I expect to receive heavy use (for example, /usr/lib/firefox, or the rpm BUILD/ directories which receive lots of I/O when building packages, and so on), and converts them into a RAM disk. This way, when anything inside such directory is accessed, it requires absolutely no hard disk I/O, the seek times are non-existent as well, and the throughput is incredible.

For example, if I build mozilla-thunderbird by using real hard disk BUILD directory, it takes almost 2 hours to build. If I use ramdisk for just the BUILD directory, the time required for such task drops down to about 30 minutes. The firefox startup time (both cold and hot – e.g., the first execution and consecutive ones) have the same time of about 1 second; and so on.

So, without further words, this is the script I am using:

#!/bin/bash
#
# This script remounts a directory in tmpfs (ramdisk) to speed it up
#

DIR=$1
SIZE=$2

if [ ! "$UID" = "0" ]; then
    # this script must run by root. Let's try sudo'ing to root..
    exec sudo $0 $*
fi

if [ ! -d $DIR ]; then
    echo "Usage: $0 <full path to a directory>"
    exit 1
fi

if [ "a$SIZE" = "a" ]; then
    OPTIONS=""
else
    OPTIONS="-o size=$SIZE"
fi

# first, copy everything somewhere to reuse it later
TMP=`mktemp`
tar cpf $TMP $DIR

# remount dir as ramdisk
mount -t tmpfs $OPTIONS $DIR $DIR

# unpack everything back
(cd / && tar xpf $TMP)
rm -f $TMP

To use it, just save it under a name like toram and use it on the directory you want to move to ramdisk. The second optional parameter is the size of the ramdisk to use – as by default tmpfs mounts itself with 50% of available ram, sometimes you may want to use more or less memory.

Just some examples on how to use it:

# toram `pwd`/BUILD (will remount current BUILD directory in RAM)
# toram /usr/lib/firefox-3.6 (will remount firefox directory in ram)

I hope this could be useful to someone :) .

It has been quite some time since I last posted here about msec. For the past few weeks, it received some attention and now I guess many of the features I wanted to push for Mandriva 2010.1 are implemented. So I’ll describe the most interesting ones in this blog post (and save some for later :) ).

First of all, starting with Mandriva 2010.1, msec will support user-defined periodicity for all periodic security checks. Therefore, it is possible to specify if each test should be executed daily (like in all previous msec versions), weekly or even monthly. In my opinion, this feature is one of the most interesting among all others, because it allows you to fine-tune the balance between security checks and daily I/O load caused by some expensive checks.

By default, checks which require lots of I/O (e.g., checking for unowned files, or world-writable files, and so on) will run weekly on the standard security level. Why so? Because this check was responsible for approximately 80% of all time required to run the periodic checks, and on most of the machines its results did not differ between consecutive days. Surely, it is nice to have a daily notification of all those changes, but the I/O cost of it is unacceptable high. Of course, you can define the periodicity of all such checks to be daily when you want, by using msecgui application of editing the configuration file manually :) .

Another interesting feature was the de-duplication of variables between main msec configuration file (security.conf) and the level configuration file (for example, level.standard). On previous versions, all variables were defined in security.conf, even if they have exactly the same value as the default one for the current security level. This way, it was easier to see all the configuration at once by looking into /etc/security/msec/security.conf file. On the other hand, it lead to duplication of almost all variables..

So for 2010.1, the behavior when saving the configuration file was modified to be more logical (and similar to the one of msecgui, which displays variables that differ from the default values for the security level in different way). If you want to redefine a variable, just specify it in security.conf and this change will take effect. If you want to disable a variable completely, just define it to an empty value (like, CHECK_SOMETHING=), like in previous versions, and it will be disabled.

To simplify this, we could use the following analogy: in previous msec versions (e.g., 2009.1 and 2010.0), the security.conf file contains the whole security configuration of msec plus the name of the security level which is used as base. In 2010.1, it contains the reference to the base security level plus only the variables which must be overridden for this level. In other words, on Mandriva 2010.1 just by looking at the msec security file it is possible to say “this machine is configured to use the same configuration as on standard security level, except those three checks that should be disabled).

There is yet another reason for this change, which will be described in details when it gets implemented (probably in a few coming weeks). So stay tuned for more news :) .

Another feature was the possibility of running the RedHat sectool checks periodically, among with all other msec checks. Just install sectool package from the contrib, and its checks will be executed automatically by msec.

Additionally, the integration between msec and msecperms applications was improved, making it easier to switch security levels and creating custom levels.

Besides those changes, several msec messages were improved to make them easier to understand by non-geek users :) , and, like usual, several bugs were fixed.

Like always, I am very interested in your feedback on those changed. Please, feel free to drop me a note whether you like these features, dislike them, or any other kind of comments about msec.

From time to time, several questions appear asking about the support for Mandriva products – either with bugfix updates, or the security ones. According to the policy, each update is assigned a specific advisory, which can affect one or more distributions. Besides, each advisory could receive an errata, to correct a regression caused by a previous update. Moreover, most of the updates fall into the bugfix (e.g., fixing some bad behavior or crash or simple improving the application), or security (fixing a security issue which could lead to remote compromising of the system, denial of service or other nasty effects) categories. We also have the general updates category, but this is not that different from bugfix updates, so I’ll count both of them together here.

Now that we are entering the year 2010, I thought that it would be interesting to give you some quick follow-up on how many updates were done during the last few years.

In 2009, there were a total of 436 security updates for all Mandriva-supported packages (e.g., the packages in Main repository), and a total of 288 bugfix updates. The bugfixes are usually provided by the package maintainers, who are responsible for issuing the fix/patch, properly testing the updated package, and send it to the secteam. Secteam does the final validation, signs the package with the update key, and releases the advisory (which is sent to a mailing list and to the Mandriva web site). Later, the packages are sent to the mirrors, and become available to the users.

With security updates, it is a bit different. The entire process is usually handled by the secteam, which is responsible for identifying the security issue, locating the relevant patch or solution, updating and testing the fix, and releasing the updated packages. After that, those updates have a similar fate to the bugfix ones (e.g., signing, releasing the advisory, and so on).

If we look into the detailed numbers, things become quite more interesting:

  • In 2006, we had 67 bugfix updates and 250 security updates. In total, 10769 RPM files were provided as updates.
  • In 2007, there were 144 bugfix updates and 262 security updates, with a total of 17786 updated rpm files
  • In 2008, we had 213 bugfix updates and 264 security updates, totaling 25718 rpms provided as updates
  • And in 2009, there were 288 bugfix updates and 436 security updates, with a total of 41024 rpms provided as updates.

So I’d say that Mandriva users are pretty well supported :) .

A few weeks ago I finally realized my old wish: I bought a real camera for me: a Nikon D40 – which is, according to many, many people, is the best DSLR out there. At least for non-professionals.

With just a few pictures it was already possible to note the difference – I could not ever EVER got close to those pictures with all my previous cameras (like Nokia N95 and Sony CyberShot W90):

Sunset at Angra dos Reis A flower and a tiny bee Rancho Panorama A beautiful flower

However, after a few days with my new camera, I found out that it came with some dust on its sensor. Not much, but clearly visible on pictures with uniform colors (like sky or white wall). For example, it is possible to see the dust spot on the left half of the following picture – if you zoom in, you’ll clearly see that there is some dark spot covering part of a cloud and appearing in the sky:

A lonely tree among clouds A lonely tree 3

One could say ‘Ahh, but that is just a small tiny spot.. nobody will notice it’. But… I do notice it, and I don’t like it. So I started looking for solutions for this issue.

In first place, I tried cleaning the sensor using a air blower (without luck). The dust spot moved a bit with the air flow (a few microns) and landed to its new place (permanently, I afraid). The next step was to ask the official Nikon support in Brazil, which is located in São Paulo city, about 250km from where I live. Their answer was is that the sensor cleaning should cost around R$ 100 (about 60 US$) + shipping. Quite expensive in my opinion.

So the next step was to start thinking like a computer geek. The photo is digital, so it is nothing more than a bunch of bits :) . So there SHOULD be some software or at least algorithm suitable for cleaning this all. After a quick research, I found that there is the Nikon Capture NX software which removes the dust pretty well. However, it is

  • commercial
  • expensive
  • orders you to take photos in RAW only. I like RAW, but… the memory card is not infinite.

So another option was to clean the dust in gimp. Manually… and it is needless to say that this approach is.. well.. boring, time-consuming and pretty much futile.

However, when all the hope was, apparently, lost, the Great Google Gods sent me a wonderful link to the Resynthesizer plugin – which is AMAZINGLY EFFICIENT in solving the dust issues.

So, dear readers, without other words, I’ll show you the few needed steps to fix the dust on your photos:

  1. Install resynthesizer plugin. On Mandriva systems, you can cheat and run a magic urpmi gimp2-resynthesizer command which will do the trick. On other systems, go to the resynthesizer web site, download, compile and install the plugin. it is trivial, so I won’t go into additional details here.

  2. Grab your dust-damaged image and open it in gimp. As you can see, there is a horrible dust on the left part of the otherwise-blue sky:

Gimp with the dust-cleaning victim

  1. Select a region around the dust to remove:

Selecting the dust to remove

  1. Press CTRL-X to remove the selected area:

Removing the dust

  1. Now, select a bit larger region around the white spot:

Selecting some space around the dust spot

  1. Go to Filters->Map->Resynthesize and run the Resynthesize filter:

The Resynthesizer plugin in all its glory

  1. Wait, wait, and…:

Magic!

  1. That’s it!:

A perfect clear sky!

Of course, it all could be done manually in gimp. However, the Resynthesizer plugin just makes it easier and better.

So what is the result? A bit more magic + some Hugin hacking and…:

Panoramic view of Ilha Bela/SP, Brazil

Yes, that’s right. Every image on panorama had a dust spot, which I cleared up with Resynthesizer. So next time you encounter some dust on your photo, remember that there is a GREAT open-source plugin for gimp out there to help!

Enjoy, and have a Happy New Year! :)

Well, the title says it all! Yep, one year has passed since I started working at Mandriva. Since then, it has been about 1100 SVN commits, about 300 closed bugz on bugzilla, around 65 security and bugfix advisories, and hundreds of git commits all around. If you are using Mandriva 2009.1 or 2010.0, you have certainly seen at least a bit of such changes – in msec, drakx-net, netprofile, net_monitor, tomoyo-gui, initscripts, shorewall, and others.

Of course, there also were some cooker breakages as well during this year :) . But, on the other hand, cooker is not fun at all when it is stable (albeit I am using it on my machine constantly).

So far, I can say that it is being a very cool experience :) . Mandriva distributions is getting better and better, and I am very proud of making part of Mandriva team and being able to contribute a bit to its development.

As Mandriva 2010 final release data approaches, the final retouches are being worked out on some of the tools I am taking care of.

Net_monitor has evolved a lot since its first/new release. The interface was compacted, more features added and overall look-and-feel improved considerable.

net_monitor monitoring a wired connection

net_monitor monitoring a wired connection

net_monitor monitoring a wireless ad-hoc connection

net_monitor monitoring a wireless ad-hoc connection

netprofile also received a few updates – most notable, the support for save, load and reset action, and a simple yet functional plymouth integration during boot:

Selecting a profile on boot

Selecting a profile on boot

plymouth2

I don’t know how useful this integration is however (at least, for me). Most of the time my computer is either in suspend or hibernating mode, so I would see this screen about once a month :) .

Working on Mandriva network tools, I looked on one of the most essential ones the network monitor (net_monitor). It was introduced a couple of releases before, and was mostly doing its job. However, it has a number of flaws and lack of features that motivated us to look closer at it.

Our old friend net_monitor, present in your favorite Mandriva distro!

Our old friend net_monitor, present in your favorite Mandriva distro!

The net_monitor currently used in all Mandriva versions is written in perl, is using internal drakx-net api (and is, therefore, only usable on Mandriva), and also have some issues such as memory leaks and non-usual interface. After a few thoughts and discussions we came to conclusion that it would be more adequate to project and rewrite it from scratch, turning it more modular, expansible and focused on common use cases.

Initially, I thought on using perl to write it, so it would still be part of drakx-net suite. However, after thinking on the code and the way it should work I felt that my brain was going to melt down :) (perl is a nice language, but it is certainly not that compatible with me). So I ended up with python, which is my language of choice (together with C). Also, I’ve received many comments saying that the net_monitor is no more relevant, as every desktop environment provides its own network monitoring tool, and it should be dropped from drakx-net. By combining those issues, we came to decision that it would be more proper to separate net_monitor into a different package – this way, it won’t depend on any drakx-net internal functionalities, and user could uninstall it if required and use his own network monitoring tool if he wants to. And, at the same time, users would still have a cute little network monitoring application on their machines.

So, as a picture says more than a thousand words, I guess I’ll just add some pictures here than additional KBs of text :) (EDIT: please note that the look and features of net_monitor have changed significantly in Mandriva since this post):

net_monitor monitoring a wireless connection

net_monitor monitoring a wireless connection

net_monitor monitoring a connection for which network accounting was not enabled

net_monitor monitoring a connection for which network accounting was not enabled

net_monitor displaying some statistics about your network usage (provided by vnstat)

net_monitor displaying some statistics about your network usage (provided by vnstat)

looking at daily traffic statistics on my notebook for the past month

looking at daily traffic statistics on my notebook for the past month

...and hourly statistics...

...and hourly statistics...

...and finding our when I killed my bandwidth..

...and finding our when I killed my bandwidth..

Surely, this is just an early and preliminary version, with many missing features and such. If you want to give it a try, just install net_monitor package, and it will create /usr/bin/net_monitor executable for you. It won’t conflict with existent net_monitor from drakx-net which is installed in /usr/sbin, so both of them may coexist on your system. If you look at /usr/share/doc/net_monitor/TODO, you’ll see some of the ideas that I intend to add to it, but the idea is to keep it simple and not transform it into an emacs of network monitoring :) . And, of course, feel free to add your comments and suggestions (and bug reports) here!

P.S.: Just to prevent comments like ‘you should focus on fixing bugs instead of wasting time writing new things’. Net_monitor is present in Mandriva for years now, and if you look at bugzilla list it has a number of bugs and issues. So I am not creating a new app – I am bringing back from the land of the dead an old one :) .

P.P.S.: Answering in advance to another question – yes, it would work on any Linux distro which has python and pygtk. You’ll just have to add some tricks into your network startup scripts to enable vnstat integration, but it will work just fine even without that.

One of non-trivial tricks involved in web site scalability is the optimization of all image files. One of the sites I am helping to take care of has a front page with more than 350KB in .jpeg images. And, obviously, it takes lots of time to load and, considering the number of accesses, the bandwidth is huge. Usually, those images can be optimized in photo editor, or saved with higher compression or lower quality, but sometimes there is not much else you can do. Or you think so.

One quick trick to improve this situation is by converting some images to png with ImageMagick and running pngcrush on them. A simple script can be used to do so:

    #!/bin/bash
    totalsize=0
    for file in *jpg; do
            # file.jpg becomes file.png
            newfile=${file/jpg/png}
            # convert to png
            convert $file 1.png
            # compact with pngcrush
            pngcrush -brute 1.png $newfile > /dev/null
            # calculate old and new sizes
            newsize=$(wc -c < $newfile)
            oldsize=$(wc -c < $file)
            if [ $newsize -lt $oldsize ]; then
                    echo "$file: reduced from $oldsize to $newsize bytes"
                    # remove old jpg file
                    rm -f $file
                    # replace all references to old file everywhere
                    sed -i -e "s/$file/$newfile/g" *
                    totalsize=$[$totalsize + $oldsize - $newsize]
            else
                    # old file is smaller, remove new file
                    rm -f $newfile
            fi
    done
    echo "total reduction: $totalsize"
    # remove temporary file
    rm -f 1.png

By running it on the website in question, it managed to shrink the front page by about 200KB of image data. Considering 10000 daily accesses, it would save about 2GB of network traffic per day.

Time has come for some msec updates.

With base on previous post, I was working (among other things) on few msec ideas. And now it looks like a good time to put them out to cooker.

First of all, I added support for exceptions into msec periodic check. I wanted to make it as flexible as possible, and I think I managed to implement everything I wanted. Right now, for each supported periodic check, it is possible to define as many exceptions as necessary. So, for example, if you run a local mandriva mirror with unsecure permissions on files, or want to exclude certain rules from firewall check, or some local users that appear unsafe to msec are safe to you, you can tell it to msec, and it will not bother you about it anymore.

For this, /etc/security/msec/exceptions file is used, and it is possible to define as many rules as necessary for each check there. The syntax is quite simple: RULE_NAME exception. To illustrate, that’s what I put into my local exception list on my machine:

CHECK_UNOWNED /home/chroot
CHECK_UNOWNED /home/images/chroot
CHECK_WRITABLE /home/chroot
CHECK_WRITABLE /home/images/chroot
CHECK_OPEN_PORT /deluge
CHECK_USER_FILES gdm
CHECK_OPEN_PORT eugeni:ircd

This way, I won’t receive msec alerts about unowned and world-writable permissions in chroots, about gdm home directory being accessible to the world, and about network ports used by deluge or connected to local ircd server. Each exception is a regexp, so the possibilities are endless.

Of course, it is possible to do it in the gui:

Showing the list of configured exceptions in msecgui

Showing the list of configured exceptions in msecgui

Adding a new exception

Adding a new exception

Besides that, as suggested in the last post, I also added a summary to periodic msec checks. So if you want to have a quick look on the results, you don’t have to read the entire mail.

Also, a few annoying bugs were fixed and few features were added.

But, besides that, I also contacted vdanen, the author of the rsec tool, and the sectool guys about some possible interaction between our projects. Hopefully, we’ll have some news soon.

Meanwhile, enjoy new msec and (as always) feel free to give your feedback over it.

With recent posts by vdanen and adamw, and a recent cooker mailing list thread, it became clear that msec is a very important project/package, and it should deserve much more attention and feedback.

As you probably know, msec underwent a huge redesign for Mandriva 2009.1, and it is getting a lot of attention for 2010.0. But that’s still not enough – even if it became a quite flexible and extensible package, it still has its rough edges, and I intend to solve them all. Of course, it won’t became a perfect package that would rule-them-all, but I intend to get as close to this objective as far as it is humanly possible :) .

So, please, if you use msec, or rsec, or sectool or any other security-concerned framework – please, speak about what you want to see in them, what are the points you are missing, and what features were left unimplemented for the time being.

As for me, I have the following items in the roadmap:

  • implement skip list/exceptions for msec, for every possible test, in a similar way to mandriva bug #53307
  • do my best to provide a nice common source base for both msec and rsec (I hope vdanen would be interested in that as well). Right now it is possible to configure msec to behave exactly as rsec, doing security checks and nothing besides that, but that is not that trivial to do (well.. it is for me, but not for any casual user out there :) ), and it should be beneficial to both projects
  • provide support for sectool plugins in msec – either directly, or by converting them to msec-parseable format
  • work with rsec/sectool/checksecurity/seccheck developers to provide a similar set of features for all those projects. We live in opensource world, and advances in one projects would certainly benefit all of us – specially in such critical area as system security.

So, if you have suggestions, ideas, features or any sort of comments – please, speak. We’ll hear you.

After a very helpful feedback on cooker mailing-list, I decided to post a more in depth screencast which illustrates how netprofile works.

Let’s think about a simple use case. You are using your notebook at home, and everything is fine. However, every time you have to go to work, you have to change several settings related to your network connection, proxy configuration and firewall. Of course, you can do it all manually, or even wrap out a script, but.. there is no need for it with the new netprofile!

So, the goal of this post is to illustrate how to accomplish this task with new netprofile and updated drakx-net applications.

The first thing you have to do is to go to draknetprofile application, and create a new network profile (Update: scroll down to the botton of the post to see the actual draknetprofile screenshots):

draknetprofile graphical interface

draknetprofile graphical interface

When you create a new profile, you have to give it a name (for example, work):

Creating new network profile

Creating new network profile

After you are finished, this new profile will be created and, automatically, activated:

New network profile was created and activated

New network profile was created and activated

From now on, whey you use other drakx-net application, they will detect that you have multiple network profiles, and show you some helpful text to let you know what profile you are using currently. So you can configure your firewall:

firewall configuration with new network profile

firewall configuration with new network profile

Your network connections:

Configuring network settings for new network profile

Configuring network settings for new network profile

Your proxy settings:

proxy configuration for new network profile

proxy configuration for new network profile

And other network settings you want:

network center displaying currently used profile

network center displaying currently used profile

When you go back home, you simply right-click on the net_applet tray icon and activate the default profile again:

net_applet switching profiles

net_applet switching profiles

And this will (almost) instantly restore your settings stored on the default profile:

draknetcenter with default profile

draknetcenter with default profile

You can repeat this procedure for any other profile and configuration. Of course, if you do not want to use netprofile at all, everything will just work.

I hope this clarifies a bit the netprofile application, and how it can help you to simplify your life in different network environment.

EDIT: Updating this post, this is how draknetprofile looks in Mandriva 2010 Beta:

Default netprofile view, with modules details hidden in Advanced section

Default netprofile view, with modules details hidden in Advanced section

Advanced view of draknetprofile, showing modules configuration

Advanced view of draknetprofile, showing modules configuration

After the last-year msec rewrite for Mandriva 2009.1, my goal was to do something similar with netprofile, yet another Mandriva-specific tool, with lots of unique functionalities, but.. abandoned for about 4 years.

What is netprofile? The idea of this application is quite simple. For different network environments one requires different network settings. For example, you may use a fixed IP at home, with firewall disabled, and no proxy. At work, you must use a corporate proxy and a DHCP address for your ethernet connection. And while at a LAN house or Internet cafe, a full-featured firewall must be used, your ethernet connection disabled and a tor proxy (for example) to be in effect.

How to achieve this in a working system? Usually you must manually reconfigure the network settings, edit configuration files for network, firewall and proxy, and so on. And this is where netprofile comes into action.

The netprofile uses the concept of network profiles to represent different network environments. You start with the ‘default’ profile, and you may use your system normally. If you want to setup a different network environment, you may ’switch’ to a different profile (a new profile will be created if necessary). Your current settings will be saved to your previous profile, and all changes to system configuration will now apply to your new profile.

To illustrate:

  • You configure your system to use fixed IP address and a specific firewall configuration.
  • You go to work, where different network environment takes place. You switch to the work profile (‘netprofile switch work’, or using net_applet gui), and if it is the first time you use this profile, it is created with base on your current settings.
  • You configure your network card to use DHCP, configure your corporate-specific proxy and firewall settings, and continue using your machine normally.
  • When you come back home, you switch the profile back to default, and your previous settings are restored.

You may also specify what network profile to use on boot, by passing the ‘PROFILE=‘ option to the boot loader. If you have multiple profiles, and no boot parameter was specified, a menu dialog will appear on boot asking you to select the profile to use.

The new netprofile is based on modular architecture. While we have a core application (netprofile), all functionality is performed by modules. Right now we have the following modules:

  • network – to store/restore network settings: ethernet, ppp, isdn, wireless and other connection settings.
  • firewall – to manage firewall (iptables and shorewall) settings
  • firewall6 – to manage firewall settings for IPv6 networks
  • proxy – to manage system-wide proxies.

Also, I am thinking on the following modules:

  • netfs – to manage remote shares and network file systems. For example, at work you may access a centralized NFS server, and at home a SMBFS/CIFS connection to your home server.
  • authentication – you may use local users at home, and ldap/yp authentication at work. Transparently. With one mouse click/command to switch between them :) .

The inevitable question: why do we need it if we have NetworkManager and similar apps? Well, I have a few arguments:

  • NetworkManager is great, has a modular design, and also supports network profiles. However, it is focused on network settings only, and not on proxy, firewall, authentication, and so on.
  • NetworkManager is also based on a pluggable architecture. However, it is not that easy to write plugins for it.
  • Not all distributions support NetworkManager. Netprofile, on its turn, will work on any unix system (or, even better, on anything that support running shell scripts. Yes, you can use it on windows too, with a few hacks :) ). Of course, it works better on Mandriva because it has drakxtools – Mandriva-specific scripts and applications. And we have draknetprofile as part of drakxtools, which works as shown on the following screenshot:
draknetprofile application to control netprofile profiles in Mandriva Linux

draknetprofile application to control netprofile profiles in Mandriva Linux

That’s it for now. If you want to experiment with netprofile, feel free to download it and play with it. It should be available on next Mandriva Linux 2010.0 release together with many other exciting new features :) !

I just finished quake4, and I am playing (again) doom3 on Linux right now. It feels great – so if anyone wants to say that there are no games on Linux, I could just show the list of some of the games I played this year and found quite impressive:

  • Nexuiz
  • OpenArena
  • Doom3
  • Quake4
  • World of Goo (this one actually managed to keep me awake until 5am for a few days)
  • Caster
  • Cube

and, besides those, we still have wine which plays most of the games just fine (except some of the bleeding edge ones, and the ones which are hurt by the the-f**ing-hating-mouse-rotation-bug like call of duty 4).

But.. even with all that progress, I miss the good old games. Of course, Crysis, Assassin’s Creed, Call of Duty 1/2/3/4, Dead Space and all other thousands of recently released games look pretty amazing, but I feel that most of modern games are not even close to the old ones. I still remember being awake for 24+ hours playing Baldur’s Gate, and loosing some of the faculty exams because of the Baldur’s Gate 2. And I’ll probably never forget how scary it was to play Doom on a 386 in a dark room. Nor wolfenstein 3d on a 286 for the first time. And, speaking about game story, few games came close to Baldur’s Gate, Planescape: Torment, Fallout 1/2, Final Fantasy VII (a.k.a. how-you-felt-when-Ariel-died??)/VIII..

But, speaking of 3d-shooters. The best so far (at least, for me) are: Doom, Doom 2, Heretic, Hexen, Duke3D/Blood/Shadow Warrior, Serious Sam 1/1.5/2, Half-Life, Prey, Quake1/2/4, …. Most (all?) of those games are based on the same concepts we have seen in early 90ths. I could mention Halo/Gears of War, which introduced some changes in the gameplay, but not that much to say that it was a break-through. You still keep walking around, grabbing new weapons (and dropping less useful ones, like in Medal of Honor/Call of Duty/Halo/…), killing stronger and more stronger enemies, and that’s it. Occasionally there are some innovations, like portals and gravity (Prey) or maybe some sort of character development (Daikatana, Call of Duty, Unreal Tournament) or time/physics manipulations (Half-Life 2) and environment interaction (Doom 3, Unreal Tournament), but nothing ground-breaking.

So far, I am feeling like the progress stopped in the way the games are developed. We have new physics, graphics, sounds, polygons and so on, but few games are introducing something truly new. On the other hand, maybe we have reached the point when everything is already implemented, and the games just have to focus on the state-of-the-art graphics only, and forget about all other items..

So, if you read so far, what do you think about that? Are there any modern games which are truly outstanding (and run on Linux – either natively or using wine)? I promise to test all the suggestion and post my impressions on this blog.

As promised in the previous post, here come some first insight into the GUI for Tomoyo Linux, which will be present in Mandriva 2010.

Initial view

Initial view

Active security domains

Active security domains

As far as I know, this is the first GUI for Tomoyo out there (except the TomoyoGUI Eclipse Plugin, but it seems to be quite eclipse-bound and abandoned. Its page is in Japanese, but the all-mighty google translator helped me to take a peek into it). But, of course, I might be wrong – so please let me know if you know of any other GUI for Tomoyo Linux.

Obviously there are still a lot of things to do:

  • add support for auditing/tomoyo security log into msec
  • add support for reloading profile on-the-fly
  • saving/loading/changing settings on the fly
  • support complex statements
  • everything else

so keep an eye on this blog for more news.

Regards, Dr. Eugeni :)

Time has come for the first msec release since Mandriva 2009.1!

This time we have several improvements, such as:

  • support for audit plugins
  • more msec auditing checks
  • improved auditing logging
  • and, of course, bugfixes.

So let me introduce some details about each one of them.

Support for audit plugins

You may remember that msec shipped with Mandriva 2009.1 introduced support for plugins infrastructure (take a look at your /usr/share/msec/plugins/ directory to see some examples). This new msec, which will be shipped with Mandriva 2010, also introduces auditing plugins.

Well, you might be asking what the ..? what is the difference between those plugins?, so let me clarify it a bit.

Msec has two main functionalities:

  • Security configuration
  • Security auditing

The security configuration is what you configure using msecgui or using security levels – basically, you say what settings should be used on your machine for ssh, user logins, and all kind of system configuration. The security auditing are those background checks that run daily on your machine, to determine what has changed since the last run and let you know about that.

In old msec, this security auditing was performed by security.sh, security_check.sh and diff_check.sh, so we had just three large and complex files with a lot of duplicated code. With new msec version, everything was split to reduce code duplication, improve readability and simplify plugins creation.

Let me show you a sample plugin which checks for changes in system users:

    #!/bin/bash
    # msec: check for changes in local users

    # check if we are run from main script
    if [ -z "$MSEC_TMP" -o -z "$INFOS" -o -z "$SECURITY" -o -z "$DIFF" ]; then
            # variables are set in security.sh and propagated to the subscripts
            echo "Error: this check should be run by the main msec security check!"
            echo "       do not run it directly unless you know what you are doing."
            return 1
    fi

    # files to log the list of today's and yesterday's, and difference between them
    USERS_LIST_TODAY="/var/log/security/users_list.today"
    USERS_LIST_YESTERDAY="/var/log/security/users_list.yesterday"
    USERS_LIST_DIFF="/var/log/security/users_list.diff"

    # update yesterday's list
    if [[ -f ${USERS_LIST_TODAY} ]]; then
        mv ${USERS_LIST_TODAY} ${USERS_LIST_YESTERDAY};
    fi

    # check for changes in users
    if [[ ${CHECK_USERS} == yes ]]; then
        getent passwd | cut -f 1 -d : | sort > ${USERS_LIST_TODAY}
        Diffcheck ${USERS_LIST_TODAY} ${USERS_LIST_YESTERDAY} ${USERS_LIST_DIFF} "local users"
    fi

that’s it. You just drop this file into /usr/share/msec/scripts/01_check_for_users.sh and this check will be executed every time msec security checks are run. The security log will be updated, the diff check mail will be created and mailed (along with all other checks), and it will be working automatically from now on.

More msec auditing checks

A few additional msec auditing checks were added:

  • CHECK_FIREWALL — checks for changes in iptables configuration
  • CHECK_USERS — checks for changes in local users (most of its code was shown above actually)
  • CHECK_GROUPS — checks for changes in local groups
  • FIX_OWNER — if unowned files are found on the system, this check gives the opportunity to change their ownership to nobody/nogroup, instead of blindly doing it automatically
  • CHECK_RPM_PACKAGES — checks for changes in installed RPM packages
  • CHECK_RPM_INTEGRITY — checks all the installed packages for changed files. Both those checks were run before under the CHECK_RPM check, but, as they are quite expensive, these two new checks were introduced instead

If you are using cooker or 2010 alpha, these options will not be added automatically to your /etc/security/msec/security.conf configuration file. The best way to experiment with them is by using msecgui, or running msec -f standard or msec -f secure to install default configuration for standard and secure levels.

Besides those items, I was thinking on an option to check for changes in PAM authentication, check for failed login attempts and support for rkhunter. And, as always, if you have any idea on some other functionality that should be interesting to have in msec, feel free to comment!

Improved auditing logging

The logging format of /var/log/security.log was changed to be compatible with syslog-based logging. This should make it easier for system applications to parse it, and for administrator to examine its contents. Now it is way easier to find information by date, kind of message and check type.

Other ideas

Among other ideas for msec I thought on the following:

  • msec supports an arbitrary number of custom security levels, but msecgui only supports two basic ones (standard and secure). It could be nice to have a combobox to select a custom profile..
  • gui for TOMOYO security framework, since the AppArmor project looks quite stone-cold dead. This is already a work in progress, so probably I’ll post some update on this later.
  • Support for administrator-supplied rules for security and diff checks. For example, to exclude everything matching ‘/var/tmp’ from any kind of checks and reports, or excluding network ports from 3000 to 5000 from open port checks.

Besides that, there is a number of bugfixes (which are going to be backported to 2009.1 shortly).

So msec is definitely is alive and getting better and better. Stay tuned for more news! :)

Well, this question appeared quite frequently to me. However, I never bothered with it, as I was either on a LAN, or had a different source from which I could resume using wget, or a file was sufficiently small to redownload it again. However, this time these approaches did not work:

  • The file was big (a DVD ISO)
  • The only way to access it was over a SSH connection
  • The only authentication method it supported was public key authentication
  • The directory from where the file was downloaded was read-only
  • The link was sloooow
  • I already had downloaded about 70% of the file

So I started looking for solutions. Most of ideas I found on google suggested using ‘rsync –partial –rsh=ssh‘, and indeed it could work. However, rsync tried to create a temporary file on the server, and, as the directory was read-only, it failed. There probably is some option to make it work, but I don’t have plenty of rsync experience. And this approach just looked to be over complicated.

After a bit of more googling, I found out that curl supported sftp backend. And, after a few minutes trying to figure out how to make it work with public key authentication, I finally figured it out:

curl -C - --pubkey ~/.ssh/key.pub --key ~/.ssh/key \
  sftp://eugeni@somewhere/mnt/.../i586/my_precious_iso.iso \
  -o my_precious_iso.iso

To shorten it up, it is possible to write a simple wrapper function (or a script) for bash:

#!/bin/bash
function scp_resume() {
        URL="$1"
        FILE="$2"
        if [ "a$FILE" == "a" ]; then
                echo "Usage: scp_resume <sftp url> <local target>"
                return 1
        fi
        # the magic
        curl -C - $URL -o $FILE
}

function scp_resume_key() {
        URL="$1"
        FILE="$2"
        KEY="$3"
        if [ "a$FILE" == "a" ]; then
                echo "Usage: scp_resume <sftp url> <local target> <key file name>"
                return 1
        fi
        # the magic
        curl -C - --key $HOME/.ssh/$KEY --pubkey $HOME/.ssh/${KEY}.pub $URL -o $FILE
}

so it did the trick.

I wondered why my .git directory of drakx-net was using about 70MB of disk space (I am accessing the SVN repository using git svn). Of course, I have read that periodic git repository clean could drastically save space and speed, but – what the heck – it is just a bunch of text files. So I never bothered with it.

However, after running git gc on top of drakx-net directory, the .git directory size went from 70MB down to 4MB. A 17.5x improvement! Unbelievable!

So I did the same to msec repository, with quite similar results — from 21MB down to 3MB!

So a mental note to myself – run git gc always. It rocks.

I am using MPD to play my small collection of mp3:

[eugeni@eugeni 16:53:31 ~] $ mpc stats
Artists:    787
Albums:     747
Songs:     9112

Everything is controlled by keybinding – for example, to run the play command, I press < Super >+Up; to run next command I press < Super >+Right, and so on. These shortcuts start a small client to mpd, which is nothing more than a shell script which:

  1. Starts MPD if it is not running (I do not start it on startup to save a few seconds of boot time)
  2. Runs mpdscribble in background to update the LAST.FM statistics
  3. Runs all required MPD commands
  4. And displays the results in a nice way

And it is multi-distro-oriented by the way :) .

    #!/bin/bash

    # Is mpd running
    mpc status 2> /dev/null
    ret=$?
    if [ ! "$ret" = "0" ]; then
            notify-send -i audio "Music" "Starting mpd.."
            # are we on arch linux?
            if [ -x "/etc/rc.d/mpd" ]; then
                    sudo /etc/rc.d/mpd start
            else
                    sudo su -c "service mpd start"
            fi
            # starting mpdscribble
            mpdscribble
           # starting sonata
            sonata --hidden
    fi

    mpc $*
    # Some black magick to get a bit more advanced mpd status
    # and convert it to shell variables
    eval `echo -e 'status\ncurrentsong\nclose\n' | \
        nc localhost 6600 | \
        sed -e '/OK/d' -e 's/: \(.*\)/="\1"/g'`
    # show the results
    notify-send -i audio "$Artist - $Album - $Title" \
        "$(mpc status | sed -e 's/&/and/g')"

Just yet one another script which contributes to world’s entropy :) .

One of most wanted features for new MSEC in Mandriva 2009.1 was the support for plugins. It is an interesting idea, as it allows to convert MSEC from a tool with fixed-and-controlled-by-msec-gods list of features into a utility that can be extended by anyone, adding their own functionality, or just implementing something specific to their organization, class, or environment.

Well, starting today, it is possible to do so :) . I just committed into cooker a new version of msec which supports plugins, and fully integrates them with other msec modules. I added a “sample” plugin (which will someday become the AppArmor plugin, but.. as it is still not working in cooker, I just added it to use as a proof-of-concept).

Plugins are automatically loaded by libmsec on startup, checking for all entries in config.PLUGINS_DIR configuration variable (which defaults to /usr/share/msec/plugins). For each file there, it is parsed as a python script, the plugin name is determined, and a plugin class is initialized with current msec settings (such as logging backend, chroot’ed configuration and list of modified system files). After that, the plugin is automatically added into the config.SETTINGS array, which correlates msec variables (such as ENABLE_APPARMOR) with corresponding callback function (libmsec.somefunction or, in our case, apparmor.enable_apparmor) and list of valid parameters (in our case, yes and no).

After that, everything continues normally. Msec processes the configuration parameters as usual, until it gets to the ENABLE_APPARMOR parameter. At this point, it detects that this functionality is provided by the apparmor plugin, and it is handled by enable_apparmor function. So it simply calls this function, in exactly the same way as any other libmsec element.

To show how simple a msec plugin can be, the following is the complete code of (not yet functional) AppArmor plugin:

#!/usr/bin/python
"""AppArmor plugin for msec """

# main plugin class name
PLUGIN = "apparmor"

# msec configuration
import config

class apparmor:
    def __init__(self, log=None, configfiles=None, root=None):
        """Initializes AppArmor plugin"""
        # initializing plugin with libmsec data
        self.log = log
        self.configfiles = configfiles
        self.root = root

        # configuring entry in global settings
        param = 'ENABLE_APPARMOR'
        callback = "%s.enable_apparmor" % PLUGIN
        valid_values = ['yes', 'no']
        config.SETTINGS[param] = (callback, valid_values)

        # insert entry into system security settings
        config.SETTINGS_SYSTEM.append(param)

    def enable_apparmor(self, params):
        """Enable AppArmor security framework on boot"""
        if self.log:
            #self.log.info("AppArmor plugin: not implemented yet!")
            pass

That’s it. Any python functionality can be added to the enable_apparmor function afterwards.

This is more like a proof-of-concept than complete plugin, but the remaining pieces will be polished soon. Keep visiting here for news :) .

Combining this with the possibility of creating custom msec frontends (right now we have command line frontend (msec) and a graphical one (msecgui)), the possibilities are endless. You could create a WEB frontend with just a few lines of python code (for example, using web.py or django), add plugins which enforce settings for your organization (for example, configure all user home directories to start with “user_” prefix, check periodically for changes into /usr/local/big_project/* files, synchronize ldap databases for offices, and so on).

Ultimamente eu uso bastante programação funcional em python para tudo. Entretanto, fiquei brincando hoje e descobri que nem sempre ela oferece os melhores resultados.

Por exemplo, vamos imaginar a função que vai fazer todas as combinações entre os elementos de uma lista. Ela pode ser escrita de forma funcional:

# permutate-func
def permutate(l):
    '''Returns all possible combinations of list values'''
    return reduce(lambda x, y: y + x, [ [(x, y) for y in l if x != y] for x in l ])

ou de forma iterativa:

# permutate-iter
def permutate(l):
    '''Returns all possible combinations of list values'''
    res = []
    for x in l:
        for y in l:
            if x != y:
                res.append((x, y))
    return res

Para listas pequenas não temos muita diferença de desempenho. Agora para listas maiores (por exemplo, com 1000 strings):

dups=['string%d' % x for x in range(1000)]
permutate(dups)

temos os seguintes resultados para programação funcional:

# time permutate-func
real    0m24.494s
user    0m20.763s
sys 0m1.698s

e os seguintes para o algoritmo iterativo:

# time permutate-iter
real    0m1.191s
user    0m1.150s
sys 0m0.036s

O tempo de 24 segundos caiu para apenas 1 segundo!

Qual conclusão tiramos disso? Embora programação funcional é extremamente poderosa, em alguns casos é melhor usar outras soluções para o problema :) .

Descobri mais uma utilidade para os decorators em python:

import threading

class Thread(threading.Thread):
    def __init__(self, f):
        threading.Thread.__init__(self)
        self.run = f

@Thread
def func():
    print "Hello world!"

func.start()

Jeito simples e eficientes para criar funções threadizadas.

Update: É possível otimizar esse código para não precisar escrever .start() na mão, e deixar as funções compatíveis com a sua versão não-threadizada:

class Thread(threading.Thread):
    def __init__(self, f):
        threading.Thread.__init__(self)
        self.run = f

    def __call__(self):
        return self.start()

@Thread
def func():
    print "Hello world!"

func()

O que a falta do que fazer não faz..

Estava eu, feliz e contente, usando Arch Linux (que, por definição, só vem com pacotes mais recentes) durante os últimos 2 anos, junto com o firefox-nightly compilado manualmente. Mas, recentemente, passei para mandriva 2009. Mas.. senti que falta alguma coisa nele. Como Mandriva 2009 é uma versão “estável”, as coisas novas demoram para aparecer.. O problema de firefox foi fácil de se resolver (já tem todos os scripts prontos para compilá-lo mesmo), mas e os outros pacotes??

A decisão foi passar para o cooker – versão unstable do Mandriva. Precisou baixar 700MB de pacotes, atualizar metade do sistema, e remover alguns dos programas que eu uso direto (por exemplo, texlive-latex e xfce-cpufreq-plugin). Mas nada impossível de resolver na mão. E também, alguns dos meus softwares favoritos do Arch não estavam inclusos na distro (mas também, nada que um rpmbuild não resolva).

O que eu tiro como conclusão parcial? Que o esquema de pacotes de Arch é o melhor que todos os outros, de longe! Mas, com um pouco de sacrifício, dá para se acostumar com os SPEC’s, e criar RPMs na mão.

Agora estou de volta à vida on-the-bleeding-edge!

Depois de um longo tempo, descobri onde que residem os exploits do wordpress. De maneira similar aos viruses dos anos 80/90, eles infectam alguns arquivos .php com o seu código (que é obfuscado, criptografado e compactado diversas vezes – o recorde que eu vi foi de 11 vezes!!).

Geralmente, se você encontrar um código similar a esse:

eval(gzinflate(base64_decode('FJ3HcqPsFkUf53YVA3IakoPIGSa3yCByDk//y5MeuO2yxXfO3mvZEirPtP9Xv...

você foi infectado.

Para descobrir todos os arquivos infectados, o seguinte comando é suficiente:

find . -type f -iname '*.php' -exec grep -q -i 'eval(gz' {} \; -print

Depois é melhor ir vendo um-por-um esses arquivos.

Esse código tem dentro de sim um exploit muito bem feito. Uma boa descrição dele pode ser vista aqui

Agora espero que resolvi esse problema definitivamente.

Quem usa o netspeed-applet do gnome e atualizou ele para versão 0.15, descobriu que esta versão não permite mais modificar o tamanho da fonte. Para mim isso é essencial (as fontes que vem pode padrão são muito grandes), por isso decidi fazer um patch para dar suporte a isso.

Para quem usa ArchLinux, o PKGBUILD já está no AUR :) .

Para quem não usa ele, esse é o patch:

netspeed-applet with editable font size option

diff -ru netspeed_applet-0.15.2/src/netspeed.c netspeed_applet-0.15.2.fontsize/src/netspeed.c
--- netspeed_applet-0.15.2/src/netspeed.c   2008-09-13 16:59:52.000000000 -0300
+++ netspeed_applet-0.15.2.fontsize/src/netspeed.c  2008-10-23 14:57:41.000000000 -0200
@@ -85,6 +85,7 @@
    gboolean show_sum, show_bits;
    gboolean change_icon, auto_change_device;
    GdkColor in_color, out_color;
+   int font_size;
    int width;

    GtkWidget *inbytes_text, *outbytes_text;
@@ -664,8 +665,11 @@

    /* Refresh the text of the labels and tooltip */
    if (applet->show_sum) {
+       add_markup_size(&applet->devinfo.sum_rate, applet->font_size);
        gtk_label_set_markup(GTK_LABEL(applet->sum_label), applet->devinfo.sum_rate);
    } else {
+       add_markup_size(&applet->devinfo.rx_rate, applet->font_size);
+       add_markup_size(&applet->devinfo.tx_rate, applet->font_size);
        gtk_label_set_markup(GTK_LABEL(applet->in_label), applet->devinfo.rx_rate);
        gtk_label_set_markup(GTK_LABEL(applet->out_label), applet->devinfo.tx_rate);
    }
@@ -891,6 +895,7 @@
    return;
     }
     panel_applet_gconf_set_string(PANEL_APPLET(applet->applet), "device", applet->devinfo.name, NULL);
+    panel_applet_gconf_set_int(PANEL_APPLET(applet->applet), "font_size", applet->font_size, NULL);
     panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "show_sum", applet->show_sum, NULL);
     panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "show_bits", applet->show_bits, NULL);
     panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "change_icon", applet->change_icon, NULL);
@@ -901,6 +906,15 @@
     applet->settings = NULL;
 }

+/* Set the font size to the new value
+ */
+static void
+font_size_adjust_cb(GtkSpinButton *spinbutton, NetspeedApplet *applet)
+{
+   applet->font_size = gtk_spin_button_get_value_as_int(spinbutton);
+   applet->width = 0;
+}
+
 /* Called when the showsum checkbutton is toggled...
  */
 static void
@@ -944,7 +958,12 @@
    GtkWidget *category_header_label;
    GtkWidget *network_device_hbox;
    GtkWidget *network_device_label;
+   GtkWidget *label_font_size_hbox;
+   GtkWidget *label_font_size_hbox2;
+   GtkWidget *label_font_size_label;
+   GtkWidget *label_font_size_spinbutton;
    GtkWidget *indent_label;
+   GtkWidget *points_label;
    GtkWidget *show_sum_checkbutton;
    GtkWidget *show_bits_checkbutton;
    GtkWidget *change_icon_checkbutton;
@@ -1033,6 +1052,31 @@
    gtk_combo_box_set_active(GTK_COMBO_BOX(applet->network_device_combo), active);
    g_object_set_data_full(G_OBJECT(applet->network_device_combo), "devices", devices, (GDestroyNotify)free_devices_list);

+   label_font_size_hbox = gtk_hbox_new(FALSE, 6);
+   gtk_box_pack_start(GTK_BOX(controls_vbox), label_font_size_hbox, TRUE, TRUE, 0);
+
+   label_font_size_label = gtk_label_new_with_mnemonic(_("Label _font size:"));
+   gtk_label_set_justify(GTK_LABEL(label_font_size_label), GTK_JUSTIFY_LEFT);
+   gtk_misc_set_alignment(GTK_MISC(label_font_size_label), 0.0f, 0.5f);
+   gtk_size_group_add_widget(category_label_size_group, label_font_size_label);
+   gtk_box_pack_start(GTK_BOX(label_font_size_hbox), label_font_size_label, FALSE, FALSE, 0);
+   
+   label_font_size_hbox2 = gtk_hbox_new(FALSE, 6);
+   gtk_box_pack_start(GTK_BOX(label_font_size_hbox), label_font_size_hbox2, TRUE, TRUE, 0);
+   
+   label_font_size_spinbutton = gtk_spin_button_new_with_range (5.0, 32.0, 1.0);
+   gtk_spin_button_set_value(GTK_SPIN_BUTTON(label_font_size_spinbutton), (double) applet->font_size);
+   gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(label_font_size_spinbutton), TRUE);
+   gtk_spin_button_set_digits(GTK_SPIN_BUTTON (label_font_size_spinbutton), 0);
+   gtk_label_set_mnemonic_widget(GTK_LABEL(label_font_size_label), label_font_size_spinbutton);
+   gtk_box_pack_start(GTK_BOX(label_font_size_hbox2), label_font_size_spinbutton, TRUE, TRUE, 0);
+   
+   points_label = gtk_label_new(_("points"));
+   gtk_label_set_justify(GTK_LABEL (points_label), GTK_JUSTIFY_LEFT);
+   gtk_misc_set_alignment(GTK_MISC (points_label), 0.0f, 0.5f);
+   gtk_size_group_add_widget(category_units_size_group, points_label);
+   gtk_box_pack_start(GTK_BOX (label_font_size_hbox2), points_label, FALSE, FALSE, 0);
+   
    show_sum_checkbutton = gtk_check_button_new_with_mnemonic(_("Show _sum instead of in & out"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_sum_checkbutton), applet->show_sum);
    gtk_box_pack_start(GTK_BOX(controls_vbox), show_sum_checkbutton, FALSE, FALSE, 0);
@@ -1048,6 +1092,9 @@
    g_signal_connect(G_OBJECT (applet->network_device_combo), "changed",
             G_CALLBACK(device_change_cb), (gpointer)applet);

+   g_signal_connect(G_OBJECT (label_font_size_spinbutton), "value-changed",
+            G_CALLBACK(font_size_adjust_cb), (gpointer)applet);
+
    g_signal_connect(G_OBJECT (show_sum_checkbutton), "toggled",
             G_CALLBACK(showsum_change_cb), (gpointer)applet);

@@ -1343,6 +1390,30 @@
    }
 }  

+/* Tries to get the desktop font size out of gconf
+ * database
+ */
+static int
+get_default_font_size(void)
+{
+   int ret = 12;
+   char *buf, *ptr;
+   
+   GConfClient *client = NULL;
+   client = gconf_client_get_default();
+   if (!client)
+       return 12;
+   buf = gconf_client_get_string(client, "/desktop/gnome/interface/font_name", NULL);
+   if (!buf)
+       return 12;
+   ptr = strrchr(buf, ' ');
+   if (ptr)
+       sscanf(ptr, "%d", &ret);
+   g_free(buf);
+       
+   return ret;
+}
+
 static gboolean
 applet_button_press(GtkWidget *widget, GdkEventButton *event, NetspeedApplet *applet)
 {
@@ -1526,6 +1597,7 @@
    applet->show_sum = FALSE;
    applet->show_bits = FALSE;
    applet->change_icon = TRUE;
+   applet->font_size = -1;
    applet->auto_change_device = TRUE;

    /* Set the default colors of the graph
@@ -1553,6 +1625,9 @@
        applet->show_bits = panel_applet_gconf_get_bool(applet_widget, "show_bits", NULL);
        applet->change_icon = panel_applet_gconf_get_bool(applet_widget, "change_icon", NULL);
        applet->auto_change_device = panel_applet_gconf_get_bool(applet_widget, "auto_change_device", NULL);
+       applet->font_size = panel_applet_gconf_get_int(applet_widget, "font_size", NULL);
+       if (!applet->font_size)
+           applet->font_size = -1;

        tmp = panel_applet_gconf_get_string(applet_widget, "device", NULL);
        if (tmp && strcmp(tmp, "")) 
@@ -1587,6 +1662,9 @@
        }
    }

+   if (applet->font_size < 1)
+       applet->font_size = get_default_font_size();
+   
    if (!applet->devinfo.name) {
        GList *ptr, *devices = get_available_devices();
        ptr = devices;

Um pequeno truque para melhorar a velocidade do startup do firefox:

/usr/bin/firefox:

#!/bin/bash
# Preloads and starts firefox

# preload profile for faster in-memory access
tar cf /dev/null $HOME/.mozilla/firefox --exclude '*/Cache/*'

exec /usr/local/firefox/firefox $*

Com isso, o perfil do firefox é carregado na memória antes de iniciar o executável, o que evita diversos seeks que ele faz. E, como já é bem conhecido :) , os seeks dos discos ATA/SATA são responsáveis por  mais de 70% de perda de desempenho de I/O.

Update: o firefox 3 também utiliza sqlite3 para muitas coisas. Com o passar do tempo, entretanto, a base dele tende a aumentar para infinito. Mesmo limpando o histórico, cache, dados de privacidade, etc, o arquivo do BD continua muito fragmentado – o que, por sua vez, resulta em muitos seeks desnecessários.  Para otimizar isso, de tempos em tempos (com firefox desligado) dá para rodar esse script:

 find $HOME/.mozilla/firefox -type f -name ‘*.sqlite’ -exec sqlite3 {} vacuum \;

Isso vai desfragmentar todos os arquivos .sqlite do firefox (places, saved forms, favicons, etc). Se o seu firefox dá umas travadas periódicas ao tentar digitar algum endereço, ou ao mostrar os bookmarks, ou simplesmente começa a mexer no disco sem nenhum motivo aparentente, você definitivamente precisa rodar esse comando!

Pois é – é possível fazer uma implementação completa de rede peer-to-peer usando somente 15 linhas de python (com um pouco de gambiarras envolvendo lambdas :) ).

Slashdot | World’s Shortest P2P App: 15 Lines

Impressionante.. como tudo em python!

Continuando a temporada de lançamentos, nesse fim da semana saiu Firefox 3 RC1. Com isso, podemos dizer que nas próximas semanas (de acordo com o cronograma de Mozilla), vamos ter a versão final do Firefox 3.0.

Eu estou usando ele desde o fim do ano, nas versões conhecidas como “nightly” (com codenome “minefield“) – são as versões compiladas diariamente. Isso tem lados positivos e negativos – entre os positivos, o desempenho dessas versões geralmente é significativamente superior ao das mais oficiais. Entre os negativos – vire e mexe algo para de funcionar (por exemplo, gmail, acentos, teclado, etc, etc). Mas em geral eu gostei da experiência que eu tive com os nightlies.

Porém, recentemente – já faz aproximadamente 1 mês -  ele tem 2 problemas extremamente irritantes:

  1. O acesso ao chrome (i.e., páginas “internas” do browser) foi desabilitado. Com isso, extensions como yardvark (para remover partes das páginas – tipo banners, fontes ilegiveis, etc) e webdeveloper (caixinha mágica dos web-developers :) ) pararam de funcionar. Enquanto o webdeveloper – de acordo com o site do seu criador – ainda tem esperança, o outro aparentemente não vai ser atualizado no futuro previsível…
  2. Os atalhos (alt-número) para trocar de tabs pararam de funcionar de vez no Linux. Isso é mais de que irritante. Inclusive eu achei o commit que quebrou isso, mas, apesar da minha experiência com o código do mozilla, não estou nem um pouco animado a mexer com isso.. hehehe

Mas, fora isso, o desempenho dos nightlies é mais de que suficiente, e qualidade de renderização também.

E, por falar em desempenho.. Acredito que muitos já perceberam que o Firefox para windows ganhou um speedup de até 4x na renderização de páginas, javascript, e funcionamento em geral. Tudo isso foi possível graças ao PGO (profile-guided optimizations) – técnica nova que apareceu nas últimas versões do GCC (junto com uma multidão de problemas, o gcc também trouxe coisas boas nas versões mais recentes :) ). Entretanto, só versões para windows são compiladas com esse suporte; as de Linux não.

Eu tentei dar uma chance a essa técnica – já que o Arch Linux, que estou usando no último ano-e-pouco, tem facilidade muito grande para criação de pacotes otimizados. E, realmente, a diferença de desempenho é MUITO grande. Não vou colocar nenhum benchmark nem nada aqui, só a minha opinião subjetiva. E ela é:

LIGUE JÁ O PGO!

hehehe.

(se você quer ver um benchmark, dê uma olhada aqui por exemplo -Firefox 3 ainda mais veloz | Open Mania).

E é isso. De forma geral, o firefox 3 parece ser muito melhor que o 2, vamos esperar o release final!

Só um pequeno resumo de vantagens e desvantagens de sistemas de controle de versões distribuídos que eu já cheguei a usar.

  • SVN + SVK – parecido com SVN, tem os mesmos problemas que ele (cria um monte de diretórios, etc). Na minha opinião, não tem muito uso prático – é melhor usar soluções distribuídas mesmo (bzr, git ou mercurial), porque todas elas tem gateways para SVN propriamente dito.
  • BZR – acho que é o meu favorito para a maioria das coisas. Facil de usar (o mais fácil de todos, na minha opinião), rápido – principalmente nas últimas versões, extensível. Os meus maiores problemas com ele foi o desempenho (que foi resolvido na versão 1.0), e o tratamento de arquivos binários grandes – ele fazia questão de colocar o commit inteiro na memória, em formato ASCII ainda. Ou seja, para fazer commit de 100MB ele usava 2GB de RAM. Mas aparentemente, isso foi arrumado recentemente.
  • GIT – extremamente poderoso, rápido e eficiente.Em contra-partida, ele tem milhares de comandos, sub-comandos, parâmetros e opções. Se você aprender tudo com ele, ele é o melhor. Entretanto, eu vivo me perdendo na hora de fazer coisas mais complexas (tipo, fazer um cherry-pick de um repositório remoto em um branch diferente). Por outro lado, só ele que permite fazer cherry-pick de forma fácil (para quem está por fora – cherry-pick permite você pegar um commit independente e embutir ele em outro branch. Se isso não fez sentido para você, provavelmente você não precisa dele :) ). A melhor coisa do GIT para mim é o suporte dele para multiplos branches locais, no mesmo diretório. E a velocidade, é claro. Porém, a complexidade dele acaba complicando demais a vida as vezes.
  • Mercurial – parecido com o BZR e GIT. Atualmente suporta branches e cherry-picks também (de forma diferente). Ele suporta queues de patches também nativamente – mas, como nunca precisei disso, não posso falar muito detalhes. Fora isso, nunca cheguei a mexer muito com ele (mas, para quem tiver interesse, tem um tutorial interessante aqui). A escolha entre ele, bzr e git muitas vezes é questão de religião mesmo :) .
  • DARCS – bastante interessante, e diferente de todos os outros sistemas. Basicamente, todo o mecanismo de commits e diferenças entre versões dele é baseado em filas de patches, aplicados em determinada ordem. A filosofia dele também é parecida com GIT – ele visa manter controle do conteúdo, e não da estrutura de versões. Isso tem lados bons (o mesmo conteúdo pode migrar de um lugar para outro – arquivo, diretório, etc) e ruins (se alguém fez essa migração, você não vai ter controle exato sobre o que foi feito).
  • GNU ARCH – acredito que hoje em dia ele tem mais interesse histórico de que prático. Muito mais complexo de usar (se bem que, comparando com GIT, acho que dá uma briga boa). As ideias dele são utilizadas em outros sistemas de controle de versões distribuídas, mas ele em si – pelo que eu sei – está parado. Eu cheguei a usar ele faz alguns anos, mas desisti logo devido à complexidade dele.
  • MONOTONE – também em desuso nos últimos tempos, o MONOTONE serviu como inspiração para GIT. Fora isso, nunca vi ninguém usar ele, então não tenho opinião formada sobre ele.

Além disso, tem diversas outras soluções caseiras (com svn, cvs (eca..), etc) que fazem a mesma coisa que DRCS’es usando algumas gambiarras (hehehe). Mas eu fico entre BZR e GIT na maioria dos casos.