Planeta GNOME Hispano
La actividad Hispana de GNOME 24 x 7

26 de abril de 2015

Lavado de cara a la web del Dr Amor :-)

Al parecer Google penaliza, o va a penalizar, aunque sea un poquito, las webs que no están optimizadas para móviles. Y la mía no podía estar peor. Así que, como no tengo ni idea de diseño web, he estado buscando plantillas responsive fáciles de utilizar y, al final, encontré una en HTML5UP que me convenció. El resto, ha sido buscar imágenes para ilustrarla (por supuesto, bajo una licencia Creative Commons que me permita copiarlas simplemente reconociendo su autoría) y adaptar el texto y las secciones (y ya puestos, meter un poco de SEO), para lo que, de paso, me he ayudado de una herramienta libre: Aptana Studio. El resultado, es éste ( Y por fin, mi web aprueba los requisitos del monopolio de google. Iré actualizando el resto de mis páginas, poco a poco. Entre ellas, este blog, que también es un poco pecadorrr…


11 de abril de 2015

Compiling node.js for Android Lollipop

While participating in the Nordic IoT Hackathon 2015 our team Hello North (wrongly tagged as «HackLab team») wanted to explore the potential of running node.js applications running native in Android.

Happily this was solved by Yaron Y. Goland and described in a post. Using his method I've compiled node.js against android-ndk-r10d running the example on a 4.2.2 rooted device.

The next step was to try in a unrooted one, but only got at first a 5.0 Lollipop one. Execution failed with a error: only position independent executables (PIE) are supported. error message. Some investigation got me to a solved bug report. The magic trick seems to be just this patch.

It took me some time to understand how to add this to the node.js building configuration system but seems got fixed just like this:

--- /home/olea/node/android-configure~  2015-04-11 02:46:04.063966802 +0200
+++ /home/olea/node/android-configure   2015-04-11 01:56:34.470154253 +0200
@@ -6,14 +6,16 @@
     --toolchain=arm-linux-androideabi-4.8 \
     --arch=arm \
     --install-dir=$TOOLCHAIN \
-    --platform=android-9
+    --platform=android-16
 export AR=arm-linux-androideabi-ar
 export CC=arm-linux-androideabi-gcc
 export CXX=arm-linux-androideabi-g++
 export LINK=arm-linux-androideabi-g++
+export CPPFLAGS="-fPIE"
+export LDFLAGS="-fPIE -pie -L$PREFIX/lib"

And this is the test:


PS: Just checked the same build using android-16 platform runs in 4.2.2. ¡Double Yepa!

30 de marzo de 2015

Bringing sanity back to my T440s

As a long time Thinkpad’s trackpoint user and owner of a Lenovo T440s, I always felt quite frustrated with the clickpad featured in this laptop, since it basically ditched away all the physical buttons I got so used to, and replace them all with a giant, weird and noisy “clickpad”.

Fortunately, following Peter Hutterer’s post on X.Org Synaptics support for the T440, I managed to get a semi-decent configuration where I basically disabled any movement in the touchpad and used it three giant soft buttons. It certainly took quite some time to get used to it and avoid making too many mistakes but it was at least usable thanks to that.

Then, just a few months ago from now, I learned about the new T450 laptops and how they introduced again the physical buttons for the trackpoint there… and felt happy and upset at the same time: happy to know that Lenovo finally reconsidered their position and decided to bring back some sanity to the legendary trackpoint, but upset because I realized I had bought the only Thinkpad to have ever featured such an insane device.

Luckily enough, I recently found that someone was selling this T450’s new touchpads with the physical buttons in eBay, and people in many places seemed to confirm that it would fit and work in the T440, T440s and T440p (just google for it), so I decided to give it a try.

So, the new touchpad arrived here last week and I did try to fit it, although I got a bit scared at some point and decided to step back and leave it for a while. After all, this laptop is 7 months old and I did not want to risk breaking it either :-). But then I kept reading the T440s’s Hardware Maintenance Manual in my spare time and learned that I was actually closer than what I thought, so decided to give it a try this weekend again… and this is the final result:

T440s with trackpoint buttons!

Initially, I thought of writing a detailed step by step guide on how to do the installation, but in the end it all boils down to removing the system board so that you can unscrew the old clickpad and screw the new one, so you just follow the steps in the T440s’s Hardware Maintenance Manual for that, and you should be fine.

If any, I’d just add that you don’t really need to remove the heatskink from the board, but just unplug the fan’s power cord, and that you can actually do this without removing the board completely, but just lifting it enough to manipulate the 2 hidden screws under it. Also, I do recommend disconnecting all the wires connected to the main board as well as removing the memory module, the Wifi/3G cards and the keyboard. You can probably lift the board without doing that, but I’d rather follow those extra steps to avoid nasty surprises.

Last, please remember that this model has a built-in battery that you need to disable from the BIOS before starting to work with it. This is a new step compared to older models (therefore easy to overlook) and quite an important one, so make sure you don’t forget about it!

Anyway, as you can see the new device fits perfectly fine in the hole of the former clickpad and it even gets recognized as a Synaptics touchpad, which is good. And even better, the touchpad works perfectly fine out of the box, with all the usual features you might expect: soft left and right buttons, 2-finger scrolling, tap to click…

The only problem is that the trackpoint’s buttons would not work that well: the left and right buttons would translate into “scroll up” and “scroll down” and the middle button would simply not work at all. Fortunately, this is also covered in Petter Hutterer’s blog, where he explains that all the problems I was seeing are expected at this moment, since some patches in the Kernel are needed for the 3 physical buttons to become visible via the trackpoint again.

But in any case, for those like me who just don’t care about the touchpad at all, this comment in the tracking bug for this issue explains a workaround to get the physical trackpoint buttons working well right now (middle button included), simply by disabling the Synaptics driver and enabling psmouse configured to use the imps protocol.

And because I’m using Fedora 21, I followed the recommendation there and simply added psmouse.proto=imps to the GRUB_CMDLINE_LINUX line in /etc/default/grub, then run grub2-mkconfig -o /boot/grub2/grub.cfg, and that did the trick for me.

Now I went into the BIOS and disabled the “trackpad” option, not to get the mouse moving and clicking randomly, and finally enabled scrolling with the middle-button by creating a file in /etc/X11/xorg.conf.d/20-trackpoint.conf (based on the one from my old x201), like this:

Section "InputClass"
        Identifier "Trackpoint Wheel Emulation"
        MatchProduct "PS/2 Synaptics TouchPad"
        MatchDriver "evdev"
        Option  "EmulateWheel"  "true"
        Option  "EmulateWheelButton" "2"
        Option  "EmulateWheelInertia" "10"
        Option  "EmulateWheelTimeout" "190"
        Option  "Emulate3Buttons" "false"
        Option  "XAxisMapping"  "6 7"
        Option  "YAxisMapping"  "4 5"

So that’s it. I suppose I will keep checking the status of the proper fix in the tracking bug and eventually move to the Synaptic driver again once all those issue get fixed, but for now this setup is perfect for me, and definitely way better than what I had before.

I only hope that I hadn’t forgotten to plug a cable when assembling everything back. At least, I can tell I haven’t got any screw left and everything I’ve tested seems to work as expected, so I guess it’s probably fine. Fingers crossed!

26 de marzo de 2015

Building a SNES emulator with a Raspberry Pi and a PS3 gamepad

It’s been a while since I did this, but I got some people asking me lately about how exactly I did it and I thought it could be nice to write a post answering that question. Actually, it would be a nice thing for me to have anyway at least as “documentation”, so here it is.

But first of all, the idea: my personal and very particular goal was to have a proper SNES emulator plugged to my TV, based on the Raspberry Pi (simply because I had a spare one) that I could control entirely with a gamepad (no external keyboards, no ssh connection from a laptop, nothing).

Yes, I know there are other emulators I could aim for and even Raspberry specific distros designed for a similar purpose but, honestly, I don’t really care about MAME, NeoGeo, PSX emulators or the like. I simply wanted a SNES emulator, period. And on top of that I was quite keen on playing a bit with the Raspberry, so I took this route, for good or bad.

Anyway, after doing some investigation I realized all the main pieces were already out there for me to build such a thing, all that was needed was to put them all together, so I went ahead and did it. And these are the HW & SW ingredients involved in this recipe:

Once I got all these things around, this is how I assembled the whole thing:

1. Got the gamepad paired and recognized as a joystick under /dev/input/js0 using the QtSixA project. I followed the instructions here, which explain fairly well how to use sixpair to pair the gamepad and how to get the sixad daemon running at boot time, which was an important requirement for this whole thing to work as I wanted it to.

2. I downloaded the source code of PiSNES, then patched it slightly so that it would recognize the PS3 DualShock gamepad, allow me define the four directions of the joystick through the configuration file, among other things.

3. I had no idea how to get the PS3 gamepad paired automatically when booting the Raspberry Pi, so I wrote a stupid small script that would basically wait for the gamepad to be detected under /dev/input/js0, and then launch the snes9x.gui GUI to choose a game from the list of ROMS available. I placed it under /usr/local/bin/snes-run-gui, and looks like this:



# Wait for the PS3 Game pad to be available
while [ ! -e /dev/input/js0 ]; do sleep 2; done

# The DISPLAY=:0 bit is important for the GUI to work
DISPLAY=:0 $BASEDIR/snes9x.gui

4. Because I wanted that script to be launched on boot, I simply added a line to /etc/xdg/lxsession/LXDE/autostart, so that it looked like this:

@lxpanel --profile LXDE
@pcmanfm --desktop --profile LXDE
@xscreensaver -no-splash

By doing the steps mentioned above, I got the following “User Experience”:

  1. Turn on the RPi by simply plugging it in
  2. Wait for Raspbian to boot and for the desktop to be visible
  3. At this point, both the sixad daemon and the snes-run-gui script should be running, so press the PS button in the gamepad to connect the gamepad
  4. After a few seconds, the lights in the gamepad should stop blinking and the /dev/input/js0 device file should be available, so snes9x.gui is launched
  5. Select the game you want to play and press with the ‘X’ button to run it
  6. While in the game, press the PS button to get back to the game selection UI
  7. From the game selection UI, press START+SELECT to shutdown the RPi
  8. Profit!

Unfortunately, those steps above were enough to get the gamepad paired and working with PiSNES, but my TV was a bit tricky and I needed to do a few adjustments more in the booting configuration of the Raspberry Pi, which took me a while to find out too.

So, here is the contents of my /boot/config.txt file in case it helps somebody else out there, or simply as reference (more info about the contents of this file in RPiConfig):

# NOOBS Auto-generated Settings:

# Set sdtv mode to PAL (as used in Europe)

# Force sound to be sent over the HDMI cable

# Set monitor mode to DMT

# Overclock the CPU a bit (700 MHz is the default)

# Set monitor resolution to 1280x720p @ 60Hz XGA

As you can imagine, some of those configuration options are specific to the TV I have it connected to (e.g. hdmi_mode), so YMMV. In my case I actually had to try different HDMI modes before settling on one that would simply work, so if you are ever in the same situation, you might want to apt-get install libraspberrypi-bin and use the following commands as well:

 $ tvservice -m DMT # List all DMT supported modes
 $ tvservice -d edid.dat # Dump detailed info about your screen
 $ edidparser edid.dat | grep mode # List all possible modes

In my case, I settled on hdmi_mode=85 simply because that’s the one that work better for me, which stands for the 1280x720p@60Hz DMT mode, according to edidparser:

HDMI:EDID DMT mode (85) 1280x720p @ 60 Hz with pixel clock 74 MHz has a score of 80296

And that’s all I think. Of course there’s a chance I forgot to mention something because I did this in my random slots of spare time I had back in July, but that should be pretty much it.

Now, simply because this post has been too much text already, here you have a video showing off how this actually works (and let alone how good/bad I am playing!):

Video: Raspberry Pi + PS3 Gamepad + PiSNES

I have to say I had great fun doing this and, even if it’s a quite hackish solution, I’m pretty happy with it because it’s been so much fun to play those games again, and also because it’s been working like a charm ever since I set it up, more than half a year ago.

And even better… turns out I got it working just in time for “Father’s Day”, which made me win the “best dad in the world” award, unanimously granted by my two sons, who also enjoy playing those good old games with me now (and beating me on some of them!).

Actually, that has been certainly the most rewarding thing of all this, no doubt about it.

23 de marzo de 2015

WebKitGTK+ 2.8.0

We are excited and proud of announcing WebKitGTK+ 2.8.0, your favorite web rendering engine, now faster, even more stable and with a bunch of new features and improvements.


Touch support is one the most important features missing since WebKitGTK+ 2.0.0. Thanks to the GTK+ gestures API, it’s now more pleasant to use a WebKitWebView in a touch screen. For now only the basic gestures are implemented: pan (for scrolling by dragging from any point of the WebView), tap (handling clicks with the finger) and zoom (for zooming in/out with two fingers). We plan to add more touch enhancements like kinetic scrolling, overshot feedback animation, text selections, long press, etc. in future versions.

HTML5 Notifications


Notifications are transparently supported by WebKitGTK+ now, using libnotify by default. The default implementation can be overridden by applications to use their own notifications system, or simply to disable notifications.

WebView background color

There’s new API now to set the base background color of a WebKitWebView. The given color is used to fill the web view before the actual contents are rendered. This will not have any visible effect if the web page contents set a background color, of course. If the web view parent window has a RGBA visual, we can even have transparent colors.


A new WebKitSnapshotOptions flag has also been added to be able to take web view snapshots over a transparent surface, instead of filling the surface with the default background color (opaque white).

User script messages

The communication between the UI process and the Web Extensions is something that we have always left to the users, so that everybody can use their own IPC mechanism. Epiphany and most of the apps use D-Bus for this, and it works perfectly. However, D-Bus is often too much for simple cases where there are only a few  messages sent from the Web Extension to the UI process. User script messages make these cases a lot easier to implement and can be used from JavaScript code or using the GObject DOM bindings.

Let’s see how it works with a very simple example:

In the UI process, we register a script message handler using the WebKitUserContentManager and connect to the “script-message-received-signal” for the given handler:

webkit_user_content_manager_register_script_message_handler (user_content, 
g_signal_connect (user_content, "script-message-received::foo",
                  G_CALLBACK (foo_message_received_cb), NULL);

Script messages are received in the UI process as a WebKitJavascriptResult:

static void
foo_message_received_cb (WebKitUserContentManager *manager,
                         WebKitJavascriptResult *message,
                         gpointer user_data)
        char *message_str;

        message_str = get_js_result_as_string (message);
        g_print ("Script message received for handler foo: %s\n", message_str);
        g_free (message_str);

Sending a message from the web process to the UI process using JavaScript is very easy:"bar");

That will send the message “bar” to the registered foo script message handler. It’s not limited to strings, we can pass any JavaScript value to postMessage() that can be serialized. There’s also a convenient API to send script messages in the GObject DOM bindings API:

webkit_dom_dom_window_webkit_message_handlers_post_message (dom_window, 
                                                            "foo", "bar");


Who is playing audio?

WebKitWebView has now a boolean read-only property is-playing-adio that is set to TRUE when the web view is playing audio (even if it’s a video) and to FALSE when the audio is stopped. Browsers can use this to provide visual feedback about which tab is playing audio, Epiphany already does that :-)


HTML5 color input

Color input element is now supported by default, so instead of rendering a text field to manually input the color  as hexadecimal color code, WebKit now renders a color button that when clicked shows a GTK color chooser dialog. As usual, the public API allows to override the default implementation, to use your own color chooser. MiniBrowser uses a popover, for example.



APNG (Animated PNG) is a PNG extension that allows to create animated PNGs, similar to GIF but much better, supporting 24 bit images and transparencies. Since 2.8 WebKitGTK+ can render APNG files. You can check how it works with the mozilla demos.



The POODLE vulnerability fix introduced compatibility problems with some websites when establishing the SSL connection. Those problems were actually server side issues, that were incorrectly banning SSL 3.0 record packet versions, but that could be worked around in WebKitGTK+.

WebKitGTK+ already provided a WebKitWebView signal to notify about TLS errors when loading, but only for the connection of the main resource in the main frame. However, it’s still possible that subresources fail due to TLS errors, when using a connection different to the main resource one. WebKitGTK+ 2.8 gained WebKitWebResource::failed-with-tls-errors signal to be notified when a subresource load failed because of invalid certificate.

Ciphersuites based on RC4 are now disallowed when performing TLS negotiation, because it is no longer considered secure.

Performance: bmalloc and concurrent JIT

bmalloc is a new memory allocator added to WebKit to replace TCMalloc. Apple had already used it in the Mac and iOS ports for some time with very good results, but it needed some tweaks to work on Linux. WebKitGTK+ 2.8 now also uses bmalloc which drastically improved the overall performance.

Concurrent JIT was not enabled in GTK (and EFL) port for no apparent reason. Enabling it had also an amazing impact in the performance.

Both performance improvements were very noticeable in the performance bot:



The first jump on 11th Feb corresponds to the bmalloc switch, while the other jump on 25th Feb is when concurrent JIT was enabled.

Plans for 2.10

WebKitGTK+ 2.8 is an awesome release, but the plans for 2.10 are quite promising.

  • More security: mixed content for most of the resources types will be blocked by default. New API will be provided for managing mixed content.
  • Sandboxing: seccomp filters will be used in the different secondary processes.
  • More performance: FTL will be enabled in JavaScriptCore by default.
  • Even more performance: this time in the graphics side, by using the threaded compositor.
  • Blocking plugins API: new API to provide full control over the plugins load process, allowing to block/unblock plugins individually.
  • Implementation of the Database process: to bring back IndexedDB support.
  • Editing API: full editing API to allow using a WebView in editable mode with all editing capabilities.

20 de marzo de 2015

GStreamer Hackfest 2015

Last weekend I visited my former office in (lovely) Staines-upon-Thames (UK) to attend the GStreamer hackfest 2015, along with other ~30 hackers from all over the world.

This was my very first GStreamer hackfest ever and it was definitely a great experience, although at the beginning I was really not convinced to attend since, after all, why bother attending an event about something I have no clue about?

But the answer turned out to be easy in the end, once I actually thought a bit about it: it would be a good opportunity both to learn more about the project and to meet people in real life (old friends included), making the most of it happening 15min away from my house. So, I went there.

And in the end it was a quite productive and useful weekend: I might not be an expert by now, but at least I broke the barrier of getting started with the project, which is already a good thing.

And even better, I managed to move forward a patch to fix a bug in PulseAudio I found on last December while fixing an downstream issue as part of my job at Endless. Back then, I did not have the time nor the knowledge to write a proper patch that could really go upstream, so I focused on fixing the problem at hand in our platform. But I always felt the need to sit down and cook a proper patch, and this event proved to be the perfect time and place to do that.

Now, thanks to the hackfest (and to Arun Raghavan in particular, thanks!), I’m quite happy to see that the right patch might be on its way to be applied upstream. Could not be happier about it! :)

Last, I’d like to thank to Samsung’s OSG, and specially to Luis, for having done a cracking job on making sure that everything would run smoothly from beginning to end. Thanks!

17 de marzo de 2015

How do you upgrade your distro? A tale of two workarounds

Every classic Linuxer would know why it's very handy to dedicate a separate partition for the /home folder of your tree: you could in theory share it between multiple OSs that you installed in your box (which you choose to run when you start your computer).

Now, I'm guessing that many people reading and nodding to the above, will also know that sharing /home/ is one thing, sharing $HOME (/home/yourUserName) is a completely different beast.

For example: you have a stable distro installed in your box; you decide to install a new version of that distro along the old one, in the same box. You run the new distro with a new account tied to the old /home/yourUserName folder: KABOOM!!! Weird things start happening. Among these:

  • The newer versions of your desktop or desktop programs don't run properly with the settings saved in your .dotDirectories (they are to blame because they didn't probably have a settings-conversion feature).
  • The newer versions of your desktop or desktop programs have a buggy settings-conversion feature; because your program does not run properly, or as well as it would have run if it had been ran for the first time with no settings saved at all.
  • The newer versions of your non-buggy desktop or desktop programs convert your settings to a new format. Then when you go back and run your old distro again, your old-versioned programs stop working because they see settings in a new format which they don't understand. (This is impossible to fix, or very hard.) It's very important that this scenario works, because the migration to the new version of your distro may not be immediate, it may take you some days to figure everything out, and until that happens, you want to still be able to run the stable version of your desktop and desktop programs
  • Etc.

To workaround these problems, I have a strategy: I use a different /home/ sub-directory for each distro installed in my system. For example, for distro X version A.B I use /home/knocteXAB/, for distro Y version C.D I use /home/knocteYCD/. The advantage about this is that you can migrate your settings manually and at your own pace. But then, you may be asking, how to really take advantage of sharing the /home folder when using this technique?

Easy: I keep non-settings data (mainly the non-dotfiles) in a different /home/ folder with no associated account in any of the distros. For example: /home/knocte/ (no version suffix). Then, from each of the suffixed /home/ subfolders, I setup symlinks to this other folder, setting the appropriate permissions. For instance:

  • /home/knocteXAB/Music -> /home/knocte/Music
  • /home/knocteXAB/Documents -> /home/knocte/Documents
  • /home/knocteYCD/Music -> /home/knocte/Music
  • /home/knocteYCD/Documents -> /home/knocte/Documents
  • Etc.
You may think that it's an interesting strategy and that I'm done with the blog post, however, when using this strategy you may start finding buggy applications that don't deal very well with symlinked paths. The one I found which annoyed the most was my favourite Gnome IDE, because it meant I couldn't develop software without problems. I mean, they were not just cosmetic problems, really:

So I had to use a workaround for my workaround: clone all my projects in $HOME instead of /home/knocte/Documents/Code/OpenSource/ (yah, I'm this organized ;) ).

I've been trying to fix these problems for a while, without much time on my hands.

But the last weeks a magical thing happened: I decided to finally sit down and try to fix the last two remaining, and my patches were all accepted and merged last week! (at least all the ones fixing symlink-related problems), woo!!!

So the lessons to learn here are:

  • Even the slickest workarounds have problems. Try to fix or report settings-conversion bugs!!
  • Don't ever quit trying to fix a problem. Some day you'll have the solution and you will realize it was simpler than you thought.
  • realpath is your friend.
  • MonoDevelop (master branch) is now less buggy and as amazing as (or more than) ever (</PUBLIC_SERVICE_ANNOUNCEMENT>).

10 de marzo de 2015

Qué es el procomún

El siguiente texto lo he preparado a la sazón del programa de actividades complementarias del Almería Creative Commons Film Festival, el primer festival, y casi la primera actividad, en Almería exclusivamente dedicado a este mundo. Me ha gustado tanto que he querido publicarlo en mi propio blog. Aquí queda:


El DRAE lo define como

        ( De pro, provecho, y común).
        1. m. Utilidad pública.

pero el filósofo Antonio Lafuente va mucho más allá:

«lo que es de todos y de nadie al mismo tiempo»

Para Antonio la expresión procomún es la traducción al español más acertada para el término inglés commons. Pero ¿tiene que ver el procomún con nuestra vida diaria? Absolutamente: el aire, el futuro, los sentimientos, el ADN, todos son procomunes cotidianos, casi personales. Otros son más distantes pero igualmente indispensables: las pesquerías, parques naturales… la lista es ¿infinita?. Y tenemos otros procomunes que están floreciendo avivados por el galopante desarrollo tecnológico: el software libre, la Wikipedia, Internet y la Web dentro de ella. El mismo HackLab Almería es un modesto procomún que nos empeñamos en construir para ponerlo a vuestra disposición.

18 de febrero de 2015

¿Cambios en la AC FNMT-RCM? Probando el servidor OCSP

#BG_1424275458364_78302 { float: right; margin-left: 1em; margin-top: 1em; margin-bottom: 1em; width: 300px; } #BG_1424277684349_27454 { float: right; margin-top: 1em; margin-bottom: 1em; margin-left: 1em; width: 300px; }

A raíz de un hilo en Twitter sobre la inexistencia del servicio de CRL de la Autoridad de Certificación de la FNMT sólo se me ha ocurrido que en vez de dedicarme a mis responsabilidades me era imperioso saber qué se estaba cociendo... La noticia más chocante es la actividad reciente en la infame entrada #435736 del bugzilla de Mozilla (abierta desde 2008 para que Mozilla acepte el certificado raiz de la AC FNMT). Parece que por fin alguien se está aplicando a resolver el problema. Y entre las perlas más suculentas allí recogidas está un documento titulado General Certification Practices Statement en el que aparecen detalles como, precisamente, las URIs de publicación de los CRL o los varios servicios OCSP aparentemente disponibles. Si eres de los que han estudiado anteriormente el uso de CERES-FNMT probablemente hayas levantado una ceja. Sí: parece que están habilitando por fin estos servicios. El que no conozca la causa de nuestra sorpresa deberá saber que hasta ahora el servicio de validación de certificados de CERES FNMT para certificados de usuario final (por ejemplo de ciudadanos corrientes y molientes) ha sido de pago (ver ilustración). Para algunos esta ha sido otra de las causas que han lastrado la adopción de la firma digital en España.

Entre los detalles me han llamado la atención las URIs de los servicios OCSP:

y claro, inmediatamente he querido verificar si ya estaban operativos, con la triste circunstancia de que no tengo ni idea de cómo hacerlo. Tras algo de investigación y con oportunismo de corta y pega he dado con una orden que creo serviría:

openssl ocsp -issuer AC_Raiz_FNMT-RCM_SHA256.cer -serial 0x36f11b19 -url -CAfile AC_Raiz_FNMT-RCM_SHA256.cer 
  • -issuer AC_Raiz_FNMT-RCM_SHA256.cer el certificado raiz de la AC en cuestión;
  • -serial 0x36f11b19 el número de serie de un certificado FNMT emitido en 2005 y caducadísimo;
  • -url la URI del servicio OCSP que usaremos, en este caso he elegido el que arriba aparece denominado «ROOT AC. Access» porque me ha parecido el más general para el servicio de particulares comparado con los otros dos;
  • -CAfile AC_Raiz_FNMT-RCM_SHA256.cer realmente no sé porqué habría de usar este parámetro, entiendo que es para verificar el resultado ofrecido por el servicio OCSP y todos los ejemplos que he encontrado lo usan de alguna forma; curiosamente sólo he conseguido eliminar los mensajes de error usando el mismo certificado que en -issuer pero no sé si es el comportamiento correcto o si en este caso funciona así por ser un certificado raiz autofirmado.

El resultado obtenido es el siguiente:

Response verify OK
0x36f11b19: good
    This Update: Nov 18 12:11:20 2014 GMT
    Next Update: May 17 11:11:20 2015 GMT

Y podréis decir «pues qué bien, ¿no?». O no. No lo sé. Ignoro los intríngulis de protocolo OCSP pero me esperaba  otra respuesta para un certificado caducado hace más de ocho años. El  caso es el que servicio sí está levantado y podemos ver más detalles usando la opción -text de openssl oscp:

OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Produced At: Feb 18 16:27:29 2015 GMT
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: BADF8AE3F7EB508C94C1BAE31E7CDC3A713D4437
      Issuer Key Hash: F77DC5FDC4E89A1B7764A7F51DA0CCBF87609A6D
      Serial Number: 36F11B19
    Cert Status: good
    This Update: Nov 18 12:11:20 2014 GMT
    Next Update: May 17 11:11:20 2015 GMT

El caso es que he probado a usar variantes del número serie aleatorias así como de certificados en vigor y siempre da un «good» por respuesta. Y lo poco que me ha podido contar alguien más familiarizado con la tecnología de AC es que este tipo de comportamiento en un servicio OCSP sería normal.


  • El servicio OCSP de FNMT, o al menos el que he usado, está levantado, sí, pero ¿ya está realmente operativo?
  • ¿Es correcta mi manera de invocarlo desde openssl? no estoy seguro;

Otras conclusiones:

Diría que efectivamente parece FNMT se ha tomado en serio configurarse como una autoridad de certificación seria. Por fin. Supongo que ha podido la presión de al menos los usuarios corporativos públicos que últimamente están emitiendo sus certifcados X509 de servidor a través de Camerfirma (verbigracia la Agencia Tributaria), supongo que cansados de que los usuarios menos avezados se hagan un lío con el proceso de instalación del certificado raiz adecuado y de no saber interpretar correctamente los mensajes de precaución de los navegadores. También parece que empiezan a dejar de usar el nombre Ceres para referirse al servicio. Al menos ha sido mi impresión.

Si alguien detecta errores en lo aquí mostrado estaré encantado de corregir lo que haga falta.


15 de febrero de 2015

I shot the Tracker

In free software some fashions never change, and some are particularly hard to overcome. Today I’ll talk about the “Tracker makes $ANYTHING slow” adage, lately gnome-music being on the spotlight here. I’m glad that I could personally clear this up to some individuals on the hackfests/conferences I’ve been around lately.

But convincing is a never ending labor, there’s still confused people around the internets, and disdainful looks don’t work as well over there. The next best thing I could do is fixing things myself to make Tracker look less like the bad guy. So, from the “can’t someone else do it” department, here’s some commits to improve the situation. The astute reader might notice that there is nothing about tracker in these changes.

There’s of course more to it, AFAICT other minor performance hits are caused by:

  • grilo emitting one signal per media item found, which is somewhat bad on huge lists
  • icon view performance generally sucking, which makes scrolling not as smooth in the Albums view while covers are loading
  • After all that, well sure, Tracker queries can be marginally optimized.

This will eventually hit master and packages, until then, do me a favor an point to this post anyone still saying how Tracker made gnome-music slow.

Developer experience hackfest

Kind of on topic with this, I attended a few weeks ago to the Developer experience hackfest. Besides trying to peg round pieces into square holes, after some talking with how much of a steep barrier was Sparql as a prerequisite for accessing Tracker data, I started there on a simpler query API that abstracted all of these gritty details. Code is just shaping up there, but I expect it to cover the most common usecases. I must thank Red Hat and Collabora for enabling me to go there, all the people there, and particularly Philip for being such a great host.

Oh, and also attended Fosdem and Devconf, even talked on the last one about the input plans going on in GNOME, busy days!

01 de febrero de 2015

¿Cambios en la AC FNMT-RCM? Probando el servidor OCSP

A raíz de un hilo en Twitter sobre la inexistencia del servicio de CRL de la Autoridad de Certificación de la FNMT sólo se me ha ocurrido que en vez de dedicarme a mis responsabilidades me era imperioso saber qué se estaba cociendo... La noticia más chocante es la actividad reciente en la infame entrada #435736 del bugzilla de Mozilla (la que está abierta desde 2008 para que Mozilla pueda aceptar el certificado raiz de la AC FNMT). Parece que por fin se han puesto en serio a resolver el problema. Y entre las perlas más suculentas está un documento titulado General Certification Practices Statement en el que aparecen detalles como precisamente las URIs de publicación de los CRL o los varios servicios OCSP aparentemente disponibles. Si eres de los que han estudiado anteriormente el uso de CERES-FNMT probablemente has levantado una ceja. Sí: parece que están habilitando por fin estos servicios, aunque en mi ignorancia técnica aún no he sido capaz de validar 100% que están operativos. El que no conozca la causa de nuestra sorpresa deberá saber que hasta ahora el servicio de validación de certificados de CERES FNMT para certificados de usuario final (por ejemplo de ciudadanos corrientes y molientes) ha sido de pago. Para algunos esta ha sido otra de las causas del impacto limitado de la adopción de la firma digital en España.

IMG ~/public_html/ilustraciones/diario/201502-fnmt-ocsp.png


28 de enero de 2015

Parcheando GHOST

GHOST es un nuevo bug de seguridad (esta vez en glibc, más en concreto en la función gehostbyname que se usa en casi cualquier aplicación que trabaje con la red, como por ejemplo, apache, mysql, ssh…) que permite tomar el control remoto de una máquina Linux. Se hizo público ayer. Dada la peligrosidad del bug, […]

08 de enero de 2015

Frogr 0.11 released

Screenshot of Frogr 0.11

So, after neglecting my responsibilities with this project for way too long, I finally released frogr 0.11 now, making the most that I’m now enjoying some kind of “parenting vacation” for a few days.

Still, do not expect this new release to be fully loaded of new features and vast improvements, as it’s more like another incremental update that adds a couple of nice new things and fixes a bunch of problems I was really unhappy about (e.g. general slowness, crashes).

Wrapping it up, the main changes included with this release are:

  • Moved to the new GTK+’s header bar plus the typical menu button when GTK+ >= 3.12 (GTK+ 3.4 is still supported). I personally like this change a lot, as it makes frogr much more compact and sleek IMHO, and much better integrated with newer releases of GNOME.
  • Added a new option to automatically replace the “date posted” field in flickr with the “date taken” value from the EXIF metadata when uploading pictures. Useful to keep your photo stream sorted regardless of when you uploaded which pictures. Thanks a lot to Luc Pionchon for requesting this feature. I never thought of it before, now I use it all the time!
  • Sped up the load of pictures into the main window, as it was a very slow process when importing tags from the XMP keywords was enabled. I measured a 3x improvement, but YMMV.
  • Fixed random crashes due to the missing initialization of the gcrypt library introduced with the recent changes to use SSL API end points. Thanks a lot Andrés for your help with this!
  • Fixed issues related to the OS X port, which prevented frogr 0.9 from having video support and caused many problems with the 0.10 release. Now it should be fine, grab the bundle from here.
  • Other things: removed calls to deprecated APIs, updated translations, fixed a few minor bugs and a bit of a clean-up here and there, which is usually good.

As usual, feel free to check the website of the project in case you want to know more about frogrhow to get it or how to contribute to it. I’m having a hard time lately to find time to devote to this pet project, so any help anyone can provide will be more than welcome :-) fosdem-15-logo

By the way, I’m going to FOSDEM this year again, so feel free to say “hi” if you want to chat and/or share a beer (or more!).

07 de enero de 2015

Streams API in WebKit at the Web Engines Hackfest

Yes, I know, I should have written this post before you know, blah, blah, excuse 1, blah, excuse 2, etc. ;)

First of course I would like to thank Igalia for allowing me to use the company time to attend the hackfest and meeting such a group of amazing programmers! It was quite intense and I tried to give my best though for different reasons (coordination, personal and so on) I missed some session.

My purpose at the hackfest was to work with Youenn Fablet from Canon on implementing the Streams API in WebKit. When we began to work together in November, Youenn had already a prototype working with some tests, so the idea was taking that, completing, polishing and shipping it. Easy, huh? Not so…

What is Streams? As you can read in the spec, the idea is to create a way of handling different kind of streams with a common high level API. Those streams can be a mapping of low level I/O system operations or can be easily created from JavaScript.

Fancy things you can do:

  • Create readable/writable streams mapping different operations
  • Read/write data from/to the streams
  • Pipe data between different streams
  • Handle backpressure (controlling the data flow) automagically
  • Handle chunks as the web application sees fit, including different data types
  • Implement custom loaders to feed different HTML tags (images, multimedia, etc.)
  • Map some existing APIs to Streams. XMLHttpRequest would be a wonderful first step.

First thing we did after the prototype was defining a roadmap:

  • General ReadableStream that you can create at JavaScript and read from it
  • XMLHttpRequest integration
  • Loaders for some HTML tags
  • WritableStream
  • Piping operations

As you can see in bugzilla we are close to finishing the first point, which took quite a lot of effort because it required:

  • Code cleaning
  • Making it build in debug
  • Improving the tests
  • Writing the promises based constructor
  • Fixing a lot of bugs

Of course we didn’t do all this at the hackfest, only Chuck Norris would have been able to do that. The hackfest provided the oportunity of meeting Youenn in person, working side by side and discussing different problems and possible strategies to solve them, like for example, the error management, queueing chunks and handling their size, etc. which are not trivial given the complexity created by the flexibility of the API.

After the hackfest we continued working and, as I said before, the result you can find at bugzilla. We hope to be able to land this soon and continue working on the topic within the current roadmap.

To close the topic about the hackfest, it was a pleasure to work with such amount of awesome web engines hackers and I would like to finish thanking the sponsors Collabora and Adobe and specially my employer, Igalia, that was sponsor and host.

16 de diciembre de 2014


In the last year working at Xamarin, I have learned lots of new things (.NET, Cocoa, …), and since the beginning of that, I was thinking on bringing some of that nice stuff to GNOME, but didn’t really had the chance to finish anything. But, fortunately, being free now (on vacation), I finally finished the 1st thing: GObservableCollection, a thread-safe collection implementation which emits signals on changes.

It is based on ideas from .NET’s ObservableCollection and concurrent collections, which I’ve used successfully for building a multi-thread data processing app (with one thread updating the collection and another consuming it), so I thought it would be a good addition to GLib’s API. This class can be used on single-threaded apps to easily get notifications for changes in a collection, and in multi-threaded ones for, as mentioned above, easily share data between different threads (as can be seen on the simple test I wrote).

This is the 1st working version, so for sure it will need improvements, but instead of keeping it private for a few more months, I thought it would be better getting some feedback before I submit it as a patch for GLib’s GIO (if that’s the best place for it, which I guess it is).

28 de septiembre de 2014

HackIt! 2014 : epílogo

Tras mi insistencia a @ramonechavarri y @abeaumont de w0pr para que nos echara un cable con el writeup de alguno de los dos levels del HackIt! 2014 que se nos quedaron en el tintero, nos pasaron hace unos días un extenso y completo texto que explica paso a paso en qué consiste y cómo superar el […]

22 de septiembre de 2014

GNOME 3.14 approaching

With 3.14 almost out of the door, it seems like a good opportunity to blow the cobwebs of this blog and highlight some shiny new features I was involved in during this cycle:

Gesture support in GTK+

It’s finally happening :), GTK+ 3.14 brings in infrastructure to handle gestures. Maybe the word “gesture” is automatically associated to “multitouch”, but actually this infrastructure is meant to deal with all kinds of pointer/touch input, and as such is used fairly intensively now within GTK+ itself, so even mouse users will be unknowingly using this.

These gesture objects are of course readily available for applications too. Individually, these are quite simple in essence, but can be easily stitched together to compound higher-level behavior. So far, eog and evince (and by extension gnome-documents) have bitten the bullet and now handle some of the gestures you’d expect on touchscreens there, the API documentation and HowDoI are available for anyone wanting to follow.

Gesture support in gnome-shell

Just to feed the cabal claiming that gnome-shell is designed for tablets, I also managed this cycle to add gesture infrastructure in mutter, so it is able to pre-process touch events before applications do, these events are then handled through ClutterGestureActions, or “rejected” and eventually handled by the application. This has been put to use in gnome-shell, making some actions readily available through multitouch.

Edge swipes

Showing the overview

Switching workspaces

Switching apps in a workspace

Note: Recorded with the help of this, bug #732367 is yet another 3.16 todo item…

Freebase support in libgdata

This one feature has certainly went underpublicited, and I found myself with little time to make use of it :(, but I nonetheless find that very interesting things can be done with this. Freebase is a community-maintained knowledge base (currently backed by Google), as seen on its homepage it is extremely wide in topics (some better covered than others), and has a very well defined ontology, think of it as a companion to Tracker on the web.

There are dedicated methods for the most usual ways to query data (search, lookup on topic…), but additionally Freebase offers a powerful MQL query method. MQL is very analogous to SPARQL, with the main difference that it’s based on JSON. All together allows for querying in very creative ways from very various data, a few examples being:

  • The mandatory “query for movie/album info” example, actually these topics are the best covered.
  • Fetching stock images for movies/cities/landmarks/directors/…, you name it.
  • Looking up monuments close to a geolocation.
  • Getting direct links to Wikipedia, in your language.

Looking forward for 3.15

It is almost time to celebrate, but I evidently won’t sit twiddling my thumbs :), a few items I’d like to tackle on the next cycle are:

  • During the 3.14 cycle I got briefly started on adding optional gesture integration to GtkStack and a new “tabs” widget, now it sounds like a good time to resume. I would also like to make gestures used integrally for event handling in GTK+ (we’re already just a few widgets away from that goal)
  • There’s a few gaps still left to solve on handling touchpad gestures, which I’d like to get closed ASAP, at least for touchpads handling >2 fingers on X11.
  • Improving gnome on Wayland. I merely got started this cycle adding DnD/clipboards support to GTK+ and bringing touchscreen behavior on mutter more or less on par to X11’s. There’s a few input details that need shuffling so they’re done in the same place on X11/wayland (pointer cursor visibility, device mapping…), and I hope the timing to be right to bring in a sort of tablet support (libinput and wayland protocol details have been shaping up despite my times on, most times off help, thanks Peter, Lyude, Jason et al!), I will be putting my hacking efforts wherever it’s necessary to make this happen.
  • WebKitGTK+ could be definitely made friendlier on touchscreens, additionally to the DOM touch event support it already does, it would be great to handle touch scroll/pinch/zoom as you can see in other pure GTK+ apps now.

26 de agosto de 2014

HackIt! 2014: final

Hubo otra prueba que nos tuvo a todos los participantes danzando al lado de la “caseta” de redes y sistemas. @marcan42 puso una Raspberry Pi enviando pings extraños vía wifi. El título del level era “Raspberry Pi(ng)” y el enunciado decía: “Hemos montado una Raspberry Pi de router wifi (¡no se lo digas a Iban!), […]

Endless changes ahead!

I know I haven’t blogged for a while, and definitely not as much as I would like, but that was partially because I was quite busy during my last days in Samsung (left on the 25th of July), where I wanted to make sure I did not leave any loose end before departure, and that everything was properly handed over to the right people there.

But that was one month ago… so what did I do since then? Many many things, and most of them away from a keyboard, at least until the past week. Main highlights:

  • One week travelling by car with my family all the way down to Spain from the UK, through France, visiting all the nice places we could (and could afford) in the way, which was a lot of fun and an incredible experience.
  • The goal of taking the car to Spain was to sell it once we were there and, surprisingly enough, we did it in record time, so one thing less to worry about…
  • 2 weeks in Spain having proper “relaxing holidays” to get some quality time off in between the two jobs, to properly recharge batteries. Not that the previous week was not holidays, but travelling 2200 km by car with two young kids on the back can be amazing and exhausting at the same time :-)
  • 1 week in the UK to make sure I had everything ready by the time I officially started in the new company, where I will initially be working from home: assemble a home office in my spare bedroom, and prepare my new laptop mainly. In the end, we (my wife helped me a lot) finished by Wednesday, so on Thursday we went for a last 2-day getaway to Wales (what a beautiful place!) by car, making the most that we were kids-free.

Endless Mobile logoTherefore, as you can imagine, I didn’t have much time for blogging lately, but still I would like to share with the world my “change of affiliation” so here it is: since yesterday I’m officially part of the amazing team at Endless, an awesome start up from San Francisco committed to break the digital divide in the developing world by taking GNOME-based technology to the end users in ways that were not imaginable before. And I have to say that’s a vision I fell in love with since the very first time I heard about it (last year in Brno, during Matt’s keynote at GUADEC).

But just in case that was not awesome enough by itself, the other thing that made me fall in love with the company was precisely the team they have assembled, because even if I’m mostly a technical guy, I still value a lot the human side of the places I work in. And in this regard Endless seems to be perfect, or even better!

So, I’m extremely happy these days because of this new challenge I’m seeing in front of me, and because of the opportunity I’m being given to have a real positive impact in the lives of millions of people who still can’t access to technology as they should be able to do it. Also, I feel blessed and privileged for having been given the chance to be part of such an amazing team of people. Could not be happier at this time! :)

Last to finish this post, I would like to say thanks to my friend Joaquim, since he was who introduced me to Matt in the first place and “created” this opportunity for me. Thank you!

14 de agosto de 2014

HackIt! 2014 _ Level 6

¿Level 6? ¿Y qué ha pasado con el level 5? El nivel 5 está cocinándose en el server de @marcan42 (prepararlo sobre un server con arquitectura Big Endian requiere su tiempo ;-). Así que vamos a por el level 6. No pudimos superarlo en la competición. Tras la Euskal, con ayuda de Timosoft, supimos por […]

13 de agosto de 2014

HackIt! 2014 _ Level 4

“Bitcode. Esta vez te toca investigar lo profundo de Python.” Para ello, nos pasan un fichero tar.gz que contiene un archivo (texto plano) y otro routines.pyc (binario). # from routines import chk_serial   _in = raw_input("Do you feel lucky?: ") print chk_serial(_in) Así que lo que queda por hacer es entender la función […]

11 de agosto de 2014

HackIt! 2014 _ Level 3

nyan0verflow, “No siempre todo es lo que parece. Y lo que aparece no es siempre el todo”. Con la foto de un gato (no es nyan cat ;-) y el texto anterior empieza el tercer reto del HackIt! Atendiendo al nombre de la imagen, a simple vista parece que han usado algún algoritmo de esteganografía […]

10 de agosto de 2014

HackIt! 2014 _ Level 2

El nivel 2 del HackIt! tiene como título “Nivel Cromado”. Nos indican que es un nivel sólo compatible con Google Chrome (o Chromium). También hay un enlace a un fichero hackit.crx (una extensión para Chrome). Para instalarla en Chrome lo tuvimos que hacer descomprimiéndola y cargándola desde el botón “Cargar extensión descomprimida” del menú chrome://extensions/ […]

08 de agosto de 2014

HackIt! 2014 _ Level 1

24 de julio, a alguna hora de la noche cercana a las 22:00. Mis compañeros de DL me indican que marcan ha dado comienzo al HackIt de este año. Esta vez no podré acudir a la presentación y me tendré que aguantar hasta el viernes 25 a eso de las 18:00, así que estaré un […]

06 de agosto de 2014

GTK+ 3 Plugins in WebKitGTK+ and Evince Browser Plugin

GTK+ 3 plugins in WebKitGTK+

The WebKit2 GTK+ API has always been GTK+ 3 only, but WebKitGTK+ still had a hard dependency on GTK+ 2 because of the plugin process. Some popular browser plugins like flash or Java use GTK+ 2 unconditionally (and it seems they are not going to be ported to GTK+ 3, at least not in the short term). These plugins stopped working in Epiphany when it switched to GTK+ 3 and started to work again when Epiphany moved to WebKit2.

To support GTK+ 2 plugins we had to build the plugin process with GTK+ 2, but also some parts of WebCore and WebKit2 (the ones depending on GTK+ and used by the plugin process) were built twice. As a result we had a WebKitPluginProcess binary of ~40MB, that was always used for all the plugins. This kind of made sense, since there were no plugins using GTK+ 3, and the GTK+ 2 dependency was harmless for plugins not using GTK+ at all. However, we realized we were making a rule for the exception, since most of the plugins don’t even use GTK+, and there weren’t plugins using GTK+ 3 because they were not supported by any browser (kind of chicken-egg problem).

Since WebKitGTK+ 2.5.1 we have two binaries for the plugin process: WebKitPluginProcess2 which is exactly the same 40MB binary using GTK+ 2 that we have always had, but that now is only used to load plugins using GTK+ 2; and WebKitPluginProcess, a 7,4K binary that is now used by default for everything except loading plugins that use GTK+ 2. And since it links to GTK+ 3, it might load plugins using GTK+ 3 as well. Another side effect is that now we can make GTK+ 2 optional, WebKitPluginProcess2 wouldn’t be built and only plugins using GTK+ 2 wouldn’t be supported.

Evince Browser Plugin

For a long time, we have maintained that PDF documents shouldn’t be opened inside the browser, but downloaded and then opened by the default document viewer. But then the GNOME design team came up with new mockups for Epiphany were everything was integrated in the browser, including PDF documents. It’s something all the major browsers do nowadays, using different approaches though (Custom PDF plugin inside the web engine, JavaScript libraries, etc.).

At the WebKitGTK+ hackfest in 2012 we started to think about how to implement the integrated document reading in Epiphany based on the design mockups. We quickly discarded the idea of implementing it as a NPAPI plugin, because that would mean we had to use a very old evince version using GTK+ 2. We can’t implement it inside WebKit using libevince because it’s a GPL library, so the first approach was to implement it inside Epiphany using libevince. I wrote a first patch, it was mostly a proof of concept hack, that added a new view widget based on EvView to be used instead of a WebView when a document supported by evince was requested. This approach has a lot of limitations, since it only works when the main resource is a document, but not for documents embedded in a HTML page or an iframe, and a lot of integration problems that makes it quite difficult to maintain inside Epiphany. All of these issues would be solved by implementing it as a NPAPI plugin and it wouldn’t require any change in Epiphany. Now that WebKitGTK+ supports GTK+ 3 plugins, there’s no reason not to do so.

Epiphany Evince Plugin

Thanks to a project in Igalia I’ve been able to work on it, and today I’ve landed an initial implementation of the browser plugin to Evince git master. It’s only a first implementation (written in C++ 11) with the basic features (page navigation, view modes, zoom and printing), and a very simple UI that needs to be updated to match the mockups. It can be disabled at compile time like all other frontends inside Evince (thumbnailer, previewer, nautilus properties page).

Epiphany embedded PDF document Epiphany standalone PDF document

Another advantage of being a NPAPI plugin is that it’s scriptable so that you can control the viewer using JavaScript.

Epiphany scriptable PDF

And you can pass initial parameters (like current page, zoom level, view mode, etc.) from the HTML tag.

<object data="test.pdf" type="application/pdf" width="600" height="300" 
                currentPage="2" zoomMode="fit-page" continuous="false">
  The pdf could not be rendered.

You can even hide the default toolbar and build your own one using HTML and JavaScript.

01 de agosto de 2014

WebKitGTK+ 2.5.1: Good bye WebKit1

WebKitGTK+ 2.5.1 is the first version of this release cycle. It comes very late mainly due to the regressions introduced by the switch to CMake and the problems we found after removing WebKit1 from the tree. It also includes some new features that I’ll talk about in other posts, probably when 2.6.0 is released. In this post I’ll only focus on the breaks introduced in this release, in order to help everybody to adapt their applications to the API changes if needed.

Wait, but why breaking the API?

Since the release of WebKitGTK+ 2.0 the WebKit1 API has been considered deprecated and in maintenance mode. The new WebKit2 API is quite complete and stable now, so the plan for WebKitGTK+ 2.6 was removing WebKit1, leaving it alive, but still in maintenance mode, in the 2.4 branch. After removing the code from trunk we realized that newer versions of WebKitGTK+ that are WebKit2 only should be parallel installable with older versions of WebKitGTK+ that also include WebKit1. After some discussions trying to find the best solution, we reached the conclusion that we had to bump the binary version. But then I thought, since we were going to force everybody to recompile, why not take advantage to introduce some small (but necessary) API changes that in most of the cases will not affect the the users anyway? And then I started to review the API and proposing some changes. I also wanted to make sure all API changes were introduced in the first unstable release, so that users only have to adapt their applications once, and that’s the main reason why the release has taken so long.

Binary version bump

The new binary version is 4.0, so to use this new release you need to update your build system to look for webkit2gtk-4.0 pkg-config file.

GObject DOM Bindings

The GObject DOM bindings API situation was actually the main reason for breaking the API. The problem was that the code for the DOM bindings is generated automatically from the IDL files. This means that every time a new IDL file was added to the build system, we ended up exposing a new class in our public API without even noticing. Same happened when a API incompatible change was introduced in an IDL file, for example to update it to the current standard. We added a script to our build bots to warn us when that happened, and then we had to manually deprecate the existing API and add exceptions to the code generator. This was a lot of work just to keep backwards compatibility of an API nobody was using. Most of the people actually use a 5-10% of the DOM bindings API.

Since WebKitGTK+ 2.5.1 the GObject DOM bindings API is split into stable and unstable parts. The stable part contains the most commonly used API that it’s unlikely to change. We will keep maintaining backwards compatibility of this part of the API. The rest of the API is considered unstable and might change at any time, you can still use it but at your own risk. We thought this solution was better than just removing the unstable API. There are two kind of unstable APIs:

  • Classes that are considered unstable: the entire class is considered unstable. The header is not included in the main webkitdom.h header, so to use them you have to include the header file explicitly.
  • Unstable symbols of stable classes: a method or constant in a stable class that is considered unstable. In this case the header file is included by the main webkitfom.h header, but it doesn’t contain any unstable symbols, they are included in a new header WebKitDOMClassNameUnstable.h that also needs to be included explicitly.

In both cases you need to define WEBKIT_DOM_USE_UNSTABLE_API before including the headers

#include <webkitdom/WebKitDOMHTMLMediaElement.h>
#include <webkitdom/WebKitDOMElementUnstable.h>

WebKit2 GTK+ API

The API changes in the WebKit2 GTK+ API could have been avoided, by deprecating symbols and adding new ones, but since we were going to break the API anyway, and the affected symbols are not that commonly used we thought it was worth it.

  • WebKitWebView::create: the signal now receives a WebKitNavigationAction parameter containing information about the navigation action that triggered the event. So now you can know the type of event (if it was a link clicked, a form submitted, etc.), the mouse button and keyboard modifiers, the URI request or even if it was a user gesture. This information is very useful to implement a popup blocker, for example.
    /* before */
    static WebKitWebView *
    web_view_created_cb (WebKitWebView *web_view,
                         gpointer       user_data)
    /* after */
    static WebKitWebView *
    web_view_created_cb (WebKitWebView          *web_view,
                         WebKitNavigationAction *navigation_action,
                         gpointer                user_data)
  • WebKitWebViewGroup has been removed. This class was only introduced to add the user stylesheets API, since most of the people actually use the default web view group. The grouping of pages inside WebKit2 is something that will be eventually removed, in favor of users doing the groups they need. The user stylesheets API has been moved to a new class WebKitUserContentManager that will also be extended to support user scripts. The settings can still be handled directly with the WebKitWebView API, so that if you want a group of web views to share the same settings you can simply call webkit_web_view_set_settings() for all the web views passing the same WebKitSettings object.
    /* before */
    WebKitWebViewGroup *group = webkit_web_view_get_group (web_view);
    webkit_web_view_group_add_user_style_sheet (group, 
                                                NULL, /* base URI */
                                                NULL, /* whitelist */
                                                NULL, /* blacklist */
    /* after */
    WebKitUserContentManager *user_content;
    WebKitUserStyleSheet     *style_sheet;
    style_sheet = webkit_user_style_sheet_new (buffer,
                                               NULL, /* whitelist */
                                               NULL /* blacklist */);
    user_content = webkit_web_view_get_user_content_manager (web_view);
    webkit_user_content_manager_add_style_sheet (user_content, style_sheet);
    webkit_user_style_sheet_unref (style_sheet);
  • WebKitCertificateInfo has been removed. This was supposed to be a convenient way of handling TLS certificates, but when trying to use it in a real case, it ended up being unconvenient. The WebKitWebView::load-failed-with-tls-errors signal now receives a GTlsCertificate and TlsCertificateFlags, and webkit_web_context_allow_tls_certificate_for_host() receives a GTlsCertificate.
    /* before */
    static gboolean
    load_failed_with_tls_errors_cb (WebKitWebView         *web_view,
                                    WebKitCertificateInfo *info,
                                    const gchar           *host,
                                    gpointer               user_data)
      WebKitWebContext *context = webkit_web_view_get_context (web_view);
      GTlsCertificate *certificate = webkit_certificate_info_get_tls_certificate (info);
      GTlsCertificateFlags errors = webkit_certificate_info_get_tls_errors (info);
      if (add_exception_for_error (host, errors))
        webkit_web_context_allow_tls_certificate_for_host (context, info, host);
    /* after */
    static gboolean
    load_failed_with_tls_errors_cb (WebKitWebView       *web_view,
                                    GTlsCertificate     *certificate,
                                    GTlsCertificateFlags errors,
                                    const gchar         *host,
                                    gpointer             user_data)
      WebKitWebContext *context = webkit_web_view_get_context (web_view);
      if (add_exception_for_error (host, errors))
        webkit_web_context_allow_tls_certificate_for_host (context, certificate, host);
  • View mode API: The view source mode was removed from WebCore, and the API was already marked as deprecated. Since it’s very unlikely we add more view modes, we just removed the API. There’s no replacement for this, but it could be easily implemented either using a external window with a GtkSourceView or embedded into a WebKitWebView by using a custom URI scheme and a JavaScript library for syntax highlighting.


Since version 2.5.1 WebKitGTK+ uses CMake instead autotools as its build system. The equivalent to configure, make and make install now would be something like this:

$ cd webkitgtk-2.5.1
$ make
(enjoy the summer in the meantime)
# make install


Sure, we are available as usual in the #webkitgtk+ IRC channel at FreeNode and our mailing list

30 de julio de 2014

Evince Hackfest

The Evince hackfest took place last week from 23rd to 25th July in Strasbourg. Yes, 3 days only, but very productive in my opinion, I’ll summarize all the cool stuff we worked on.


This work was initially started by Owen, and then Germán kept the patches up to date with evince git master. I reviewed all the pending patches and updated the thumbnails one and the result is that evince doesn’t look blurry on HiDPI screens any more.

Evince running with GDK_SCALE=2

Evince running with GDK_SCALE=2

Recent View

This was a GSoC project of 2013, but the patch provided by the student was never in an “upstreamable” state. Again Germán, who always loved this feature, took care of the patch addressing my review comments. At the beginning of the hackfest most of the work has already been done, we only needed a few more review iterations during the hackfest to finally push this feature to master. The idea is to show the list of recent documents as an icon view with thumbnails and documents metadata. This view is loaded when evince is launched without any document replacing the useless empty window we had before. It also replaces the recent documents submenu in the gear menu.

Evince Recent View

UI improvements

The move to the header bar recently made the toolbar look a bit cluttered, mainly because the title might use a lot of space. We discussed several ideas to improve the header bar and implemented some of them:

Evince header bar improvements


Juanjo Marín also wrote a patch to change the default zoom mode to “Automatic”, since several people commented that the current “Fit Width” mode doesn’t look good in screens with higher resolutions. The patch is still waiting review.


Giselle and Anuj, our GSoc students this year, worked on their projects to improve the annotations support in both Evince and poppler.

    • Anuj wrote some patches to add support for Free Text annotations to poppler glib API. After a couple of review iterations and discussions about the API, the patches are now in bugzilla waiting for a final review (I hope to find the time soon)
    • Giselle was focused on adding support for highlight annotations to Evince, since poppler already has all the required API for this. The patches are not yet ready, but they look really promising.


Caret navigation and accessibility

Joanie and API continued improving the evince a11y support and fixing some remaining issues from the FoG project. Antía fought with the caret navigation implementation again to implement some missing key bindings and fixing other issues.

Comics backend

Juanjo Marín focused on the comics backend, working on a patch to use libarchive to uncompress the documents instead of spawning external command line tools.


I started to review the gestures branch during the hackfest, patches looked clean and simple, but since I was not familiarized with the new GTK+ touch API and I didn’t have a touch screen to try it out either, I decided to wait after the hackfest and see it in action in garnacho’s laptop during GUADEC. Carlos explained to me how the touch API works in GTK+ and I could check it actually works great. The code doesn’t affect the normal use with the mouse, so the branch will be merged in master soon.

Evince hackfest dinner

And of course not everything was hacking


Many thanks to Alexandre Franke for the local organization, everything worked perfectly. Of course thanks to the GNOME Foundation for sponsoring the GSoC students, Giselle and Anuj, and Igalia for sponsoring all the Igalians attending the hackfest. Thanks also to Epitech for allowing us to do the hackfest there before the GUADEC.

Igalia S.L. GNOME FoundationEPITECH

06 de julio de 2014

Bloqueando el seguimiento de Facebook con Adblock Plus

Hace unos días leí en Genbeta que en Adblock Plus se podía bloquear el seguimiento que hace Facebook de nuestra navegación añadiendo la lista”Fanboy’s Annoyance List” disponible en la web de las diferentes listas de bloqueo de Adblock Plus. Esta lista, en realidad, bloquea botones “+1″, “Me gusta” y demás que podamos poner en nuestras páginas (y que permiten a Facebook y compañía hacernos seguimiento cuando navegamos por cualquier web que los incorpore).

Sin embargo, no era suficiente: veía que en muchas páginas seguía apareciendo mi usuario para introducir comentarios, con lo que entendí que Facebook estaría, de nuevo, siguiéndonos. Comprendo que a mucha gente no le apetezca que le sigan, así que busqué información y encontré la forma de arreglarlo en esta entrada del foro de Adblock Plus: se trata de bloquear los plugin “sociales” de Facebook. Y listo. Eso sí, en las páginas afectadas ya no podremos hacer comentarios.

En realidad, estos trucos los suelo tener desactivados. Pero comprendo que a mucha gente le preocupe, y con razón, el seguimiento que los grandes de Internet hagan de la actividad de los usuarios, incluso navegando fuera de sus sitios web.

Dejo abajo el vídeo. Seguro que muchos tenéis reglas para bloquear otros plugins “sociales” de Google+, twitter, Youtube y demás. Agradezco comentarios.

PD: Si te ha gustado este artículo, haz “Me gusta” ya puestos X-))" frameborder="0" type="text/html" class="__youtube_prefs__" allowfullscreen webkitallowfullscreen mozallowfullscreen >

25 de junio de 2014

C#/Cocoa – Animate a split view’s collapsing/expanding

When I started working at Xamarin, I had the intention to blog about new technologies I was learning, but it’s been already 6 months and it didn’t happen at all, so better to start late than never. I’ll start then with a nice piece of code I came up with, and which is this:

public static class CocoaExtensions
	public static void AnimatedSetPositionOfDivider (this NSSplitView splitView, float position, int divider)
		var view0 = splitView.Subviews [0];
		var view1 = splitView.Subviews [1];

		var newFrame0 = view0.Frame;
		var newFrame1 = view1.Frame;
		if (splitView.IsVertical) {
			newFrame0.Width = position == 0 ? 0 : position - splitView.DividerThickness;
			newFrame1.Width = position == splitView.MaxPositionOfDivider (divider)
				? 0
				: splitView.Bounds.Width - position - splitView.DividerThickness;
		} else {
			newFrame0.Height = position == 0 ? 0 : position - splitView.DividerThickness;
			newFrame1.Height = position == splitView.MaxPositionOfDivider (divider)
				? 0
				: splitView.Bounds.Height - position - splitView.DividerThickness;

		newFrame0.Width = newFrame0.Width < 0 ? 0 : newFrame0.Width;
		newFrame0.Height = newFrame0.Height < 0 ? 0 : newFrame0.Height;
		newFrame1.Width = newFrame1.Width < 0 ? 0 : newFrame1.Width;
		newFrame1.Height = newFrame1.Height < 0 ? 0 : newFrame1.Height;

		view0.Hidden = view1.Hidden = false;
		view0.AutoresizesSubviews = view1.AutoresizesSubviews = true;

		if ((newFrame0.Width == 0 && newFrame0.Height == 0) ||
		    (newFrame1.Width == 0 && newFrame1.Height == 0)) {

		var singleAnimation0 = new NSMutableDictionary ();
		singleAnimation0 [NSViewAnimation.TargetKey] = view0;
		singleAnimation0 [NSViewAnimation.EndFrameKey] = NSValue.FromRectangleF (newFrame0);

		var singleAnimation1 = new NSMutableDictionary ();
		singleAnimation1 [NSViewAnimation.TargetKey] = view1;
		singleAnimation1 [NSViewAnimation.EndFrameKey] = NSValue.FromRectangleF (newFrame1);

		var animation = new NSViewAnimation (new NSDictionary[] { singleAnimation0, singleAnimation1 });
		animation.Duration = 0.25f;
		animation.StartAnimation ();

The main reason to share this code is because I couldn’t find anything that worked to do that (animate the collapsing and expanding of a NSSplitView, which is, yes, you got it right, a split view, like GTK’s GtkPaned), so I hope it is useful for someone. But it also shows a few interesting things about both C# and Cocoa:

  • The most obvious one: writing Cocoa apps in C# is much better than using Objective C (although, to be honest, I also like Objective C).
  • Cocoa (and CoreAnimation) lets you easily add animations to your UI, by having the animations layer tightly integrated into the API. Of course, animations are not always great, but in some cases, like this one where the collapsing/expansion of the split view’s subviews is animated, it makes such a huge difference to the UI that it’s very nice to be able to do it that easily.
  • C# allows extending existing classes, by writing extension methods (static methods in static classes that have a “this” modifier in the 1st argument, which specifies the class the method extends). This is a great way to extend existing classes, without having to do any subclassing. Once you have the extension method, you can just call it on any NSSplitView:
    mySplitView.AnimatedSetPositionOfDivider (position, divider);

    You can extend any class, and this what a lot of technologies (LINQ, Reactive Extensions, etc) in the .NET world use.

I started also, when I started working at Xamarin, getting some of the nice ideas from Cocoa and C# into GLib/GTK, so will publish that as soon as I get something useful from it. Hopefully it won’t be another 6 months :-D

And yes, Xamarin is hiring. If interested, drop me a mail, or just apply directly, as you wish.

17 de junio de 2014

Frogr 0.10 released

frogrQuick post to let the world know that I’ve just released a new version of frogr right now, in order to address a few issues present in the previous version. Mainly:

  • Deprecation of non-SSL end points for the Flickr API (see these two posts for more info). From now on, frogr will use SSL-only API calls.
  • Address issues with frogr‘s AppData file. Apparently, the AppData file was neither valid (according to appdata-validate) nor being installed properly, preventing frogr from showing up nicely in the GNOME Software app.
  • Allow disabling video uploads at configuration time (enabled by default), instead of making the decision depending on the detected platform. This will hopefully make life easier for packagers of other platforms (e.g. MacPorts).
  • Removed libsoup-gnome code once and for all (API deprecated a while ago).
  • Other things: updated translations and fixed a few minor bugs.

As usual, feel free to check the website of the project in case you want to know more about frogrhow to get it or how to contribute to it.

04 de junio de 2014

Receta rápida para optimizar MySQL

Siguiendo con el post anterior (recordemos, tengo un servidor muy humilde en recursos que quiero aprovechar al máximo), le toca el turno al servidor MySQL. Tengo un libro (High Performance MySQL, de la editorial O’Reilly) que -entre otras cosas- se dedica a explicar cómo obtener el mejor rendimiento de un servidor MySQL, así que en […]

31 de mayo de 2014

Desactivando módulos innecesarios en Apache

Tengo un servidor Apache montado en una máquina física muy justita de recursos (especialmente de memoria RAM). El servidor Apache que viene por defecto tendría que cambiarlo por nginx. Por lo que dicen en los mentideros de Internet parece que consume menos recursos que Apache… mientras tomo la decisión de migrar, he optado por recortar […]

29 de mayo de 2014

Introducción a Open edX (III). Devstack

Como dijimos en el anterior post, Devstack es una instancia Vagrant diseñada para facilitar la vida a los desarrolladores de Open edX. Diferenciaremos Devstack de Fullstack en que ésta última es una instancia Vagrant diseñada para tener todos los servicios de edX en un único servidor de producción. Además, Devstack simplifica algunas características de Fullstack para hacerlo más ligero […]

27 de mayo de 2014

Introducción a Open edX (II)

La arquitectura de la plataforma edX cuenta con varios componentes, tal y como puede apreciarse en la figura adjunta. Iremos desgranando todos ellos en diferentes posts. Hoy empezaremos a tratar los dos más importantes: el LMS (Learning Management System) y el CMS (Content Management System), éste último también conocido como edX Studio. El primero (LMS) forma […]

21 de mayo de 2014

Introducción a Open edX

Los que leéis este blog ya sabéis qué es un MOOC (Massive Open Online Course). Lo que no se suele tratar tanto es la infraestructura que hay detrás. ¿Qué sistema permite ofrecer cursos masivos online con alta disponibilidad y multitud de características asociadas a estos MOOC (soporte de vídeos, subtítulos, evaluación colaborativa, distintos tipos de […]

20 de mayo de 2014

Banshee GSoC-2014 projects under Gnome umbrella

Here we are, at the beginning of a great summer!

This time, Google has given plenty of slots to the GNOME project, so we could accept many participants, including 3 brilliant students to work on the Banshee project. In case they haven't blogged about it, or didn't give much detail, I'll elaborate a bit about what they will be aiming to do these months:

  • Nicholas Little will be working on creating a new extension for Bluetooth synchronization, and if time permits, refactoring our MTP support. In regards to the latter, if you have an Android phone you might have experienced some bugs getting it to work with Banshee lately (our MassStorage synchronization support is great, but the latest versions of Android have been deprecating this mode in favour of MTP, which we never supported very well); we have been working hard on fixing them, but Nicholas is going to try to give it that extra push at the end of the summer, which I'm confident he will do very well (he was the developer who brought Symbian support for the masses -or rather, for his Nokia N95 ;) -, on Banshee 2.9.0). And you may be wondering, why do we need Bluetooth sync? Well, we understand that it's much slower than USB or Wifi, but:
  1. USB can work for the first sync, but whenever you update your library, I never remember to connect my phone again with my cable, or I'm too lazy to do it. Now imagine that whenever your phone is near your computer (and of course if you have Banshee running), they could negotiate together to update the sync without the need of moving a finger!
  2. Wifi could work also for the use case I just explained, but getting Wifi to work, compared to Bluetooth, would involve creating an app for the phone that could talk with Banshee. And we all know what are the problems associated with that: we would need to be cross-platform for at least the 3 main mobile platforms out there (well, iOS wouldn't even work neither with this nor with Bluetooth, because there are no public APIs to integrate with the music database of the OS, sigh iTunes...), and that means a lot of maintenance burden (even if we choose a same-language native platform like Xamarin), and a user experience that is not so seamless (as it would require the user to install an app first).
  • Marcin Kolny, which has convinced us that he will do a great job given his great patches and the fact that he's already very involved in opensource (maintainer of C++ bindings to GStreamer if I recall correctly), will be working on integration with AcoustID. To summarize it very bluntly, AcoustID is the open-source alternative to Shazam, so thanks to this, if you have many tracks in your library which didn't get ripped properly with tags, or you got from some friend which is not very metadata-driven ;) then you will be able to fix this situation! We will be likely reusing the MetadataFixer extension that we already have in Banshee, to not reinvent the UI wheel.
  • Dmitriy Petukhov, a very motivated Russian student, will be helping us get two extensions in shape, which were developed in the last GSoC (more details about this in my previous blog post), but were not ready for mainstream yet. The FanArt.TV extension, which retrieves artist logos and shows them next to your album icons, needs some caching (we could even violate FanArt.TV service's ToS if we don't do this) and UI polish (our ListView widget doesn't play well with differently-sized images, so we need to modify this custom GTK widget to allow rendering rows with different heights). The SongKick extension works great, but also needs caching, and it especially needs GeoLocation to maybe even work autonomously (imagine, you don't even know what SongKick is, and because you installed the banshee-community-extensions package of your distro, you suddenly get told that one of your favorite bands is soon playing a gig near your city!).
As you can see, most things are work under-the-hood this year, with little UI work. That's good for me because I'm no design expert. However, there is one area which we could do with some help: the new backgound tasks that will be implemented will need a way to notify the user (i.e. SongKick: when a new gig is discovered; AcoustID: when new/better metadata is found). In this respect, maybe Hylke Bons (our chief designer for the last Gnome .NET hackfest) and Garrett LeSage (assistance that Hylke proposed now to avoid getting himself swamped!) will be able to help! (BTW, if you're interested in participating in this year's Gnome .NET hackfest, message David Nielsen, which started to plan it recently.)

I'm very happy about starting the mentoring of these projects this year. And I'm specially jealous about my students... I became mentor of GSoC myself without being GSoC student first! (Maybe I should switch roles in the future?)

Wish them good luck! It was actually just yesterday when GSoC really started! (gotta love mondays)

UPDATE: Fixed embarrassing typo: I meant AcoustID, not OpenID!

09 de mayo de 2014

A late devX hackfest report, gestures

Last week the developer experience hackfest took place in Berlin. Quite some blogging has happened during and since, nonetheless this was a pretty good excuse to blow the cobwebs off my blog and chime in too :).

The event was quite intense, plenty of discussion happened around the GNOME platform, developer tools, API documentation generation, and introspection. My main point of interest there was GTK+, it was great to see a roadmap shape up, and a consensus about the gestures branch (more about that below). I also offered to look into doing something that could replace GtkNotebook in the future, which I started hacking on during the hackfest. I also had a nice opportunity to chat with Philip about Freebase support in libgdata, and solve a few questions around Tracker.

Other than that, nice chatting, and a very fine choice of places for food and beverages. Many thanks to Chris Kühl and the Endocode guys for making this as much enjoyable!


One point in the GTK+ meeting agenda was gesture support. The gestures branch (which has had a somewhat intermitent history during the last ~2.5 years) has lately shaped up into something that was agreed mergeable for 3.14. This branch introduces “gesture” objects that abstract away all the intricacies of (multi)touch management. These objects handle events, tracking individual touches, when gestures enters in a “recognized” state, high-level signals will be emitted. This has been made to work parallelly to regular event delivery, in order to allow for different degrees of interoperation with handlers there, and making single-touch gestures to work with pointer events is just a call away.

There is of course a need of cooperation between gestures, both within a widget, and across the widget “stack” that’s receiving events for each individual touch, each of those will be triggering a number of gesture objects as the touchpoint moves. To cater for that, gestures have a none/claimed/denied state on each tracked touch, and changes in those are communicated across the stack (possibly causing cancellation on child widgets also handling the touchpoint, or cancelling other same-level gestures that previously claimed the sequence).

Intra-widget, some simultaneity may be wanted when handling touchpoints (eg. long press and nth-click handling), gestures may be grouped so those share the same state and can act upon the same events, a widget can have multiple mutually-exclusive gesture groups (eg. scrolling and “switch page” panning on a scrolledwindow).

So that is it! in a very tiny nutshell, the API added in the branch is documented, that will be a more accurate source :). Now, a video showcasing this, unedited because Pitivi didn’t get along today. A 42 seconds journey from well-known lands to barren plains of insanity, made manageable thanks to this branch:

The branches for eog and evince are available too, for anyone willing to play soon with this. But as said, hopefully everything will be soon in master!

05 de mayo de 2014

GSoC 2013 with Gnome

So let this be a belated report about previous GSoC! sorry for the delay.

In summer 2013, Tomasz Maczynski worked on Banshee as a GSoC student, and he did great work! He developed a SongKick extension, and a one. Both were worked on in the banshee-community-extensions repository. They work very well but there are a few downsides about this work, which we didn't have time to fix:
  • The FanArt.TV extension depended on some Banshee API that hasn't been added yet to mainline. The patch to add it lived in bugzilla for a while, in a bug about a feature request to have images in the artist list. The reason for not committing the patch even if I had already reviewed it was because I was wary about it, since it allowed FanArt.TV to hook its ArtistList widget, but wouldn't be really extension friendly. What I mean is that if there was other extension that wanted to also attach a different ArtistList, it would conflict with FanArt extension when enabled at the same time. The ideal thing would be to expose this functionality as an extension point, so that if more than one extension attached a new kind of ArtistList widget, the user could switch between the two from the UI when both extensions were enabled. When I mentioned this in the bug, awesome Banshee-extension developer Frank Ziegler jumped in and created the extension interface necessary for this. I've been reviewing the patches in the last days (couldn't do it before because I really wanted to release 2.9.1 and 2.6.2 versions before landing this work) and I'll likely commit them this week.
  • The FanART.TV extension uses Hyena's ListView widget to show images. This is the main widget that Banshee uses for showing the tracks in the main view. It's a great custom widget because it allows very fast rendering of data coming from an SQLite database, but it wasn't optimized for rendering images. The main disadvantage of it is in the case that images have different heights, because the ListView will just allocate a height for each row equal to the tallest of the images used. This means that the widget shown could be a bit ugly if you have many artists in your library and some of them have very differently sized images. Tomasz worked on this a bit, but couldn't finish it because of lack of time (we have a WIP patch). But fortunately this will be fixed this summer!
  • Both SongKick and FanArt.TV don't implement caching yet. This is not only important to save bandwidth from the point of view of the client, but also from the point of view of the server! (We could even violate their ToS if we didn't implement this, IIRC.) Fortunately this will be fixed this summer!
  • SongKick extension provides several ways to discover gigs: searching by city, by artist, etc. It even suggests you artists extracted from your library that composed songs which you marked with a high rating! But IMO this is not enough, SongKick extension should even be smarter and query ahead of time looking for your favorite artists *and* near your area (doing the latter via GeoLocation). Fortunately this will be fixed this summer! (and we will use Gnome infrastructure for it)

That is all folks! Stay tuned for the next blog post, which will explain the plan for GSoC 2014 (this year I get to mentor three students!).

03 de mayo de 2014

Belated Gnome .NET Hackfest post

OMG, I should feel embarrassed about posting such a belated blog post (yes, the hackfest was more than 6 months ago), but oh well, at least I can say I have enough excuses:
  • I got my house refurbished in the last months, which has been such a long planning endeavour, and a real stressful PITA while it was being done.
  • Before the above started, and after it was finished, I had to move, so that's 2 moves! (I hate moving)
  • I've been kind of busy in regards to Gnome-related contributions: we released Banshee 2.6.2, GStreamer-Sharp 0.99.0, Banshee 2.9.1, and a big etcetera (including pre-mentoring for GSoC! more about that in a subsequent post).
So this doesn't leave enough room for blogging, which is a necessary but a less appealing task. But I have to say it somewhere: the hackfest that David Nielsen organized was amazing, the best kind I have attended so far, as I came to meet for the first time some awesome hackers such as him, and:
  • Hylke Bons, sparkleshare creator, Red Hat designer.
  • Mirco Bauer, smuxi creator and debian developer (mono packager).
  • Jo Shields, debian developer (mono packager), Collabora sysadmin.
  • Robert Nordan, Pinta contributor.
  • Jared Jennings, Tomboy contributor.
  • Stephen Shaw, ex-Novell coworker (build developer), and currently at Xamarin. (Yes, I was Stephen's team-mate when at Novell, but had never met him in person!)
  • Stefan Hammer, Tomboy contributor and hackfest local-host.
  • Timo Dörr, Tomboy and Banshee contributor, GSoC student.
  • Stephan Sundermann, GSoC student for GStreamerSharp and Bindinator.

(BTW I didn't include the awesome Bertrand Lorentz, fellow Banshee co-maintainer and GtkSharp gatekeeper, in the list, because I had already met him before, it wasn't my first time!).

And it was with the latter Stephan (not Stefan) the one I ended up spending more time with, because we decided to work on the new GStreamerSharp bindings since the 2nd day of the hackfest (the 1st day I mainly worked with Bertrand to release Banshee 2.9.0, our first Gtk3 compatible release, which he already blogged about).

So what was special about this work?
  • GStreamerSharp 0.10.x releases were not compatible with GStreamer 1.x releases, so this had to be fixed soon. However, much of the architecture of this old version of the bindings used many manually crafted binding code.
  • Stephan, by using the new Bindinator (a GObjectIntrospection metadata parser that outputs GAPI metadata, that allows generating .NET bindings, created by Andreia Gaita) in his GSoC, created a better foundation for the new bindings.
  • He targetted GI metadata from GStreamer 1.0 and 1.2 versions (the jump from 0.10 to 1.0 was a big and not easy leap, since lots of APIs were modified and deprecated).
  • We needed to polish them enough to make Banshee be able to consume them without glitches.
"Polish" sounds like easy work, but it wasn't. We fixed lots of crashes, and we contributed fixes to GObject-Introspection metadata upstream. And we proposed big patches for the gtk-sharp GAPI generator. And of course we updated our Banshee managed playback backend to the new GStreamerSharp API.

Main kudos should go to him though. I mainly added Banshee expertise, gtk-sharp contributing expertise, and lots of motivation (or at least I thought).

We had a big success: a Banshee playing audio with GStreamerSharp. Unfortunately video playback was freezing. But some months later after the hackfest we fixed it, and we released first GStreamerSharp 1.0 preview, which we called "0.99.0", and we released the first Banshee release that depends on this work: 2.9.1.

And it was my first time in Austria (and in Vienna). Overall a great experience, and I need to mention our awesome sponsors:

The GNOME Foundation, providers of the GNOME desktop

The University of Vienna and the Institute for Theoretical Chemistry, our venue sponsors

Collabora Ltd, Open Source Consulting

Norkart AS, Norway’s premier supplier of Geographic Information Systems and related consulting

Novacoast IT, Professional Services and Product Development

Hotel Schottenpoint, our hotel partner

28 de abril de 2014

Tu país también se merece otra bandera

Porque la República Checa también se merece otra bandera, con sus estereotipos y su todo:

New flag of the Czech Republic

La todopoderosa cerveza.
Los malditos knedliky.
Los cutres zapatos que casi todos llevan en el trabajo.

Etiquetas: , ,

11 de abril de 2014

09 de abril de 2014

perl: warning: Setting locale failed

Conectamos por ssh contra nuestro servidor, lanzamos un comando erróneo y aparte del mensaje de error el intérprete de comandos nos suelta el siguiente sermón: # comando erróneo perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LC_PAPER = "es_ES.UTF-8", LC_ADDRESS = "es_ES.UTF-8", LC_MONETARY = […]

08 de abril de 2014

Parchear Ubuntu para evitar el bug OpenSSL Heartbleed

Ayer a la tarde se levantó una buena polvareda con el bug Heartbleed de OpenSSL. Básicamente, cualquier usuario podría acceder a una zona de 64Kb de memoria del servidor, cercana a la zona donde se gestionan las operaciones con SSLv3. Esto podría llegar a permitir acceder a información privilegiada, como por ejemplo la clave privada […]

06 de abril de 2014

04 de abril de 2014

01 de abril de 2014

Resize de volúmenes en LVM

Tenemos un sistema de discos LVM con las siguientes “particiones”: [juanan@S000161 ~]$ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_s000161-lv_root 50G 39G 8.6G 82% / tmpfs 5.8G 316K 5.8G 1% /dev/shm /dev/mapper/ddf1_4c5349202020202080862925000000004711471100001450p1 485M 58M 402M 13% /boot /dev/mapper/vg_s000161-lv_home 395G 87G 288G 24% /home Si nos fijamos, el volumen lógico (lv) asignado a / […]

30 de marzo de 2014

Primeros días con Ubuntu 14.04: problemas wifi y otros

Ya me pasé a Ubuntu 14.04 LTS (Beta 2). Las mejoras no parecen de momento muy visibles frente a la versión que tenía (y yo trabajo siempre con la LTS, así que para dos años sin cambiar, creo que debería notarlo más). Finalmente deseché cambiar a Ubuntu Gnome (aunque me pareció una muy buena alternativa) y me quedé con lo conocido.

Eso sí, echo en falta el instalar cómodamente el soporte de 32 bits (antes se podía instalando el paquete ia32-libs). Actualmente, aun es posible hacerlo, pero me ha costado un poco averiguar el cómo. Ya sé que vivimos en un mundo de 64 bits, pero, hoy por hoy, muchos todavía tenemos que instalar, por razones de trabajo, pequeñas aplicaciones privativas que no las publican en 64 bits. En mi caso, para añadir el soporte de 32 bits que necesitaba primero añadí el soporte de instalación de paquetes de este tipo:

dpkg --add-architecture i386

y luego instalé lo que necesitaba en ese momento:

apt-get install nspluginwrapper lib32z1 libc6-i386 libxml2:i386 \
  libstdc++6:i386 libxerces-c3.1:i386 libcanberra-gtk-module:i386 \
  libcurl3:i386 libasound2-plugins:i386 libgstreamer-plugins-base0.10-0:i386

Esto me sirve para utilizar sin problemas cosas como Citrix Receiver o el Forticlient VPN SSL. Cosas de mi trabajo…

Trabajando ya con el sistema, lo más molesto que me he encontrado es una inusual inestabilidad de la conexión Wifi. Continuamente se me reconectaba la wifi con mensajes en el sistema como éstos (reconectando a 1 Mbps con cierta frecuencia):

wlan0: Limiting TX power to 20 (20 - 0) dBm as advertised by xx:xx:xx:xx:xx:xx
wlan0: deauthenticated from xx:xx:xx:xx:xx:xx (Reason: 6)
Calling CRDA to update world regulatory domain
cfg80211: World regulatory domain updated:
cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)

Aunque apenas lo notaba, el verdadero problema es que en algún momento no era capaz de renegociar y me topaba con un:

IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready

y la única solución para seguir conectado era, desconectar y reconectar las funciones de radio (Fn-F2 en mi portátil, un Dell V131). Finalmente, examinando varios bugs de Ubuntu (marcados como inválidos, y pocas veces corregidos, como suele ocurrir: ejemplo 1, ejemplo 2) encontré la recomendación de algún usuario final: desactivar 802.11n. Gracias a esto, ya no se desconecta y siempre tengo 54 Mbps en la tarjeta. Para hacerlo, ver más abajo el fichero personal-opts.conf.

Otro problema que he tenido, esta vez con el lector de tarjetas flash integrado, es que está continuamente enviando estos mensajes, los cuales ralentizan un poco el sistema:

sd 6:0:0:0: [sdb] Test WP failed, assume Write Enabled
sd 6:0:0:0: [sdb] Asking for cache data failed
sd 6:0:0:0: [sdb] Assuming drive cache: write through

Examinando bugs he encontrado que tal vez se podría solucionar cargando el módulo ums_realtek con la opción ss_en=0. Sin embargo, no es suficiente: en este caso lo que sucede es que aparentemente el dispositivo se conecta y desconecta continuamente al bus USB. Finalmente, lo que he tenido que hacer es ponerlo en la lista negra para evitar que cargue el driver. Total, para lo que uso el lector de tarjetas…

Para dejar fijas ambas soluciones (entiendo que temporales, ya veremos) he creado un archivo /etc/modprobe.d/personal-opts.conf con el siguiente contenido:

options iwlwifi 11n_disable=1
blacklist ums-realtek
# options ums-realtek ss_en=0

Después de hacer estos cambios, se puede decir que ya disfruto de mi nuevo Ubuntu 14.04 LTS en 64 bits ;-)

27 de marzo de 2014

Depurar, editar y guardar ficheros JS en Google Chrome

Receta rápida para los desarrolladores JavaScript interesados, y para retomar el blog tras un parón de unos cuantos meses (he estado ocupado :-) La cuestión es: las DevTools de Google Chrome permiten editar y depurar código JavaScript desde el propio navegador. Pero cuando editas un fichero .js y lo intentas guardar, salta el siguiente error: […]

24 de marzo de 2014

WebKitGTK+ 2.4.0: the multiprocess made easy

Yes, we did it again, we have just released WebKitGTK+ 2.4.0, another major stable release with a lot of bug fixes, some new features and more complete API.

Multiple Web Processes

This is the most important new feature included in this release, and the one we have spent most of the release cycle with. All started during the WebKitGTK+ hackfest when a team of around 10 people worked together to implement the base of the multi-process support. And at the very end of the release cycle we have been able to turn it on by default in Epiphany.

DOM touch events support

WebKitWebView now processes the touch events happening in the widget to notify the DOM, making modern websites using DOM touch API properly work. Carlos Garnacho has taken a screencast to show it in action

Plugins cache

When the first page containing plugins was loaded, the UI process got blocked for some time, while the plugins were scanned. This was one of the most annoying bugs of WebKitGTK+ introduced in 2.0. Plugins are synchronously scanned on demand during the page load, and it’s something that can’t be avoided. WebKitGTK+ 2.4 uses a persistent cache to store information about all plugins, so that plugins are only scanned the first time or when they change.


As always a huge thanks to all the contributors that make this possible, and very specially in this release to the sponsors of the WebKitGTK+ hackfest 2013 (Igalia and the GNOME Foundation).

WebKit1 deprecation

There’s one last thing I would like to mention. Even when WebKit1 API has been deprecated since we released WebKitGTK+ 2.0, we have kept shipping both APIs in our tarball releases. A decision hasn’t been made yet, but this is probably the last release including the WebKit1 API, we have plans to remove the WebKit1 code from trunk and move all the build bots to run only WebKit2 tests. We encourage everybody to port their applications to WebKit2, submitting bug reports if there’s anything preventing the switch, and of course we are happy to help on IRC, mailing list, etc.

14 de marzo de 2014

Cargador de signo de exclamación en Atari – Decodificado

El famoso signo de exclamación

Cuando los computadores Atari recién llegaron a Chile, practicamente todos los juegos que se podían encontrar en cassette usaban el famoso cargador del signo de exclamación.  Se iniciaba la carga de cassete encendiendo el computador con las teclas OPTION + START presionadas, sonaba un beep, se presionaba una tecla y después de unos 10 segundos sonaban unos 6 “pitos” y aparecía un signo de exclamación en la parte inferior derecha de la pantalla, luego pasaban unos 10 segundos más y comenzaba a sonar la carga del juego en sí, a veces amenizada por alguna simple pantalla de presentación.

Si algo fallaba durante la carga, se debía comenzar desde cero, por lo que toda la ansiedad acumulada durante los varios minutos de carga se veía absolutamente recompensada cuando finalmente aparecía el juego en pantalla.  Posteriormente aparecieron mejores sistemas de carga aplicando “turbo” (mayor bitrate) y un mecanismo de recuperación de errores que permitía continuar la carga desde el punto de falla y así no comenzar todo desde cero.  Estos sistemas de carga avanzados merecen un artículo propio, lo que vamos a ver acá es el cargador original del signo de exclamación.

Básicamente estos sistemas de carga funcionaban así: Al iniciar el sistema, la tecla OPTION presionada indicaba al sistema operativo del ATARI que desconectara la ROM del lenguaje BASIC (su espacio era ocupado por muchos juegos), y la tecla START indicaba que se quería hacer un boot desde cassette.  Cuando el usuario presionaba una tecla después del beep, el sistema operativo del ATARI cargaba un archivo y lo ejecutaba.  En el caso de practicamente todos los juegos, este archivo era un cargador un poco más inteligente que se encargaba de cargar el juego en un formato más flexible (XEX).  Si vieramos la cinta como un esquema, sería así:

| ------- CARGADOR EN FORMATO BOOT DE ATARI -------|---------- JUEGO EN FORMATO XEX ----------|
| CARRIER - BLK1 - BLK2 - BLK3 - BLK4 - BLK5 - EOF | CARRIER - BLK1 - BLK2 - ... - BLKn - EOF |

Siempre quise saber exactamente qué hacía el código de este cargador tan simple, y por qué era tan grande (unos 640 bytes). Gracias al usuario AsCrNet de AtariWare que me envió un dump del cargador pude finalmente decodificarlo y ver qué hacía.

Formato XEX

Para que sea más fácil entender el cargador conviene entender primero cuál era el formato del archivo que procesaba el cargador, el formato “del juego”.  Este formato es conocido con el nombre XEX y tiene más o menos la siguiente estructura

|---------------- Archivo en formato XEX ------------- ...
|------ ENCABEZADO ------ | DATA |------ ENCABEZADO -- ...

Un archivo XEX son varios bloques de datos.  Cada bloque comienza opcionalmente con un marcador con la secuencia FF FF (hexadecimal), luego viene la dirección de inicio expresada como 2 bytes (INIL INIH) y la dirección de término expresada también como 2 bytes (ENDL ENDH).  Estos 6 bytes son la cabecera del bloque, luego vienen los datos propiamente tal.  Por ejemplo si el juego tiene dos bloques, uno desde 32768 hasta 40959 y otro desde 3072 a 4096 veríamos la siguiente secuencia hexadecimal

|---------------------------- Archivo en formato XEX ----------------------------|
|--------------- BLOQUE 1 ----------------|------------- BLOQUE 2 ---------------|
|--- ENCABEZADO ---|-------DATOS----------|--- ENCABEZADO --|-------DATOS--------|
|FF FF 00 80 FF 99 | 16384 bytes de datos |FF FF 00 0C FF 0F| 1024 bytes de datos|

Después de cargar cada bloque, el cargador ejecuta una llamada a la dirección apuntada por el par de direcciones 738 y 739 ($02E2, $02E3).  Si el cargador quisiese ejecutar un código durante la carga, por ejemplo para mostrar una presentación, debía poner un bloque que escribiera en esas direcciones.  Supongamos que el código que muestra la presentación está en la direcció $0A3B, entonces aparecería un bloque así:

FF FF E2 02 E3 02 3B 0A

Cuando se llega al final de la carga, se transfiere el control al código apuntado por las direcciones 736 y 737 ($02E0, $02E1) utilizando el mismo esquema recién explicado.

El cargador

El cargador tiene el formato de BOOT propio de Atari, obviamente ya que de otro modo el sistema no lo podría ejecutar.  El sistema de BOOT de Atari comienza con 6 bytes para definir el número de bloques de datos, la dirección de inicio de carga y la dirección de ejecución.  En este cargador vienen los valores (hex) : 20  05  00 07 20 07 que son interpretados como : 5 bloques cargados a partir de $0700, inicio de ejecución en $0720. Por qué suenan 6 bloques de carga y acá dice que son 5? Porque son 5 de datos y el 6to es el EOF (End of File).

Si bien la dirección de ejecución es $0720, el sistema operativo de Atari primero ejecuta lo que está a continuación de este encabezado, en este caso es lo que está en $0706.  Y ahí comienzan las sorpresas!!!

Lo primero que me llamó la atención es que eset vil cargador está protegido.  Si uno trata de ver el código directamente, no se puede a menos que se vaya revisando la ejecución paso a paso.  Lo primero que hace el cargador es automodificarse para comenzar a ejecutarse en una dirección diferente a la que viene cargada originalmente. De la siguiente forma (ordenado por legibilidad):

706  32 244   8  JSR STOPANDPATCH ; $8F4


8f4  32 207   8 JSR MOTOROFF
8f7  32 213   8 JSR PATCHJSR
8fa  96         RTS

8cf 169  60     LDA #60
8d1 141   2 211 STA 54018
8d4 96          RTS

8d5 169  32     LDA #32   ; JSR
8d7 141   9   7 STA $709
8da 169 157     LDA #157  ; $9D
8dc 141  10   7 STA $70A
8df 169   8     LDA #8    ; $08
8e1 141  11   7 STA #70B
8e4  96         RTS

Cuando se ejecuta PATCHJSR se modifica el código que se ejecutará justo después de volver via RTS en $8D4, para que salte a $089D, y qué encontramos ahí? La rutina que desprotege el resto del código invirtiendo todos los bits mediante XOR #$FF, una ténica que podríamos considerar milenaria.

A partir de ese momento, el código queda legible completamente.

No voy a analizar el detalle del cargador, pero sí me interesa destacar las siguientes curiosidades:

  • No logré identificar la parte en donde se pone el signo de interrogación en la pantalla.  Sólo veo la impresión de un caracter que limpia la pantalla.  Será el signo de exclamación un bug del sistema operativo del Atari?
  • El código de carga XEX en este cargador es HO-RRI-BLE.  Esto se debe principalmene a que está mezclada la llamada a las rutinas del sistema operativo para cargar datos desde cassette, con la interpretación de los encabezados XEX. En comparación, cargadores más modernos como CAIN (ahem!) usan una abstracción tipo stream, en donde los bytes se procesan uno a uno y la carga física de los bloques se procesa en forma independiente, como si se tratara de un sistema opaco subyacente (le puse color ah).  En todo caso, se entiende que sea así, hay que pensar que ese código debe ser de principios de los ’80, cuando muchos de nosotros no sabíamos ni ir a comprar el pan.
  • Si la carga falla en algún momento, se invoca a la rutina del sistema operativo que imprime BOOT ERROR.  Por algún motivo, en los computadores que conocí esto nunca fue así, y el sistema simplemente se colgaba.  Es probable que la dirección de rutina haya sido válida sólo para equipos antiguos (400/800) y no para sistemas operativos más modernos (XL/XE).
  • Se nota que el código fue parchado a nivel binario, ya que usaron NOP en varias partes, desactivando código.
  • Derivado de lo anterior, hay muchos accesos de 16 bit a direcciones que están en la página cero, en donde se pueden usar instrucciones especiales que direccionan con sólo 8 bits (ej, 133, 2 en vez de 141, 2, 0).
  • Si hay un cartridge insertado, aparece un mensaje en pantalla que lo advierte.  Este mensaje nunca lo había visto, y es muy probable de que hasta el momento nadie lo haya visto tampoco!  Les adjunto una captura al final de este artículo foryourpleasure.

Para quién quiera ver el detalle de cargador, les dejo los siguientes archivos en una carpeta de DropBox:

  • casboot.asm : Archivo de texto con el código del cargador. Lo decodifiqué a mano, por lo que el código no es compatible con ningún assembler.
  • dump.c : Programa en C para hacer un dump del código que me envió AsCrNet.  Al cambiar UNPROTECT a 1, se aplica el XOR #$255 para desproteger el código
  • casboot.atr : Imagen de disco que contiene un pequeño programa en BASIC que hice para saber cómo se vería el mensaje del cartridge insertado (cartmsg.bas)

PD1 : La imagen del cargador que encabeza este artículo es un fake.  Fue lo más rápido que pude hacer.

PD2 : Por algún motivo se borró la mitad de este artículo mientras lo estaba creando. Lo tuve que hacer de nuevo. NOT FUN.

PD3 : Ningún juego fue dañado durante la creación de este artículo.

ACTUALIZACIÓN: Gracias a los aportes de Guillermo Fuenzalida y ArCrNet finalmente fue resuelto el enigma del signo de exclamación.  Cuando el cargador imprime el caracter de limpiar pantalla, lo hace con el siguiente código:

765 169 125     LDA #125   ; CLEAR SCREEN
767 32  164 246 JSR PRINT  ; $F6A4

Sin embargo la rutina del SO para imprimir en $F6A4 sólo es válida para la ROM de la generación Atari 400/800, porque en la ROM de los Atari XL/XE se encuentra en otro lugar.  Según Mapping the XL/XE:

Many 400/800 programs made direct jumps to keyboard ‘get’ and ‘put’ routines rather than through the proper vectors, which makes them incompatible with XL/XE machines. The get routines in the XL/XE begin at 62026 ($F24A). This was 63038 ($F63E) in the 800. The put routines begin at 62128 ($F2B0). or 63140 ($F6A4) in the 800. If you have a program which won’t work on your XL/XE, try finding if it uses these locations and change them.

Por lo tanto, el famoso caracter “!” de este cargador aparece debido a un bug sin mayores consecuencias.  Para comprobarlo, modifiqué la llamada a $F6A4 y la cambié por $F2B0 y efectivamente, se limpia la pantalla y no aparece el caracter “!”.  Lo mismo demostró ArCrNet usando el cargador en un emulador con la ROM del 400/800, nada de signo de exclamación.

Cartridge insertado

Mensaje que aparece si hay un cartridge insertado


27 de febrero de 2014

New media controls in WebKitGtk+ (reloaded)

In December we organized in A Coruña the WebKitGTK+ hackfest at the Igalia premises as usual and also as usual it was an awesome oportunity to meet the rest of the team. For more information about the progress done in the hackfest, you can have a look at KaL’s post.

As part of the hackfest I decided to take a task that it would take some time so that I could focus and I decided to go for rewriting once again the WebKitGTK+ multimedia controls. People who just read this post will wonder why I say again and the reason is that last year we completely redesigned the multimedia controls. This time I have not redesigned them (well, a bit) but rewritten them in JavaScript as the Apple guys had done before.

To get the job done, the first step was bundling the JavaScript code and activating the codepath to use those controls. I used the Apple controls as template so you can imagine that the first result was a non-working monster that at some point reminded to Safari multimedia controls. At that point I could do two things, forking or inheriting. I decided to go with inheritance because it keeps the spirit of WebKit (and almost all Free Software projects) of sharing as much code as possible and because forking later is easier than merging. Then step by step I kept redefining JavaScript methods and tweaking some stuff in the C++ and CSS code to create the current user experience that we had so far.

Some of the non-aesthetic changes are the following:

  • Focus rings are now managed from CSS instead of C++.
  • Tests got new fixes, rebaselines and more love.
  • CMake support for the new controls.
  • Load captions icon from theme.
  • Load and hide elements handled now with CSS (and JavaScript).

The captions icon problem was interesting because I found out that the one we were using was “user-invisible-symbolic” and it was hardcoded directly in the CSS code. I changed it to be loaded from the theme but it raised the issue of using the incorrect metaphor though the current icon looks nice for captions. I filed a GNOME bug (and another WebKit bug to follow this up) so that a new icon can be created for captions/subtitles with the correct metaphor.

And which are the controls aesthetic changes?

  • Show a very subtle gradient when the elements are focused or active to improve the accessibility support (which won’t be complete until bug 117857 is fixed).
  • Volume slider rolls up and down with a nice animation.
  • Some other elements are not shown when they are not needed.
  • Captions menu shows up with both click and mouse hover for coherence with the volume slider.
  • Captions menu is also animated the same way as the volume slider.
  • Captions menu was propertly centered.
  • Captions menu style was changed to make it more similar to the rest of the controls (fonts, margings…)
  • Volume slider shows below the media element when it is too close to the page top and it cannot be shown on it. This was a regression that I introduced with the first rewrite, happy to have it fixed now.

As I already said the aesthetic differences with the former C++ are not a big deal unless you compare them with the original controls:

Starting point

To appreciate the new controls I cannot just show a screenshot, because the nicest thing are the animations. Therefore a video is needed (and if you have WebKit compiled you can experience them yourself)):

Of course, I thank our hackfest sponsors as the it was possible because of them:

Igalia GNOME Foundation

23 de febrero de 2014

La caída de whatsapp… y los fallos de Telegram

Ayer fue un día curioso: seguramente muchos usuarios de smartphones descubrieron que había una aplicación llamada “LINE“; incluso que existía una función de fábrica llamada “SMS” y que hasta podían llamar por el teléfono. Pero a fin de mes podrían llegar a ver algunos experimentos reflejados en su factura…

Lo que realmente pasó ya lo sabemos: Whatsapp, el producto sobrevalorado por Facebook, sufrió un colapso durante más de tres horas. Y mira por donde su mejor rival, Telegram, sufrió la mayor demanda que se conoce, que ha tenido que poner las pilas a sus dueños. Porque se vino abajo: sencillamente no pudo soportar algo que, probablemente, Whatsapp sí que soporta: 100 usuarios nuevos por segundo. Millón y pico de usuarios nuevos en un día.


Lo que ha pasado es clara señal de que Telegram es el rival con más peligro: es el rival que además de más seguro, fiable, barato y bla bla que Whatsapp, es, sobre todo, el más parecido. Y probablemente esta sea la causa de su próximo éxito y no otra cosa.

Ahora, un aviso para navegantes (o mejor, para los creadores de Telegram): tiene un muy buen punto de partida, pero aun tiene importantes fallos y su proyecto de desarrollo debe tener cariño/financiación suficientes para corregirlos. Sin ir más lejos, el otro día notifiqué un fallo que me descubrió un compañero de trabajo, que hace que el cliente descarte los mensajes cuando la conexión no es posible en un plazo de tiempo. Esto en Whatsapp no pasa, pero con Telegram sí; y esto es fácil que nos afecte si escribimos un mensaje a un contacto cuando estamos, por ejemplo, atravesando un túnel sin cobertura. La respuesta de los desarrolladores a mi correo fue, inicialmente, casi decirme que más que fallo era una característica; tras mi insistencia reconocieron que lo arreglarían cuando pudiesen.

Por cierto, la crisis del Whatsapp me trajo ayer una pequeña avalancha de contactos nuevos desde mi agenda telefónica. Felicidades a los desarrolladores, pero también a los usuarios: por elegir una alternativa mucho mejor, aunque no sepan muy bien por qué.

Nota: Este artículo no contiene enlaces a medios de «AEDE» y, en todo caso, se acoge al derecho de cita de la vigente LPI para la publicación de los mismos.

09 de febrero de 2014

Adición de un controlador de dominio (DC) con Samba 4

Continuando con el artículo anterior, vamos a ver a continuación como añadir controladores de dominio adicionales a nuestra red con Samba 4. Partiremos de la existencia de al menos un controlador de dominio implementado preferiblemente con Samba 4, o con Windows Server en su defecto. Nuevamente, nuestro servidor contará con CentOS 6.x como sistema operativo y los paquetes de Enterprise Samba.


Debemos contar con un servidor con CentOS 6.x o Red Hat Enterprise Linux 6.x, y los paquetes de Enterprise Samba ya instalados; así como los paquetes de Bind modificados, de acuerdo a como indicamos en el artículo anterior.

Disponibilidad del directorio activo

Para comprobar su disponibilidad, probaremos un login con Kerberos. Creamos un fichero /etc/krb5.conf como el siguiente:

 default_realm = DRAMOR.INT
 dns_lookup_realm = false
 dns_lookup_kdc = true

También, verificaremos que el sistema tiene puesto como servidor DNS, el del otro controlador de dominio:

# cat /etc/resolv.conf

Y trataremos de obtener un ticket:

# kinit Administrador@DRAMOR.INT
Password: xxxx
Warning: Your password will expire in 41 days on Sun Mar 23 13:19:48 2014

Si todo ha ido correcto podremos conectarnos a algún recurso con ese usuario:

# smbclient -k //centos6ad/netlogon
Domain=[DRAMOR] OS=[Unix] Server=[Samba 4.1.4-SerNet-RedHat-7.el6]
smb: \> quit
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: Administrador@DRAMOR.INT
Valid starting Expires Service principal
02/08/14 23:43:38 02/09/14 09:43:41 krbtgt/DRAMOR.INT@DRAMOR.INT
 renew until 02/09/14 23:43:38
02/08/14 23:43:54 02/09/14 09:43:41 cifs/centos6ad@DRAMOR.INT

Unión como controlador de dominio (DC)

Nos uniremos con la orden samba-tool. Nos pedirá la contraseña del administrador y a continuación se unirá mostrándonos información abundante sobre el proceso de replicación de datos:

# samba-tool domain join DC -UAdministrator --dns-backend=BIND9_DLZ
Finding a writeable DC for domain ''
Found DC
Password for [DRAMOR\Administrator]:
workgroup is DRAMOR
realm is
checking sAMAccountName
Adding CN=CENTOS6AD2,OU=Domain Controllers,DC=dramor,DC=int
Adding CN=CENTOS6AD2,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=dramor,DC=int
Adding CN=NTDS Settings,CN=CENTOS6AD2,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=dramor,DC=int
Adding SPNs to CN=CENTOS6AD2,OU=Domain Controllers,DC=dramor,DC=int
Setting account password for CENTOS6AD2$
Enabling account
Adding DNS account CN=dns-CENTOS6AD2,CN=Users,DC=dramor,DC=int with dns/ SPN
Setting account password for dns-CENTOS6AD2
Calling bare provision
No IPv6 address will be assigned
Provision OK for domain DN DC=dramor,DC=int
Starting replication
Schema-DN[CN=Schema,CN=Configuration,DC=dramor,DC=int] objects[402/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=dramor,DC=int] objects[804/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=dramor,DC=int] objects[1206/1550] linked_values[0/0]
Schema-DN[CN=Schema,CN=Configuration,DC=dramor,DC=int] objects[1550/1550] linked_values[0/0]
Analyze and apply schema objects
Partition[CN=Configuration,DC=dramor,DC=int] objects[402/1620] linked_values[0/0]
Partition[CN=Configuration,DC=dramor,DC=int] objects[804/1620] linked_values[0/0]
Partition[CN=Configuration,DC=dramor,DC=int] objects[1206/1620] linked_values[0/0]
Partition[CN=Configuration,DC=dramor,DC=int] objects[1608/1620] linked_values[0/0]
Partition[CN=Configuration,DC=dramor,DC=int] objects[1620/1620] linked_values[28/0]
Replicating critical objects from the base DN of the domain
Partition[DC=dramor,DC=int] objects[98/98] linked_values[23/0]
Partition[DC=dramor,DC=int] objects[313/215] linked_values[23/0]
Done with always replicated NC (base, config, schema)
Replicating DC=DomainDnsZones,DC=dramor,DC=int
Partition[DC=DomainDnsZones,DC=dramor,DC=int] objects[41/41] linked_values[0/0]
Replicating DC=ForestDnsZones,DC=dramor,DC=int
Partition[DC=ForestDnsZones,DC=dramor,DC=int] objects[19/19] linked_values[0/0]
Partition[DC=ForestDnsZones,DC=dramor,DC=int] objects[38/19] linked_values[0/0]
Committing SAM database
Sending DsReplicateUpdateRefs for all the replicated partitions
Setting isSynchronized and dsServiceName
Setting up secrets database
Joined domain DRAMOR (SID S-1-5-21-2470081830-1300756272-1234487377) as a DC


Ajuste de entradas DNS

Comprobaremos si se creó una entrada DNS para el nuevo servidor en el servidor al que nos hemos unido. Para ello intentamos resolver:

# host -t A
Host not found: 3(NXDOMAIN)

Si nos da error, debemos dar de alta el registro DNS. Podemos hacerlo con samba-tool. Si la IP del servidor DNS es y la del servidor que acabamos de unir (centos6ad) es introduciríamos una orden como:

# samba-tool dns add centos6ad2 a -Uadministrador
Password for [DRAMOR\administrador]:
Record added successfully

Probamos de nuevo:

# host -t A has address

Tanto si hemos tenido que añadir este registro como si no, seguramente tendremos que añadir el GUID del servidor como registro CNAME del DNS. Comprobaremos si existe, en primer lugar obteniendo el GUID:

# ldbsearch -H /var/lib/samba/private/sam.ldb '(invocationid=*)' --cross-ncs objectguid
# record 1
dn: CN=NTDS Settings,CN=CENTOS6AD2,CN=Servers,CN=Nombre-predeterminado-primer-sitio,CN=Sites,CN=Configuration,DC=dramor,DC=int
objectGUID: 99889a59-e3b6-4c9d-a005-dc61fa238cad

Buscamos el registro:

# host -t CNAME
Host not found: 3(NXDOMAIN)

Si nos da este error, lo creamos:

# samba-tool dns add 99889a59-e3b6-4c9d-a005-dc61fa238cad CNAME -Uadministrador
Password for [DRAMOR\administrador]:
Record added successfully

Y probamos de nuevo:

# host -t CNAME is an alias for

Configuración de BIND

Para configurar y arrancar el servicio DNS tenemos que realizar las mismas configuraciones y posteriores revisiones de permisos de ficheros que hicimos con el primer controlador de dominio (ver artículo anterior).

Una vez arrancado podemos probar con dig que es capaz de resolver cualesquiera de los equipos de la red, por ejemplo, los dos servidores DC configurados hasta ahora (centos6ad y centos6ad2):

# host -t A
Using domain server:
Aliases: has address
# host -t A
Using domain server:
Aliases: has address


Arranque de Samba

Para arrancar Samba4 en modo directorio activo, editamos el fichero /etc/default/sernet-samba cambiando la variable SAMBA_START_MODE al valor “ad” en lugar de “none”. Finalmente, arrancamos con “service sernet-samba-ad start”.

Si vemos en los logs ( /var/log/samba/log.samba ) un error similar a este:


Failed to bind to uuid e3514235-4b06-11d1-ab04-00c04fc2dcd2 for e3514235-4b06-
11d1-ab04-00c04fc2dcd2@ncacn_ip_tcp:b78fee18-83b9-4478-9239-0d9a13b654c2._msdcs.[1024,seal,krb5] NT_STATUS_UNSUCCESSFUL

normalmente reiniciando el samba de esa máquina se soluciona.

Una vez dejemos de ver los errores, podemos comprobar que los objetos del directorio activo se replican, para ello desde uno de los servidores creamos un usuario:

# samba-tool user add usuario1
Password: XXXX
# samba-tool user list

Tras unos segundos, ejecutando la misma orden (samba-tool user list) en el otro servidor DC debemos ver que también aparece el usuario1 recién creado.

Interacción con DC Windows Server

Si el servidor DC es Windows Server y no Samba 4, debemos tener en cuenta que tras añadir el servidor Samba 4 y arrancar Samba, no funcionará la replicación. Esto se verá con un error en los logs de Samba, similares a:

UpdateRefs failed with WERR_DS_DRA_BAD_NC/NT

Para solucionarlo, debemos ejecutar “repadmin /kcc” en el servidor Windows, o bien el siguiente comando en el Samba 4:

# samba-tool drs kcc -Uadministrator
 Consistency check on successful.

Tras esto podemos verificar la replicación con:

# samba-tool drs showrepl
 DSA Options: 0x00000001
 DSA object GUID: b78fee18-83b9-4478-9239-0d9a13b654c2
 DSA invocationId: 45869512-53e2-4e3e-9478-3c874e4352d7
 Default-First-Site-Name\W2003SRV via RPC
 DSA object GUID: ff97c348-e990-4a6a-a9c5-879c9b1e2dea
 Last attempt @ Sun Feb 9 14:04:42 2014 CET was successful
 0 consecutive failure(s).
 Last success @ Sun Feb 9 14:04:42 2014 CET
 Default-First-Site-Name\W2003SRV via RPC
 DSA object GUID: ff97c348-e990-4a6a-a9c5-879c9b1e2dea
 Last attempt @ Sun Feb 9 14:04:43 2014 CET was successful
 0 consecutive failure(s).
 Last success @ Sun Feb 9 14:04:43 2014 CET



También nos fallará el backend DNS BIND_DLZ, si el servidor es Windows 2003. Esto es en este momento, un error conocido sin resolver en Samba4, Se puede evitar utilizando el backend DNS interno de Samba 4, aunque habrá que tener en cuenta sus limitaciones.


05 de febrero de 2014

#AllTrials: campaña de cabildeo a los eurodiputados

Desde informan de los avances en la campaña para que la Unión Europea regule la transparencia de los resultados de todos los ensayos clínicos que se realicen a la hora de estudiar posibles nuevas medicinas.

Para el siguiente paso nos solicitan dirigirnos a nuestros eurodiputados para hacerles llegar una carta pidiéndoles el voto a favor del llamado informe Willmott en una votación que tendrá lugar el próximo 3 de abril. Me he tomado la libertad de traducirla a español y ponerla a disposición de todos los interesados:

Estimado parlamentario:

Me dirijo a usted para rogarle que apoye al Informe Willmot acerca de la Regulación de Ensayos Clínicos.

El próximo 3 de abril de 2014 suya será la oportunidad de votar a favor de aumentar significativamente la transparencia de los datos obtenidos en las pruebas clínicas. Una vez que la regulación esté en marcha todas las compañías farmacéuticas y los patrocinadores no comerciales de ensayos clínicos tendrán la obligación de:

  • enviar un resumen de los resultados a una base de datos accesible públicamente en el plazo de un año tras concluir la investigación;
  • enviar un resumen comprensible para un observador neutral;
  • enviar los informes completos de estudios clínicos de los ensayos cuando se solicite la puesta en el mercado de una medicina;
  • registrar o publicar ensayos anteriores si con ellos se pretende respaldar solicitudes para nuevos ensayos;
  • someterse a penalizaciones económicas si no se cumplen los requisitos de transparencia.

Es de enfatizar que estas reglas aplicarán en cualquier caso, no importa si el resultado del ensayo ha sido exitoso, un fracaso o inconcluyente.

Aproximadamente la mitad de todos los ensayos clínicos no han sido publicados. Algunos siquiera han sido registrados. Si no se toman medidas urgentes, el detalle de qué es lo que se ha hecho y qué se descubrió durante los ensayos podría perderse para siempre, en perjuicio de elecciones de tratamientos, oportunidades perdidas para hacer buena medicina y ensayos que habrían de ser repetidos innecesariamente.

¿Va a ayudar a mejorar la seguridad de los pacientes, a la ciencia más sólida y al avance de la medicina votando a favor del informe el 3 de abril?

Atentamente (el signatario)

La idea es enviar una copia de esta carta a nuestros europarlamentarios. También tenéis disponible el enlace a las páginas de su perfiles en la web del Parlamento Europeo, que a su vez contienen al menos el correo electrónico, en un único fichero pdf.

Desde aquí sólo puedo animaros a apoyar este extraordinario ejercicio de transparencia dirigiéndoos a vuestros parlamentarios.

02 de febrero de 2014

Creación de Directorio Activo con Samba 4 en CentOS 6

A finales de 2012 se publicó la versión 4 de Samba. La gran novedad fue la capacidad para implementar controladores de dominio de directorio activo. Durante el pasado año se ha mejorado bastante esta versión de Samba, ampliando las funcionalidades soportadas, aunque aun tiene algunas limitaciones. Por el momento no repararemos en ellas, y baste decir que en muchos entornos facilitará la implementación del directorio sin necesidad de invertir en licencias de Windows Server.

El presente procedimiento permite construir rápidamente un Directorio Activo con paquetes compilados de Samba4 en CentOS 6.x o Red Hat 6.x, ya que la mayoría de procedimientos existentes no se encuentran preparados para CentOS o requieren la compilación del código fuente. Los paquetes elegidos han sido los de Enterprise Samba, debido a la calidad de los mismos.


Partiremos de una máquina con CentOS 6 o Red Hat Enterprise Linux 6, recién instalada en la que desactivaremos SELINUX e IPTABLES para mayor comodidad. Posteriormente, se puede reactivar IPTABLES aunque habrá que abrir algunos puertos relacionados con la conexión de clientes al directorio activo.

Para acceder a los paquetes de Enterprise Samba 4, es necesario registrarse. Para ello iremos a y nos registraremos (Sign Up). Una vez dentro, debemos descargarnos el fichero sernet-samba-4.1.repo, en el que debemos modificar los valores USERNAME y ACCESSKEY con los que nos aparecerán en la página web anterior. Este archivo lo llevaremos a /etc/yum.repos.d/. Por ejemplo, podría quedar así:


name=SerNet Samba 4.1 Packages (centos-6)

Instalación de paquetes

Instalaremos entonces algunos paquetes:

yum -y install wget gcc make wget postfix bind bind-libs bind-utils ntp krb5-workstation

Los paquetes relacionados con bind (bind, bind-libs, bind-utils) deben instalarse desde fuentes, recompilando sin la opción –disable-isc-spnego si queremos que el servidor DNS soporte actualizaciones dinámicas desde los clientes. Para ello, se recomienda instalar el grupo de paquetes “Development Tools” y buscar el paquete fuente de CentOS para reconstruir los binarios eliminando la opción anterior en el bind.spec.

También es necesario configurar NTP. Basta una configuración sencilla que haga que nuestra máquina sea servidora de hora, para que los clientes puedan sincronizar sus relojes con el servidor y así no tener problemas con Kerberos.

A continuación, instalamos desde Enterprise Samba los paquetes para crear el directorio activo:

yum install sernet-samba-ad

Provisión del directorio activo

Procedemos a provisionar el directorio con el comando samba-tool. La mayoría de los valores se pueden dejar como vienen por defecto, en particular el nombre del dominio se tomará con el dominio DNS en el que se encuentre el servidor, lo cual será suficiente en la mayoría de los casos. Por ejemplo, en mi caso puse lo siguiente:

[root@CENTOS6AD ~]# samba-tool domain provision
Realm [DRAMOR.NET]: 
 Domain [DRAMOR]: 
 Server Role (dc, member, standalone) [dc]: 
Administrator password: 
Retype password:

La contraseña deberá ser compleja, es decir, incluir mayúsculas, minúsculas, números y algún signo de puntuación. Si no lo hacemos así, el proceso de creación fallará.

Si todo va bien, veremos el proceso automático de creación del directorio:

Looking up IPv4 addresses
Looking up IPv6 addresses
No IPv6 address will be assigned
Setting up share.ldb
Setting up secrets.ldb
Setting up the registry
Setting up the privileges database
Setting up idmap db
Setting up SAM db
Setting up sam.ldb partitions and settings
Setting up sam.ldb rootDSE
Pre-loading the Samba 4 and AD schema
Adding DomainDN: DC=dramor,DC=net
Adding configuration container
Setting up sam.ldb schema
Setting up sam.ldb configuration data
Setting up display specifiers
Modifying display specifiers
Adding users container
Modifying users container
Adding computers container
Modifying computers container
Setting up sam.ldb data
Setting up well known security principals
Setting up sam.ldb users and groups
Setting up self join
Adding DNS accounts
Creating CN=MicrosoftDNS,CN=System,DC=dramor,DC=net
Creating DomainDnsZones and ForestDnsZones partitions
Populating DomainDnsZones and ForestDnsZones partitions
See /var/lib/samba/private/named.conf for an example configuration include file for BIND
and /var/lib/samba/private/named.txt for further documentation required for secure DNS updates
Setting up sam.ldb rootDSE marking as synchronized
Fixing provision GUIDs
A Kerberos configuration suitable for Samba 4 has been generated at /var/lib/samba/private/krb5.conf
Once the above files are installed, your Samba4 server will be ready to use
Server Role: active directory domain controller
Hostname: CENTOS6AD
DNS Domain:
DOMAIN SID: S-1-5-21-2963293665-1815356632-74099400

Hemos marcado en negrita las advertencias sobre ficheros creados que nos harán falta en los siguientes pasos (BIND y Kerberos).

Configuración de BIND

Pasamos a configurar BIND. El fichero de configuración debe tener en cuenta las indicaciones recibidas durante la creación del directorio activo y algunas más. El siguiente diff contiene los cambios realizados sobre el named.conf que viene con el paquete Bind original de CentOS 6.5:

--- named.conf.orig 2010-07-19 15:34:15.000000000 +0200
+++ named.conf 2014-02-01 20:51:30.490129384 +0100
@@ -8,13 +8,13 @@

 options {
- listen-on port 53 {; };
- listen-on-v6 port 53 { ::1; };
+ listen-on port 53 { any; };
+ listen-on-v6 port 53 { any; };
 directory "/var/named";
 dump-file "/var/named/data/cache_dump.db";
 statistics-file "/var/named/data/named_stats.txt";
 memstatistics-file "/var/named/data/named_mem_stats.txt";
- allow-query { localhost; };
+ allow-query { any; };
 recursion yes;

 dnssec-enable yes;
@@ -25,6 +25,8 @@
 bindkeys-file "/etc/named.iscdlv.key";

 managed-keys-directory "/var/named/dynamic";
+ tkey-gssapi-keytab "/var/lib/samba/private/dns.keytab";

 logging {
@@ -41,4 +43,5 @@

 include "/etc/named.rfc1912.zones";
 include "/etc/named.root.key";
+include "/var/lib/samba/private/named.conf";
+include "/etc/rndc.key";

El fichero /etc/rndc.key lo generamos con:

rndc-confgen -a -r /dev/urandom

Antes de arrancar el Bind tendremos que ajustar algunos permisos en para permitir que el usuario named alcance los ficheros indicados ( /var/lib/samba/private/named.conf, /var/lib/samba/private/dns.keytab). En general, se trata de hacer que el grupo de los archivos de /var/lib/samba/private sea named en lugar de root.

Si al arrancar el Bind (service named start) vemos que da un error, podemos examinar /var/log/messages para averiguar qué sucedió. Casi siempre se detectarán problemas de permisos.

Una vez arrancado, comprobamos que funciona con el comando dig, buscando resolver el dominio que ha creado Samba4:

# dig @
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.el6_5.1 <<>> @
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55516
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
; IN A
;; Query time: 4 msec
;; WHEN: Sat Feb 1 21:00:11 2014
;; MSG SIZE rcvd: 84

Si todo ha ido correctamente, activaremos el arranque de named con el equipo (chkconfig named on) y cambiaremos el fichero /etc/resolv.conf para que utilice este servidor:


Arranque y prueba de Samba 4

Para arrancar Samba4 en modo directorio activo, editamos el fichero /etc/default/sernet-samba cambiando la variable SAMBA_START_MODE al valor “ad” en lugar de “none”. Finalmente, arrancamos con “service sernet-samba-ad start”.

El siguiente paso es probar a autenticarnos en el reino Kerberos creado por Samba4. Para ello copiamos a /etc/krb5.conf:

cp /var/lib/samba/private/krb5.conf /etc/krb5.conf

El fichero tendrá este contenido:

 default_realm = DRAMOR.NET
 dns_lookup_realm = false
 dns_lookup_kdc = true

Y comprobamos que podemos entrar y examinar el servidor, ya que durante la provisión del directorio se generó un fichero smb.conf que implementa las funciones de servidor necesarias:

# kinit Administrator@DRAMOR.NET
Password for Administrator@DRAMOR.NET:
Warning: Your password will expire in 41 days on Sat Mar 15 20:35:20 2014
# smbclient -k -L  CENTOS6AD
Domain=[DRAMOR] OS=[Unix] Server=[Samba 4.1.4-SerNet-RedHat-7.el6]
Sharename Type Comment
 --------- ---- -------
 netlogon Disk 
 sysvol Disk 
 IPC$ IPC IPC Service (Samba 4.1.4-SerNet-RedHat-7.el6)

A continuación ya podemos tomar un cliente Windows XP Profesional, por ejemplo, y unirlo al dominio normalmente.

Dado que Samba4 no incluye herramientas de gestión cómodas, podemos instalar en un cliente Windows las herramientas de Microsoft (herramientas RSAT en Windows 7, Administration Tools en Windows XP, etc). Samba 4 implementa la mayoría de las características del directorio activo y de las políticas GPO, si bien las políticas de contraseñas se gestionan exclusivamente con el comando samba-tool. Por ejemplo, con el comando “samba-tool domain passwordsettings set –complexity=off” podemos quitar la exigencia de complejidad en las contraseñas.




31 de enero de 2014


Se está escribiendo bastante sobre Telegram un nuevo candidato para destronar a Whatsapp. La verdad, lo tiene muy difícil, pero creo que un poco menos que LINE. Algunas características que lo hacen interesante:


  • Las más importantes, para mí, son la privacidad y la seguridad (al menos las que prometen): los mensajes viajan cifrados, con un protocolo expuesto públicamente, y las implementaciones de los clientes actuales son todas software libre, lo que facilita que las auditemos para comprobar si son tan seguras como prometen.
  • La más importante para el público en general, creo que es su parecido (digamos que calcado) con Whatsapp, en su manejo y hasta en los emoticonos.
  • No menos importante, la prometida gratuidad. La aplicación “es y será siempre gratuita”. Esto es un ataque frontal a Whatsapp, que desde hace al menos dos años propone a sus usuarios una suerte de micropago anual. Otra cosa es que lo cobren realmente: no conozco nadie de mi entorno que haya pagado hasta la fecha un céntimo a Whatsapp. Y es que, una y otra vez, cuando caduca la cuenta nos invitan a pagar durante unas horas o días y luego, por arte de magia, todo vuelve a funcionar.
  • Además, la aplicación es rápida y más ligera (ocupa menos memoria RAM y almacenamiento en los dispositivos) que cualquier competidor. Eso dicen, pero yo he verificado con algún móvil gama media, que whatsapp pese a ocupar algo más, también se abre más rápido.
  • Y encima hoy mismo ha sido publicada en español, al menos para quien use un dispositivo Android.

Pero no todo son ventajas. Telegram ya tiene algunas críticas importantes. Y no me refiero a cosas como la masa crítica de usuarios o a que no tenga videollamadas. Para el personal preocupado por la seguridad, la oferta de 200.000 dólares por romper el protocolo no convence. Además, es cierto que el protocolo es abierto y han publicado software libre suficiente para implementar clientes Telegram de todo tipo (Android, iOS, Windows…) pero del software del servidor no dicen nada. Ojalá me equivoque, pero la red Telegram ahora mismo es un servicio coleccionista de datos personales, igualito que el de Whatsapp (y LINE). Respecto al protocolo, ¿por qué reinventarlo del todo? ¿Acaso no tenemos XMPP?

El fin de semana pasado fue la explosión de Telegram. Muchos contactos míos (sobre todo, relacionados con el software libre) se lanzaron a instalarlo. El aviso de unión a Telegram de mis contactos (que en la aplicación oficial no se puede, a día de hoy, omitir) empezó a ser realmente pesado. Sin embargo, tras la tormenta llegó la calma, y casi nadie se ha vuelto a dar de alta. Al final, alrededor del 5% de mis contactos tienen Telegram, y para el resto sigue estando Whatsapp y en menor medida LINE.

Personalmente estoy convencido que el resto de mis contactos tecnófilos se unirán a Telegram cuando crean definitivamente en lo que promete. Quizás haciendo software libre el software de servidor y por tanto permitiendo que cualquiera pueda montarse uno que compita con el principal. Además de poder auditar su código. Yo le estoy dando una oportunidad, especialmente para dentro de unos días, cuando mi cuenta en Whatsapp caduque por n-sima vez. Pero bueno, tampoco estoy muy convencido ya que con mucha probabilidad, Whatsapp, también por n-sima vez, me regalará otro año.

29 de enero de 2014

Work madness: dehumanization

Work, work, work... and more work.

We can (and we usually do) lose some time checking Facebook, reading online newspapers, magazines, blogs and other stuff, but if someone calls you at work you freak out and do not pick up, unless the caller insists a lot. Doesn't matter much if you know that person a lot or not, probably if you don't know the number or the person you will be very likely less prone to pick up the call, but in any case, nowadays many (myself included) think that is not very professional to take personal calls at work. Even if it's important (or we don't know yet that it is).

And once you have picked up that call, you will say you're very busy, that do not have enough time and... put-here-whatever-the-excuse-you-want. Sometimes is just because you don't want to talk to that person, but in the end there is always that work feeling that tells you that you're being unprofessional. As if Facebooking and so on were not procrastinating... like your company does not have a proxy and a list of all the websites you visit and how muchtime you spend on each one...

But work is the perfect excuse not to talk to that person, that day, at that very same moment.

We are becoming fucking zombies.

Etiquetas: , ,

17 de enero de 2014

Frogr 0.9 released

So, after a bit more than one year without releasing any version of frogr, I finally managed to get some “spare” time to put all the pieces together and ship the ninth version of it, which I believe/hope is going to be a quite solid one.

Frogr 0.9

In all honesty, though, this version does not come with many new features as the previous ones, yet some changes and fixes that I believe were quite necessary, and therefore should help improving the user experience in some subtle ways.

For instance, the layout of the dialog to edit the details of a picture has changed (as per Ana Rey‘s comments during GUADEC) to enable a more efficient usage of vertical space, so much needed these days in small widescreen laptops. Of course, design-wise still sucks, but I believe it’s much more convenient now from a pragmatical point of view.

Also, frogr is now a little bit more “modern” in things such as that it now supports GStreamer 1.0 (0.10 still supported), a lot of deprecated code (e.g. Stock items, GtkActions) has been replaced internally and it now integrates better with GNOME Shell’s search box. Ah! and it also now provides an AppData file to integrate with GNOME Software Center, which is a nice touch too.

Another interesting thing is that I finally fixed the problem that we have with multiple selections in the main view, which was neither intuitive nor very useful, as Ctrl and Shift modifiers did not work as expected. So, from now on, it is finally possible to work with disjoint multiple selections of pictures, a feature I was missing so much.

Last, I fixed two important problems in the code that caused frogr consume two much memory, specially after uploading pictures. It was a quite severe problem since frogr was not properly freeing the memory used by pictures even after those were uploaded and removed from the UI, causing important issues in cases where people tried to upload a lot of pictures at once. It’s hopefully fixed now.

And that’s all I think. As usual, you can check the website of the project to know how to install frogr on your system if you don’t want to wait for your favourite distribution to ship it, or if you just want to check more information about the project or to contribute to it.


Ah! By the way… I’m going to FOSDEM again this year, but this time by train. Can’t wait to be there! :)

15 de enero de 2014

Updating X.509 certificates for CentOS

My SSL/TLS certificate has expired so I need to request a new one and I'm summing here all the process.

As my current configuration is more or less a mess, I'm starting from the very begining but I assume you are registered at and you are able to request server certificates for your verified domains. I'll use my server as the hostname example.

The better way to me is to use key and CSR creation script (which uses openssl), specially needed when you want to add several domains to the certificate.
# sh csr
Private Key and Certificate Signing Request Generator
This script was designed to suit the request format needed by
the CAcert Certificate Authority.

Short Hostname (ie. imap big_srv www2): tormento
FQDN/CommonName (ie. :
Type SubjectAltNames for the certificate, one per line. Enter a blank line to finish
SubjectAltName: DNS:
Running OpenSSL...
Generating a 2048 bit RSA private key
writing new private key to '/root/tormento_privatekey.pem'
Copy the following Certificate Request and paste into CAcert website to obtain a Certificate.
When you receive your certificate, you 'should' name it something like tormento_server.pem


The Certificate request is also available in /root/tormento_csr.pem
The Private Key is stored in /root/tormento_privatekey.pem

Note: I found the genkey tool (from the crypto-utils package) takes a lot of more time to generate a same key lenght. Probably due to some kind design goal. I think you could use genkey to generate the key and the csr script for the multi-dns CSR request.

Then I move files to correct systems places:

mv /root/tormento_csr.pem /etc/pki/tls/certs/
mv /root/tormento_privatekey.pem /etc/pki/tls/private/

Then I ask for a certification at CAcert website. CAcert recomends to select a Class 3 root certificate.

Cut and paste the certificate from the browser into the system:

# cat > /etc/pki/tls/certs/

You can check the certificate is correct using openssl. And you'll receive an email from CAcert reporting about the new certificate.

Then you can configure your applications to use the new crypto key and certificate.


These are the applications I've configured for my needs. You have other configuration examples at CAcert website.


# grep tls /etc/postfix/

smtpd_tls_key_file = /etc/pki/tls/private/
smtpd_tls_cert_file = /etc/pki/tls/certs/
smtpd_tls_CAfile = /etc/pki/tls/certs/CAcert_chain.pem
smtp_use_tls = yes
smtp_tls_key_file = /etc/pki/tls/private/
smtp_tls_cert_file = /etc/pki/tls/certs/
smtp_tls_CAfile = /etc/pki/tls/certs/CAcert_chain.pem


Create a key + certificate file:
# cat /etc/pki/tls/private/ > /etc/pki/ejabberd/certs/ejabberd.pem
# cat /etc/pki/tls/certs/ >> /etc/pki/ejabberd/certs/ejabberd.pem
# chown -R ejabberd.ejabberd /etc/pki/ejabberd/
# chmod a-rw,u+r -R /etc/pki/ejabberd/



Common things you would need to do with your certificates and keys:

Export public key:

openssl rsa -in /etc/pki/tls/private/ -pubout -out  /etc/pki/tls/public/ -outform PEM

Print human readable key data:

openssl rsa -noout -text -in /etc/pki/tls/private/

Print human readable certificate contents:

openssl x509 -noout -text -in /etc/pki/tls/certs/

Other info of interest

I've not studied it yet but probably it's worth to read the Fedora developments on managing system crypto keys and signatures:

14 de enero de 2014

Convocatoria: encuentro del taller de hardware abierto

La chavalada, la #GenteQueHaceCosas con hardware en Almería, se ha organizado en un taller permanente de hardware abierto y ha decidido realizar su primer encuentro presencial específicamente dedicado al cacharreo.

Dirigido a

  • Ti, que te mola el cacharreo.
  • Para ti también, que tienes ganas locas de empezar.
  • A ti también, que te dedicas profesionalmente a estos temas pero que ahora quieres jugar.
  • A ti también, aunque sabemos que sólo lo haces para impresionar a las visitas.
  • Tú, que no has pensado todavía qué hacer para el proyecto de fin de carrera, vente un rato y alguna idea se te puede ocurrir entre tanto disparate.
  • Y a ti también, que para las pocas chicas que suelen venir no queremos que faltes. Tráete a tus amigas, por favor.
  • Y si tu eres de los que ha ganado algún campeonato de Lego Mindstorms vente y explícale tu arte a todos estos aprendices.


  • Charla: electrónica libre. Estado del arte y presentación de dispositivos y proyectos.
  • Debate: ¿Se puede vivir haciendo electrónica libre? ¿Cómo hacerlo? ¿Qué licencias elegir? ¿Hay que patentar?
  • Propuestas para definir un programa de actividades dentro de los próximos encuentros de hardware libre.

Traed vuestras propuestas. Traed a todas vuestras amistades que tengan interés. Y si tenéis vuestros propios trastos, traedlos e impresionad a los parroquianos.

Coordenadas espacio-temporales


Los amiguetes de La Oficina Cultural se prestan a darnos cobijo en su local y la cita es:

miércoles 22 de enero

Recordad que en La Oficina hay comercio y bebercio a precios populares y que consumiendo todos un poquito les ayudamos a mantener la actividad..

¡Happy hacking!