Search Results: "tanguy"

21 March 2017

Tanguy Ortolo: Bad support of ZIP archives with extra fields

For sharing multiple files, it is often convenient to pack them into an archive, and the most widely supported format to do so is probably ZIP. Under *nix, you can archive a directory with Info-ZIP:
% zip -r something/
(When you have several files, it is recommended to archive them in a directory, to avoid cluttering the directory where people will extract them.)Unsupported ZIP archive Unfortunately, while we would expect ZIP files to be widely supported, I found out that this is not always the case, and I had many recipients failing to open them under operating systems such as iOS. Avoid extra fields That issue seems to be linked to the usage of extra file attributes, that are enabled by default, in order to store Unix file metadata. The field designed to store such extra attributes was designed from the beginning so each implementation can take into account attributes it supports and ignore any other ones, but some buggy ZIP implementation appear not to function at all with them. Therefore, unless you actually need to preserve Unix file metadata, you should avoid using extra fields. With Info-ZIP, you would have to add the option -X:
% zip -rX something/

23 November 2016

Tanguy Ortolo: Generate man pages for awscli

No man pages, but almost The AWS Command Line Interface, which is available in Debian, provides no man page. Instead, that tool has an integrated help system, which allows you to run commands such as aws rds help, that, for what I have seen, generates some reStructuredText, then converts it to a man page in troff format, then calls troff to convert it to text with basic formatting, and eventually passes it to a pager. Since this is close to what man does, the result looks like a degraded man page, with some features missing such as the adaptation to the terminal width. Well, this is better than nothing, and better than what many under-documented tools can offer, but for several reasons, it still sucks: most importantly, it does not respect administrators' habits and it does not integrate with the system man database. You it does not allow you to use commands such as apropos, and you will get no man page name auto-completion from your shell since there is no man page.Generate the man pages Now, since the integrated help system does generate a man page internally, we can hack it to output it, and save it to a file:
Description: Enable a mode to generate troff man pages
 The awscli help system internally uses man pages, but only to convert
 them to text and show them with the pager. This patch enables a mode
 that prints the troff code so the user can save the man page.
 To use that mode, run the help commands with an environment variable
 OUTPUT set to 'troff', for instance:
     OUTPUT='troff' aws rds help
Forwarded: no
Author: Tanguy Ortolo <>
Last-Update: 2016-11-22
Index: /usr/lib/python3/dist-packages/awscli/
--- /usr/lib/python3/dist-packages/awscli/       2016-11-21 12:14:22.236254730 +0100
+++ /usr/lib/python3/dist-packages/awscli/       2016-11-21 12:14:22.236254730 +0100
@@ -49,6 +49,8 @@
     Return the appropriate HelpRenderer implementation for the
     current platform.
+    if 'OUTPUT' in os.environ and os.environ['OUTPUT'] == 'troff':
+        return TroffHelpRenderer()
     if platform.system() == 'Windows':
         return WindowsHelpRenderer()
@@ -97,6 +99,15 @@
         return contents
+class TroffHelpRenderer(object):
+    """
+    Render help content as troff code.
+    """
+    def render(self, contents):
+        sys.stdout.buffer.write(publish_string(contents, writer=manpage.Writer()))
 class PosixHelpRenderer(PagingHelpRenderer):
     Render help content on a Posix-like system.  This includes
This patch must be applied from the root directory with patch -p0, otherwise GNU patch will not accept to work on files with absolute names. With that patch, you can run help commands with an environment variable OUTPUT='troff' to get the man page to use it as you like, for instance:
% OUTPUT='troff' aws rds help > aws_rds.1
% man -lt aws_rds.1   lp
Generate all the man pages Now that we are able to generate the man page of any aws command, all we need to generate all of them is a list of all the available commands. This is not that easy, because the commands are somehow derived from functions provided by a Python library named botocore, which are derived from a bunch of configuration files, and some of them are added, removed or renamed. Anyway, I have been able to write a Python script that does that, but it includes a static list of these modifications:
#! /usr/bin/python3
import subprocess
import awscli.clidriver
def write_manpage(command):
    manpage = open('%s.1' % '_'.join(command), 'w')
    process = subprocess.Popen(command,
            env= 'OUTPUT': 'troff' ,
driver = awscli.clidriver.CLIDriver()
command_table = driver._get_command_table()
renamed_commands = \
        'config': 'configservice',
        'codedeploy': 'deploy',
        's3': 's3api'
added_commands = \
        's3': ['cp', 'ls', 'mb', 'mv', 'presign', 'rb', 'rm', 'sync',
removed_subcommands = \
        'ses': ['delete-verified-email-address',
        'ec2': ['import-instance', 'import-volume'],
        'emr': ['run-job-flow', 'describe-job-flows',
                'add-job-flow-steps', 'terminate-job-flows',
                'list-bootstrap-actions', 'list-instance-groups',
        'rds': ['modify-option-group']
added_subcommands = \
        'rds': ['add-option-to-option-group',
# Build a dictionary of real commands, including renames, additions and
# removals.
real_commands =  
for command in command_table:
    subcommands = []
    subcommand_table = command_table[command]._get_command_table()
    for subcommand in subcommand_table:
        # Skip removed subcommands
        if command in removed_subcommands \
                and subcommand in removed_subcommands[command]:
    # Add added subcommands
    if command in added_subcommands:
        for subcommand in added_subcommands[command]:
    # Directly add non-renamed commands
    if command not in renamed_commands:
        real_commands[command] = subcommands
    # Add renamed commands
        real_commands[renamed_commands[command]] = subcommands
# Add added commands
for command in added_commands:
    real_commands[command] = added_commands[command]
# For each real command and subcommand, generate a manpage
for command in real_commands:
    write_manpage(['aws', command])
    for subcommand in real_commands[command]:
        write_manpage(['aws', command, subcommand])
                         'sync', 'website'] 
This script will generate more than 2,000 man page files in the current directory; you will then be able to move them to /usr/local/share/man/man1. Since this is a lot of man pages, it may be appropriate to concatenate them by major command, for instance all the aws rds together

8 June 2016

Tanguy Ortolo: Process command line arguments in shell

When writing a wrapper script, one often has to process the command line arguments to transform them according to his needs, to change some arguments, to remove or insert some, or perhaps to reorder them.Naive approach The naive approach to do that is :
# Process arguments, building a new argument list
for arg in "$@"
    case "$arg"
            # Convert --foobar to the new syntax --foo=bar
            new_args="$args --foo=bar"
            # Take other options as they are
            new_args="$args $arg"
# Call the actual program
exec program $new_args
This naive approach is simple, but fragile, as it will break on arguments that contain a space. For instance, calling wrapper --foobar "some file" (where some file is a single argument) will result in the call program --foo=bar some file (where some and file are two distinct arguments). Correct approach To handle spaces in arguments, we need either: except standard shell does support arrays, or rather, it does support one specific array: the positional parameter list "$@" . This leads to one solution to process arguments in a reliable way, which consists in rebuilding the positional parameter list with the built-in command set --:
# Process arguments, building a new argument list in "$@"
# "$@" will need to be cleared, not right now but on first iteration only
for arg in "$@"
    if [ "$first_iter" -eq 1 ]
        # Clear the argument list
        set --
    case "$arg"
        --foobar) set -- "$@" --foo=bar ;;
        *) set -- "$@" "$arg" ;;
# Call the actual program
exec program "$@"
  1. I you prefer, for arg in "$@" can be simplified to just for arg.
  2. As a reminder, and contrary to what it looks like, quoted "$@" does not expand to a single field, but to one field per positional parameter.

15 April 2016

Tanguy Ortolo: Let's Encrypt: threat or opportunity to other certificate authorities?

Let's Encrypt is a certificate authority (CA) that just left beta stage, that provides domain name-validated (DV) X.509 certificates for free and in an automated way: users just have to run a piece of software on their server to get and install a certificate, resulting in a valid TLS setup. A threat to other certificate authorities By providing certificates for free and automatically, Let's Encrypt is probably a threat a other CAs, a least for part of their activity. Indeed, for people that are satisfied with DV certificates, there are not many reasons to pay a commercial CA to get certificates in a non-automated way. For the CAcert non-commercial CA, that may mean a slow death, as this is their main activity . For people that want organization-validated (OV) or extended validation (EV) certificates, Let's Encrypt is not suitable, so it will not change anything regarding that. An opportunity for the most reactive The entrance of Let's Encrypt is also a significant opportunity for the certificate authorities that will be reactive enough to take advantage of their innovation. Indeed, they introduced automation in both domain name validation and certificate issuance (and revocation), by defining an open protocol that is meant to become an Internet standard. That protocol, named ACME, is not tied to Let's Encrypt and has several free software implementations, so it could be used for the same purpose by commercial CAs. A certification authority could, for instance: Such processes may require or benefit from improvements of the ACME protocol, which is the very reason Internet standards are defined in an open way. The first certification authority that would implement such a process could gain an advantage over its competitors, as it would greatly simplify getting and renewing certificates. I think even Let's Encrypt people would be happy to see that happen, as it would serve their goal, that is basically to help securing the Internet! Personally, I could buy such a service (assuming it is not restricted to juridical persons, according to a quite common (and detestable) sale discrimination against natural persons ). Notes
  1. CAcert is an unrecognised certificate authority, that provides an identity validation through a web of trust, and issues DV server certificates that do not include the validated identity. Now that Let's Encrypt can issue valid DV certificates, CAcert is no longer relevant for that activity. It also issues personal certificates, that do include the validated identity, and that can be used for encryption (e.g. S/MIME), signing (e.g. code signing) or authentication, which is an activity Let's Encrypt does not compete with.
  2. Yes, the Organization field of a certificate is probably not relevant to indicate a physical person's name, but the CommonName field is. Yes, that field is usually abused to store the domain name, but a proper use would be to put the owner's name in the CommonName field, and the domain names in the subjectAltName field.

21 January 2016

Tanguy Ortolo: Removing sam2p from Debian

Issues with sam2p and removal I have been maintaining the Debian package of sam2p for some time. Unfortunately, the upstream development of that program is no longer active, and it is using an old custom build chain that no longer works with recent version of GCC. This package is currently failing to build from source, and while I have been able to patch some issues in the past, and it may still be possible to fix it again, this is not really sustainable. I am therefore considering to remove sam2p from Debian, unless someone has a very good reason to keep it and is able and willing to maintain it.Alternative sam2p is a raster image conversion tool that can convert PNG and JPEG to EPS and PDF while keeping their compression, which is mostly useful to use them in documents compiled with LaTeX. Fortunately, the same can be done with ImageMagick. If you want to convert to EPS, you have to specify that you want EPS 2 or 3, otherwise it would produce EPS level 1 which does not provide native raster compression:
% convert debian-openlogo-raster100.png \
% convert debian-openlogo-raster100.png \
% ls -lh
1.7K debian-openlogo-raster100.png
6.0K debian-openlogo-raster100.eps
8.8K debian-openlogo-raster100.pdf
% convert photograph.jpg eps3:photograph.eps
% convert photograph.jpg photograph.pdf
% ls -lh
657K photograph.jpg
662K photograph.eps
664K photograph.pdf
% convert scanned-document.png eps3:scanned-document.eps
% convert scanned-document.png scanned-document.pdf
140K scanned-document.png
145K scanned-document.eps
150K scanned-document.pdf
This is a bit less efficient than sam2p, as convert seems to add some fixed overhead, but it does keep the appropriate compression algorithm. See this documentation page from ImageMagick for more information. Using appropriate formats As a reminder, when writing LaTeX documents, depending on your build chain, you can use:
JPEG or EPS (converted from JPEG with ImageMagick);
raster drawings, screenshots
PNG or EPS (converted from PNG with ImageMagick);
vector graphics
PDF or EPS (convertes from SVG with Inkscape).

26 January 2015

Tanguy Ortolo: Scale manufacturers

Dear manufacturers of kitchen scales, could you please stop considering your clients as idiots, and start developing useful features?Liquid measurement: this is one feature that is available on almost every electronic scale available. Except it is completely useless to people that use the metric system, as all it does is replace the usual display in grammes by centilitres and divide the number on display by ten. Thank you, but no person that has been to school in a country that uses the metric system needs electronic assistance to determine the volume corresponding to a given weight of water, and for people that have not, a simple note written on the scale, stating that for water or milk, divide the weight in grammes by ten to get the volume in centilitres should be enough. Now, there is still one thing that an electronic scale could be useful for, which is determining the volume of liquids other than water (density 1 g/ml) or milk (density approx. equal to 1 g/ml), most importantly: oil (density approx. equal to .92 g/ml for edible oils like sunflower, peanut, olive and canola).

8 January 2015

Tanguy Ortolo: Proof of address: use common sense!

As I have just moved to a new home, I had to declare my new address to all my providers, including banks and administrations which require a proof of address, which can be a phone, DSL or electricity bill. Well, this is just stupid, as, by definition, one will only have a bill after at least a month. Until then, that means the bank will keep a false address, and that the mail they send may not be delivered to the customer.Now, bankers and employees of similar administrations, if you could use some common sense, I have some information for you: when someone moves to a new home, unless he is hosted by someone else, he is either renter or owner. Well, you should now that a renter has one contract that proves it, which is called a lease. And an owner has one paper that proves it, which is called a title, or, before it has been issued by administration, a certificate of sale. Now if you do not accept that as a proof of address, you just suck. Besides, such a zeal to check one's address is just pointless, as it is just to get a proof of address without waiting for a phone, DSL or electricity bill (or to prove a false address, actually ) by just faking one. And as a reminder, at least in France, forgery is punishable by law but defined as an alteration of truth which can cause a prejudice, which means modifying a previous electricity bill to prove your actual address is not considered as a forgery (but using the same mean to prove a false address is, of course!).

9 December 2014

Tanguy Ortolo: Using bsdtar to change an archive format

Streamable archive formats Package icon Archive formats such as tar(5) and cpio(5) have the advantage of being streamable, so you can use them for transferring data with pipes and remote shells, without having to store the archive in the middle of the process, for instance:
$ cd public_html/blog
$ rgrep -lF "archive" data/articles \
        pax -w \
        ssh newserver "mkdir public_html/blog ;
                       cd public_html/blog ;
                       pax -r"
Turning a ZIP archive into tarball Unfortunately, many people will send you data in non-streamable archive formats such as ZIP . For such cases, bsdtar(1) can be useful, as it is able to convert an archive from one format to another:
$ bsdtar -cf - \
These arguments tell bsdtar to: The result is a tape archive, which is easier to manipulate in a stream than a ZIP archive. Notes
  1. Some will say that although ZIP is based on an file index, it can be stream because that index is placed at the end of the archive. In fact, that characteristic only allows to stream the archive creation, but requires to store the full archive before being able to extract it. .

13 November 2014

Tanguy Ortolo: Re: About choice

This is a reply to Josselin Mouette's blog article About choice, since his blog does not seem to accept comments . Please note that this is not meant to be systemd-bashing, just a criticism base one a counter-example refutation of Josselin's implication that there is no use case better covered by SysV init: this is false, as there is at least one. And yes, there are probably many cases better covered by systemd, I am making no claims about that.A use case better covered by SysV init: encrypted block devices So, waiting for a use case better covered by SysV init? Rejoice, you will not die waiting, here is one: encrypted block devices. That case works just fine with SysV init, without any specific configuration, whereas systemd just sucks at it. There exist a way to make it work , but: If you know any better, I would be glad to try it. Believe me, I like the basic principles of systemd and I would be glad to have it working correctly on my system. Notes
  1. Well, it does accept comments, but marks them as span and does not show them, which is roughly equivalent.
  2. Installing an additional piece of software, Plymouth, is supposed to make systemd work correctly with encrypted block devices. Yes, this is additional configuration, as that piece of software does not come when you install systemd, and it is not even suggested so a regular user cannot guess it.
  3. Though I must say I hate the way it is pushed into the GNU/Linux desktop systems.

17 October 2014

Tanguy Ortolo: Trying systemd [ OK ] Switching back to SysV [ OK ]

Since systemd is now the default init system under Debian Jessie, it got installed to my system and I had a chance to test it. The result is disappointing: it does not work well with cryptsetup, so I am switching back to SysV init and RC.The problem comes from the fact that I am using encrypted drives with cryptsetup, and while this is correctly integrated with SysV, it just sucks with systemd, where the passphrase prompt is mixed up with service start messages, a bit like that (from memory, since I did not take a picture of my system booting):
Enter passphrase for volume foobar-crypt:
[ OK ] Sta*rting serv*ice foo**
[ OK ] ***Starting service bar**
[ OK ] Starting service baz****
The stars correspond to the letters I type, and as you can see, as the passphrase prompt does not wait for my input, they get everywhere in the boot messages, and there is no clear indication that the passphrase was accepted. This looks like some pathological optimization for boot speed, where even interactive steps are run in parallel with services startup: sorry, but this is just insane. There may exist ways to work around this issue, but I do not care: SysV init works just fine with no setup at all, and I since have no real need for another init system, systemd as a replacement is only acceptable if it works at least as fine for my setup, which is not the case. Goodbye systemd, come back when you are ready.

23 July 2014

Tanguy Ortolo: GNU/Linux graphic sessions: suspending your computer

Major desktop environments such as Xfce or KDE have a built-in computer suspend feature, but when you use a lighter alternative, things are a bit more complicated, because basically: only root can suspend the computer. There used to be a standard solution to that, using a D-Bus call to a running daemon upowerd. With recent updates, that solution first stopped working for obscure reasons, but it could still be configured back to be usable. With newer updates, it stopped working again, but this time it seems it is gone for good:
$ dbus-send --system --print-reply \
            --dest='org.freedesktop.UPower' \
            /org/freedesktop/UPower org.freedesktop.UPower.Suspend
Error org.freedesktop.DBus.Error.UnknownMethod: Method "Suspend" with
signature "" on interface "org.freedesktop.UPower" doesn't exist
The reason seems to be that upowerd is not running, because it no longer provides an init script, only a systemd service. So, if you do not use systemd, you are left with one simple and stable solution: defining a sudo rule to start the suspend or hibernation process as root. In /etc/sudoers.d/power:
%powerdev ALL=NOPASSWD: /usr/sbin/pm-suspend, \
                        /usr/sbin/pm-suspend-hybrid, \
That allows members of the powderdev group to run sudo pm-suspend, sudo pm-suspend-hybrid and sudo pm-hibernate, which can be used with a key binding manager such as your window manager's or xbindkeys. Simple, efficient, and contrary to all that ever-changing GizmoKit and whatsitd stuff, it has worked and will keep working for years.

2 July 2014

Tanguy Ortolo: PayPal cut a secure email project's funds

It should be no news that PayPal have made an habit of opposing to projects that fight for the respect of freedom and democracy by cutting their funds. Anyway, they have just provided us another example of such an abuse, against the ProtonMail project.ProtonMail is a secure email service project, similar to the defunct Lavabit service, with characteristics that should allow it a greater resistance to external pressure: it is based in Switzerland (which has specific privacy laws and with a strong democratic control) and developed by CERN and MIT researchers. Well, it seems that this project was not appreciated by some organization, for which PayPal is just a puppet. Long story short, PayPal cut ProtonMail's funds without prior warning nor real explanation. When pressed to explain themselves, they eventually asked them if their email encryption project was approved by the government (which one, by the way?)! As I said in introduction, this is not really a surprise, but it remind us that PayPal's major position is a threat to freedom and democracy as they still behave as enemies of these values (or as collaborator to known harmful organization, which is close enough) and that no project should rely on them. Fortunately, ProtonMail does not.,

2 June 2014

Rapha&#235;l Hertzog: My Free Software Activities since January 2014

If you follow my blog closely, you noticed that I skipped all my usual monthly summaries in 2014. It s not that I stopped doing free software work, instead I was just too busy to be able to report about what I did. As an excuse, let me tell you that we just moved into a new house which was in construction since may last year. The lack of visible activity on my blog resulted in a steady decrease of the amount of donations received (January: 70.72 , February: 71.75 , March: 51.25 , April: 39.9 , May: 40.33 ). Special thanks to all the people who kept supporting my work even though I stopped reporting about it. So let s fix this. This report will be a bit less detailed since it covers the whole period since the start of the year. Debian France Preparations related to general assemblies. The year started with lots of work related to Debian France. First I took care of setting up limesurvey with Alexandre Delano to handle the vote to pick our new logo:
The new logo of Debian France I also helped Sylvestre Ledru to finalize and close the accounting books for 2013 in preparation for the general assembly that was due later in the month. I wrote the moral report of the president to be presented to the assembly. And last step, I collected vote mandates to ensure that we were going to meet the quorum for the extraordinary assembly that was planned just after the usual yearly assembly. The assemblies took place during a two days mini-debconf in Paris (January 17-18) where I was obviously present even though I gave no talk besides announcing the logo contest winner and thanking people for their participation.
Assembl e g n rale 2014 de Debian France

The Debian France members during the general assembly

It s worth noting that the extraordinary assembly was meant primarily to enshrine in our bylaws the possibility to act as a trusted organization for Debian. This status should be officialized by the Debian project leader (Lucas Nussbaum) in the upcoming weeks since we answered satisfactorily to all questions. Our paypal donation form and the accounting tools behind it are ready. Galette packaging and members map. I managed to hand over the package maintenance of galette to Fran ois-R gis Vuillemin. I sponsored all his uploads and we packaged a new plugin that allows to create a map with all the members who accept to share their location. The idea was to let people meet each other when they don t live far away with the long term goal to have Debian France organized activities not only in Paris but everywhere in France. New contributor game. Last but not least, I organized a game to encourage people to do their first contribution to Debian by offering them a copy of my book if they managed to complete a small Debian project. We got many interesting projects but the result so far seem to be very mixed. Many people did not complete their project (yet) that said for the few that did substantial work, it was rather good and they seem to be interested to continue to contribute. Debian France booth at Solutions Linux in Paris. Like each year, I spent two days in Paris to help man the Debian France booth at Solutions Linux. We had lots of goodies on sale and we made more than 2000 EUR in earnings during the two days. I also used this opportunity to try to convince companies to support the new Debian LTS effort.
Debian France booth at Solutions Linux

Tanguy Ortolo and Fernando Lagrange behind the Debian France booth

The Debian Administrator s Handbook In the last days of 2013, we released the wheezy update of the book. Then I quickly organized everything needed so that the various translation teams can now focus their efforts on the latest release of the book. Later (in February) I announced the availability of the French and Spanish translations. Debian Squeeze LTS When the security team called for help to try to put in place long term support for Squeeze, I replied positively because I m convinced that it s very important if Debian wants to stay an acceptable choice in big deployments and because I knew that some of my customers would be interested Thus I followed all the discussions (on a semi-private list first and then on and contributed my own experience. I have also taken up the responsibility to coordinate with the Debian contributors who can be hired to work on Squeeze LTS so that we have a clear common offer for all the companies who have offered financial support towards Squeeze LTS. Expect further news on this front in the upcoming days/weeks. Tryton I have been a long time user of SQL-Ledger to manage the accounting of my company Freexian. But while the license is free software, the project is not. It s the work of a single developer who doesn t really accept help. I have thus been considering to move to something else for a long time but never did anything. This year, after some rough evaluation, I decided to switch to Tryton for my company. It s probably not a wise choice from a business perspective because that migration took me many hours of unpaid labor but from a free software perspective it s definitely better than everything else I saw. I contributed a lot of bug reports and a few patches already (#3596, #3631, #3633, #3665, #3667, #3694, #3695, #3696, #3697) mainly about problems found in the French chart of accounts but also about missing features for my use case. I also accepted to sponsor Matthias Berhle, who is maintaining the official Debian packages of Tryton. He s already a Debian maintainer so it s mainly a matter of reviewing new source packages and granting him the required rights. Misc Debian work Thanks See you next month for a new summary of my activities.

2 comments Liked this article? Click here. My blog is Flattr-enabled.

28 May 2014

Tanguy Ortolo: GNU/Linux graphic sessions: allowing computer suspend and disabling a monitor

Allowing computer suspend Major desktop environments such as Xfce or KDE have a built-in computer suspend feature, but when you use a lighter alternative, things are a bit more complicated, because basically: only root can suspend the computer. Possible solutions include: With recent updates of the related Debian packages no idea of which one exactly the latter solution may not work any more, in which case it will only return the following error:
Error org.freedesktop.UPower.GeneralError: not authorized
It appears that this error is linked to ConsoleKit, a part of all this modern *Kit gizmo pile. If you are in this case, try prefixing your session launcher with the undocumented dark magic call ck-launch-session. For instance, this is what I have in my .xsession to launch my window manager i3:
exec ck-launch-session i3
Note: I do not know what ck-launch-session does exactly, why it is needed, and I do not want to know. To me, all that WhatsitKit pile is just some opaque, under-documented as in: no man page crap, that no one but their author really understand, designed to solve theoretical problems no one really cares about like: how to allow locally connected users to use the sound card while forbidding it to remote users while creating new issues such as this one. This stuff is too complex and under-documented for me to dive into it, so if it does not work out of the box, it is just some crap that gets in my way to using my computer as I wish. Disabling a monitor In some configurations, you have two monitors and want to disable one. For instance, in addition to my LCD monitor, I have a projector which I only use for movies. According to xorg.conf's man page, it can be disabled this way:
Section "Device"
    Identifier  "Internal graphic card"
    Option      "Monitor-DVI"   "LCD Monitor"
    Option      "Monitor-VGA"   "Projector"
Section "Monitor"
    Identifier  "LCD Monitor"
Section "Monitor"
    Identifier  "Projector"
    Option      "Enable"    "false"
Except that does not work, because contrary to what the man page says the real option to use is not Enable but Disable! So here is the correct configuration to disable that monitor at start-up:
Section "Device"
    Identifier  "Internal graphic card"
    Option      "Monitor-DVI"   "LCD Monitor"
    Option      "Monitor-VGA"   "Projector"
Section "Monitor"
    Identifier  "LCD Monitor"
Section "Monitor"
    Identifier  "Projector"
    Option      "Disable"   "true"
Note: yes, I will send a bug report with a patch against xorg.conf's man page.

8 April 2014

Tanguy Ortolo: Disable your spammed addresses with Postfix

Using address extension Postfix (and many other mail servers) offers one nice address extension feature: addresses like <user+whaterver@> are implicit aliases to <user@>. This allows users to implement a simple measure to fight spam:
  1. when SomeCompany or whatever asks for your email address, give them <user+somecompany@>;
  2. if you start receiving spam at that address, you know who sold or was stolen your address;
  3. finally, you will be able to disable that address so messages are simply refused with a permanent error code.
Road sign  you shall not pass  with Gandalf
Disabling an extended address So, here is how to implement that last step with Postfix, when you detect that your extended address <user+evilcorp@> is being spammed. In /etc/postfix/
smtpd_recipient_restrictions =
    check_recipient_access hash:/etc/postfix/recipients,
    [ ]
Then, create /etc/postfix/recipients containing the addresses to disable:   553 5.7.1 I did not subscribe to receive spam, go away
Of course, the error codes and message can be freely configured, just make sure you are using a permanent error code so senders do not retry. Hash that table, reload Postfix and it is done:
# postmap /etc/postfix/recipients
# service postfix reload
After that, your mail server will reject messages sent to these addresses. And it will do so at the RCPT TO step, saving your bandwidth for more useful things.

19 March 2014

Tanguy Ortolo: Self-Destructing Cookies for Firefox

Web cookies are meant to store user preferences for a website, but they are often misused for evil purposes, such as tracking him, sometimes across distinct websites.For the user, there is a simple solution to that problem: set up his browser to refuse cookies by default, and use an extension such as Cookie Monster to accept them on trusted websites where they are known to be useful. Unfortunately, that reveals another problem: some shitty websites will just not work at all without cookies. Well, there is a Firefox extension that brings the solution to that: Self-Destructing Cookies. It works in a fairly simple way: cookies for each are accepted for each website, but destroyed when the user leaves it. So, does EvilCorp want to use a cookie, and refuse to work without it? No problem, here it is. Want to retrieve it on next visit? No way.

13 December 2013

Tanguy Ortolo: Pure Sensia digital and Internet radio receiver: good idea, bad design

Thanks to a corporate reward program, I just got a Pure Sensia digital and Internet radio receiver: basically, it is a device able to play streams from FM, DAB, HTTP and USB sticks. In overall, it works fine, and it has a remote controller, so it makes a nice addition to my home equipment, but it has what I consider a major flaw, which I suspect to have been designed on purpose.For playing streams from FM or DAB, the process is rather simple: you select a frequency and it plays, nothing else is involved. I did not try USB yet but it should be similar: you select a file or a playlist and it plays it. But for HTTP streams, it is quite different: you select a stream from a the Pure Connect directory which is a list of HTTP streaming services maintained by the manufacturer Pure. This raises three concerns:
  1. If all HTTP stream access is made from that remote directory, it probably means Pure knows, and possibly logs, every stream you listen to. That is not acceptable.
  2. What will happen when that service is shut down? Not if it is shut down, mind you, but when it is, because it will, since I never heard of any company keeping a service forever, or any company lasting forever itself actually. Well, here is what will happen: all these digital and Internet radio receivers will become digital but not Internet radio receiver. That is not acceptable: when you buy a radio receiver, you buy a device, not a service of indefinite term.
  3. What do you do if you want to listen to an HTTP stream which is not listed on Pure's directory? Answer of Pure's support: you can add custom streams by URL to your Pure account's favourites. Well, good try, but that is not enough or rather, that is too much: requiring a Pure account to do that, is an artificial restriction, which suffers from exactly the same flaw as the Pure directory. And letting a single company know every Internet stream you listen to is not acceptable either.
Considering that flaw, here is my overall comment about that radio receiver: it is based on a good idea, and it has a good overall design, but it implements it in a precarious way. If you buy one of these things, you should know that you are not buying a complete digital and Internet radio receiver but only a digital radio receiver with some Internet features with privacy concerns, which will work for a time and one day stop working on Pure's decision.

29 November 2013

Tanguy Ortolo: Mutt: encrypt all messages sent to known PGP users

GnuPG logo This is one thing I have wanted to do for a long time: configure Mutt to encrypt all messages sent to addresses for which I have a valid public key. Well, here is an awk-based script to generate that configuration. (Yes, I know, a similar script was already written. But I did not see it at first, and I find mine more readable. :-) )Code
#! /bin/sh
set -e
# Specific hooks set global configuration values for Mutt, which are not
# reset for new messages, so a default hook is needed to set the default
# value (do not try encrypting all messages).
printf "send-hook . unset crypt_autoencrypt\n\n"
cat <<EOF
# This group contains all known PGP users, and can be used to define
# hooks, for instance to encrypt all messages sent to PGP users, or to
# add a specific signature to promote PGP usage to non-PGP users.
# Generate a machine-readable list of known keys
gpg2 --batch --with-colons --list-keys \
      awk -- '
            FS = ":"
            # A flag that indicates whether or not we are in a public
            # key with usable encryption capability
            usable = 0
        # Detect beginning of public keys with usable encryption
        # capability
        $1 == "pub" && $12 ~ /E/   usable = 1  
        # Detect beginning of public keys without usable encryption
        # capability
        $1 == "pub" && $12 !~ /E/   usable = 0  
        # Only consider user IDs from public keys with usable encryption
        # capability and with regular, marginal, full or ultimate
        # validity (n, m, f or u in the second field)
        usable && $1 == "uid" && $2 ~ /[nmfu]/ && $10 ~ /@/  
            # Remove everything before and after the email address in
            # brackets
            sub(/^[^<]*</, "", $10)
            sub(/>[^>]*$/, "", $10)
            # Finally print the email address
            print $10
         ' \
      sort -u \
        # Group addresses by ten to reduce the number of Mutt commands
        while [ $finished -ne 1 ]
            for i in 0 1 2 3 4 5 6 7 8 9
                if read address
                    addresses="$addresses $address"
            # Add PGP users' addresses to a pgp-users group
            printf "group -group pgp-users -addr %s\n" \
# Build a hook to try encrypting messages sent to PGP users
printf "\n# Encrypt all messages sent to known PGP users\n"
printf "send-hook \"%%C pgp-users\" set crypt_autoencrypt\n" \
printf "\n# Add a specific signature to promote PGP usage to non-PGP users\n"
printf "#send-hook \"!%%C pgp-users\" set signature=~/.signature.use-pgp\n"
Usage Script usage This script generates uses GnuPG to print a list of all known keys, takes only valid ones, and uses them to build a series of configuration instructions for Mutt, that define hooks that are triggered when you write a message to them. This configuration has to be written to your Mutt configuration file:
$ bin/ >> ~/.muttrc
Or better (far better, in fact), to a dedicated configuration file you will refer to in your main one:
$ bin/ > ~/.muttrc.crypt-recipients
$ echo "source ~/.muttrc.crypt-recipients" >> ~/.muttrc
You may want to adapt this script to it directly writes to that file rather than having to redirect it. Also, remember to run it when you refresh your public keyring or add new keys to it. Mutt usage These hooks will make Mutt try to encrypt all messages you send to at least one known PGP user. That means it will try it even for messages you send to a PGP user and to non-PGP ones. In these cases, it will not find keys for all the recipient, and ask you which key to use; as you have none, you will have to quit that prompt by typing ^G, and manually disable encryption by accessing the PGP options menu with the key p.

14 November 2013

Tanguy Ortolo: Using Wine with sound under Debian testing (Jessie)

If you are using Wine under Debian testing with PulseAudio, you probably noticed that you cannot get sound playback any more. This is because: Loudspeaker icon
  1. Wine uses ALSA, which uses a plugin to play through PulseAudio;
  2. Wine being in 32 bits, all that has to be installed in i386 versions;
  3. recent versions of libasound2-plugins depend on libavcodec54 which depends on libopus0 which is not multiarch-capable and thus cannot be installed in both i386 and amd64 versions;
  4. libopus0:amd64 cannot be reasonably removed to install only libopus0:i386 because many multimedia software depend on it (in other words: try that and you will end removing VLC and everything similar too).
No need to despair though, as there are several ways to work around that problem until the maintainer of libasound2-plugins has converted it to multiarch.Use ALSA directly Since the problem is that Wine tries to use the ALSA PulseAudio plugin which is not available in 32 bits, the most direct solution is to configure it not to use it. Run winecfg, go to the audio tab and manually select your audio devices, which will then be used directly with ALSA without trying to use the PulseAudio plugin.
Screenshot of winecfg

Wine configuration

Downgrade ALSA plugins Since the problem is caused by a dependency chain that only exists with the testing (Jessie) version of the libasound2-plugins package, another solution is to downgrade it to a previous version. To do that, make sure you have enabled the Debian repositories for both the stable (Wheezy) and testing (Jessie) in /etc/apt/sources.list: deb jessie main deb jessie/updates main contrib non-free deb wheezy main deb wheezy/updates main contrib non-free Then, forcefully install the stable version of libasound2-plugins for both i386 and amd64: # apt-get install libasound2-plugins:i386/stable \ libasound2-plugins:amd64/stable

31 October 2013

Tanguy Ortolo: How to implement a Postfix spam trap?

Open envelope Spam trap Dear lazyweb, I am considering to implement spam traps and evaluate their efficiency. The idea as rather simple:
  1. publish some real-looking email addresses on websites, in ways that no human would use them to send legitimate mail, for instance in hidden texts, or in texts clearly stating they should not be used;
  2. when my mail server receives a message for one of these address, blacklist the originating server for some time so it cannot spam real recipients.
Practical implementation Now, I have to decide on how to implement that with my Postfix server. I am thinking of using fail2ban to simply detect attempts to send mail to my spam traps and blocking these spammers at iptables-level, but I do not think that will give me much tuning possibilities. Do you have other suggestions? Implementation details I also have to think about some specific details. Here is what I identified so far, do you think I am missing something that may be useful?