diff --git a/104fx_import_esr52_stspreload.pl b/104fx_import_esr52_stspreload.pl deleted file mode 100755 index affc1aa9f..000000000 --- a/104fx_import_esr52_stspreload.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/perl -s - -$source ||= "../esr52/security/manager/ssl/nsSTSPreloadList.inc"; -open(W, $source) || die("unable to open $source: $!\nspecify -source=/path ?\n"); -print <<'EOF'; -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/*****************************************************************************/ -/* This is an automatically generated file. If you're not */ -/* nsSiteSecurityService.cpp, you shouldn't be #including it. */ -/*****************************************************************************/ - -/* imported from ESR52 by TenFourFox conversion script */ - -#include -EOF - -# let's have a little paranoia. -while() { - if (/^const PRTime gPreloadListExpirationTime = INT64_C/) { - print; - $got_time = 1; - } - if (/kSTSHostTable/) { - $got_host = 1; - last; - } -} -die("unexpected format of $source\n") if (!$got_time || !$got_host); -print <<'EOF'; - -class nsSTSPreload -{ - public: - const char *mHost; - const bool mIncludeSubdomains; -}; - -static const nsSTSPreload kSTSPreloadList[] = { -EOF - -while() { - if (/^\s*\/\* ("[^"]+", )(true|false)\s\*\//) { - print " { $1$2 },\n"; - } -} - -print "};\n"; - diff --git a/104fx_import_shavar_cryptominers.pl b/104fx_import_shavar_cryptominers.pl new file mode 100755 index 000000000..1677e2560 --- /dev/null +++ b/104fx_import_shavar_cryptominers.pl @@ -0,0 +1,411 @@ +#!/usr/bin/perl -s + +# This descends from huepl and TTYtter, and is therefore under the Floodgap +# Free Software License. It is not required to build or run Firefox or +# TenFourFox. + +BEGIN { + $VERSION = "v0.5"; + if ($] >= 5.014000 && $ENV{'PERL_SIGNALS'} ne 'unsafe') { + $signals_use_posix = 1; + } else { + $ENV{'PERL_SIGNALS'} = 'unsafe'; + } +} + +$lastexception = 0; +@wend = ('-L', '-s', '-m', '20', '-A', '', '-H', 'Expect:'); +eval "use POSIX;"; +$URL = "https://raw.githubusercontent.com/mozilla-services/shavar-prod-lists/master/disconnect-blacklist.json"; + +$exit_mode = 0; +$stringify_args = sub { + my $basecom = shift; + my $resource = shift; + my $data = shift; + my $p; + my $l = ''; + + foreach $p (@_) { + if ($p =~ /^-/) { + $l .= "\n" if (length($l)); + $l .= "$p "; + next; + } + $l .= $p; + } + $l .= "\n"; + + # if resource is an arrayref, then it's a GET with URL + # and args + $resource = join('?', @{ $resource }) + if (ref($resource) eq 'ARRAY'); + $l .= "url = \"$resource\"\n"; + $data =~ s/"/\\"/g; + $l .= "data = \"$data\"\n" if length($data); + return ("$basecom -K -", $l, undef); +}; + +sub sigify { + # this routine abstracts setting signals to a subroutine reference. + # check and see if we have to use POSIX.pm (Perl 5.14+) or we can + # still use $SIG for proper signalling. We prefer the latter, but + # must support the former. + my $subref = shift; + my $k; + + if ($signals_use_posix) { + my @w; + my $sigaction = POSIX::SigAction->new($subref); + while ($k = shift) { + my $e = &posix_signal_of($k); + # some signals may not exist on all systems. + next if (!(0+$e)); + POSIX::sigaction($e, $sigaction) + || die("sigaction failure: $! $@\n"); + } + } else { + while ($k = shift) { $SIG{$k} = $subref; } + } +} +sub posix_signal_of { + die("never call posix_signal_of if signals_use_posix is false\n") + if (!$signals_use_posix); + + # this assumes that POSIX::SIG* returns a scalar int value. + # not all signals exist on all systems. this ensures zeroes are + # returned for locally bogus ones. + return 0+(eval("return POSIX::SIG".shift)); +} + +sub parsejson { + my $data = shift; + my $my_json_ref = undef; # durrr hat go on foot + my $i; + my $tdata; + my $seed; + my $bbqqmask; + my $ddqqmask; + my $ssqqmask; + + # test for single logicals + return { + 'ok' => 1, + 'result' => (($1 eq 'true') ? 1 : 0), + 'literal' => $1, + } if ($data =~ /^['"]?(true|false)['"]?$/); + + # first isolate escaped backslashes with a unique sequence. + $bbqqmask = "BBQQ"; + $seed = 0; + $seed++ while ($data =~ /$bbqqmask$seed/); + $bbqqmask .= $seed; + $data =~ s/\\\\/$bbqqmask/g; + + # next isolate escaped quotes with another unique sequence. + $ddqqmask = "DDQQ"; + $seed = 0; + $seed++ while ($data =~ /$ddqqmask$seed/); + $ddqqmask .= $seed; + $data =~ s/\\\"/$ddqqmask/g; + + # then turn literal ' into another unique sequence. you'll see + # why momentarily. + $ssqqmask = "SSQQ"; + $seed = 0; + $seed++ while ($data =~ /$ssqqmask$seed/); + $ssqqmask .= $seed; + $data =~ s/\'/$ssqqmask/g; + + # here's why: we're going to turn doublequoted strings into single + # quoted strings to avoid nastiness like variable interpolation. + $data =~ s/\"/\'/g; + + # and then we're going to turn the inline ones all back except + # ssqq, which we'll do last so that our syntax checker still works. + $data =~ s/$bbqqmask/\\\\/g; + $data =~ s/$ddqqmask/"/g; + + print STDOUT "$data\n" if ($superverbose); + + # first, generate a syntax tree. + $tdata = $data; + 1 while $tdata =~ s/'[^']*'//; # empty strings are valid too ... + $tdata =~ s/-?[0-9]+\.?[0-9]*([eE][+-][0-9]+)?//g; + # have to handle floats *and* their exponents + $tdata =~ s/(true|false|null)//g; + $tdata =~ s/\s//g; + + print STDOUT "$tdata\n" if ($superverbose); + + # now verify the syntax tree. + # the remaining stuff should just be enclosed in [ ], and only {}:, + # for example, imagine if a bare semicolon were in this ... + if ($tdata !~ s/^\[// || $tdata !~ s/\]$// || $tdata =~ /[^{}:,]/) { + $tdata =~ s/'[^']*$//; # cut trailing strings + if (($tdata =~ /^\[/ && $tdata !~ /\]$/) + || ($tdata =~ /^\{/ && $tdata !~ /\}$/)) { + # incomplete transmission + &exception(10, "*** JSON warning: connection cut\n"); + return undef; + } + if ($tdata =~ /(^|[^:])\[\]($|[^},])/) { # oddity + &exception(11, "*** JSON warning: null list\n"); + return undef; + } + # at this point all we should have are structural elements. + # if something other than JSON structure is visible, then + # the syntax tree is mangled. don't try to run it, it + # might be unsafe. + if ($tdata =~ /[^\[\]\{\}:,]/) { + &exception(99, "*** JSON syntax error\n"); + die(<<"EOF"); +--- data received --- +$data +--- syntax tree --- +$tdata +--- JSON PARSING ABORTED DUE TO SYNTAX TREE FAILURE -- +EOF + exit; + return undef; + } + } + + # syntax tree passed, so let's turn it into a Perl reference. + # have to turn colons into ,s or Perl will gripe. but INTELLIGENTLY! + 1 while + ($data =~ s/([^'])'\s*:\s*(true|false|null|\'|\{|\[|-?[0-9])/\1\',\2/); + + # removing whitespace to improve interpretation speed actually made + # it SLOWER. + #($data =~ s/'\s*,\s*/',/sg); + #($data =~ s/\n\s*//sg); + + # finally, single quotes, just before interpretation. + $data =~ s/$ssqqmask/\\'/g; + + # now somewhat validated, so safe (?) to eval() into a Perl struct + eval "\$my_json_ref = $data;"; + print STDOUT "$data => $my_json_ref $@\n" if ($superverbose); + + # do a sanity check + if (!defined($my_json_ref)) { + &exception(99, "*** JSON syntax error\n"); + print STDOUT <<"EOF" if ($verbose); +--- data received --- +$data +--- syntax tree --- +$tdata +--- JSON PARSING FAILED -- +$@ +--- JSON PARSING FAILED -- +EOF + } + + return $my_json_ref; +} + +sub backticks { + # more efficient/flexible backticks system + my $comm = shift; + my $rerr = shift; + my $rout = shift; + my $resource = shift; + my $data = shift; + my $dont_do_auth = shift; + my $buf = ''; + my $undersave = $_; + my $pid; + my $args; + + ($comm, $args, $data) = &$stringify_args($comm, $resource, + $data, $dont_do_auth, @_); + print STDOUT "$comm\n$args\n$data\n" if ($superverbose); + if(open(BACTIX, '-|')) { + while() { + $buf .= $_; + } close(BACTIX); + $_ = $undersave; + return $buf; # and $? is still in $? + } else { + $in_backticks = 1; + &sigify(sub { + die( + "** user agent not honouring timeout (caught by sigalarm)\n"); + }, qw(ALRM)); + alarm 120; # this should be sufficient + if (length($rerr)) { + close(STDERR); + open(STDERR, ">$rerr"); + } + if (length($rout)) { + close(STDOUT); + open(STDOUT, ">$rout"); + } + if(open(FRONTIX, "|$comm")) { + print FRONTIX "$args\n"; + print FRONTIX "$data" if (length($data)); + close(FRONTIX); + } else { + die( + "backticks() failure for $comm $rerr $rout @_: $!\n"); + } + $rv = $? >> 8; + exit $rv; + } +} + +sub wherecheck { + my ($prompt, $filename, $fatal) = (@_); + my (@paths) = split(/\:/, $ENV{'PATH'}); + my $setv = ''; + + push(@paths, '/usr/bin'); # the usual place + @paths = ('') if ($filename =~ m#^/#); # for absolute paths + + foreach(@paths) { + if (-r "$_/$filename") { + $setv = "$_/$filename"; + 1 while $setv =~ s#//#/#; + last; + } + } + if (!length($setv)) { + die ($fatal) if ($fatal); + exit(1); + } + return $setv; +} + +sub url_oauth_sub { + my $x = shift; + $x =~ s/([^-0-9a-zA-Z._~])/"%".uc(unpack("H*",$1))/eg; return $x; +} + +# this is a sucky nonce generator. I was looking for an awesome nonce +# generator, and then I realized it would only be used once, so who cares? +# *rimshot* +sub generate_nonce { unpack("H32", pack("u", rand($$).$$.time())); } + +sub exception { + my ($num, $tex) = (@_); + $lastexception = $num; + print STDOUT "$tex" if ($verbose); +} + +sub grabjson { + my $url = shift; + my $no_auth = shift; + my $data; + chomp($data = &backticks($curl, + '/dev/null', undef, $url, undef, + $no_auth, @wind)); + return &genericnetworkjson($data, $url, $no_auth); +} +sub postjson { + my $url = shift; + my $postdata = shift; + my $no_auth = shift; + my $data; + chomp($data = &backticks($curl, + '/dev/null', undef, $url, $postdata, + $no_auth, @wend)); + return &genericnetworkjson($data, $url, $no_auth); +} +sub putjson { + my $url = shift; + my $postdata = shift; + my $no_auth = shift; + my $data; + chomp($data = &backticks($curl, + '/dev/null', undef, $url, $postdata, + $no_auth, @wund)); + return &genericnetworkjson($data, $url, $no_auth); +} + +sub genericnetworkjson { + my $data = shift; + my $url = shift; + my $no_auth = shift; + my $my_json_ref = undef; # durrr hat go on foot + my $i; + my $tdata; + my $seed; + + my $k = $? >> 8; + $data =~ s/[\r\l\n\s]*$//s; + $data =~ s/^[\r\l\n\s]*//s; + + if (!length($data) || $k == 28 || $k == 7 || $k == 35) { + &exception(1, "*** warning: timeout or no data\n"); + return undef; + } + + if ($k > 0) { + &exception(4, +"*** warning: unexpected error code ($k) from user agent\n"); + return undef; + } + + # handle things like 304, or other things that look like HTTP + # error codes + if ($data =~ m#^HTTP/\d\.\d\s+(\d+)\s+#) { + $code = 0+$1; + print $stdout $data if ($superverbose); + + # 304 is actually a cop-out code and is not usually + # returned, so we should consider it a non-fatal error + if ($code == 304 || $code == 200 || $code == 204) { + &exception(1, "*** warning: timeout or no data\n"); + return undef; + } + &exception(4, +"*** warning: unexpected HTTP return code $code from server\n"); + return undef; + } + + $my_json_ref = &parsejson($data); + $laststatus = 0; + return $my_json_ref; +} + +$curl ||= &wherecheck("checking for cURL", "curl", <<"EOF"); + +cURL is required. if cURL is not usually in your path, you can +hardcode it with -curl=/path/to/curl + +EOF + +$vv = `$curl --version`; +($vv =~ /^curl (\d+)\.(\d+)/) && ($major = $1, $minor = $2); +die("at least cURL 7.58 required, you have ${major}.${minor}.\n\n$vv\n") + if ($major < 7 || ($major == 7 && $minor < 58)); + +$json_ref = &grabjson("https://raw.githubusercontent.com/mozilla-services/shavar-prod-lists/master/disconnect-blacklist.json"); + +die("this doesn't look like the right format\n\ncheck URL\n$url\n") +if (!defined($json_ref->{'license'}) || + !defined($json_ref->{'categories'}) || + !defined($json_ref->{'categories'}->{'Cryptomining'})); + +select(STDOUT); $|++; +%dupedupe = (); +foreach $a (@{ $json_ref->{'categories'}->{'Cryptomining'} }) { + foreach $b (keys(%{ $a })) { + die("illegal newline: $b\n") if ($b =~ /[\r\n]/s); + print "// $b\n"; + + foreach $c (keys(%{ $a->{$b} })) { + next if ($c eq 'performance'); + die("illegal newline: $c\n") if ($c =~ /[\r\n]/s); + + print "// $c\n"; + foreach $d (@{ $a->{$b}->{$c} }) { + die("illegal quote: $d\n") if ($d =~ /"/); + next if ($dupedupe{$d}++); + + print " BLOK(\"$d\") ||\n"; + } + } + } +} diff --git a/104fx_upcerts.sh b/104fx_upcerts.sh index fd0a457db..0fe7d2ce1 100755 --- a/104fx_upcerts.sh +++ b/104fx_upcerts.sh @@ -14,4 +14,5 @@ cp ../esr60/security/nss/lib/ckfw/builtins/certdata.txt security/nss/lib/ckfw/bu cp ../esr60/security/manager/ssl/StaticHPKPins.h security/manager/ssl/StaticHPKPins.h cp ../esr60/netwerk/dns/effective_tld_names.dat netwerk/dns/effective_tld_names.dat perl ./104fx_import_esr60_stspreload.pl > security/manager/ssl/nsSTSPreloadList.inc +perl ./104fx_import_shavar_cryptominers.pl > caps/shavar-blocklist.h diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 113cc752a..2ed28260f 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -1151,6 +1151,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, BLOK("buy.tinypass.com") || BLOK("cdn.tinypass.com") || +#include "shavar-blocklist.h" 0) { #undef BLOK diff --git a/caps/shavar-blocklist.h b/caps/shavar-blocklist.h new file mode 100644 index 000000000..dea66276e --- /dev/null +++ b/caps/shavar-blocklist.h @@ -0,0 +1,105 @@ +// a.js +// http://zymerget.bid + BLOK("alflying.date") || + BLOK("alflying.win") || + BLOK("anybest.site") || + BLOK("flightsy.bid") || + BLOK("flightsy.win") || + BLOK("flightzy.bid") || + BLOK("flightzy.date") || + BLOK("flightzy.win") || + BLOK("zymerget.bid") || + BLOK("zymerget.faith") || +// CashBeet +// http://cashbeet.com + BLOK("cashbeet.com") || + BLOK("serv1swork.com") || +// CoinHive +// https://coinhive.com + BLOK("ad-miner.com") || + BLOK("authedmine.com") || + BLOK("bmst.pw") || + BLOK("cnhv.co") || + BLOK("coin-hive.com") || + BLOK("coinhive.com") || + BLOK("wsservices.org") || +// CoinPot +// http://coinpot.co + BLOK("coinpot.co") || +// CryptoLoot +// https://crypto-loot.com + BLOK("cryptaloot.pro") || + BLOK("crypto-loot.com") || + BLOK("cryptolootminer.com") || + BLOK("flashx.pw") || + BLOK("gitgrub.pro") || + BLOK("reauthenticator.com") || + BLOK("statdynamic.com") || + BLOK("webmine.pro") || +// CryptoWebMiner +// https://www.crypto-webminer.com + BLOK("bitcoin-pay.eu") || + BLOK("crypto-webminer.com") || + BLOK("ethpocket.de") || + BLOK("ethtrader.de") || +// Gridcash +// https://www.gridcash.net/ + BLOK("adless.io") || + BLOK("gridcash.net") || +// JSE +// http://jsecoin.com + BLOK("freecontent.bid") || + BLOK("freecontent.date") || + BLOK("freecontent.stream") || + BLOK("hashing.win") || + BLOK("hostingcloud.racing") || + BLOK("hostingcloud.science") || + BLOK("jsecoin.com") || +// MinerAlt +// http://mineralt.io + BLOK("1q2w3.website") || + BLOK("analytics.blue") || + BLOK("aster18cdn.nl") || + BLOK("belicimo.pw") || + BLOK("besstahete.info") || + BLOK("dinorslick.icu") || + BLOK("feesocrald.com") || + BLOK("gramombird.com") || + BLOK("istlandoll.com") || + BLOK("mepirtedic.com") || + BLOK("mineralt.io") || + BLOK("pampopholf.com") || + BLOK("tercabilis.info") || + BLOK("tulip18.com") || + BLOK("vidzi.tv") || + BLOK("yololike.space") || +// Minescripts +// http://minescripts.info + BLOK("minescripts.info") || + BLOK("sslverify.info") || +// MineXMR +// http://minexmr.stream + BLOK("minexmr.stream") || +// NeroHut +// https://nerohut.com + BLOK("nerohut.com") || + BLOK("nhsrv.cf") || +// Service4refresh +// https://service4refresh.info + BLOK("service4refresh.info") || +// SpareChange +// http://sparechange.io + BLOK("sparechange.io") || +// SwiftMining +// https://swiftmining.win/ + BLOK("swiftmining.win") || +// Webmine +// https://webmine.cz/ + BLOK("authedwebmine.cz") || + BLOK("webmine.cz") || +// WebminePool +// http://webminepool.com + BLOK("webminepool.com") || +// Webmining +// https://webmining.co/ + BLOK("webmining.co") ||