Skip to content

Commit ac5c759

Browse files
committed
Added main files.
1 parent 55bd242 commit ac5c759

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

Diff for: .htaccess

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Order Deny,Allow
2+
Allow from all
3+
# ALLOW-LIST-START
4+
# ALLOW-LIST-END

Diff for: allowme_config.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/**
4+
* TODO: use a more flexible config file package.
5+
*/
6+
7+
return array(
8+
// Start and end markers.
9+
// Only "allow from" statements will appear between these markers.
10+
// The markers must be present once only, and in the correct order.
11+
12+
'marker_start' => '# ALLOW-LIST-START',
13+
'marker_end' => '# ALLOW-LIST-END',
14+
15+
// Password to get yourself added to the list.
16+
'password' => 'whatever',
17+
18+
// Location of the htaccess file to update.
19+
'htaccess' => __DIR__ . '/../.htaccess',
20+
21+
// Newlines to use when generating the file.
22+
'newline' => "\n",
23+
24+
// Header code, if placing markers for the first time.
25+
'header' => array(
26+
'# Section added by allowme script ' . date('Y-m-d'),
27+
'Order Deny,Allow',
28+
'Deny from all'
29+
),
30+
31+
);

Diff for: index.php

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/**
4+
* Maintain dynamic allow list in .htaccess
5+
*
6+
* By visiting this script with the correct password, your
7+
* IP address will be added to the allow list in the
8+
* .htaccess file.
9+
*
10+
* TODO: ability to lock the file, so two processes do not write to
11+
* it at the same time.
12+
* There is an assumption that the htaccess file will not be too long,
13+
* and so can be easily processes in memory.
14+
* TODO: Take a backup of the file before writing.
15+
* TODO: if htaccess does not contain any markers, then place a pair
16+
* right at the start, with appropriate deny statements. [DONE]
17+
* FIXME: a blank line is being added to the end of the file, each time an
18+
* IP address is added. [HACK: remove *any* blank lines from the end]
19+
*/
20+
21+
// TODO: use a package to get the config data, which can include defaults
22+
// and overrides, and perhaps a config directory.
23+
$config = include('allowme_config.php');
24+
25+
$nl = $config['newline'];
26+
27+
// Read teh current htaccess file into three variables: before, within,
28+
// and after the section to update.
29+
30+
// So we can detect various line endings when reading the htaccess file.
31+
ini_set('auto_detect_line_endings',true);
32+
33+
$content = array(
34+
'before' => '',
35+
'marker_start' => $config['marker_start'] . $nl,
36+
'within' => '',
37+
'marker_end' => $config['marker_end'] . $nl,
38+
'after' => ''
39+
);
40+
41+
$state = 'before';
42+
43+
if (!file_exists($config['htaccess'])) die('htaccess file not found');
44+
if (!is_writable($config['htaccess'])) die('htaccess file not writable');
45+
46+
$fd = fopen($config['htaccess'], 'r');
47+
while(!feof($fd)) {
48+
// Get the line, removing any end-of-line characters it may have.
49+
// Use a regex to support multiple line-end characters in any order.
50+
$line = preg_replace('/[\r\n]*$/', '', fgets($fd));
51+
52+
if (trim($line) == $config['marker_start']) {
53+
if ($state != 'before') die('Out of order markers');
54+
$state = 'within';
55+
continue;
56+
}
57+
58+
if (trim($line) == $config['marker_end']) {
59+
if ($state != 'within') die('Out of order markers');
60+
$state = 'after';
61+
continue;
62+
}
63+
64+
$content[$state] .= $line . $nl;
65+
//echo "line=$line; ";
66+
}
67+
fclose($fd);
68+
69+
// Now we should have the file in three sections.
70+
// If we do not, then the markers were missing.
71+
72+
if ($state == 'within') die('Missing or invalid markers');
73+
74+
if ($state == 'before') {
75+
// We never found the markers, so add them now, right at the
76+
// start of the file.
77+
78+
// Move the before section to the end, with a blank line before it.
79+
$content['after'] = $nl . $content['before'];
80+
$content['before'] = implode($nl, $config['header']) . $nl;
81+
}
82+
83+
// Get the user's IP.
84+
$ip = $_SERVER['REMOTE_ADDR'];
85+
86+
if (empty($ip) || !preg_match('/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/', $ip)) die('IP address not known');
87+
88+
// Look to see if the IP address is already there.
89+
if (preg_match('/ '.$ip.'[^0-9]/', $content['within'])) die('IP already listed');
90+
91+
// Still here? Add this IP.
92+
93+
$content['within'] = 'Allow from ' . $ip . $nl . $content['within'];
94+
95+
// Flatten the new file content.
96+
$flattened = array_reduce(
97+
$content,
98+
function(&$result, $item) {return $result . $item;},
99+
''
100+
);
101+
102+
// Remove blank lines from the end. This is a sort of hack.
103+
$flattened = preg_replace('/['.$nl.']+$/', $nl, $flattened);
104+
105+
// Now write the whole file.
106+
file_put_contents($config['htaccess'], $flattened, LOCK_EX);
107+
108+
echo "IP added";
109+
110+
//echo "<pre>"; var_dump($flattened); echo "</pre>";

0 commit comments

Comments
 (0)