4 use warnings FATAL
=> 'all';
20 tails-security-check [ ATOM_FEED_BASE_URL ]
22 ATOM_FEED_BASE_URL will be appended /index.XX.atom,
23 for XX in (current locale's language code, 'en'),
24 until success is reported by the HTTP layer.
28 Tails developers <tails@boum.org>
29 See https://tails.boum.org/.
36 use Carp
::Assert
::More
;
38 use Fatal
qw{open close};
49 IO
::Socket
::SSL
::set_ctx_defaults
(
50 verify_mode
=> Net
::SSLeay
->VERIFY_PEER(),
51 ca_file
=> '/usr/local/etc/ssl/certs/tails.boum.org-CA.pem',
54 use LWP
::UserAgent
; # needs to be *after* IO::Socket::SSL's initialization
56 setlocale
(LC_MESSAGES
, "");
61 my $version_file = '/etc/amnesia/version';
62 my $default_base_url = 'https://tails.boum.org/security/';
68 Returns the two-letters language code of the current session.
72 my ($code) = ($ENV{LANG
} =~ m/([a-z]{2}).*/);
79 Argument: an Atom feed URL
81 Returns the Atom's feed content on success, undef on failure.
88 $ENV{HTTPS_VERSION
} = 3;
90 my $ua = LWP
::UserAgent
->new;
91 $ua->proxy([qw(http https)] => 'socks://127.0.0.1:9062')
92 unless $ENV{DISABLE_PROXY
};
93 my $req = HTTP
::Request
->new('GET', $url);
94 my $res = $ua->request($req);
95 if (defined $res && $res->is_success) {
104 Arguments: the Atom feed URL.
106 Returns the list of XML::Atom::Entry objects from the feed.
108 We use this manual Accept-Language algorithm as the website
109 layout does not allow us to use content negotiation.
113 my $base_url = shift;
114 assert_defined
($base_url);
115 assert_nonblank
($base_url);
118 $separator = '/' unless $base_url =~ m
{/\z
}xms
;
121 $base_url . $separator . 'index.' . current_lang
() . '.atom',
122 $base_url . $separator . 'index.en.atom',
126 foreach my $url (@try_urls) {
127 last if ($feed_str = atom_str
($url));
129 assert_defined
($feed_str);
131 return XML
::Atom
::Feed
->new(\
$feed_str)->entries();
136 Use the Desktop Notifications framework to notify the user about the
137 Atom entries passed as arguments.
143 my $notify = Desktop
::Notify
->new();
145 my $summary = gettext
('This version of Tails has known security issues:');
149 $body .= '- ' . '<a href="' . $_->id . '">' . $_->title . '</a>' . "\n";
154 $notify->create(summary
=> $summary,
156 timeout
=> 0)->show();
161 Return the list of categories of the input XML::Atom::Entry object.
166 my $ns = XML
::Atom
::Namespace
->new(
167 dc
=> 'http://purl.org/dc/elements/1.1/'
169 my @category = ($entry->can('categories'))
173 ?
(map { $_->label || $_->term } @category)
174 : $entry->getlist($ns, 'subject');
179 Returns true iff. the input XML::Atom::Entry object hasn't the
185 assert_isa
($entry, 'XML::Atom::Entry');
187 ! grep { $_ eq 'security/fixed' } categories
($entry);
190 =head2 unfixed_entries
192 Filter the input list of XML::Atom::Entry objects to only keep entries
193 that are not marked as fixed yet.
196 sub unfixed_entries
{
199 grep { is_not_fixed
($_) } @entries;
207 if (! -e
"$version_file") {
208 die "The Tails version file ($version_file) does not exist."
210 if (! -r
"$version_file") {
211 die "The Tails version file ($version_file) is not readable."
214 =head2 parse command line args
217 my $base_url = shift || $default_base_url;
218 my $opt_since = shift;
224 my @unfixed_entries = unfixed_entries
(get_entries
($base_url));
226 if (! @unfixed_entries) {
230 notify_user
(@unfixed_entries);