Gio's Tilde - debian-planethttps://www.giovannimascellani.eu/2020-11-21T21:00:00+01:00Giovanni MascellaniHaving fun with signal handlers2020-11-21T21:00:00+01:002020-11-21T21:00:00+01:00Giovanni Mascellanitag:www.giovannimascellani.eu,2020-11-21:/having-fun-with-signal-handlers.html<p>As every C and C++ programmer knows far too well, if you dereference a
pointer that points outside of the space mapped on your process'
memory, you get a segmentation fault and your programs crashes. As far
as the language itself is concerned, you don't have a second chance
and …</p><p>As every C and C++ programmer knows far too well, if you dereference a
pointer that points outside of the space mapped on your process'
memory, you get a segmentation fault and your programs crashes. As far
as the language itself is concerned, you don't have a second chance
and you cannot know in advance whether that dereferencing operation is
going to set a bomb off or not. In technical terms, you are invoking
<em>undefined behaviour</em>, and you should never do that: you are
responsible for knowing in advance if your pointers are valid, and if
they are not you keep the pieces.</p>
<p>However, turns out that most actual operating system give you a second
chance, although with a lot of fine print attached. So I tried to
implement a function that tries to dereference a pointer: if it can,
it gives you the value; if it can't, it tells you it couldn't. Again,
I stress this should never happen in a real program, except possibly
for debugging (or for having fun).</p>
<p>The prototype is</p>
<div class="highlight"><pre><span></span><code><span class="n">word_t</span> <span class="nf">peek</span><span class="p">(</span><span class="n">word_t</span> <span class="o">*</span><span class="n">addr</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">success</span><span class="p">);</span>
</code></pre></div>
<p>The function is basically equivalent to <code>return *addr</code>, except that if
<code>addr</code> is not mapped it doesn't crash, and if <code>success</code> is not NULL it
is set to <code>0</code> or <code>1</code> to indicate that <code>addr</code> was not mapped or
mapped. If <code>addr</code> was not mapped the return value is meaningless.</p>
<p>I won't explain it in detail to leave you some fun. Basically the idea
is to install a handler for <code>SIGSEGV</code>: if the address is invalid, the
handler is called, which basically fixes everything by advancing a
little bit the instruction pointer, in order to skip the faulting
instruction. The dereferencing instruction is written as hardcoded
Assembly bytes, so that I know exactly how many bytes I need to skip.</p>
<p>Of course this is very architecture-dependent: I wrote the <code>i386</code> and
<code>amd64</code> variants (no <code>x32</code>). And I don't guarantee there are no bugs
or subtelties!</p>
<p>Another solution would have been to just parse <code>/proc/self/maps</code>
before dereferencing and check whether the pointer is in a mapped
area, but it would have suffered of a
<a href="https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use">TOCTTOU</a>
problem: another thread might have changed the mappings between the
time when <code>/proc/self/maps</code> was parsed and when the pointer was
dereferenced (also, parsing that file can take a relatively long
amount of time). Another less architecture-dependent but still not
pure-C approach would have been to establish a <code>setjmp</code> before
attempting the dereference and <code>longjmp</code>-ing back from the signal
handler (but again you would need to use different <code>setjmp</code> contexts
in different threads to exclude race conditions).</p>
<p>Have fun! (and again, don't try this in real programs)</p>
<p><strong>EDIT</strong> I realized I should specify the language for source code
highlighting to work decently. Now it's better!</p>
<p><strong>EDIT 2</strong> I also realized that my version of <code>peek</code> has problems when
there are other threads, because signal actions are per-process, not
per-thread (as I initially thought). See the comments for a better
version (though not perfect).</p>
<div class="highlight"><pre><span></span><code><span class="cp">#define _GNU_SOURCE</span>
<span class="cp">#include</span> <span class="cpf"><stdint.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><signal.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><assert.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><stdlib.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><stdio.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><ucontext.h></span><span class="cp"></span>
<span class="cp">#ifdef __i386__</span>
<span class="k">typedef</span> <span class="kt">uint32_t</span> <span class="n">word_t</span><span class="p">;</span>
<span class="cp">#define IP_REG REG_EIP</span>
<span class="cp">#define IP_REG_SKIP 3</span>
<span class="cp">#define READ_CODE __asm__ __volatile__(".byte 0x8b, 0x03\n" </span><span class="cm">/* mov (%ebx), %eax */</span><span class="cp"> \</span>
<span class="cp"> ".byte 0x41\n" </span><span class="cm">/* inc %ecx */</span><span class="cp"> \</span>
<span class="cp"> : "=a"(ret), "=c"(tmp) : "b"(addr), "c"(tmp));</span>
<span class="cp">#endif</span>
<span class="cp">#ifdef __x86_64__</span>
<span class="k">typedef</span> <span class="kt">uint64_t</span> <span class="n">word_t</span><span class="p">;</span>
<span class="cp">#define IP_REG REG_RIP</span>
<span class="cp">#define IP_REG_SKIP 6</span>
<span class="cp">#define READ_CODE __asm__ __volatile__(".byte 0x48, 0x8b, 0x03\n" </span><span class="cm">/* mov (%rbx), %rax */</span><span class="cp"> \</span>
<span class="cp"> ".byte 0x48, 0xff, 0xc1\n" </span><span class="cm">/* inc %rcx */</span><span class="cp"> \</span>
<span class="cp"> : "=a"(ret), "=c"(tmp) : "b"(addr), "c"(tmp));</span>
<span class="cp">#endif</span>
<span class="k">static</span> <span class="kt">void</span> <span class="n">segv_action</span><span class="p">(</span><span class="kt">int</span> <span class="n">sig</span><span class="p">,</span> <span class="kt">siginfo_t</span> <span class="o">*</span><span class="n">info</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">ucontext</span><span class="p">)</span> <span class="p">{</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">sig</span><span class="p">;</span>
<span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="n">info</span><span class="p">;</span>
<span class="n">ucontext_t</span> <span class="o">*</span><span class="n">uctx</span> <span class="o">=</span> <span class="p">(</span><span class="n">ucontext_t</span><span class="o">*</span><span class="p">)</span> <span class="n">ucontext</span><span class="p">;</span>
<span class="n">uctx</span><span class="o">-></span><span class="n">uc_mcontext</span><span class="p">.</span><span class="n">gregs</span><span class="p">[</span><span class="n">IP_REG</span><span class="p">]</span> <span class="o">+=</span> <span class="n">IP_REG_SKIP</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="nc">sigaction</span> <span class="n">peek_sigaction</span> <span class="o">=</span> <span class="p">{</span>
<span class="p">.</span><span class="n">sa_sigaction</span> <span class="o">=</span> <span class="n">segv_action</span><span class="p">,</span>
<span class="p">.</span><span class="n">sa_flags</span> <span class="o">=</span> <span class="n">SA_SIGINFO</span><span class="p">,</span>
<span class="p">.</span><span class="n">sa_mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<span class="p">};</span>
<span class="n">word_t</span> <span class="nf">peek</span><span class="p">(</span><span class="n">word_t</span> <span class="o">*</span><span class="n">addr</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">success</span><span class="p">)</span> <span class="p">{</span>
<span class="n">word_t</span> <span class="n">ret</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">tmp</span><span class="p">,</span> <span class="n">res</span><span class="p">;</span>
<span class="k">struct</span> <span class="nc">sigaction</span> <span class="n">prev_act</span><span class="p">;</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">sigaction</span><span class="p">(</span><span class="n">SIGSEGV</span><span class="p">,</span> <span class="o">&</span><span class="n">peek_sigaction</span><span class="p">,</span> <span class="o">&</span><span class="n">prev_act</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">res</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">READ_CODE</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">sigaction</span><span class="p">(</span><span class="n">SIGSEGV</span><span class="p">,</span> <span class="o">&</span><span class="n">prev_act</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="n">assert</span><span class="p">(</span><span class="n">res</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">success</span><span class="p">)</span> <span class="p">{</span>
<span class="o">*</span><span class="n">success</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">ret</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">success</span><span class="p">;</span>
<span class="n">word_t</span> <span class="n">number</span> <span class="o">=</span> <span class="mi">22</span><span class="p">;</span>
<span class="n">word_t</span> <span class="n">value</span><span class="p">;</span>
<span class="n">number</span> <span class="o">=</span> <span class="mi">22</span><span class="p">;</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">peek</span><span class="p">(</span><span class="o">&</span><span class="n">number</span><span class="p">,</span> <span class="o">&</span><span class="n">success</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%d %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">success</span><span class="p">,</span> <span class="n">value</span><span class="p">);</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">peek</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="o">&</span><span class="n">success</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%d %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">success</span><span class="p">,</span> <span class="n">value</span><span class="p">);</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">peek</span><span class="p">((</span><span class="n">word_t</span><span class="o">*</span><span class="p">)</span><span class="mh">0x1234</span><span class="p">,</span> <span class="o">&</span><span class="n">success</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%d %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">success</span><span class="p">,</span> <span class="n">value</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>Bye bye Python 2!2020-08-03T21:00:00+02:002020-08-03T21:00:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2020-08-03:/bye-bye-python2.html<p>And so, today, while I was browsing updates for my Debian unstable
laptop, I noticed that <code>aptitude</code> wouldn't automatically upgrade
<code>python2</code> and related packages (I don't know why, and at this point
don't care). So I decided to dare: I removed the <code>python2</code> package to
see what the dependency solver …</p><p>And so, today, while I was browsing updates for my Debian unstable
laptop, I noticed that <code>aptitude</code> wouldn't automatically upgrade
<code>python2</code> and related packages (I don't know why, and at this point
don't care). So I decided to dare: I removed the <code>python2</code> package to
see what the dependency solver would have proposed me. It turned out
that there was basically nothing I couldn't live without.</p>
<p>So, bye bye Python 2. It was a long ride and I loved programming with
you. But now it's the turn of your younger brother.</p>
<div class="highlight"><pre><span></span><code>$ python
bash: python: comando non trovato
</code></pre></div>
<p>(guess what "comando non trovato" means?)</p>
<p>And thanks to all those who made this possible!</p>DKIM for Debian Developers2020-04-13T15:00:00+02:002020-04-13T15:00:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2020-04-13:/dkim-for-debian-developers.html<h1>What is DKIM?</h1>
<p><a href="https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail">DKIM (DomainKeys Identified
Mail)</a>, as
Wikipedia puts it, "is an email authentication method designed to
detect forged sender addresses in emails (email spoofing), a technique
often used in phishing and email spam". More prosaically, one of the
reasons email spam is so abundant is that, given a …</p><h1>What is DKIM?</h1>
<p><a href="https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail">DKIM (DomainKeys Identified
Mail)</a>, as
Wikipedia puts it, "is an email authentication method designed to
detect forged sender addresses in emails (email spoofing), a technique
often used in phishing and email spam". More prosaically, one of the
reasons email spam is so abundant is that, given a certain email
message, there is no simple way to know for certain who sent it and
how reputable they are. So even if people having addresses
<code>@debian.org</code> are very nice and well-behaving, any random spammer can
easily send emails from <code>whatever@debian.org</code>, and even if you trust
people from <code>@debian.org</code> you cannot easily configure your antispam
filter to just accept all emails from <code>@debian.org</code>, because spammers
would get in too.</p>
<p>Since nearly ten years DKIM is there to help you. If you send an email
from <code>@debian.org</code> with DKIM, it will have a header like this:</p>
<div class="highlight"><pre><span></span><code>DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=debian.org;
s=vps.gio.user; t=1586779391;
bh=B6tckJy2cynGjNRdm3lhFDrp0tD7fF8hS4x0FCfLADo=;
h=From:Subject:To:Date:From;
b=H4EDlATxVm7XNqPy2x7IqCchBUz1SxFtUSstB23BAsdyTKJIohM0O4RRWhrQX+pqE
prPVhzcfNALMwlfExNE69940Q6pMCuYsoxNQjU7Jl/UX1q6PGqdVSO+mKv/aEI+N49
vvYNgPJNLaAFnYqbWCPI8mNskLHLe2VFYjSjE4GJFOxl9o2Gpe9f5035FYPJ/hnqBF
XPnZq7Osd9UtBrBq8agEooTCZHbNFSyiXdS0qp1ts7HAo/rfrBfbQSk39fOOQ5GbjV
6FehkN4GAXFNoFnjfmjrVDJC6hvA8m0tJHbmZrNQS0ljG/SyffW4OTlzFzu4jOmDNi
UHLnEgT07eucw==
</code></pre></div>
<p>The field <code>d=debian.org</code> is the domain this email claims to be from
and the fields <code>bh=</code> and <code>b=</code> are a cryptographic public key signature
certifying this fact. How do I check that the email is actually from
<code>@debian.org</code>? I use the selector <code>s=vps.gio.user</code> to fetch the public
key via DNS, and then use the public key to verify the signature.</p>
<div class="highlight"><pre><span></span><code>$ host -t TXT vps.gio.user._domainkey.debian.org
vps.gio.user._domainkey.debian.org descriptive text "v=DKIM1; k=rsa; s=email; h=sha256; p=" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsM/W/kxtKWT58Eak0cfm/ntvurfbkkvugrG2jfvSMnHHkFyfJ34Xvn/HhQPLwX1QsjhuLV+tW+BQtxY7jxSABCee6nHQRBrpDej1t86ubw3CSrxcg1mzJI5BbL8un0cwYoBtUvhCYAZKarv1W2otCGs43L0s" "GtEqqtmYN/hIVVm4FcqeYS1cYrZxDsjPzCEocpYBhqHh1MTeUEddVmPHKZswzvllaWF0mgIXrfDNAE0LiX39aFKWtgvflrYFKiL4hCDnBcP2Mr71TVblfDY0wEdAEbGEJqHR1SxvWyn0UU1ZL4vTcylB/KJuV2gMhznOjbnQ6cjAhr2JYpweTYzz3wIDAQAB"
</code></pre></div>
<p>There it is! Debian declares in its DNS record that that key is
authorized to sign outbound email from <code>@debian.org</code>. The spammer
hopefully does not have access to Debian's DKIM keys, and they cannot
sign emails.</p>
<p>Many large and small email services have already deployed DKIM since
years, while most <code>@debian.org</code> emails still do not use it. Why not?
Because people send <code>@debian.org</code> emails from many different
servers. Basically, every DD used their <code>@debian.org</code> address sends
email from their own mail server, and those mail servers (fortunately)
do not have access to Debian's DNS record to install their DKIM
keys. Well, that was true until yesterday! :-)</p>
<p>A few weeks ago I poked DSA asking to allow any Debian Developer to
install their DKIM keys, so that DDs could use DKIM to sign their
emails and hopefully reduce the amount of spam sent from
<code>@debian.org</code>. They have done it (thank you DSA very much, especially
<code>adsb</code>), and now it is possible to use it!</p>
<h1>How do I configure it?</h1>
<p>I will not write here a full DKIM tutorial, there are
<a href="https://wiki.debian.org/opendkim">many</a>
<a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy">around</a>. You
have to use <code>opendkim-genkey</code> to generate a key and then configure
your mail server to use <code>opendkim</code> to digitally sign outbound email.</p>
<p>There are a few Debian-specific things you have to care about, though.</p>
<p>First the have to choose a <em>selector</em>, which is a string used to
distinguish many DKIM keys belonging to the same domain. Debian allows
you to installa a key whose selector is <code><something>.<uid>.user</code>,
where <code><uid></code> is your Debian uid (this is done both for namespacing
reasons and for exposing who might be abusing the system). So check
carefully that your selector has this form.</p>
<p>Then you cannot edit directly Debian's DNS record. But you can use the
email-LDAP gateway on <a href="https://db.debian.org"><code>db.debian.org</code></a> to
install your key in a way similar to how entries in <code>debian.net</code> are
handled (see the <a href="https://db.debian.org/doc-mail.html">updated
documentation</a>). Specifically,
suppose that <code>opendkim-genkey</code> generated the following thing for
selector <code>vps.gio.user</code> and domain <code>debian.org</code>:</p>
<div class="highlight"><pre><span></span><code>vps.gio.user._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsM/W/kxtKWT58Eak0cfm/ntvurfbkkvugrG2jfvSMnHHkFyfJ34Xvn/HhQPLwX1QsjhuLV+tW+BQtxY7jxSABCee6nHQRBrpDej1t86ubw3CSrxcg1mzJI5BbL8un0cwYoBtUvhCYAZKarv1W2otCGs43L0sGtEqqtmYN/hIVVm4FcqeYS1cYrZxDsjPzCEocpYBhqHh1MTeUE"
"ddVmPHKZswzvllaWF0mgIXrfDNAE0LiX39aFKWtgvflrYFKiL4hCDnBcP2Mr71TVblfDY0wEdAEbGEJqHR1SxvWyn0UU1ZL4vTcylB/KJuV2gMhznOjbnQ6cjAhr2JYpweTYzz3wIDAQAB" ) ; ----- DKIM key vps.gio.user for debian.org
</code></pre></div>
<p>Then you have to carefully copy the content of the <code>p=</code> field (without
being fooled by it being split between different strings) and
construct a request of the form:</p>
<div class="highlight"><pre><span></span><code>dkimPubKey: vps.gio.user MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsM/W/kxtKWT58Eak0cfm/ntvurfbkkvugrG2jfvSMnHHkFyfJ34Xvn/HhQPLwX1QsjhuLV+tW+BQtxY7jxSABCee6nHQRBrpDej1t86ubw3CSrxcg1mzJI5BbL8un0cwYoBtUvhCYAZKarv1W2otCGs43L0sGtEqqtmYN/hIVVm4FcqeYS1cYrZxDsjPzCEocpYBhqHh1MTeUEddVmPHKZswzvllaWF0mgIXrfDNAE0LiX39aFKWtgvflrYFKiL4hCDnBcP2Mr71TVblfDY0wEdAEbGEJqHR1SxvWyn0UU1ZL4vTcylB/KJuV2gMhznOjbnQ6cjAhr2JYpweTYzz3wIDAQAB
</code></pre></div>
<p>and then send it GPG-signed to <code>changes@db.debian.org</code>:</p>
<div class="highlight"><pre><span></span><code>echo 'dkimPubKey: vps.gio.user blahblahblah' | gpg --clearsign | mail changes@db.debian.org
</code></pre></div>
<p>Then use <code>host -t TXT vps.gio.user._domainkey.debian.org</code> to chech the
key gets published (it will probably take some minutes/hours, I don't
know). Once it is published, you can enable DKIM in you mail server
and your email will be signed. Congratulations, you will not look like
a spammer any more!</p>
<p>You can send an email to <code>check-auth@verifier.port25.com</code> to check
that your setup is correct. They will reply with a report, including
the success of DKIM test.</p>
<p>Notice that currently Debian's setup only allows you to use RSA DKIM
keys and doesn't allow you to set other DKIM fields (but you probably
won't need to set them).</p>
<p><strong>EDIT</strong> DSA made an <a href="https://lists.debian.org/debian-devel-announce/2020/04/msg00004.html">official announcement about DKIM
support</a>,
which you might want to check out as well, together with its links.</p>
<p><strong>EDIT 2</strong> Now ed25519 keys are supported, the syntax for specifying
keys on LDAP is a little bit more flexible and you can also insert
<code>CNAME</code> records. See the <a href="https://db.debian.org/doc-mail.html">official
documentation</a> for the updated
details.</p>
<h1>So we have solved our problems with spam?</h1>
<p>Ha, no! DKIM is only a small step. Useful, also because it enable
other steps to be taken in the future, but small.</p>
<p>In particular, DKIM enables you to say: "This particular email
actually comes from <code>@debian.org</code>", but doesn't tell anybody what to
do with emails that are not signed. A third-party mail server might
wonder whether <code>@debian.org</code> emails are actually supposed to be signed
or not.</p>
<p>There is another standard for dealing with that, which is called
DMARD, and I believe that Debian should eventually use it, but not
now: the problem is that currently virtually no email from
<code>@debian.org</code> is signed with DKIM, so if DMARC was enabled other mail
servers would start to nuke all <code>@debian.org</code> emails, except those
which are already signed, a minority. If people and services sending
emails from <code>@debian.org</code> will start configuring DKIM on their
servers, which is now possible, it will eventually come a time when
DMARC can be enabled, and spammers will find themselves unable to send
forged <code>@debian.org</code> emails. We are not there yet, but todays we are a
little step closer than yesterday.</p>
<p>Also, notice that having DKIM on <code>@debian.org</code> only counters spam
pretending to be from <code>@debian.org</code>, but there is much more. The
policy on what to <em>accept</em> is mostly independent on that on what you
<em>send</em>. However, knowing that <code>@debian.org</code> emails have DKIM and DMARC
would mean that we can set our spam filters to be more aggressive in
general, but whitelist official Debian Developers and services. And
the same can be done for other domains using DKIM and DMARC.</p>
<p>Finally, notice that some incompatibilities between DKIM and mailing
lists are known, and do not have a definitive answer yet. Basically,
most mailing list engines modify either the body of the headers in
forwarded emails, which means that DKIM does not validate any
more. There are many proposed solutions, possibly none completely
satisfying, but since spam is not very satisfying as well, something
will have to be worked out. I wrote a lot already, though, so I wont't
discuss this here.</p>Debian init systems GR2019-12-15T15:30:00+01:002019-12-15T15:30:00+01:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-12-15:/debian-init-system-gr.html<p>This is <a href="https://www.debian.org/vote/2019/vote_002">my vote</a>:</p>
<div class="highlight"><pre><span></span><code><span class="err">-=-=-=-=-=- Don't Delete Anything Between These Lines =-=-=-=-=-=-=-=-</span>
<span class="err">7b77e0f2-4ff9-4adb-85e4-af249191f27a</span>
<span class="err">[ 1 ] Choice 5: H: Support portability, without blocking progress</span>
<span class="err">[ 2 ] Choice 4: D: Support non-systemd systems, without blocking progress</span>
<span class="err">[ 3 ] Choice 7: G: Support portability and multiple implementations</span>
<span class="err">[ 4 ] Choice 3: A: Support for multiple init systems is …</span></code></pre></div><p>This is <a href="https://www.debian.org/vote/2019/vote_002">my vote</a>:</p>
<div class="highlight"><pre><span></span><code><span class="err">-=-=-=-=-=- Don't Delete Anything Between These Lines =-=-=-=-=-=-=-=-</span>
<span class="err">7b77e0f2-4ff9-4adb-85e4-af249191f27a</span>
<span class="err">[ 1 ] Choice 5: H: Support portability, without blocking progress</span>
<span class="err">[ 2 ] Choice 4: D: Support non-systemd systems, without blocking progress</span>
<span class="err">[ 3 ] Choice 7: G: Support portability and multiple implementations</span>
<span class="err">[ 4 ] Choice 3: A: Support for multiple init systems is Important</span>
<span class="err">[ 5 ] Choice 2: B: Systemd but we support exploring alternatives</span>
<span class="err">[ 6 ] Choice 1: F: Focus on systemd</span>
<span class="err">[ 7 ] Choice 8: Further Discussion</span>
<span class="err">[ 8 ] Choice 6: E: Support for multiple init systems is Required</span>
<span class="err">-=-=-=-=-=- Don't Delete Anything Between These Lines =-=-=-=-=-=-=-=---</span>
</code></pre></div>
<p>I don't think that nowadays the choice of the init system can neutral:
like the choice of a kernel, a libc and some other core components,
you cannot just pretend that everything can be transparently swapped
with anything else, therefore Debian rightly has to choose a default
thing (Linux, glibc, the GNU userland, and now systemd) which is the
standard proposal to the casual user. Systemd has clearly become the
mainstream thing for a lot of good reasons, and it is the choice the
most Debian users and developers should adopt (this is not to say that
systemd, its development mode or its goals are perfect; but we have to
choose between alternatives that exist, not between ideal ones). This
is the reason why imposing that any init system should be supported at
the same level is silly to me, and therefore why option E is the last
one, and the only one below Further Discussion; in much the same way
as it would be silly to impose that kFreeBSD, Mach and musl should be
supported at the same level of their default counterparts (although I
would be pretty excited to see that happening!). We cannot expect any
Debian contributor to have the resources to contribute scripts/units
for any init system randomly appearing.</p>
<p>At the same time, I like Debian to be Universal in the sense of
potentially being home for any reasonable piece of
software. Diversity, user choice and portability are still values,
although not absolute ones, and nobody in Debian should make it
impossible to pursue them. I also share the "glue" vision proposed by
the principles of choices G and H. Therefore work extending support
for non-default init systems (and, again, kernels, libc's,
architectures, any core component) should be loyally accepted by all
involved contributors, even if they do not see the need for such
components.</p>
<p>For these reasons I consider option H the one that, despite being
possibly a bit too verbose, spells out my thoughts. All the other
options are essentially ordered in how close I percieve them to option
H.</p>
<p>I'd like to thanks Ian Jackson for having proposed option H and for
<a href="https://diziet.dreamwidth.org/3999.html">having collected a few important criteria to find a way in the jungle
of all the available
options</a>.</p>My take on OpenPGP best practices2019-07-26T23:30:00+02:002019-07-26T23:30:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-07-26:/my-take-on-openpgp-best-practices.html<p>After having seen a few talks at DebConf on GnuPG and related things,
I would like to document here how I currently manage my OpenPGP keys,
in the hope they can be useful for other people or for
discussion. This is not a tutorial, meaning that I do not give …</p><p>After having seen a few talks at DebConf on GnuPG and related things,
I would like to document here how I currently manage my OpenPGP keys,
in the hope they can be useful for other people or for
discussion. This is not a tutorial, meaning that I do not give you the
commands to do what I am saying, otherwise it would become way too
long. If there is the need to better document how to implement these
best practices, I will try to write another post.</p>
<p>I actually do have two OpenPGP certificates,
<a href="http://eu.pool.sks-keyservers.net/pks/lookup?op=vindex&fingerprint=on&search=0x9EDCC991D9AB457E">D9AB457E</a>
and
<a href="http://eu.pool.sks-keyservers.net/pks/lookup?op=vindex&fingerprint=on&search=0x7E7B209DE535FA6D">E535FA6D</a>. The
first one is RSA 4096 and the second one is Curve25519. The reason for
having two certificates is algorithm diversity: I don't know which one
between RSA and Curve25519 will be the first to be considered less
secure or insecure, therefore I would like to be ready for both
scenarios. Having two certificates already allows me to do signature
hunting on both, in such a way that it is easy to transition from one
to the other as soon as there is the need.</p>
<p>The key I currently use is the RSA one, which is also the one
available in the Debian keyring.</p>
<p>(If you search on the keyservers you will find many other keys with my
name; they are obsolete, meant for my internal usage or otherwise not
in use; just ignore them!)</p>
<p>Even if the two primary keys are different, their subkeys are the same
(apart from some older cruft now revoked), meaning that they have the
same key material. This is useful, because I can use the same hardware
token for both keys (most hardware token only have three key slot, one
for each subkey capability, so to have two primary keys ready for use
you need two tokens, unless the two keys share their subkeys). I have
one subkey for each subkey capability (sign, encrypt and
authentication), wich are Curve25519 keys and are stored in a Nitrokey
Start token. I also have, but tend to not use, one RSA subkey for each
capability, which are stored on a OpenPGP card. Thanks to some date
tweaking, both certificates are configured in such a way that
Curve25519 subkeys are always preferred over RSA subkeys, but I also
want to retain the RSA keys for corner cases where Curve25519 is not
available.</p>
<p>The reason to choose Curve25519 over RSA for default usage is that
they are faster and generate smaller signatures. I have no idea which
one is considered more secure, but I believe that <a href="https://www.xkcd.com/538/">neither of them is
the weak link in my security chain</a>.</p>
<p>The primary keys have an expiration date, which is always my
birthday. Such choice is for remembering, a couple of months in
advance, to extend it of one year, so that the key remains
valid. Choosing the update interval here is of course a compromise
between security and convenience. One year seems fine. I see no
advantage in setting an expiration date on subkeys, since I can always
use the primary key to revoke them. It might be useful to set an
expiration date if I had a subkey rotation strategy, but I don't, and
unfortunately with OpenPGP is a bit difficult to have one, since all
subkeys are stored forever in the certificate, which would quickly
become bloated.</p>
<p>The primary keys' private material is stored in a external disk that
is normally disconnected from any computer, so completely inaccessible
from the Internet. I connect it to my computer when I need to do
operations that require the primary key, like signing other keys,
managing subkeys or extending the key validity. This setup is not
ideal, because it would be better to only connect the external storage
to a machine that is always offline (and therefore is less likely to
have been compromised). But that would require maintaining another
machine, and as usual one has to compromise between security and
convenience. Also, that external disk also contains other data, so it
gets connected to my laptop also for other operations than working
with OpenPGP certificates. I could improve here, but it is still
better than bringing the primary key as a file in my computer.</p>
<p>I also have copies of my keys' private material (both for primary keys
and subkeys) and revokation certificates on a bunch of paper sheets
hidden somewhere in my house, just in case the external disk should
fail. A common tool for this step is
<a href="http://www.jabberwocky.com/software/paperkey/">paperkey</a>, although <a href="https://schnouki.net/post/2010/howto-backup-your-gnupg-secret-key-on-paper/">I
did follow this tutorial to encode the secret key in a number of data
matrices</a>.</p>
<p>Overall, while my setup is perfectible, I believe it also reasonably
secure for my use case, and quite convenient to use.</p>Bootstrappable Debian BoF2019-07-22T02:30:00+02:002019-07-22T02:30:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-07-22:/bootstrappable-debian-bof.html<p>Greetings from DebConf 19 in Curitiba! Just a quick reminder that I
will run a <a href="https://debconf19.debconf.org/talks/152-bootstrappable-debian-bof/">Bootstrappable Debian
BoF</a>
on Tuesday 23rd, at 13.30 Brasilia time (which is 16.30 UTC, if I am
not mistaken). If you are curious about bootstrappability in Debian,
why do we want it and …</p><p>Greetings from DebConf 19 in Curitiba! Just a quick reminder that I
will run a <a href="https://debconf19.debconf.org/talks/152-bootstrappable-debian-bof/">Bootstrappable Debian
BoF</a>
on Tuesday 23rd, at 13.30 Brasilia time (which is 16.30 UTC, if I am
not mistaken). If you are curious about bootstrappability in Debian,
why do we want it and where we are right now, you are welcome to come
in person if you are at DebCon or to follow the streaming.</p>DQIB, the Debian Quick Image Baker2019-06-09T15:00:00+02:002019-06-09T15:00:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-06-09:/dqib-debian-quick-image-baker.html<p>Debian supports (either officially or unofficially) a lot of
architectures, which is of course a nice thing. Sometimes you want to
play with some exotic architecture you are not familiar with, or you
want to debug a problem with that architecture, but you do not have a
computer implementing that …</p><p>Debian supports (either officially or unofficially) a lot of
architectures, which is of course a nice thing. Sometimes you want to
play with some exotic architecture you are not familiar with, or you
want to debug a problem with that architecture, but you do not have a
computer implementing that architecture. Fortunately QEMU is able to
emulate most of the architectures supported by Debian (<code>ia64</code> being an
exception), however it can be difficult to install it or to find
ready-to-use images on the Internet (there are some, but usually they
are quite a few years old). Let's also say that for some reason you
cannot or do not want to use the Debian porterboxes (maybe you are not
a DD, or you want to mess up with the network, or you want to be
root). What do you do?</p>
<p>Mostly for the fun of hacking on some exotic architectures, I tried to
brew together a little script, the <a href="https://gitlab.com/giomasce/dqib">Debian Quick Image
Baker</a> (DQIB). It is basically a
wrapper that calls <code>qemu-debootstrap</code> with the right options (where
"right" means "those that I have experimentally found to work"), with
some thin icing layer on top. <code>qemu-debootstrap</code> is basically another
wrapper on top of <code>debootstrap</code>, which of course does the heavy
lifting, and <code>qemu-user-static</code>, that allows <code>debootstrap</code> to run
executables for foreign architectures.</p>
<p>With DQIB you can quickly create working images for most Debian
official architectures (<code>i386</code>, <code>amd64</code>, <code>mips</code>, <code>mipsel</code>, <code>mips64el</code>,
<code>armhf</code>, <code>arm64</code>, <code>ppc64el</code>). <code>s390x</code> works, but requires a little
workaround because of <a href="https://bugs.launchpad.net/qemu/+bug/1815024">a little
bug</a> that was fixed in
recent QEMU versions. Images for <code>armel</code> can be created, but the only
Linux kernel offered by Debian for <code>armel</code> does not work on any QEMU
machine. I don't know of a workaround here. I would also like to
support non official architectures, but this is work in progress. For
all the non official architecture, either <code>qemu-debootstrap</code> fails for
some reason, or I cannot find the right options to make the
Debian-distributed kernel running (except for <code>riscv64</code>, where I know
how to make the kernel work, but it requires some non trivial changes
to the DQIB script; however, the <code>riscv64</code> panorama is very dynamical
and things could change in very little time).</p>
<p>You can either clone the repository and run DQIB on you computer
(check out the
<a href="https://gitlab.com/giomasce/dqib/blob/master/README.md">README</a>), or
download <a href="https://people.debian.org/~gio/dqib/">pre-baked images</a>
regenerated weekly by a CI process (which include the right command
line to launch QEMU; see above for the definition of "right").</p>
<p>(You might ask why this is hosted on <a href="https://gitlab.com/">Gitlab.com</a>
instead of the <a href="https://salsa.debian.org/">Debian Developer's obvious
choice</a>. The reason is that the artifacts
generated by the CI are rather large, and I am not sure DSA would be
happy to have them on their servers)</p>
<p>Have fun, and if know how to support more architectures please let me
know!</p>Italy's liberation day2019-04-25T12:00:00+02:002019-04-25T12:00:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-04-25:/liberation-day.html<p>Today is <a href="https://en.wikipedia.org/wiki/Liberation_Day_(Italy)">Italy's liberation
day</a>. On this
day of year 1945 partisan insurrections in Milan and Turin freed those
cities from the Nazi and Fascist occupation. It took a few more days
to actually end the war, but that is the date that was later chosen as
national holiday.</p>
<p>I …</p><p>Today is <a href="https://en.wikipedia.org/wiki/Liberation_Day_(Italy)">Italy's liberation
day</a>. On this
day of year 1945 partisan insurrections in Milan and Turin freed those
cities from the Nazi and Fascist occupation. It took a few more days
to actually end the war, but that is the date that was later chosen as
national holiday.</p>
<p>I am grateful to all the people that fought for a free country and for
putting an end to the Fascist and Nazi regimes. I am also grateful to
all the people that starting from those days and to the present time
worked and work for building a united and peaceful Europe of friend
countries and people.</p>
<p>There is still a lot of work to do and a lot of dangers to be aware
of: peace is never acquired for ever and it faces new challenges every
decade. I hope that through the efforts of many people one day the
whole world will live in peace and freedom.</p>
<p>Happy liberation day! Buona festa della liberazione!</p>Paris BSP and this blog2019-04-18T11:00:00+02:002019-04-18T11:00:00+02:00Giovanni Mascellanitag:www.giovannimascellani.eu,2019-04-18:/paris-bsp-and-this-blog.html<p>Hello everybody!</p>
<p>I've never had a blog up to today, and apparently now I do. Why? Well,
it happened that there was a <a href="https://wiki.debian.org/BSP">Debian Bug Squashing
Party</a> in
<a href="https://wiki.debian.org/BSP/2019/03/fr/Paris">Paris</a> a few weeks ago,
and I thought that it might be nice to go, meet some nice people and
humbly help …</p><p>Hello everybody!</p>
<p>I've never had a blog up to today, and apparently now I do. Why? Well,
it happened that there was a <a href="https://wiki.debian.org/BSP">Debian Bug Squashing
Party</a> in
<a href="https://wiki.debian.org/BSP/2019/03/fr/Paris">Paris</a> a few weeks ago,
and I thought that it might be nice to go, meet some nice people and
humbly help releasing
<a href="https://www.debian.org/releases/testing/">Buster</a>. Great news is that
the Debian project <a href="https://lists.debian.org/debian-devel-announce/2018/06/msg00006.html">is willing to reimbourse its members some of the
expenses</a>
for taking part to a BSP, asking in return to communicate publicly
about what you do during a BSP so that others are motivated to
participate as well.</p>
<p>So I guessed that might be the occasion for me to start a blog, and
start writing something about what I do in Debian. Here it goes!</p>
<p>It was my first BSP ever, and I am very happy of it. We met for a
couple of days at very nice Mozilla's office in Paris (I think they
are moving and we were at the old one, though). We were probably
around 15 people, mostly from France, Belgium, the Netherlands and UK
(which is not surprising if you look at the <a href="https://en.wikipedia.org/wiki/High-speed_rail_in_Europe">high-speed rail
map</a> in
Europe; or any map of Europe, as a matter of facts).</p>
<p>The great thing of a BSP is that you have a very short loop to other
developers. Since a BSP is all about getting RC bugs closed, it is
useful to talk directly to Release Team members, and discuss whether
they would unblock your fix or not when you are not sure. This saves a
lot in terms of human bandwidth and context-switching. Also, I had the
occasion to watch more experienced developers in action and learn how
to tackle issues I haven't dealt with ever before, like bumping up a
library SONAME.</p>
<p>So here is what I managed to do during the BSP, in roughly
chronological order.</p>
<ul>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=920209">Bug
#920209</a>:
that is a bug I already had written a patch for a few months ago,
but the whole thing had stagnated and the patch was never
uploaded. A simple ping to the maintainer was enough: an easy one!</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=917711">Bug
#917711</a>:
a FTBFS caused by failing tests, in turn caused by a broken internal
interface between two libraries. I was able to cook up a patch, but
I was not really sure it was the right thing, so I opened <a href="https://github.com/steveire/grantlee/issues/51">a bug
upstream</a>, to which
upstream never replied. However, upstream itself wrote <a href="https://github.com/steveire/grantlee/commit/3cb4bd24e127b7f55d463d934cad27f8c07c4406">a similar
patch</a>
a few days after, which was then up uploaded to Debian by ivodd.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925957">Bug
#925957</a>:
this is a bug on a package I maintain, so it was imperative to get
it
done. <a href="https://packages.debian.org/search?keywords=fstransform">fstransform</a>
is a tool to convert a filesystem to another format (like, XFS to
ext4) without having to copy all the data to another filesystem and
then back (see the <a href="https://github.com/cosmos72/fstransform">upstream
readme</a> for more
details). It is no mistery to anyone that such an operation is
inherently dangerous, so both the program and its documentation warn
prominently that data loss are always an option. The idea is: if
fstransform can be useful for you, use it, but never on data you
cannot afford to lose (you should always have a backup of such data,
anyway). So this bug was about a reproducible failure case for
fstransform when it was ran with a too little copying buffer. Of
course the best thing is to have a proper fix, but since the
<a href="https://github.com/cosmos72/fstransform/issues/13">upstream bug</a>
had stalled for an year an a half without a solution, the road of
fixing it myself seemed implausible, especially because I do not
know fstransform's internals. So <a href="https://salsa.debian.org/debian/fstransform/commit/0bcbc742e90bca91be81dcf3547507a69bae8e66">my
fix</a>
was to add a warning message (that the user has to explicitly
acknowledge); this fits my model for fstransform: the user is
advised that things might go wrong, but if they are ok, then good
for them. This was also unblocked by the Release Team. Of course it
is not the ideal solution, but at least the user knows what to
expect from the program, which can still be useful if you are
properly warned: given that Buster should be released as soon as
possible this is, to me, a reasonable compromise. The bug submitter
did not agree and reopened the bug. Fortunately a few days later the
upstream author managed to find the proper fix, which I then
uploaded.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=912467">Bug
#912467</a>:
a FTBFS due to an updated reverse dependencies, a relatively common
between Java packages. A partial patch had already been begun by
andrewsh, but was never completed. Using that as a base and drawing
from the <a href="https://github.com/TIBCOSoftware/jasperreports/commit/b7bd874137d357e0c27e04d1595086826c38995b">corresponding upstream
patch</a>,
it was not difficult to fix the build, as the API changes were
mostly cosmetic. I uploaded <a href="https://salsa.debian.org/java-team/jasperreports/commit/90fdfb5a6f1e413ba81f9be56513a92605634350">my
patch</a>
to salsa, but not the the archive, because I would like someone else
to review it. So far, it has not happened, and maybe I should have
another look at it.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=917501">Bug
#917501</a>:
a rather nasty Eisenbug, that I could not really understand during
the BSP: the bug occurred when I built with <code>sbuild</code>, but not when I
build directly in my system, so that I could not debug it. Yesterday
it was finally traced back to the usage of <code>eatmydata</code> by sanvila,
which is plausible because I also use <code>eatmydata</code> with <code>sbuild</code> (it
really boosts package installation!). The bug was downgraded to
<code>normal</code> severity, and I guess it should also be reassigned to
<code>eatmydata</code>, since it would be <code>eatmydata</code>'s duty to be transparent
to what is happening above it.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=915319">Bug
#915319</a>:
a FTBFS due to a bad library detection procedure by CMake. The
detection of <code>libsmbclient.h</code> failed because CMake insisted to
compile with <code>-std=c89</code> (or so), while that header requires
C11. Easy to patch.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870267">Bug
#870267</a>:
Very very easy: the bug had already been solved, but was left open.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877773">Bug
#877773</a>:
it was quite easy to understand what had to be done here (i.e., a
SONAME bump), but I had never done it. So I asked around and
jcristau showed me how to do it, including requesting a mini
transition and stuff. Very instructive, and, I think, really one of
the points of gathering together instead of working everybody at
home.</p>
</li>
<li>
<p><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=905697">Bug
#905697</a>:
I ported some of the <code>kdepimlibs</code> libraries to <code>libical3</code>, so that
<code>libical2</code> can be dropped from the archive. The difficult part was
to backtrace the corresponding upstream patches, because in the
meantime the libraries had reorganized in different repositories. In
the end I found <a href="https://github.com/KDE/kcalcore/commit/27eaa211b23a6bb0bcba5a91cf7cadfc1e888e21?diff=unified">this
patch</a>,
and it was not difficult to make it ready for Debian.</p>
</li>
<li>
<p>One last thing not coming from a bug: Debian Buster should finally
support Secure Boot, so that the computer's firmware can
cryptographically validate the operating system before launching
it. The Debian EFI team recently updated the <a href="https://wiki.debian.org/SecureBoot">Secure Boot page on
the wiki</a> with a clear
description of how it works and how to enable it in Debian. I
reviewed it and sent <a href="https://lists.debian.org/debian-efi/2019/03/msg00095.html">an email with my
thoughts</a>
to the relevant mailing list.</p>
</li>
</ul>
<p>So here it is, my blog and my report. Now, Debian, give me my money!
:-P</p>
<p>Many many thanks to Mozilla for allowing us to use their spaces for
the BSP, and to jcristau and olasd who organized it. Now let's try to
get Buster released and maybe see you in Brazil (I'm not sure yet I
will be able to come, because of <code>[INSERT_REASONS_HERE]</code>, but I hope
so).</p>