Importing SMF IPv6 mod
Jeremy D

Jeremy D commited on 2011-09-28 12:07:14
Showing 6 changed files, with 841 additions and 0 deletions.

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