Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 71 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
Generate | |
0.00% |
0 / 66 |
|
0.00% |
0 / 4 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 56 |
|
0.00% |
0 / 1 |
110 | |||
showProgress | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
canExecuteWithoutLocalSettings | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\TrustedXFF; |
4 | |
5 | use MediaWiki\Maintenance\Maintenance; |
6 | use Wikimedia\IPSet; |
7 | use Wikimedia\IPUtils; |
8 | |
9 | require_once getenv( 'MW_INSTALL_PATH' ) !== false |
10 | ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php' |
11 | : __DIR__ . '/../../../maintenance/Maintenance.php'; |
12 | |
13 | class Generate extends Maintenance { |
14 | public function __construct() { |
15 | parent::__construct(); |
16 | $this->addDescription( 'Generates the PHP/JSON XFF file from the trusted-hosts.txt file' ); |
17 | $this->addOption( 'outdir', 'The output directory, default ' . dirname( __DIR__ ) ); |
18 | |
19 | // This script does not require the extension to be installed |
20 | } |
21 | |
22 | public function execute() { |
23 | $outDir = $this->getOption( 'outdir', dirname( __DIR__ ) ); |
24 | $inFileName = dirname( __DIR__ ) . '/trusted-hosts.txt'; |
25 | $inFile = fopen( $inFileName, 'r' ); |
26 | if ( !$inFile ) { |
27 | $this->fatalError( "Unable to open input file \"$inFileName\"\n" ); |
28 | } |
29 | |
30 | $lineNum = 0; |
31 | $ranges = []; |
32 | $names = []; |
33 | |
34 | while ( !feof( $inFile ) ) { |
35 | $line = fgets( $inFile ); |
36 | $lineNum++; |
37 | if ( $line === false ) { |
38 | break; |
39 | } |
40 | // Remove comment |
41 | $hashPos = strpos( $line, '#' ); |
42 | if ( $hashPos !== false ) { |
43 | $line = substr( $line, 0, $hashPos ); |
44 | } |
45 | // Strip spaces |
46 | $line = trim( $line ); |
47 | |
48 | if ( $line === '' ) { |
49 | // Comment or blank line |
50 | continue; |
51 | } |
52 | |
53 | [ $start, ] = IPUtils::parseRange( $line ); |
54 | if ( $start === false ) { |
55 | // Try DNS |
56 | $names[] = [ $lineNum, $line ]; |
57 | continue; |
58 | } |
59 | $ranges[] = $line; |
60 | } |
61 | |
62 | $this->output( count( $names ) . " DNS queries to do...\n" ); |
63 | |
64 | foreach ( $names as $i => $nameInfo ) { |
65 | [ $lineNum, $name ] = $nameInfo; |
66 | $ips = gethostbynamel( $name ); |
67 | if ( $ips === false ) { |
68 | $this->output( "Not a valid host or IP address on line $lineNum: $name\n" ); |
69 | } else { |
70 | $ranges = array_merge( $ranges, $ips ); |
71 | } |
72 | $this->showProgress( $i, count( $names ) ); |
73 | // Don't DoS the recursor |
74 | usleep( 10000 ); |
75 | } |
76 | $this->output( "\n" ); |
77 | |
78 | natsort( $ranges ); |
79 | $ranges = array_values( array_unique( $ranges ) ); |
80 | |
81 | $header = sprintf( |
82 | "Generated by %s/%s on %s;\nNote this file is deprecated in favour of trusted-hosts.json.", |
83 | basename( __DIR__ ), |
84 | basename( __FILE__ ), |
85 | gmdate( 'c' ) |
86 | ); |
87 | |
88 | $out = "<" . "?php\n" . preg_replace( '/^/m', '# ', $header ) . "\nreturn [\n"; |
89 | foreach ( $ranges as $range ) { |
90 | $out .= "\t" . var_export( $range, true ) . ",\n"; |
91 | } |
92 | $out .= "];\n"; |
93 | file_put_contents( |
94 | "$outDir/trusted-hosts.php", |
95 | $out |
96 | ); |
97 | |
98 | file_put_contents( |
99 | "$outDir/trusted-hosts.json", |
100 | json_encode( new IPSet( $ranges ) ) |
101 | ); |
102 | |
103 | $count = count( $ranges ); |
104 | $this->output( "$count ips or ranges listed\n" ); |
105 | } |
106 | |
107 | /** |
108 | * @param int $current |
109 | * @param int $total |
110 | */ |
111 | private function showProgress( $current, $total ) { |
112 | $length = 50; |
113 | $dots = intval( ( $current + 1 ) / $total * $length ); |
114 | printf( "%6.2f%% [" . |
115 | str_repeat( '=', $dots ) . str_repeat( '.', $length - $dots ) . "]\r", |
116 | ( $current + 1 ) / $total * 100 |
117 | ); |
118 | } |
119 | |
120 | public function canExecuteWithoutLocalSettings(): bool { |
121 | return true; |
122 | } |
123 | } |
124 | |
125 | $maintClass = Generate::class; |
126 | require_once RUN_MAINTENANCE_IF_MAIN; |