niedziela, 9 października 2011

Web of Trust

This document is based on tests and some source code analysis of GnuPG. It has been written because available sources weren't enough for me to understand how the web of trust works.

Properties

Validity

  • indicates if a signature made by an individual is going to be approved or if a warning about uncertainty of one's identity pops up,
  • validity is calculated by the web of trust algorithm,
  • validity == "full" or "ultimate" means that the identity is considered true.

Trust

  • indicates how much I trust an individual when it comes to him/her verifying identity of others,
  • in others words - how much his/her signature on keys of other individuals influences validity of these keys,
  • trust is set manually by the user.

Current validity of keys can be printed using the following command:
$ gpg --list-keys --list-options show-uid-validity

Web of trust algorithms

In the GnuPG manual following methods are listed:

  • pgp,
  • classic,
  • direct,
  • always.

Currently pgp is the one used by default and described in this document.

Chaotic keywords

Terminology is chaotic. According to some sources the property called validity takes one of these values:

  • undefined,
  • marginal,
  • complete.

According to the same source the property called trust takes one of these values:

  • don't know,
  • untrustworthy,
  • marginal,
  • full.

As far as GnuPG is concerned the same set of values is used for both properties. Whenever there is not enough data to determine the trust the "unknown" label is used.

If the user does not know if some individual's signatures can be trusted one can indicate it setting trust to "undefined".

"Untrustworthy" becomes "never". "Marginal" stays "marginal". The "complete" label is divided into more specific "full" and "ultimate".

"Ultimate" is a special label used only for user's own keys.

There are two other labels used in the source code: "expired" and "revoked". They are not described in this document.

Deceiving keywords

I think labels "marginal" and "full" are deceiving. In reality in case of trust they indicate if an individual is believed to be able to verify identity of others by himself or only as a member of a group. By default GnuPG finds a key valid (validity == "full") if a key has:

  • 1 signature of a person with
    trust == "full" and validity == "full"
    or
  • 3 signatures of people with
    trust == "marginal" and validity == "full".

These thresholds are not saved in the web of trust file (trustdb.gpg). They can be set on the command line using parameters:

  • --marginals-needed,
  • --completes-needed
or similarly in the configuration file (gpg.conf).

Validity == "full"

When a user signs a key GnuPG considers that key to have validity ==  "full" (from that user's point of view).

Calculating validity through iterations

The validity calculation starts from an "ultimate" key and goes towards more remote keys.

The calculation process does not skip missing graph edges. So for a key to be considered valid there has to be a path from an "ultimate" key to that key. That path cannot be longer than the threshold set by the max-cert-depth setting (5 by default).

It means that a key will not become valid if it is signed by an individual with the trust property set but there is no path leading to that user (from an "ultimate" key).

The user can force the web of trust rebuilding executing the following command:
$ gpg --update-trustdb

The algorithm uses only those keys which get validity == "full" during the calculation. The "marginals-needed" and "completes-needed" are associated with the manually set trust property, not with the validity property.

The algorithm continues to go deeper while at least one of the "marginals-needed" or "completes-needed" conditions is true. It means to continue while there were enough keys with validity == "full" and trust == "ultimate"/"full"/"marginal" in the previous iteration to create another key with validity == "full".

During the last iteration keys being reachable but without enough signatures (but still with at least one signature made with a key with validity == "full") are labeled with validity == "marginal".

An example of a web of trust

$ gpg --homedir me --update-trustdb --marginals-needed 2
gpg: 2 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   2  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1  valid:   2  signed:   4  trust: 0-, 0q, 0n, 2m, 0f, 0u
gpg: depth: 2  valid:   3  signed:   1  trust: 0-, 3q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2012-09-30

There were 3 iterations.

At level (depth) 0 my key gets validity == "ultimate" because it has my signature and trust == "ultimate" (1u).

At level 1 the GnuPG stumbles upon 4 keys signed by 2 individuals with trust == "marginal" (2m).

At level 2 the GnuPG stumbles upon 1 key signed by 3 individuals with trust == "undefined" (3q).

The printed description of the process becomes more complicated when there are multiple paths with different lengths leading to a key. This can be seen in this example as well. A key at level 3 is signed by:

  • 1 individual from level 1 and
  • 3 individuals from level 2.

As we can see we did not get to to level 3 iteration. But a key at this level is reachable -- it has signatures but not enough of them. This is why it gets validity == "marginal".

This is the signatures structure:
me → friends → guys → alien,
additionally Friend Two has signed the Alien's key.

$ gpg --homedir me --list-keys --list-options show-uid-validity
--------------
pub   2048R/AFA302BF 2011-10-01
uid       [ultimate] The Me 
sub   2048R/E4FF8420 2011-10-01

pub   1024R/6921DF3D 2011-10-01 [expires: 2012-09-30]
uid       [  full  ] The Friend 
uid       [ unknown] The Friend (alternate) 
sub   1024R/DD37730B 2011-10-01 [expires: 2012-09-30]

pub   1024D/1E71B2C3 2011-10-01
uid       [  full  ] Friend Two 
sub   1024g/B2F94583 2011-10-01

pub   1024D/0DE1BC29 2011-10-01
uid       [  full  ] Guy 1 
sub   1024g/ACA329E3 2011-10-01

pub   1024D/0FC4A4A7 2011-10-01
uid       [  full  ] Guy Two 
sub   1024g/38445EB3 2011-10-01

pub   1024D/9674B894 2011-10-01
uid       [  full  ] Guy Drei 
sub   1024g/95A9CB7E 2011-10-01

pub   1024D/AC4EC9F7 2011-10-01
uid       [marginal] Alien 
sub   1024g/4A46043E 2011-10-01

sobota, 11 grudnia 2010

Zabawna (?) alternatywa dla DNS

Gdzieś tam w RSSach pojawił się link do artykułu o tym, jak sobie radzić w momencie, gdy państwo wycina z DNSów niewygodne adresy. Ponieważ, inaczej niż to się zwykło pisać na gazeta.pl, niedziałający/wadliwy DNS nie powoduje, że pudełko z Internetem nie działa - są rozwiązania na czas kryzysu.

We wspomnianym artykule mowa jest m.in. o projekcie 4 little words (4LW). W aktualnej wersji zamienia każdy z czterech oktetów IPv4 na układ 4 słów w kolejności: przymiotnik, rzeczownik, czasownik, rzeczownik. Przydatność narzędzia jest dyskusyjna, bo chyba łatwiej wpisać sobie brakujące adresy do /etc/hosts i nosić plik ze sobą na pendrive'ie. Przy okazji jednak można obejrzeć, skąd wzięła się lista słów i przeczytać o pewnym RFC.

A tak w ogóle narzędzie ma tę zaletę, że co jakiś czas wypluwa coś śmiesznego.

Politechnika żądna krwi

www.pw.edu.pl194.29.151.5relevant.blood.matches.aid

Społeczności

nasza-klasa.pl195.93.178.6religious.gas.puts.aim
www.gadu-gadu.pl91.197.14.140full.sign.applies.love

Co wybierze Mikołaj

allegro.pl193.23.48.134relative.bed.chooses.list

Nomen omen

failblog.org74.200.247.59extra.site.warns.day
failblog.org76.74.254.120familiar.fact.worries.king

Bitwy dystrybucji

gentoo.org204.74.99.100serious.fact.fits.gun
www.redhat.com95.100.144.112good.gun.lives.hope

Eksperymentatorzy

lwn.net72.51.34.34expensive.coal.blows.book
www.gnu.org140.186.70.148medical.run.derives.milk

Transfery pieniędzy

www.python.org82.94.164.162financial.gate.orders.park
mozilla.com63.245.209.106economic.wife.sits.heat
microsoft.com207.46.197.32similar.cause.sells.body

Taki jest duży

ing.pl193.201.34.35relative.size.blows.box

Sprawa patrona Polski wydaje się jaśniejsza

sejm.gov.pl195.187.136.11religious.sale.learns.art

Służby

policja.pl195.164.254.6religious.past.worries.aim
www.fbi.gov204.160.120.86serious.pain.holds.flow

Telewizja

www.tvp.pl195.245.213.150religious.wife.sorts.mine
www.tvn24.pl213.180.146.124social.road.loses.lady
www.polsat.pl217.17.36.172special.ball.brings.rabbit

No tak, wiadomo było

wodny.org91.189.252.37full.seal.wishes.brain

czwartek, 17 czerwca 2010

libfm, GIO, absence of Gnome, priority of the extension module

Yesterday I've upgraded some packages on my Debian system. Surprisingly applications using Gnome libraries stopped to open URIs using applications defined in GConf /desktop/gnome/url-handlers. So I've checked if gnome-open is able to open a URI:

$ gnome-open http://wodny.org
Error showing url: No application is registered as handling this file

The short (picture) version of the text below is available.

This was interesting. I realized that gnome-open first downloaded headers from the specified URI and then searched for a helper application according to the found Content-Type.

At first I was surprised that some Gnome libs do secret work behind my back.

The ability to download something in the background comes from backends installed. The HTTP one came from the gvfs-backends package.

So I was dealing with the GVfs "a userspace virtual file system with backends for protocols like SFTP, FTP, DAV, SMB, ObexFTP. GVFS is the replacement for GNOME-VFS". Specifically I was also dealing with its part - GIO "a new shared library that is part of GLib and provides the API for GVFS".

So I read some API documentation. This was quite fun. GIO can take a URI from me and provide a magic File interface to it. I looked through some source code. I like the magical special function called g_app_info_launch_default_for_uri. It first searches for a handler for the scheme used (for example http) and if it doesn't find one - it determines the content type using a backend. For the HTTP backend a HEAD request is sent and the Content-Type header is used. Then it searches for a handler for that content type.

I've also used Python to do some debug.

>>> import gio
>>> gio.app_info_get_default_for_uri_scheme("http")
The call returned nothing, while it should have returned something like this:
<gio.unix.DesktopAppInfo at 0xb76972d4: iceweasel>

So for some reason GConf /desktop/gnome/url-handlers settings were not taken into account and instead of ending the search on the scheme handler it continued through the content type phase (as I didn't define a handler for text/html - it has failed).

During the upgrade there was a lot of packages being installed. One of them was libfm. It comes with a module called libgiofm.so, which resides in /usr/lib/gio/modules. This module provides a GIO extension and registers an implementation of the G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME (gio-desktop-app-info-lookup) extension point.

Looking through /usr/lib/gio/modules/giomodule.cache I noticed that libgiofm.so isn't the only one providing this extension. There was also the libgiogconf.so module (from the gvfs package). And libgiogconf.so was here earlier as it's the Gnome's module for reading GConf settings.

When an extension registers itself it also sets its priority. The Gnome module registers itself with priority value of 10. The libfm one registers itself with priority value of 9 if it detects a Gnome session via the GNOME_DESKTOP_SESSION_ID environmental variable or 90 if it doesn't.

As I'm using Openbox, the module doesn't detect the variable. With priority 90 it takes precedence over the Gnome module. I didn't define scheme handlers for the libfm (for example using libfm-pref-apps) so GIO didn't know what to do with URIs.

For now I'm going to use a workaround. I will set the GNOME_DESKTOP_SESSION_ID environmental variable. But There are two problems with that:

  1. I don't have Gnome, but neither do I have LXDE - I just use some applications from both under Openbox
  2. I could set this variable for example in .bashrc, but:
    1. I can't really find any documentation on this variable
    2. I've found a comment, where someone suggests it's deprecated

I could define applications through libfm-pref-apps, but it has less options than GConf, I have a problem with launching mutt with mailto: URIs and I don't want to duplicate settings.

I've sent the libfm developers a request to change that behaviour and allow to change the priority for example via XDG system/user's settings.

poniedziałek, 27 lipca 2009

Linux, Bluetooth, mobile, Internet

There is something about Bluetooth

Last week I've decided to go wireless and connect to the Internet with my netbook via a cellphone without using a USB cable.

Connecting to the Internet with a USB cable is quite simple - a glimpse at /var/log/syslog is enough. Usually /dev/ttyACM0 appears. What you have to do then is to just use pppd. It's similar when using Bluetooth, but getting to the moment when a device analogous to ttyACM0 appears (usually /dev/rfcomm0) may be difficult.

This article presents how to achieve the goal using command line tools. It's quite probable that it's possible to get a similar effect using blueman or gnome-bluetooth. It's a pity these tools have so many bugs. What's also important I would like to know what really happens. I hope I won't have to use them, as I don't use NetworkManager (popular in distributions like Ubuntu). Being in charge in exchange for convenience.

Ingredients (nontechnical version)

  • A computer with a Bluetooth interface (Asus Eee PC 1000 has one built-in)
  • A cell phone with Bluetooth (in my case Nokia E66)
  • Enabled Internet service to use with your SIM card (I suppose it's a standard nowadays)

My experimental platform

Bluetooth module in my EeePC:

$ lsusb
ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
idVendor 0x0b05 ASUSTek Computer, Inc.
idProduct 0xb700 Broadcom Bluetooth 2.1

My cell phone Bluetooth module features:

# hcitool info <bd_addr>
Requesting information ...
BD Address: <bd_addr>
Device Name: Topik
LMP Version: 2.0 (0x3) LMP Subversion: 0x2222
Manufacturer: Broadcom Corporation (15)
Features: 0xbf 0xee 0x0f 0x4e 0x98 0x19 0x00 0x00
<3-slot> <5-slot> <encryption> <slot>
<timing> <role> <sniff> <rssi>
<channel> <sco> <hv3> <u-law>
<a-law> <cvsd> <paging> <power>
<transparent> <edr> <edr>
<enhanced> <inquiry> <afh>
<afh> <3-slot> <5-slot>
<afh> <afh>

Debian and its packages:

ii  bluez  4.42-2         Bluetooth tools and daemons
ii ppp 2.4.4rel-10.1 Point-to-Point Protocol (PPP) - daemon
Optional:
ii  bluez-hcidump  1.42-1+b1     Analyses Bluetooth HCI packets

Environment check

Check if the kernel loaded any Bluetooth modules:

$ lsmod | grep bt
btusb 10276 2
bluetooth 47060 9 bnep,sco,rfcomm,l2cap,btusb
usbcore 125888 9 btusb,usbhid,snd_usb_audio,snd_usb_lib,uvcvideo,usb_storage,uhci_hcd,ehci_hcd

During this experiment it's useful to keep hcidump running. It may help in debugging process or at least provide handful of information on sent packets.

For the beginning hciconfig:

$ /usr/sbin/hciconfig
hci0: Type: USB
BD Address: 00:15:AF:F8:EA:75 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING PSCAN
RX bytes:56525 acl:734 sco:0 events:1053 errors:0
TX bytes:21903 acl:752 sco:0 commands:335 errors:0
We can see our local PC Bluetooth interface.


Now, let's search for mobile devices in proximity (it's a good moment to turn Bluetooth on in the cell phone):

$ hcitool scan
Scanning ...
<bd_addr> Topik
We can see our mobile. We get the information about its BD_ADDR (Bluetooth Device Address) which is a cousin of the Ethernet MAC addresses.

Now using the SDP protocol (special protocol for service discovery) we will know what we can do with our cell.

$ sdptool browse <the BD_ADDR from the previous section>
[...]
Service Name: Dial-Up Networking
Service RecHandle: 0x1004c
Service Class ID List:
"Dialup Networking" (0x1103)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 4
Language Base Attr List:
code_ISO639: 0x454e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Dialup Networking" (0x1103)
Version: 0x0100
[...]
You can see we can establish an Internet connection via the mobile. By the way, please notice which channel Dial-Up Networking (DUN) service and profile uses (Channel: 4).

It's convenient to create a script which is going to detect the right channel before every connection. Services' channels may change after turning the phone off and on again. The getDUNchannel.sh script:

#!/bin/sh

MAC=$1

if [ "$1" ]; then
MAC="--bdaddr $MAC"
fi

sdptool search $MAC DUN | grep Channel: | grep -o '[0-9]*'

Preparing for the connection

Firstly, we are going to configure an element which we are going to use last - pppd. This is a configuration for the PlusGSM network, for other networks it's similar or even the same - you can always ask your operator for assistance.

pppd

/etc/ppp/peers/plus:

connect "/usr/sbin/chat -v -f /etc/chatscripts/plus"
debug
/dev/rfcomm0
115200
defaultroute
noipdefault
usepeerdns
noauth

/etc/chatscripts/plus:

ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
'' ATZ
OK-AT-OK AT+CGDCONT=1,"IP","internet"
OK-AT-OK "ATDT*99#"
CONNECT ''

bluetooth-agent

During devices pairing a PIN code (chosen by the user) is needed. It's going to be entered on both devices. Tools from the bluez package have their agent called bluetooth-agent. They request a PIN code from it if they need one.

rfcomm

Application is called rfcomm, same as the protocol stack layer which it provides. This is a layer that emulates a RS-232 port in Bluetooth devices. Thanks to that feature we can communicate with the mobile as we would with a modem.

Rfcomm can read configuration from /etc/bluetooth/rfcomm.conf, but I can't find any advantages of this solution. Channel for the DUN service is going to change, so we want it to be easy to provide during execution. That is why we're going to pass all the arguments via the command line.

Starting sequence

In a couple of terminals execute in sequence:
  1. During the first connection (pairing process) rfcomm will need a PIN agent.
    bluetooth-agent <wybrany PIN>
    It will print PIN requests on the screen. This tool won't be needed during subsequent connections, because a key is going to be generated (based on BD_ADDR, PIN and a random part), which both devices will remember.
  2. $ rfcomm connect 0 <bd_addr> `./getDUNchannel.sh <bd_addr>`
    We should get an emulated RS-232 port /dev/rfcomm0.
  3. Upon success we should see:
    Connected /dev/rfcomm0 to <bd_addr> on channel 4
    Press CTRL-C for hangup
  4. pppd file /etc/ppp/peers/plus
    Via tail -f /var/log/syslog we can watch what's happening.
And that's it.

Literature

Literature is a big word but I've used these sites:

niedziela, 26 lipca 2009

PulseAudio, the beginning

Sound on my Linux


I thought it would be useful to gather all the information that let me configure my system in quite a neat way at one place. This includes Firefox Flash plugin using PulseAudio.

What PulseAudio is


PulseAudio is a sound server. It's not the first such a project. But this the first one I really use and it doesn't grind my gears (too much).
It's an entity consisting of libraries (and optionally a daemon), which allows you to manage sound streams on a higher abstraction level than the physical device level. It enables software mixing, sound card switching during playback, additional software amplification of the volume.
Additionally PulseAudio is network transparent.
It is a standard package in the Ubuntu distribution.

Why I need PulseAudio


In the nearest future I'm going to examine network features of this system, but the real reason of the installation was different. For a couple of years now I've been using two sound cards connected to my notebook. Usually sound comes into my head through headphones connected to the external SB Live!. The first problem with this sound card is that streams mixing has never worked - so I couldn't listen to YouTube and mplayer at the same time. The second problem - I want to hear Stepmania through the integrated sound card, YouTube on both, mplayer on the external one. ALSA by itself isn't so flexible. And we have Flash which is impossible to configure in a sensible way - it uses the default card.
And last but not least: the buggy asoundconf tool, which by the way is going to disappear soon (see the Appendix 1.).

Base configuration


GNU/Linux Debian. Lenny, with a scent of testing and unstable (Squeez and current Sid).
ALSA is the low level sound system here.

Packages You will need



ii libasound2-plugins 1.0.19-2 ALSA library additional plugins
ii pulseaudio 0.9.15-2 PulseAudio sound server


Packages making PulseAudio cool



ii padevchooser 0.9.3-2 PulseAudio Device Chooser
ii pavucontrol 0.9.8-1 PulseAudio Volume Control
ii paprefs 0.9.8-1 PulseAudio Preferences

These tools will give you GUI control over PulseAudio.

To really feel the advantages of PulseAudio



ii flashplugin-nonfree 1:2.6 Adobe Flash Player - browser plugin

This package currently downloads (Firefox about:config):

Shockwave Flash
File name: libflashplayer.so
Shockwave Flash 10.0 r22


Dependencies


Dependencies are going to be fulfilled by some kind of apt. Personally I use aptitude.

Details on packages selection


You have to omit the installation of flashplugin-nonfree-extrasound and pulseaudio-esound-compat. They are redundant in this configuration. This is because Adobe Flash Player 10 uses ALSA by default, so another emulation layer is not needed.

How it works


As far as I understand this, it works like that...
1) Firefox Flash Plugin sends sounds to ALSA
2) ALSA reads the configuration file (.asoundrc) in my home directory, which orders it to use an ALSA plugin (libasound2-plugins) which sends the sound to PulseAudio
3) PulseAudio gets to physical devices back through an ALSA sink
4) Let there be sound

The configuration file


From Arch Linux wiki a recipe for the .asoundconf file in the home directory:

pcm.pulse {
type pulse
}
ctl.pulse {
type pulse
}

pcm.!default {
type pulse
}
ctl.!default {
type pulse
}


Testing


By default PulseAudio doesn't act as a daemon (as the configuration file states - it's better this way). It's run per (graphical) session.

Let's assure PulseAudio is running (probably this step is redundant as the first use of PulseAudio will launch it):

pgrep pulseaudio

or

ps axu | grep pulseaudio

If we get a line containing pulseaudio - it's working.

If we didn't get that kind of line, we can force the PulseAudio launch by executing:

padevchooser &

We should see an icon appear in the notification area. PulseAudio has started. You can click on the icon and then on the "Manager..." menu option to see the details.

Before starting to panic because there is no sound, we should check if ALSA understood what it shoud do. Execute:
aplay -v /usr/share/sounds/alsa/Noise.wav
we should see a line like this:
ALSA <-> PulseAudio PCM I/O Plugin

Final cuts


Let's assure that every time our Desktop shows up padevchooser starts as well. You will manage to do the rest using the PulseAudio Volume Control (pavucontrol).

Appendix 1: asoundconf fades out


As the alsa-utils package changelog states:

alsa-utils (1.0.19-1) unstable; urgency=low

This upload removes alsaconf and asoundconf, two scripts which
could be used to modify certain ALSA parametres, as they caused
more problems than provided solutions, were outdated and generally
unuseful.

alsaconf was upstream's way to detect sound cards and generate
system-wide ALSA configurations. However, this should have been
unnecessary for a very long time, with the introduction of udev
support and its automatic hardware detection. If this isn't the
case for you, it's a bug which should be filed and fixed properly.

asoundconf was a tool introduced by Ubuntu which could be used to
generate asoundrc files for systems with special needs. The script
was not being maintained and was getting buggy, and the Debian and
Ubuntu teams have agreed to get rid of it for the next release. Users
can use Pulse or similar technologies to configure their preferred
sound devices and sinks.

-- Jordi Mallach Sat, 28 Mar 2009 12:53:02 +0100