tails-restricted-network-detector 2.34 KB
Newer Older
1
2
3
4
5
6
7
8
9
#!/usr/bin/env perl

use strict;
use warnings;

#man{{{

=head1 NAME

10
tails-restricted-network-detector
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

=head1 VERSION

Version X.XX

=head1 AUTHOR

Tails dev team <tails@boum.org>
See https://tails.boum.org/.

=cut

#}}}

use File::Tail;
use Parse::Syslog;
27
use IPC::System::Simple qw(runx);
28
use Locale::gettext;
Tails developers's avatar
Tails developers committed
29
30
use I18N::Langinfo qw{langinfo CODESET};
use Encode qw{decode find_encoding};
31
32
33
34
35
36
use POSIX;

setlocale(LC_MESSAGES, "");
textdomain("tails");

sub notify_maybe_blocked {
Tails developers's avatar
Tails developers committed
37
38
39
    my $encoding = find_encoding(langinfo(CODESET()));
    my $summary  = $encoding->decode(gettext('Network connection blocked?'));
    my $body     = $encoding->decode(gettext(
40
41
        'It looks like you are blocked from the network. This may be ' .
        'related to the MAC spoofing feature. For more information, see the ' .
42
43
44
        '<a href=\"file:///usr/share/doc/tails/website/doc/first_steps/' .
        'startup_options/mac_spoofing.en.html#blocked\">MAC spoofing ' .
        'documentation</a>.'));
45
46
47
    # We can't use Desktop::Notify since this script is supposed to be run
    # as root (for access to syslog), started in an env without DESKTOP etc,
    # which also causes issues with opening links in the text body.
Tails developers's avatar
Tails developers committed
48
    # All this works fine with tails-notify-user.
49
    runx('/usr/local/sbin/tails-notify-user', ($summary, $body, '30000'));
50
51
}

52
my %state;
53
54
55
56
57
58
59
60
61
62
63
my $syslog = File::Tail->new(name => "/var/log/syslog",
                             maxinterval => 1,
                             interval => 1);
my $parser = Parse::Syslog->new($syslog, allow_future => 1);
while(my $sl = $parser->next) {
    next if !($sl->{program} eq "NetworkManager");
    my $text = $sl->{text};
    if ($text =~ /Activation \(([^)]+)\) starting connection/) {
        # The beginning of *all* (not only wireless) new
        # connections. We drop any previous state so it won't
        # interfere.
64
        $state{$1} = "";
65
66
67
68
69
70
71
72
73
74
75
76
    } elsif ($text =~ /\(([^)]+)\): supplicant connection state:.*-> (.*)$/) {
        # Wireless connection state transition.
        $state{$1} = $2;
    } elsif ($text =~ /Activation \(([^)]+)\/[^)]*\): association took too long/) {
        # Wireless connection failure. If it happens during
        # "associating" it *may* indicate that the AP is blocking the
        # MAC address in use.
        if ($state{$1} eq "associating") {
            notify_maybe_blocked();
        }
    }
}