Browse code

Importing SMF IPv6 mod

Jeremy D authored on 28/09/2011 12:07:14
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+Copyright (c) 2011, SleePy (smf-mods-license@sleepycode.com)
1
+All rights reserved.
2
+
3
+Redistribution and use in source and binary forms, with or without
4
+modification, are permitted provided that the following conditions are met:
5
+    * Redistributions of source code must retain the above copyright
6
+      notice, this list of conditions and the following disclaimer.
7
+    * Redistributions in binary form must reproduce the above copyright
8
+      notice, this list of conditions and the following disclaimer in the
9
+      documentation and/or other materials provided with the distribution.
10
+    * Neither the name of the <organization> nor the
11
+      names of its contributors may be used to endorse or promote products
12
+      derived from this software without specific prior written permission.
13
+
14
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
18
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 24
\ No newline at end of file
1 25
new file mode 100755
... ...
@@ -0,0 +1,18 @@
0
+IPv6 support for SMF 2.0+ Only.  I will not backport these changes to 1.1.
1
+
2
+This customization will add support for the IPv6 enabled clients in SMF 2.0.  Specifically posts, ip tracking and ban management have been changed.  Member search from the admin panel does support this by default.
3
+
4
+Due to the size and necessity of the changes, please do not continue with installation if any change should fail the test.  This may lead to unexpected results or a unusable forum.
5
+
6
+Note: During uninstallation, all IPv6 enabled bans will be disabled.  This customization makes attempts to track those changes in columns it adds to the ban_items table.  If you remove the database changes, this tracking will be lost.  In addition upon reinstallation this customization makes attempts to re-enable those bans that should still be active.
7
+
8
+Note: Currently you are unable to link via iurl/url or auto linking ipv6 urls.  This is due to the square brackets that ipv6 addresses are enclosed in.  However this doesn't affect domains.
9
+
10
+Thanks to [url=http://www.soucy.org]Ray Soucy[/url]'s for his IPv6 functions he wrote and allowing usage of them in this customization.
11
+
12
+This customization is released under the BSD 3-Clause license. The terms of the license are including in this package (LICENSE.txt) or available on Simple Machines website at http://www.simplemachines.org/about/smf/license.php.
13
+
14
+ChangeLog:
15
+
16
+Version 1.0
17
+! Release
0 18
new file mode 100755
... ...
@@ -0,0 +1,108 @@
0
+<?php
1
+error_reporting(E_ALL);
2
+
3
+// Hopefully we have the goodies.
4
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF'))
5
+{
6
+	$using_ssi = true;
7
+	require_once(dirname(__FILE__) . '/SSI.php');
8
+}
9
+elseif (!defined('SMF'))
10
+	exit('<b>Error:</b> Cannot install - please verify you put this in the same place as SMF\'s index.php.');
11
+
12
+global $db_prefix, $modSettings, $func, $smcFunc;
13
+
14
+// Fields to add
15
+$new_fields = array(
16
+	'is_ipv6' => array('name'=> 'is_ipv6', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
17
+	'ip_low5' => array('name'=> 'ip_low5', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
18
+	'ip_high5' => array('name'=> 'ip_high5', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
19
+	'ip_low6' => array('name'=> 'ip_low6', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
20
+	'ip_high6' => array('name'=> 'ip_high6', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
21
+	'ip_low7' => array('name'=> 'ip_low7', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
22
+	'ip_high7' => array('name'=> 'ip_high7', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
23
+	'ip_low8' => array('name'=> 'ip_low8', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
24
+	'ip_high8' => array('name'=> 'ip_high8', 'type'=>'SMALLINT(255)', 'unsigned' => true, 'default' => 0),
25
+);
26
+
27
+$changed_fields = array(
28
+	'ip_low1' => array('name'=> 'ip_low1', 'type'=>'SMALLINT(255)'),
29
+	'ip_high1' => array('name'=> 'ip_high1', 'type'=>'SMALLINT(255)'),
30
+	'ip_low2' => array('name'=> 'ip_low2', 'type'=>'SMALLINT(255)'),
31
+	'ip_high2' => array('name'=> 'ip_high2', 'type'=>'SMALLINT(255)'),
32
+	'ip_low3' => array('name'=> 'ip_low3', 'type'=>'SMALLINT(255)'),
33
+	'ip_high3' => array('name'=> 'ip_high3', 'type'=>'SMALLINT(255)'),
34
+	'ip_low4' => array('name'=> 'ip_low4', 'type'=>'SMALLINT(255)'),
35
+	'ip_high4' => array('name'=> 'ip_high4', 'type'=>'SMALLINT(255)'),
36
+);
37
+
38
+// Load up the board info, we will only add these once.
39
+$table_columns = $smcFunc['db_list_columns']($db_prefix . 'ban_items');
40
+
41
+// Do the loopy, loop, loe.
42
+foreach ($new_fields as $column_name => $column_attributes)
43
+	if (!in_array($column_name, $table_columns))
44
+		$smcFunc['db_add_column']($db_prefix . 'ban_items', $column_attributes);
45
+
46
+// Do the loopy, loop, loe.
47
+foreach ($changed_fields as $column_name => $column_attributes)
48
+	$smcFunc['db_change_column']($db_prefix . 'ban_items', $column_attributes);
49
+
50
+// Find any IPv6 bans and reenable them again.
51
+// !!! Note, We changed is_ipv6 to the time stamp of when it is supposed of expired, 1 if it was a perm ban.
52
+$result = $smcFunc['db_query']('', '
53
+	SELECT id_ban_group, is_ipv6
54
+	FROM {db_prefix}ban_items
55
+	WHERE is_ipv6 < {int:is_ipv6}',
56
+	array(
57
+		'is_ipv6' => '1'
58
+));
59
+
60
+$enabled_bans = array();
61
+$disabled_bans = array();
62
+$lost_bans = array();
63
+while ($row = $smcFunc['db_fetch_assoc']($request))
64
+{
65
+	if ($row['is_ipv6'] == 1)
66
+		$enabled_bans[] = $row['id_ban_group'];
67
+	elseif ($row['is_ipv6'] > 1 && time() < $row['is_ipv6'])
68
+		$enabled_bans[] = $row['id_ban_group'];
69
+	elseif ($row['is_ipv6'] > 1 && time() > $row['is_ipv6'])
70
+		$disabled_bans[] = $row['id_ban_group'];
71
+	// Where did you come from?
72
+	else
73
+		$lost_bans[] = $row['id_ban_group'];
74
+
75
+	// Not the best way, but will do the job.
76
+	$smcFunc['db_query']('', '
77
+		UPDATE {db_prefix}ban_groups
78
+		SET expire_time = {raw:expire}
79
+		WHERE id_ban_group = {int:ban_group}',
80
+		array(
81
+			'expire' => $row['is_ipv6'] == 1 ? 'NULL' : $row['is_ipv6'],
82
+			'ban_group' => $row['id_ban_group'],
83
+	));
84
+}		
85
+
86
+// Ok, We just re-enable these.
87
+$smcFunc['db_query']('', '
88
+	UPDATE {db_prefix}ban_items
89
+	SET is_ipv6 = {int:enabled}
90
+	WHERE is_ipv6 < {int:enabled}',
91
+	array(
92
+		'enabled' => '1',
93
+));
94
+
95
+// Handle our lost bans.
96
+if (!empty($lost_bans) && !empty($using_ssi))
97
+	echo 'We had some bans that we could not properly enable. Please check these ban ids:', implode(', ', $lost_bans), '<br />';
98
+
99
+// For debugging/support purposes.
100
+if (!empty($lost_bans))
101
+log_error('Lost bans during IPV6 re-enabling:', implode(', ', $lost_bans), 'critical');
102
+
103
+// Update our ban time, forcing rechecks to occur.
104
+updateSettings(array('banLastUpdated' => time()));
105
+
106
+if(!empty($using_ssi))
107
+	echo 'If no errors, Success!';
0 108
new file mode 100755
... ...
@@ -0,0 +1,56 @@
0
+<?php
1
+error_reporting(E_ALL);
2
+
3
+// Hopefully we have the goodies.
4
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF'))
5
+{
6
+	$using_ssi = true;
7
+	require_once(dirname(__FILE__) . '/SSI.php');
8
+}
9
+elseif (!defined('SMF'))
10
+	exit('<b>Error:</b> Cannot install - please verify you put this in the same place as SMF\'s index.php.');
11
+
12
+global $db_prefix, $modSettings, $func, $smcFunc;
13
+
14
+// Find any IPv6 bans.
15
+$result = $smcFunc['db_query']('', '
16
+	SELECT bi.id_ban_group, bi.is_ipv6, bg.expire_time
17
+	FROM {db_prefix}ban_items AS bi
18
+		INNER JOIN {db_prefix}ban_groups AS bg ON (bi.id_ban_group = bg.id_ban_group)
19
+	WHERE bi.is_ipv6 = {int:is_ipv6}',
20
+	array(
21
+		'is_ipv6' => '1'
22
+));
23
+
24
+$ipv6_bans = array();
25
+while($row = $smcFunc['db_fetch_assoc']($request))
26
+{
27
+	if ($row['expire_time'] != 'NULL')
28
+		$smcFunc['db_query']('', '
29
+			UPDATE {db_prefix}ban_items
30
+			SET is_ipv6 = {raw:expire_time}
31
+			WHERE id_ban_group = {int:ban_group}',
32
+			array(
33
+				'expire_time' => $row['expire_time'],
34
+				'ban_group' => $row['id_ban_group'],
35
+		));
36
+
37
+	$ipv6_bans[] = $row['id_ban_group'];
38
+}
39
+
40
+// Do a mass update to disable these bans.
41
+$smcFunc['db_query']('', '
42
+	UPDATE {db_prefix}ban_groups
43
+	SET expire_time = {int:expired_time}
44
+	WHERE id_ban_group IN ({array_int:bans})',
45
+	array(
46
+		'expired_time' => time() - 60, // 1 minute ago should do.
47
+		'bans' => $ipv6_bans
48
+));
49
+
50
+// Update our ban time, forcing rechecks to occur.
51
+updateSettings(array('banLastUpdated' => time()));
52
+
53
+if(!empty($using_ssi))
54
+	echo 'If no errors, Success!';
55
+?>
0 56
\ No newline at end of file
1 57
new file mode 100644
... ...
@@ -0,0 +1,618 @@
0
+<?xml version="1.0"?>
1
+<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification">
2
+<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/">
3
+
4
+	<id>sleepy:ipv6_support</id>
5
+
6
+	<version>1.0</version>
7
+
8
+	<file name="$sourcedir/ManageSearchEngines.php">
9
+
10
+		<operation>
11
+
12
+			<search position="after"><![CDATA[	foreach ($spider_data as $spider)
13
+	{
14
+		// User agent is easy.
15
+]]></search>
16
+
17
+			<add><![CDATA[	// IPv6!!! I have no idea why we do a preg match when we already validated the ip in QueryString. I wont do it.
18
+	if (empty($ip_parts) && strpos($_SERVER['REMOTE_ADDR'], ':') !== false)
19
+		$ip_parts = smf_ipv6_to_ints($_SERVER['REMOTE_ADDR']);
20
+
21
+]]></add>
22
+
23
+		</operation>
24
+
25
+	</file>
26
+
27
+	<file name="$sourcedir/ManageBans.php">
28
+
29
+		<operation>
30
+
31
+			<search position="after"><![CDATA[		);
32
+
33
+		// Preset all values that are required.
34
+]]></search>
35
+
36
+			<add><![CDATA[			'is_ipv6' => 0,
37
+			'ip_low5' => 0,
38
+			'ip_high5' => 0,
39
+			'ip_low6' => 0,
40
+			'ip_high6' => 0,
41
+			'ip_low7' => 0,
42
+			'ip_high7' => 0,
43
+			'ip_low8' => 0,
44
+			'ip_high8' => 0,
45
+]]></add>
46
+
47
+		</operation>
48
+
49
+		<operation>
50
+
51
+			<search position="after"><![CDATA[			);
52
+		}
53
+		else
54
+]]></search>
55
+
56
+			<add><![CDATA[				'is_ipv6' => 'int',
57
+				'ip_low5' => 'int',
58
+				'ip_high5' => 'int',
59
+				'ip_low6' => 'int',
60
+				'ip_high6' => 'int',
61
+				'ip_low7' => 'int',
62
+				'ip_high7' => 'int',
63
+				'ip_low8' => 'int',
64
+				'ip_high8' => 'int',
65
+]]></add>
66
+
67
+		</operation>
68
+
69
+		<operation>
70
+
71
+			<search position="replace"><![CDATA[				ip_low4 = {int:ip_low4}, ip_high4 = {int:ip_high4}';
72
+]]></search>
73
+
74
+			<add><![CDATA[				ip_low4 = {int:ip_low4}, ip_high4 = {int:ip_high4},
75
+				is_ipv6 = {int:is_ipv6},
76
+				ip_low5 = {int:ip_low5}, ip_high5 = {int:ip_high5},
77
+				ip_low6 = {int:ip_low6}, ip_high6 = {int:ip_high6},
78
+				ip_low7 = {int:ip_low7}, ip_high7 = {int:ip_high7},
79
+				ip_low8 = {int:ip_low8}, ip_high8 = {int:ip_high8}';
80
+]]></add>
81
+
82
+		</operation>
83
+
84
+		<operation>
85
+
86
+			<search position="after"><![CDATA[			$modlogInfo['ip_range'] = $_POST['ip'];
87
+		}
88
+		elseif ($_POST['bantype'] == 'hostname_ban')
89
+]]></search>
90
+
91
+			<add><![CDATA[			if (strpos($ip, ':') !== false)
92
+				$values['is_ipv6'] = 1;
93
+
94
+]]></add>
95
+
96
+		</operation>
97
+
98
+		<operation>
99
+
100
+			<search position="after"><![CDATA[					);
101
+
102
+					$ban_logs[] = array(
103
+]]></search>
104
+
105
+			<add><![CDATA[						!empty($ip_parts[4]['low']) ? 1 : 0,
106
+						$ip_parts[4]['low'],
107
+						$ip_parts[4]['high'],
108
+						$ip_parts[5]['low'],
109
+						$ip_parts[5]['high'],
110
+						$ip_parts[6]['low'],
111
+						$ip_parts[6]['high'],
112
+						$ip_parts[7]['low'],
113
+						$ip_parts[7]['high'],
114
+]]></add>
115
+
116
+		</operation>
117
+
118
+		<operation>
119
+
120
+			<search position="after"><![CDATA[					);
121
+					$ban_logs[] = array(
122
+						'hostname' => $_POST['hostname'],
123
+]]></search>
124
+
125
+			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
126
+]]></add>
127
+
128
+		</operation>
129
+
130
+		<operation>
131
+
132
+			<search position="after"><![CDATA[					);
133
+					$ban_logs[] = array(
134
+						'email' => $_POST['email'],
135
+]]></search>
136
+
137
+			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
138
+]]></add>
139
+
140
+		</operation>
141
+
142
+		<operation>
143
+
144
+			<search position="after"><![CDATA[					);
145
+					$ban_logs[] = array(
146
+						'member' => $_POST['bannedUser'],
147
+]]></search>
148
+
149
+			<add><![CDATA[						0, 0, 0, 0, 0, 0, 0, 0, 0,
150
+]]></add>
151
+
152
+		</operation>
153
+
154
+		<operation>
155
+
156
+			<search position="replace"><![CDATA[						if (count($ip_parts) != 4)
157
+]]></search>
158
+
159
+			<add><![CDATA[						if (count($ip_parts) != 4 || count($ip_parts) != 8)
160
+]]></add>
161
+
162
+		</operation>
163
+
164
+		<operation>
165
+
166
+			<search position="after"><![CDATA[						);
167
+						$ban_logs[] = array(
168
+							'ip_range' => $ip,
169
+]]></search>
170
+
171
+			<add><![CDATA[							!empty($ip_parts[4]['low']) ? 1 : 0,
172
+							$ip_parts[4]['low'],
173
+							$ip_parts[4]['high'],
174
+							$ip_parts[5]['low'],
175
+							$ip_parts[5]['high'],
176
+							$ip_parts[6]['low'],
177
+							$ip_parts[6]['high'],
178
+							$ip_parts[7]['low'],
179
+							$ip_parts[7]['high'],
180
+]]></add>
181
+
182
+		</operation>
183
+
184
+		<operation>
185
+
186
+			<search position="after"><![CDATA[					),
187
+					$ban_triggers,
188
+					array('id_ban')
189
+]]></search>
190
+
191
+			<add><![CDATA[						'is_ipv6' => 'int', 'ip_low5' => 'int', 'ip_high5' => 'int', 'ip_low6' => 'int', 'ip_high6' => 'int', 'ip_low7' => 'int', 'ip_high7' => 'int', 'ip_low8' => 'int', 'ip_high8' => 'int',
192
+]]></add>
193
+
194
+		</operation>
195
+
196
+		<operation>
197
+
198
+			<search position="after"><![CDATA[				bg.id_ban_group, bg.name, bg.ban_time, bg.expire_time, bg.reason, bg.notes, bg.cannot_access, bg.cannot_register, bg.cannot_login, bg.cannot_post,
199
+				IFNULL(mem.id_member, 0) AS id_member, mem.member_name, mem.real_name
200
+			FROM {db_prefix}ban_groups AS bg
201
+]]></search>
202
+
203
+			<add><![CDATA[				bi.is_ipv6, bi.ip_low5, bi.ip_high5, bi.ip_low6, bi.ip_high6, bi.ip_low7, bi.ip_high7, bi.ip_low8, bi.ip_high8,
204
+]]></add>
205
+
206
+		</operation>
207
+
208
+		<operation>
209
+
210
+			<search position="replace"><![CDATA[					$context['ban_items'][$row['id_ban']]['ip'] = range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4']));
211
+]]></search>
212
+
213
+			<add><![CDATA[					$context['ban_items'][$row['id_ban']]['ip'] = range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4'] ,$row['ip_low5'], $row['ip_low6'], $row['ip_low7'], $row['ip_low8']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'], $row['ip_high5'], $row['ip_high6'], $row['ip_high7'], $row['ip_high8']));
214
+]]></add>
215
+
216
+		</operation>
217
+
218
+		<operation>
219
+
220
+			<search position="after"><![CDATA[				mem.member_name, mem.real_name
221
+			FROM {db_prefix}ban_items AS bi
222
+				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = bi.id_member)
223
+]]></search>
224
+
225
+			<add><![CDATA[				bi.is_ipv6, bi.ip_low5, bi.ip_high5, bi.ip_low6, bi.ip_high6, bi.ip_low7, bi.ip_high7, bi.ip_low8, bi.ip_high8,
226
+]]></add>
227
+
228
+		</operation>
229
+
230
+		<operation>
231
+
232
+			<search position="replace"><![CDATA[				'value' => empty($row['ip_low1']) ? '' : range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'])),
233
+]]></search>
234
+
235
+			<add><![CDATA[				'value' => empty($row['ip_low1']) ? '' : range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4'], $row['ip_low5'], $row['ip_low6'], $row['ip_low7'], $row['ip_low8']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'], $row['ip_high5'], $row['ip_high6'], $row['ip_high7'], $row['ip_high8'])),
236
+]]></add>
237
+
238
+		</operation>
239
+
240
+		<operation>
241
+
242
+			<search position="after"><![CDATA[	if (count($low) != 4 || count($high) != 4)
243
+		return '';
244
+
245
+]]></search>
246
+
247
+			<add><![CDATA[	// IPv6 check.
248
+	if (!empty($low[5]))
249
+		return range2ip_ipv6($low, $high);
250
+
251
+]]></add>
252
+
253
+		</operation>
254
+
255
+		<operation>
256
+
257
+			<search position="after"><![CDATA[function checkExistingTriggerIP($ip_array, $fullip = '')
258
+{
259
+	global $smcFunc, $scripturl;
260
+
261
+]]></search>
262
+
263
+			<add><![CDATA[function range2ip_ipv6($low, $high)
264
+{
265
+	if (count($low) != 8 || count($high) != 8)
266
+		return '';
267
+
268
+	$ip = array();
269
+	for ($i = 0; $i < 8; $i++)
270
+	{
271
+		if ($low[$i] == $high[$i])
272
+			$ip[$i] = dechex($low[$i]);
273
+		elseif ($low[$i] == '0' && $high[$i] == '255')
274
+			$ip[$i] = '*';
275
+		else
276
+			$ip[$i] = dechex($low[$i]) . '-' . dechex($high[$i]);
277
+	}
278
+
279
+	return implode(':', $ip);
280
+}
281
+
282
+]]></add>
283
+
284
+		</operation>
285
+
286
+		<operation>
287
+
288
+			<search position="replace"><![CDATA[	if (count($ip_array) == 4)
289
+]]></search>
290
+
291
+			<add><![CDATA[	if (count($ip_array) == 4 || count($ip_array) == 8)
292
+]]></add>
293
+
294
+		</operation>
295
+
296
+		<operation>
297
+
298
+			<search position="after"><![CDATA[		);
299
+	else
300
+		return false;
301
+]]></search>
302
+
303
+			<add><![CDATA[			'ip_low5' => $ip_array[4]['low'],
304
+			'ip_high5' => $ip_array[4]['high'],
305
+			'ip_low6' => $ip_array[5]['low'],
306
+			'ip_high6' => $ip_array[5]['high'],
307
+			'ip_low7' => $ip_array[6]['low'],
308
+			'ip_high7' => $ip_array[6]['high'],
309
+			'ip_low8' => $ip_array[7]['low'],
310
+			'ip_high8' => $ip_array[7]['high'],
311
+]]></add>
312
+
313
+		</operation>
314
+
315
+		<operation>
316
+
317
+			<search position="after"><![CDATA[		LIMIT 1',
318
+		$values
319
+	);
320
+]]></search>
321
+
322
+			<add><![CDATA[			AND ip_low5 = {int:ip_low5} AND ip_high5 = {int:ip_high5}
323
+			AND ip_low6 = {int:ip_low6} AND ip_high6 = {int:ip_high6}
324
+			AND ip_low7 = {int:ip_low7} AND ip_high7 = {int:ip_high7}
325
+			AND ip_low8 = {int:ip_low8} AND ip_high8 = {int:ip_high8}
326
+]]></add>
327
+
328
+		</operation>
329
+
330
+	</file>
331
+
332
+	<file name="$sourcedir/QueryString.php">
333
+
334
+		<operation>
335
+
336
+			<search position="replace"><![CDATA[		$_SERVER['REMOTE_ADDR'] = 'unknown';
337
+]]></search>
338
+
339
+			<add><![CDATA[	{
340
+		// !! ADDED
341
+		// Wait, maybe its IPv6? This is not pretty.
342
+		if (preg_match('~^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$~', $_SERVER['REMOTE_ADDR']) === 0)
343
+			$_SERVER['REMOTE_ADDR'] = 'unknown';
344
+	}
345
+]]></add>
346
+
347
+		</operation>
348
+
349
+		<operation>
350
+
351
+			<search position="replace"><![CDATA[	if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0))
352
+]]></search>
353
+
354
+			<add><![CDATA[	if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0))
355
+]]></add>
356
+
357
+		</operation>
358
+
359
+		<operation>
360
+
361
+			<search position="replace"><![CDATA[	if (!empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0))
362
+]]></search>
363
+
364
+			<add><![CDATA[	if (!empty($_SERVER['HTTP_CLIENT_IP']) && (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_CLIENT_IP']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0))
365
+]]></add>
366
+
367
+		</operation>
368
+
369
+		<operation>
370
+
371
+			<search position="replace"><![CDATA[				if (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $ip) != 0 && preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) == 0)
372
+]]></search>
373
+
374
+			<add><![CDATA[				if (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $ip) != 0 && preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) == 0)
375
+]]></add>
376
+
377
+		</operation>
378
+
379
+		<operation>
380
+
381
+			<search position="replace"><![CDATA[		elseif (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['HTTP_X_FORWARDED_FOR']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown)~', $_SERVER['REMOTE_ADDR']) != 0)
382
+]]></search>
383
+
384
+			<add><![CDATA[		elseif (preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['HTTP_X_FORWARDED_FOR']) == 0 || preg_match('~^((0|10|172\.(1[6-9]|2[0-9]|3[01])|192\.168|255|127)\.|unknown|::1|fe80::|fc00::)~', $_SERVER['REMOTE_ADDR']) != 0)
385
+]]></add>
386
+
387
+		</operation>
388
+
389
+		<operation>
390
+
391
+			<search position="replace"><![CDATA[		$_SERVER['BAN_CHECK_IP'] = '';
392
+]]></search>
393
+
394
+			<add><![CDATA[	{
395
+		// Wait, maybe its IPv6? This is not pretty.
396
+		if (preg_match('~^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$~', $_SERVER['BAN_CHECK_IP']) === 0)
397
+			$_SERVER['BAN_CHECK_IP'] = '';
398
+	}
399
+]]></add>
400
+
401
+		</operation>
402
+
403
+		<operation>
404
+
405
+			<search position="after"><![CDATA[?>
406
+]]></search>
407
+
408
+			<add><![CDATA[// Working with them as if they where IPv4 numbers, makes it SMF compatible.
409
+function smf_ipv6_to_ints($ip)
410
+{
411
+	// Expand the IP out.
412
+	$ip = explode(':', smf_ipv6_expand($ip));
413
+
414
+	$new_ip = array();
415
+	foreach ($ip as $int)
416
+		$new_ip[] = hexdec($int);
417
+
418
+	return implode($new_ip, '-');
419
+}
420
+
421
+
422
+/**
423
+ * IPv6 Address Functions for PHP
424
+ *
425
+ * Functions to manipulate IPv6 addresses for PHP
426
+ *
427
+ * Copyright (C) 2009 Ray Patrick Soucy
428
+ *
429
+ * LICENSE:
430
+ *
431
+ * This program is free software: you can redistribute it and/or modify
432
+ * it under the terms of the GNU General Public License as published by
433
+ * the Free Software Foundation, either version 3 of the License, or
434
+ * (at your option) any later version.
435
+ *
436
+ * This program is distributed in the hope that it will be useful,
437
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
438
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
439
+ * GNU General Public License for more details.
440
+ *
441
+ * You should have received a copy of the GNU General Public License
442
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
443
+ *
444
+ * @package   inet6
445
+ * @author    Ray Soucy <rps@soucy.org>
446
+ * @version   1.0.1
447
+ * @copyright 2009 Ray Patrick Soucy 
448
+ * @link      http://www.soucy.org/
449
+ * @license   GNU General Public License version 3 or later
450
+ * @since     File available since Release 1.0.1
451
+ */
452
+function smf_ipv6_expand($addr, $strict_check = true)
453
+{
454
+	/* Check if there are segments missing, insert if necessary */
455
+	if (strpos($addr, '::') !== false)
456
+	{
457
+		$part = explode('::', $addr);
458
+		$part[0] = explode(':', $part[0]);
459
+		$part[1] = explode(':', $part[1]);
460
+		$missing = array();
461
+		for ($i = 0; $i < (8 - (count($part[0]) + count($part[1]))); $i++)
462
+			array_push($missing, '0000');
463
+		$missing = array_merge($part[0], $missing);
464
+		$part = array_merge($missing, $part[1]);
465
+	}
466
+	else
467
+		$part = explode(":", $addr);
468
+
469
+	/* Pad each segment until it has 4 digits */
470
+	foreach ($part as &$p)
471
+		while (strlen($p) < 4)
472
+			$p = '0' . $p;
473
+
474
+	unset($p);
475
+
476
+    /* Join segments */
477
+	$result = implode(':', $part);
478
+
479
+	/* Quick check to make sure the length is as expected */ 
480
+	if (!$strict_check || strlen($result) == 39)
481
+		return $result;
482
+	else
483
+		return false;
484
+}
485
+
486
+]]></add>
487
+
488
+		</operation>
489
+
490
+	</file>
491
+
492
+	<file name="$sourcedir/Security.php">
493
+
494
+		<operation>
495
+
496
+			<search position="after"><![CDATA[			// We use '255.255.255.255' for 'unknown' since it's not valid anyway.
497
+			elseif ($user_info['ip'] == 'unknown')
498
+				$ban_query[] = '(bi.ip_low1 = 255 AND bi.ip_high1 = 255
499
+]]></search>
500
+
501
+			<add><![CDATA[			// Again, the IP was validated, why use regex when we can split.
502
+			elseif (strpos($user_info[$ip_number], ':') !== false)
503
+			{
504
+				if ($ip_number == 'ip2' && $user_info['ip2'] == $user_info['ip'])
505
+					continue;
506
+
507
+				$ip_parts = array_map('hexdec', explode(':', smf_ipv6_expand($user_info[$ip_number])));
508
+
509
+				$ban_query[] = '((' . $ip_parts[0] . ' BETWEEN bi.ip_low1 AND bi.ip_high1)
510
+							AND (' . $ip_parts[1] . ' BETWEEN bi.ip_low2 AND bi.ip_high2)
511
+							AND (' . $ip_parts[2] . ' BETWEEN bi.ip_low3 AND bi.ip_high3)
512
+							AND (' . $ip_parts[3] . ' BETWEEN bi.ip_low4 AND bi.ip_high4)
513
+							AND (' . $ip_parts[4] . ' BETWEEN bi.ip_low5 AND bi.ip_high5)
514
+							AND (' . $ip_parts[5] . ' BETWEEN bi.ip_low6 AND bi.ip_high6)
515
+							AND (' . $ip_parts[6] . ' BETWEEN bi.ip_low7 AND bi.ip_high7)
516
+							AND (' . $ip_parts[7] . ' BETWEEN bi.ip_low8 AND bi.ip_high8))';
517
+
518
+				// IP was valid, maybe there's also a hostname...
519
+				if (empty($modSettings['disableHostnameLookup']))
520
+				{
521
+					$hostname = host_from_ip($user_info[$ip_number]);
522
+					if (strlen($hostname) > 0)
523
+					{
524
+						$ban_query[] = '({string:hostname} LIKE bi.hostname)';
525
+						$ban_query_vars['hostname'] = $hostname;
526
+					}
527
+				}
528
+			}
529
+]]></add>
530
+
531
+		</operation>
532
+
533
+	</file>
534
+
535
+	<file name="$sourcedir/Profile-View.php">
536
+
537
+		<operation>
538
+
539
+			<search position="replace"><![CDATA[	if (preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/', $context['ip']) == 0)
540
+]]></search>
541
+
542
+			<add><![CDATA[	if (preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/', $context['ip']) == 0 && preg_match('~^((([0-9A-Fa-f*]{1,4}:){7}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){6}:[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){5}:([0-9A-Fa-f*]{1,4}:)?[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){4}:([0-9A-Fa-f*]{1,4}:){0,2}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){3}:([0-9A-Fa-f*]{1,4}:){0,3}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){2}:([0-9A-Fa-f*]{1,4}:){0,4}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f*]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f*]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f*]{1,4}::([0-9A-Fa-f*]{1,4}:){0,5}[0-9A-Fa-f*]{1,4})|(::([0-9A-Fa-f*]{1,4}:){0,6}[0-9A-Fa-f*]{1,4})|(([0-9A-Fa-f*]{1,4}:){1,7}:))$~', $context['ip']) == 0)
543
+]]></add>
544
+
545
+		</operation>
546
+
547
+	</file>
548
+
549
+	<file name="$sourcedir/Subs.php">
550
+
551
+		<operation>
552
+
553
+			<search position="after"><![CDATA[	// Pretend that 'unknown' is 255.255.255.255. (since that can't be an IP anyway.)
554
+	if ($fullip == 'unknown')
555
+		$fullip = '255.255.255.255';
556
+]]></search>
557
+
558
+			<add><![CDATA[	if (strpos($fullip, ':') !== false)
559
+		return ip2range_ipv6($fullip);
560
+
561
+]]></add>
562
+
563
+		</operation>
564
+
565
+		<operation>
566
+
567
+			<search position="after"><![CDATA[	return $ip_array;
568
+}
569
+
570
+]]></search>
571
+
572
+			<add><![CDATA[
573
+	// Makes it simpiler to work with.
574
+	$ip_array[5] = array('low' => 0, 'high' => 0);
575
+	$ip_array[6] = array('low' => 0, 'high' => 0);
576
+	$ip_array[7] = array('low' => 0, 'high' => 0);
577
+	$ip_array[8] = array('low' => 0, 'high' => 0);
578
+
579
+]]></add>
580
+
581
+		</operation>
582
+
583
+		<operation>
584
+
585
+			<search position="after"><![CDATA[// Lookup an IP; try shell_exec first because we can do a timeout on it.
586
+function host_from_ip($ip)
587
+{]]></search>
588
+
589
+			<add><![CDATA[// Convert a single IPv6 to a ranged IPv6.
590
+function ip2range_ipv6($fullip)
591
+{
592
+	$ip_parts = explode(':', smf_ipv6_expand($fullip, false));
593
+	$ip_array = array();
594
+
595
+	if (count($ip_parts) != 8)
596
+		return array();
597
+
598
+	for ($i = 0; $i < 8; $i++)
599
+	{
600
+		if ($ip_parts[$i] == '*')
601
+			$ip_array[$i] = array('low' => '0', 'high' => hexdec('ffff'));
602
+		elseif (preg_match('/^([0-9A-Fa-f]{1,4})\-([0-9A-Fa-f]{1,4})$/', $ip_parts[$i], $range) == 1)
603
+			$ip_array[$i] = array('low' => hexdec($range[1]), 'high' => hexdec($range[2]));
604
+		elseif (is_numeric(hexdec($ip_parts[$i])))
605
+			$ip_array[$i] = array('low' => hexdec($ip_parts[$i]), 'high' => hexdec($ip_parts[$i]));
606
+	}
607
+
608
+	return $ip_array;
609
+}
610
+
611
+]]></add>
612
+
613
+		</operation>
614
+
615
+	</file>
616
+
617
+</modification>
0 618
\ No newline at end of file
1 619
new file mode 100755
... ...
@@ -0,0 +1,17 @@
0
+<?xml version="1.0"?>
1
+<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info">
2
+<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/">
3
+	<id>SleePy:ipv6_support</id>
4
+	<name>IPv6 Support</name>
5
+	<version>1.0</version>
6
+	<type>modification</type>
7
+	<install for="2.0-2.0.99">
8
+		<readme>README.txt</readme>
9
+		<modification>ipv6.xml</modification>
10
+		<database>database_install.php</database>
11
+	</install>
12
+	<uninstall for="2.0-2.0.99">
13
+		<modification reverse="true">ipv6.xml</modification>
14
+		<database>database_remove.php</database>
15
+	</uninstall>
16
+</package-info>
0 17
\ No newline at end of file